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

Vrml2DisplayDevice.C

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

Generated on Sat May 26 01:48:40 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002