Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages

Vrml2DisplayDevice.C

Go to the documentation of this file.
00001 /***************************************************************************
00002 *cr 
00003 *cr (C) Copyright 1995-2019 The Board of Trustees of the 
00004 *cr University of Illinois 
00005 *cr All Rights Reserved 
00006 *cr 
00007 ***************************************************************************/
00008 /***************************************************************************
00009 * RCS INFORMATION:
00010 *
00011 * $RCSfile: Vrml2DisplayDevice.C,v $
00012 * $Author: johns $ $Locker: $ $State: Exp $
00013 * $Revision: 1.47 $ $Date: 2020年07月01日 06:09:05 $
00014 *
00015 ***************************************************************************/
00027 #include <math.h>
00028 #include <stdlib.h>
00029 #include <stdio.h>
00030 #include <string.h>
00031 #include "Vrml2DisplayDevice.h"
00032 #include "Matrix4.h"
00033 #include "utilities.h"
00034 #include "DispCmds.h" // needed for line styles
00035 #include "Hershey.h" // needed for Hershey font rendering fctns
00036 
00037 // The default radius for points and lines (which are displayed
00038 // as small spheres or cylinders, respectively)
00039 #define DEFAULT_RADIUS 0.002f
00040 #define DASH_LENGTH 0.02f
00041 
00043 
00044 // constructor ... initialize some variables
00045 Vrml2DisplayDevice::Vrml2DisplayDevice(void) : 
00046 FileRenderer("VRML-2", "VRML 2.0 (VRML97)", "vmdscene.wrl", "true") {
00047 }
00048 
00050 void Vrml2DisplayDevice::set_color(int mycolorIndex) {
00051 #if 0
00052 write_cindexmaterial(mycolorIndex, materialIndex);
00053 #endif
00054 }
00055 
00056 
00057 void Vrml2DisplayDevice::text(float *pos, float size, float thickness,
00058 const char *str) {
00059 float textpos[3];
00060 hersheyhandle hh;
00061 
00062 // transform the world coordinates
00063 (transMat.top()).multpoint3d(pos, textpos);
00064 float textsize = size * 1.5f;
00065 // XXX text thickness not usable with VRML2 since we don't have a line
00066 // thickness parameter when drawing indexed line sets, apparently...
00067 // float textthickness = thickness*DEFAULT_RADIUS;
00068 
00069 while (*str != '0円') {
00070 float lm, rm, x, y, ox, oy;
00071 int draw, odraw;
00072 ox=oy=x=y=0.0f;
00073 draw=odraw=0;
00074 
00075 hersheyDrawInitLetter(&hh, *str, &lm, &rm);
00076 textpos[0] -= lm * textsize;
00077 
00078 while (!hersheyDrawNextLine(&hh, &draw, &x, &y)) {
00079 float oldpt[3], newpt[3];
00080 if (draw) {
00081 newpt[0] = textpos[0] + textsize * x;
00082 newpt[1] = textpos[1] + textsize * y;
00083 newpt[2] = textpos[2];
00084 
00085 if (odraw) {
00086 // if we have both previous and next points, connect them...
00087 oldpt[0] = textpos[0] + textsize * ox;
00088 oldpt[1] = textpos[1] + textsize * oy;
00089 oldpt[2] = textpos[2];
00090 
00091 // ugly and wasteful, but it will work
00092 fprintf(outfile, "Shape {\n");
00093 fprintf(outfile, " ");
00094 write_cindexmaterial(colorIndex, materialIndex);
00095 fprintf(outfile, " geometry IndexedLineSet { \n");
00096 fprintf(outfile, " coordIndex [ 0, 1, -1 ]\n");
00097 fprintf(outfile, " coord Coordinate { point [ %g %g %g, %g %g %g ] }\n",
00098 oldpt[0], oldpt[1], oldpt[2], newpt[0], newpt[1], newpt[2]);
00099 
00100 float col[3];
00101 vec_copy(col, matData[colorIndex]);
00102 fprintf(outfile, " color Color { color [ %.3f %.3f %.3f, %.3f %.3f %.3f ] }\n",
00103 col[0], col[1], col[2], col[0], col[1], col[2]);
00104 fprintf(outfile, " }\n");
00105 fprintf(outfile, "}\n");
00106 }
00107 }
00108 
00109 ox=x;
00110 oy=y;
00111 odraw=draw;
00112 }
00113 textpos[0] += rm * textsize;
00114 
00115 str++;
00116 }
00117 }
00118 
00119 
00120 // draw a sphere
00121 void Vrml2DisplayDevice::sphere(float *xyzr) {
00122 float cent[3], radius;
00123 
00124 // transform the coordinates
00125 (transMat.top()).multpoint3d(xyzr, cent);
00126 radius = scale_radius(xyzr[3]);
00127 
00128 fprintf(outfile, "Transform {\n");
00129 fprintf(outfile, " translation %g %g %g\n", cent[0], cent[1], cent[2]);
00130 fprintf(outfile, " children [ Shape {\n");
00131 fprintf(outfile, " ");
00132 write_cindexmaterial(colorIndex, materialIndex);
00133 fprintf(outfile, " geometry Sphere { radius %g }\n", radius);
00134 fprintf(outfile, " }]\n");
00135 fprintf(outfile, "}\n");
00136 }
00137 
00138 
00139 // draw a point
00140 void Vrml2DisplayDevice::point(float * xyz) {
00141 float txyz[3];
00142 
00143 // transform the coordinates
00144 (transMat.top()).multpoint3d(xyz, txyz);
00145 
00146 // ugly and wasteful, but it will work
00147 fprintf(outfile, "Shape {\n");
00148 fprintf(outfile, " ");
00149 write_cindexmaterial(colorIndex, materialIndex);
00150 
00151 fprintf(outfile, " geometry PointSet { \n");
00152 fprintf(outfile, " coord Coordinate { point [%g %g %g] }\n",
00153 txyz[0], txyz[1], txyz[2]);
00154 
00155 float col[3];
00156 vec_copy(col, matData[colorIndex]);
00157 fprintf(outfile, " color Color { color [%.3f %.3f %.3f] }\n",
00158 col[0], col[1], col[2]);
00159 fprintf(outfile, " }\n");
00160 fprintf(outfile, "}\n");
00161 }
00162 
00163 
00166 void Vrml2DisplayDevice::line(float *a, float*b) {
00167 float ta[3], tb[3];
00168 
00169 if (lineStyle == ::SOLIDLINE) {
00170 // transform the coordinates
00171 (transMat.top()).multpoint3d(a, ta);
00172 (transMat.top()).multpoint3d(b, tb);
00173 
00174 // ugly and wasteful, but it will work
00175 fprintf(outfile, "Shape {\n");
00176 fprintf(outfile, " ");
00177 write_cindexmaterial(colorIndex, materialIndex);
00178 fprintf(outfile, " geometry IndexedLineSet { \n"); 
00179 fprintf(outfile, " coordIndex [ 0, 1, -1 ]\n");
00180 fprintf(outfile, " coord Coordinate { point [ %g %g %g, %g %g %g ] }\n",
00181 ta[0], ta[1], ta[2], tb[0], tb[1], tb[2]);
00182 
00183 float col[3];
00184 vec_copy(col, matData[colorIndex]);
00185 fprintf(outfile, " color Color { color [ %.3f %.3f %.3f, %.3f %.3f %.3f ] }\n", 
00186 col[0], col[1], col[2], col[0], col[1], col[2]);
00187 
00188 fprintf(outfile, " }\n");
00189 fprintf(outfile, "}\n");
00190 } else if (lineStyle == ::DASHEDLINE) {
00191 float dirvec[3], unitdirvec[3], tmp1[3], tmp2[3];
00192 int i, j, test;
00193 
00194 // transform the world coordinates
00195 (transMat.top()).multpoint3d(a, tmp1);
00196 (transMat.top()).multpoint3d(b, tmp2);
00197 
00198 // how to create a dashed line
00199 vec_sub(dirvec, tmp2, tmp1); // vector from a to b
00200 vec_copy(unitdirvec, dirvec);
00201 vec_normalize(unitdirvec); // unit vector from a to b
00202 test = 1;
00203 i = 0;
00204 while (test == 1) {
00205 for (j=0; j<3; j++) {
00206 ta[j] = (float) (tmp1[j] + (2*i )*DASH_LENGTH*unitdirvec[j]);
00207 tb[j] = (float) (tmp1[j] + (2*i + 1)*DASH_LENGTH*unitdirvec[j]);
00208 }
00209 if (fabsf(tmp1[0] - tb[0]) >= fabsf(dirvec[0])) {
00210 vec_copy(tb, tmp2);
00211 test = 0;
00212 }
00213 
00214 // ugly and wasteful, but it will work
00215 fprintf(outfile, "Shape {\n");
00216 fprintf(outfile, " ");
00217 write_cindexmaterial(colorIndex, materialIndex);
00218 fprintf(outfile, " geometry IndexedLineSet { \n"); 
00219 fprintf(outfile, " coordIndex [ 0, 1, -1 ]\n");
00220 fprintf(outfile, " coord Coordinate { point [ %g %g %g, %g %g %g ] }\n",
00221 ta[0], ta[1], ta[2], tb[0], tb[1], tb[2]);
00222 
00223 float col[3];
00224 vec_copy(col, matData[colorIndex]);
00225 fprintf(outfile, " color Color { color [ %.3f %.3f %.3f, %.3f %.3f %.3f ] }\n", 
00226 col[0], col[1], col[2], col[0], col[1], col[2]);
00227 
00228 fprintf(outfile, " }\n");
00229 fprintf(outfile, "}\n");
00230 i++;
00231 }
00232 } else {
00233 msgErr << "Vrml2DisplayDevice: Unknown line style "
00234 << lineStyle << sendmsg;
00235 }
00236 }
00237 
00238 
00239 // draw a cylinder
00240 void Vrml2DisplayDevice::cylinder(float *a, float *b, float r, int filled) {
00241 float ta[3], tb[3], radius;
00242 
00243 // transform the coordinates
00244 (transMat.top()).multpoint3d(a, ta);
00245 (transMat.top()).multpoint3d(b, tb);
00246 radius = scale_radius(r);
00247 
00248 cylinder_noxfrm(ta, tb, radius, filled);
00249 }
00250 
00251 
00252 void Vrml2DisplayDevice::cylinder_noxfrm(float *ta, float *tb, float radius, int filled) {
00253 if (ta[0] == tb[0] && ta[1] == tb[1] && ta[2] == tb[2]) {
00254 return; // we don't serve your kind here
00255 }
00256 
00257 float height = distance(ta, tb);
00258 
00259 fprintf(outfile, "Transform {\n");
00260 fprintf(outfile, " translation %g %g %g\n", 
00261 ta[0], ta[1] + (height / 2.0), ta[2]);
00262 
00263 float rotaxis[3];
00264 float cylaxdir[3];
00265 float yaxis[3] = {0.0, 1.0, 0.0};
00266 
00267 vec_sub(cylaxdir, tb, ta);
00268 vec_normalize(cylaxdir);
00269 float dp = dot_prod(yaxis, cylaxdir);
00270 
00271 cross_prod(rotaxis, cylaxdir, yaxis);
00272 vec_normalize(rotaxis);
00273 
00274 // if we have decent rotation vector, use it
00275 if ((rotaxis[0]*rotaxis[0] + 
00276 rotaxis[1]*rotaxis[1] + 
00277 rotaxis[2]*rotaxis[2]) > 0.5) { 
00278 fprintf(outfile, " center 0.0 %g 0.0\n", -(height / 2.0));
00279 fprintf(outfile, " rotation %g %g %g %g\n", 
00280 rotaxis[0], rotaxis[1], rotaxis[2], -acosf(dp));
00281 } else if (dp < -0.98) {
00282 // if we have denormalized rotation vector, we can assume it is
00283 // caused by a cylinder axis that is nearly coaxial with the Y axis.
00284 // If this is the case, we either perform no rotation in the case of a
00285 // angle cosine near 1.0, or a 180 degree rotation for a cosine near -1.
00286 fprintf(outfile, " center 0.0 %g 0.0\n", -(height / 2.0));
00287 fprintf(outfile, " rotation 0 0 -1 -3.14159\n");
00288 }
00289 
00290 fprintf(outfile, " children [ Shape {\n");
00291 fprintf(outfile, " ");
00292 write_cindexmaterial(colorIndex, materialIndex);
00293 
00294 #if 0
00295 // draw the cylinder
00296 fprintf(outfile, " geometry Cylinder { "
00297 "bottom %s height %g radius %g side %s top %s }\n", 
00298 filled ? "TRUE" : "FALSE",
00299 height, 
00300 radius, 
00301 "TRUE",
00302 filled ? "TRUE" : "FALSE");
00303 #else
00304 if (filled) {
00305 fprintf(outfile, " geometry Cylinder { "
00306 "height %g radius %g }\n", height, radius);
00307 } else {
00308 fprintf(outfile, " geometry VMDCyl { "
00309 "h %g r %g }\n", height, radius);
00310 }
00311 #endif
00312 
00313 fprintf(outfile, " }]\n");
00314 fprintf(outfile, "}\n");
00315 }
00316 
00317 
00318 void Vrml2DisplayDevice::cone(float *a, float *b, float r, int /* resolution */) {
00319 float ta[3], tb[3], radius;
00320 
00321 if (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]) {
00322 return; // we don't serve your kind here
00323 }
00324 
00325 // transform the coordinates
00326 (transMat.top()).multpoint3d(a, ta);
00327 (transMat.top()).multpoint3d(b, tb);
00328 radius = scale_radius(r);
00329 
00330 float height = distance(ta, tb);
00331 
00332 fprintf(outfile, "Transform {\n");
00333 fprintf(outfile, " translation %g %g %g\n", 
00334 ta[0], ta[1] + (height / 2.0), ta[2]);
00335 
00336 float rotaxis[3];
00337 float cylaxdir[3];
00338 float yaxis[3] = {0.0, 1.0, 0.0};
00339 
00340 vec_sub(cylaxdir, tb, ta);
00341 vec_normalize(cylaxdir);
00342 float dp = dot_prod(yaxis, cylaxdir);
00343 
00344 cross_prod(rotaxis, cylaxdir, yaxis);
00345 vec_normalize(rotaxis);
00346 
00347 if ((rotaxis[0]*rotaxis[0] + 
00348 rotaxis[1]*rotaxis[1] + 
00349 rotaxis[2]*rotaxis[2]) > 0.5) { 
00350 fprintf(outfile, " center 0.0 %g 0.0\n", -(height / 2.0));
00351 fprintf(outfile, " rotation %g %g %g %g\n", 
00352 rotaxis[0], rotaxis[1], rotaxis[2], -acosf(dp));
00353 }
00354 
00355 fprintf(outfile, " children [ Shape {\n");
00356 fprintf(outfile, " ");
00357 write_cindexmaterial(colorIndex, materialIndex);
00358 
00359 // draw the cone
00360 fprintf(outfile, " geometry Cone { bottomRadius %g height %g }\n", 
00361 radius, height);
00362 
00363 fprintf(outfile, " }]\n");
00364 fprintf(outfile, "}\n");
00365 }
00366 
00367 
00368 // draw a triangle
00369 void Vrml2DisplayDevice::triangle(const float *a, const float *b, const float *c, 
00370 const float *n1, const float *n2, const float *n3) {
00371 float ta[3], tb[3], tc[3], tn1[3], tn2[3], tn3[3];
00372 
00373 // transform the world coordinates
00374 (transMat.top()).multpoint3d(a, ta);
00375 (transMat.top()).multpoint3d(b, tb);
00376 (transMat.top()).multpoint3d(c, tc);
00377 
00378 // and the normals
00379 (transMat.top()).multnorm3d(n1, tn1);
00380 (transMat.top()).multnorm3d(n2, tn2);
00381 (transMat.top()).multnorm3d(n3, tn3);
00382 
00383 // ugly and wasteful, but it will work
00384 fprintf(outfile, "Shape {\n");
00385 fprintf(outfile, " ");
00386 write_cindexmaterial(colorIndex, materialIndex);
00387 fprintf(outfile, " geometry IndexedFaceSet { \n"); 
00388 fprintf(outfile, " solid FALSE coordIndex [ 0, 1, 2, -1 ]\n");
00389 fprintf(outfile, " coord Coordinate { point [ %g %g %g, %g %g %g, %g %g %g ] }\n",
00390 ta[0], ta[1], ta[2], tb[0], tb[1], tb[2], tc[0], tc[1], tc[2]);
00391 
00392 fprintf(outfile, " normal Normal { vector [ %g %g %g, %g %g %g, %g %g %g ] }\n",
00393 tn1[0], tn1[1], tn1[2], tn2[0], tn2[1], tn2[2], tn3[0], tn3[1], tn3[2]);
00394 
00395 fprintf(outfile, " }\n");
00396 fprintf(outfile, "}\n");
00397 }
00398 
00399 
00400 // draw a color-per-vertex triangle
00401 void Vrml2DisplayDevice::tricolor(const float * a, const float * b, const float * c, 
00402 const float * n1, const float * n2, const float * n3,
00403 const float *c1, const float *c2, const float *c3) {
00404 float ta[3], tb[3], tc[3], tn1[3], tn2[3], tn3[3];
00405 
00406 // transform the world coordinates
00407 (transMat.top()).multpoint3d(a, ta);
00408 (transMat.top()).multpoint3d(b, tb);
00409 (transMat.top()).multpoint3d(c, tc);
00410 
00411 // and the normals
00412 (transMat.top()).multnorm3d(n1, tn1);
00413 (transMat.top()).multnorm3d(n2, tn2);
00414 (transMat.top()).multnorm3d(n3, tn3);
00415 
00416 // ugly and wasteful, but it will work
00417 fprintf(outfile, "Shape {\n");
00418 fprintf(outfile, " ");
00419 write_cindexmaterial(colorIndex, materialIndex);
00420 fprintf(outfile, " geometry IndexedFaceSet { \n"); 
00421 fprintf(outfile, " solid FALSE coordIndex [ 0, 1, 2, -1 ]\n");
00422 fprintf(outfile, " coord Coordinate { point [ %g %g %g, %g %g %g, %g %g %g ] }\n",
00423 ta[0], ta[1], ta[2], tb[0], tb[1], tb[2], tc[0], tc[1], tc[2]);
00424 
00425 fprintf(outfile, " color Color { color [ %.3f %.3f %.3f, %.3f %.3f %.3f, %.3f %.3f %.3f ] }\n", 
00426 c1[0], c1[1], c1[2], c2[0], c2[1], c2[2], c3[0], c3[1], c3[2]);
00427 
00428 fprintf(outfile, " normal Normal { vector [ %.3f %.3f %.3f, %.3f %.3f %.3f, %.3f %.3f %.3f ] }\n",
00429 tn1[0], tn1[1], tn1[2], tn2[0], tn2[1], tn2[2], tn3[0], tn3[1], tn3[2]);
00430 
00431 fprintf(outfile, " }\n");
00432 fprintf(outfile, "}\n");
00433 }
00434 
00435 
00436 // use an efficient mesh primitve rather than individual triangles
00437 // when possible.
00438 void Vrml2DisplayDevice::trimesh_c4n3v3(int numverts, float * cnv,
00439 int numfacets, int * facets) {
00440 int i;
00441 
00442 fprintf(outfile, "Shape {\n");
00443 fprintf(outfile, " ");
00444 write_cindexmaterial(colorIndex, materialIndex);
00445 fprintf(outfile, " geometry IndexedFaceSet { \n"); 
00446 
00447 // loop over all of the facets in the mesh
00448 fprintf(outfile, " coordIndex [ ");
00449 for (i=0; i<numfacets*3; i+=3) {
00450 fprintf(outfile, "%c %d, %d, %d, -1", (i==0) ? ' ' : ',',
00451 facets[i], facets[i+1], facets[i+2]);
00452 }
00453 fprintf(outfile, " ]\n");
00454 
00455 // loop over all of the vertices
00456 fprintf(outfile, " coord Coordinate { point [ ");
00457 for (i=0; i<numverts; i++) {
00458 const float *v = cnv + i*10 + 7;
00459 float tv[3];
00460 (transMat.top()).multpoint3d(v, tv);
00461 fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', tv[0], tv[1], tv[2]);
00462 }
00463 fprintf(outfile, " ] }\n");
00464 
00465 // loop over all of the colors
00466 fprintf(outfile, " color Color { color [ ");
00467 for (i=0; i<numverts; i++) {
00468 const float *c = cnv + i*10;
00469 fprintf(outfile, "%c %.3f %.3f %.3f", (i==0) ? ' ' : ',', c[0], c[1], c[2]);
00470 }
00471 fprintf(outfile, " ] }\n");
00472 
00473 // loop over all of the normals
00474 fprintf(outfile, " normal Normal { vector [ ");
00475 for (i=0; i<numverts; i++) {
00476 const float *n = cnv + i*10 + 4;
00477 float tn[3];
00478 (transMat.top()).multnorm3d(n, tn);
00479 fprintf(outfile, "%c %.3f %.3f %.3f", (i==0) ? ' ' : ',', tn[0], tn[1], tn[2]);
00480 }
00481 fprintf(outfile, " ] }\n");
00482 
00483 // close the IndexedFaceSet node
00484 fprintf(outfile, " }\n");
00485 
00486 // close the shape node
00487 fprintf(outfile, "}\n");
00488 }
00489 
00490 
00491 // use an efficient mesh primitve rather than individual triangles
00492 // when possible.
00493 void Vrml2DisplayDevice::trimesh_c4u_n3b_v3f(unsigned char *c, 
00494 signed char *n, 
00495 float *v, int numfacets) {
00496 int i;
00497 int numverts = 3*numfacets;
00498 
00499 const float ci2f = 1.0f / 255.0f; // used for uchar2float and normal conv
00500 const float cn2f = 1.0f / 127.5f;
00501 
00502 fprintf(outfile, "Shape {\n");
00503 fprintf(outfile, " ");
00504 write_cindexmaterial(colorIndex, materialIndex);
00505 fprintf(outfile, " geometry IndexedFaceSet { \n"); 
00506 
00507 // loop over all of the facets in the mesh
00508 fprintf(outfile, " coordIndex [ ");
00509 for (i=0; i<numfacets*3; i+=3) {
00510 fprintf(outfile, "%c %d, %d, %d, -1", (i==0) ? ' ' : ',', i, i+1, i+2);
00511 }
00512 fprintf(outfile, " ]\n");
00513 
00514 // loop over all of the vertices
00515 fprintf(outfile, " coord Coordinate { point [ ");
00516 for (i=0; i<numverts; i++) {
00517 float tv[3];
00518 int idx = i * 3;
00519 (transMat.top()).multpoint3d(&v[idx], tv);
00520 fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', tv[0], tv[1], tv[2]);
00521 }
00522 fprintf(outfile, " ] }\n");
00523 
00524 // loop over all of the colors
00525 fprintf(outfile, " color Color { color [ ");
00526 for (i=0; i<numverts; i++) {
00527 int idx = i * 4;
00528 
00529 // conversion from GLubyte format, Table 2.6, p. 44 of OpenGL spec 1.2.1
00530 // float = c/(2^8-1)
00531 fprintf(outfile, "%c %.3f %.3f %.3f",
00532 (i==0) ? ' ' : ',',
00533 c[idx ] * ci2f,
00534 c[idx+1] * ci2f,
00535 c[idx+2] * ci2f);
00536 }
00537 fprintf(outfile, " ] }\n");
00538 
00539 // loop over all of the normals
00540 fprintf(outfile, " normal Normal { vector [ ");
00541 for (i=0; i<numverts; i++) {
00542 float tn[3], ntmp[3];
00543 int idx = i * 3;
00544 
00545 // conversion from GLbyte format, Table 2.6, p. 44 of OpenGL spec 1.2.1
00546 // float = (2c+1)/(2^8-1)
00547 ntmp[0] = n[idx ] * cn2f + ci2f;
00548 ntmp[1] = n[idx+1] * cn2f + ci2f;
00549 ntmp[2] = n[idx+2] * cn2f + ci2f;
00550 
00551 (transMat.top()).multnorm3d(ntmp, tn);
00552 fprintf(outfile, "%c %.2f %.2f %.2f", (i==0) ? ' ' : ',', tn[0], tn[1], tn[2]);
00553 }
00554 fprintf(outfile, " ] }\n");
00555 
00556 // close the IndexedFaceSet node
00557 fprintf(outfile, " }\n");
00558 
00559 // close the shape node
00560 fprintf(outfile, "}\n");
00561 }
00562 
00563 
00564 // use an efficient mesh primitve rather than individual triangles
00565 // when possible.
00566 void Vrml2DisplayDevice::tristrip(int numverts, const float * cnv,
00567 int numstrips, const int *vertsperstrip,
00568 const int *facets) {
00569 int i;
00570 // render triangle strips one triangle at a time
00571 // triangle winding order is:
00572 // v0, v1, v2, then v2, v1, v3, then v2, v3, v4, etc.
00573 int strip, v = 0;
00574 int stripaddr[2][3] = { {0, 1, 2}, {1, 0, 2} };
00575 
00576 fprintf(outfile, "Shape {\n");
00577 fprintf(outfile, " ");
00578 write_cindexmaterial(colorIndex, materialIndex);
00579 fprintf(outfile, " geometry IndexedFaceSet { \n"); 
00580 
00581 // loop over all of the facets in the mesh
00582 // emit vertex indices for each facet
00583 fprintf(outfile, " coordIndex [ ");
00584 for (strip=0; strip < numstrips; strip++) {
00585 for (i=0; i<(vertsperstrip[strip] - 2); i++) {
00586 // render one triangle, using lookup table to fix winding order
00587 fprintf(outfile, "%c %d, %d, %d, -1", (i==0) ? ' ' : ',',
00588 facets[v + (stripaddr[i & 0x01][0])],
00589 facets[v + (stripaddr[i & 0x01][1])],
00590 facets[v + (stripaddr[i & 0x01][2])]);
00591 v++; // move on to next vertex
00592 }
00593 v+=2; // last two vertices are already used by last triangle
00594 }
00595 fprintf(outfile, " ]\n");
00596 
00597 // loop over all of the vertices
00598 fprintf(outfile, " coord Coordinate { point [ ");
00599 for (i=0; i<numverts; i++) {
00600 const float *v = cnv + i*10 + 7;
00601 float tv[3];
00602 (transMat.top()).multpoint3d(v, tv);
00603 fprintf(outfile, "%c %g %g %g", (i==0) ? ' ' : ',', tv[0], tv[1], tv[2]);
00604 }
00605 fprintf(outfile, " ] }\n");
00606 
00607 // loop over all of the colors
00608 fprintf(outfile, " color Color { color [ ");
00609 for (i=0; i<numverts; i++) {
00610 const float *c = cnv + i*10;
00611 fprintf(outfile, "%c %.3f %.3f %.3f", (i==0) ? ' ' : ',', c[0], c[1], c[2]);
00612 }
00613 fprintf(outfile, " ] }\n");
00614 
00615 // loop over all of the normals
00616 fprintf(outfile, " normal Normal { vector [ ");
00617 for (i=0; i<numverts; i++) {
00618 const float *n = cnv + i*10 + 4;
00619 float tn[3];
00620 (transMat.top()).multnorm3d(n, tn);
00621 fprintf(outfile, "%c %.3f %.3f %.3f", (i==0) ? ' ' : ',', tn[0], tn[1], tn[2]);
00622 }
00623 fprintf(outfile, " ] }\n");
00624 
00625 // close the IndexedFaceSet node
00626 fprintf(outfile, " }\n");
00627 
00628 // close the shape node
00629 fprintf(outfile, "}\n");
00630 }
00631 
00632 
00633 void Vrml2DisplayDevice::multmatrix(const Matrix4 &mat) {
00634 }
00635 
00636 
00637 void Vrml2DisplayDevice::load(const Matrix4 &mat) {
00638 }
00639 
00640 
00641 void Vrml2DisplayDevice::comment(const char *s) {
00642 fprintf (outfile, "# %s\n", s);
00643 }
00644 
00646 
00647 // initialize the file for output
00648 void Vrml2DisplayDevice::write_header(void) {
00649 fprintf(outfile, "#VRML V2.0 utf8\n");
00650 fprintf(outfile, "# Created with VMD: "
00651 "http://www.ks.uiuc.edu/Research/vmd/\n");
00652 
00653 // define our special node types
00654 fprintf(outfile, "# Define some custom nodes VMD to decrease file size\n");
00655 fprintf(outfile, "# custom VMD cylinder node\n");
00656 fprintf(outfile, "PROTO VMDCyl [\n");
00657 fprintf(outfile, " field SFBool bottom FALSE\n");
00658 fprintf(outfile, " field SFFloat h 2 \n");
00659 fprintf(outfile, " field SFFloat r 1 \n");
00660 fprintf(outfile, " field SFBool side TRUE \n");
00661 fprintf(outfile, " field SFBool top FALSE\n");
00662 fprintf(outfile, " ] {\n");
00663 fprintf(outfile, " Cylinder {\n"); 
00664 fprintf(outfile, " bottom IS bottom\n");
00665 fprintf(outfile, " height IS h \n");
00666 fprintf(outfile, " radius IS r \n");
00667 fprintf(outfile, " top IS top \n");
00668 fprintf(outfile, " }\n");
00669 fprintf(outfile, "}\n\n");
00670 
00671 fprintf(outfile, "# custom VMD materials node\n");
00672 fprintf(outfile, "PROTO VMDMat [\n");
00673 fprintf(outfile, " field SFFloat Ka 0.0\n"); 
00674 fprintf(outfile, " field SFColor Kd 0.8 0.8 0.8\n");
00675 fprintf(outfile, " field SFColor emissiveColor 0.0 0.0 0.0\n");
00676 fprintf(outfile, " field SFFloat Ksx 0.0\n"); 
00677 fprintf(outfile, " field SFColor Ks 0.0 0.0 0.0\n");
00678 fprintf(outfile, " field SFFloat Kt 0.0\n"); 
00679 fprintf(outfile, " ] {\n");
00680 fprintf(outfile, " Appearance {\n");
00681 fprintf(outfile, " material Material {\n");
00682 fprintf(outfile, " ambientIntensity IS Ka \n");
00683 fprintf(outfile, " diffuseColor IS Kd \n");
00684 fprintf(outfile, " emissiveColor IS emissiveColor\n");
00685 fprintf(outfile, " shininess IS Ksx \n");
00686 fprintf(outfile, " specularColor IS Ks \n");
00687 fprintf(outfile, " transparency IS Kt \n");
00688 fprintf(outfile, " }\n");
00689 fprintf(outfile, " }\n");
00690 fprintf(outfile, "}\n\n");
00691 
00692 fprintf(outfile, "\n");
00693 fprintf(outfile, "# begin the actual scene\n");
00694 fprintf(outfile, "Group {\n");
00695 fprintf(outfile, " children [\n");
00696 
00697 if (backgroundmode == 1) {
00698 // emit background sky color gradient
00699 fprintf(outfile, "Background { skyColor [%g %g %g, %g %g %g, %g %g %g] ",
00700 backgradienttopcolor[0], // top pole
00701 backgradienttopcolor[1],
00702 backgradienttopcolor[2],
00703 (backgradienttopcolor[0]+backgradientbotcolor[0])/2.0f, // horizon
00704 (backgradientbotcolor[1]+backgradienttopcolor[1])/2.0f,
00705 (backgradienttopcolor[2]+backgradientbotcolor[2])/2.0f,
00706 backgradientbotcolor[0], // bottom pole
00707 backgradientbotcolor[1],
00708 backgradientbotcolor[2]);
00709 fprintf(outfile, "skyAngle [ 1.5, 3.0] }");
00710 } else {
00711 // otherwise emit constant color background sky
00712 fprintf(outfile, "Background { skyColor [ %g %g %g ] }",
00713 backColor[0], backColor[1], backColor[2]);
00714 }
00715 fprintf(outfile, "\n");
00716 }
00717 
00718 void Vrml2DisplayDevice::write_trailer(void) {
00719 fprintf(outfile, " ]\n");
00720 fprintf(outfile, "}\n");
00721 }
00722 
00723 void Vrml2DisplayDevice::write_cindexmaterial(int cindex, int material) {
00724 write_colormaterial((float *) &matData[cindex], material);
00725 }
00726 
00727 void Vrml2DisplayDevice::write_colormaterial(float *rgb, int) {
00728 
00729 #if 0
00730 // use the current material definition
00731 fprintf(outfile, " appearance Appearance {\n");
00732 fprintf(outfile, " material Material {\n"); 
00733 fprintf(outfile, " ambientIntensity %g\n", mat_ambient);
00734 fprintf(outfile, " diffuseColor %g %g %g\n",
00735 mat_diffuse * rgb[0],
00736 mat_diffuse * rgb[1],
00737 mat_diffuse * rgb[2]);
00738 fprintf(outfile, " shininess %g\n", mat_shininess);
00739 fprintf(outfile, " specularColor %g %g %g\n",
00740 mat_specular,
00741 mat_specular,
00742 mat_specular);
00743 fprintf(outfile, " transparency %g\n", 1.0 - mat_opacity);
00744 fprintf(outfile, " }\n");
00745 fprintf(outfile, " }\n");
00746 #else
00747 // use the current material definition
00748 fprintf(outfile, "appearance VMDMat { ");
00749 if (mat_ambient > 0.0) {
00750 fprintf(outfile, "Ka %g ", mat_ambient);
00751 } 
00752 
00753 fprintf(outfile, "Kd %g %g %g ",
00754 mat_diffuse * rgb[0],
00755 mat_diffuse * rgb[1],
00756 mat_diffuse * rgb[2]);
00757 
00758 if (mat_specular > 0.0) {
00759 fprintf(outfile, "Ksx %g ", mat_shininess);
00760 fprintf(outfile, "Ks %g %g %g ", mat_specular, mat_specular, mat_specular);
00761 }
00762 
00763 if (mat_opacity < 1.0) {
00764 fprintf(outfile, "Kt %g ", 1.0 - mat_opacity);
00765 }
00766 fprintf(outfile, " }\n");
00767 #endif
00768 }
00769 
00770 
00771 

Generated on Wed Nov 19 02:47:34 2025 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002

AltStyle によって変換されたページ (->オリジナル) /