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

RadianceDisplayDevice.C

Go to the documentation of this file.
00001 
00002 /***************************************************************************
00003  *cr                                                                       
00004  *cr            (C) Copyright 1995-2011 The Board of Trustees of the           
00005  *cr                        University of Illinois                       
00006  *cr                         All Rights Reserved                        
00007  *cr                                                                   
00008  ***************************************************************************/
00009 
00010 /***************************************************************************
00011  * RCS INFORMATION:
00012  *
00013  *      $RCSfile: RadianceDisplayDevice.C,v $
00014  *      $Author: johns $        $Locker:  $             $State: Exp $
00015  *      $Revision: 1.45 $       $Date: 2011/02/25 04:13:18 $
00016  *
00017  ***************************************************************************
00018  * DESCRIPTION:
00019  *  Writes to the format for Radiance.  For more information about that
00020  * package, see http://radsite.lbl.gov/radiance/HOME.html .  It provides
00021  * conversion programs to go from its format to something normal (eg,
00022  * ra_ps, ra_tiff, and ra_gif).
00023  *
00024  ***************************************************************************/
00025 #include <stdio.h>
00026 #include <string.h>
00027 #include <math.h>
00028 #include "RadianceDisplayDevice.h"
00029 #include "Matrix4.h"
00030 #include "DispCmds.h"
00031 #include "Inform.h"
00032 #include "utilities.h"
00033 
00034 #define DEFAULT_RADIUS 0.002
00035 #define DASH_LENGTH 0.02
00036 
00037 // Be careful when you modify the coordinates.  To make things view the
00038 // right way, I have to rotate everything around the (x,y,z) = (1,1,1)
00039 // vector so that x->z, y->x, and z->y
00040 
00041 #define ORDER(x,y,z) -z, -x, y
00042 
00044 
00045 // constructor ... initialize some variables
00046 RadianceDisplayDevice::RadianceDisplayDevice() 
00047 : FileRenderer("Radiance", "Radiance 4.0", "vmdscene.rad", 
00048  "oconv %s > %s.oct; rview -pe 100 -vp -3.5 0 0 -vd 1 0 0 %s.oct") {
00049   reset_vars(); // initialize state variables
00050 }
00051                
00052 //destructor
00053 RadianceDisplayDevice::~RadianceDisplayDevice(void) { }
00054 
00055 void RadianceDisplayDevice::reset_vars(void) {
00056   // clear out the r/g/b/t arrays
00057   red.clear();
00058   green.clear();
00059   blue.clear();
00060   trans.clear();
00061 
00062   cur_color = 0;
00063 }
00064 
00065 
00067 
00068 // draw a point
00069 void RadianceDisplayDevice::point(float * spdata) {
00070   float vec[3];
00071 
00072   // transform the world coordinates
00073   (transMat.top()).multpoint3d(spdata, vec);
00074    
00075   // draw the sphere
00076   set_color(colorIndex);
00077 
00078   fprintf(outfile, "color%d sphere ball\n0\n0\n4 %4f %4f %4f %4f\n",
00079           cur_color, ORDER(vec[0], vec[1], vec[2]), 
00080           float(lineWidth) * DEFAULT_RADIUS);
00081 }
00082 
00083 // draw a sphere
00084 void RadianceDisplayDevice::sphere(float * spdata) {
00085   
00086   float vec[3];
00087   float radius;
00088     
00089   // transform the world coordinates
00090   (transMat.top()).multpoint3d(spdata, vec);
00091   radius = scale_radius(spdata[3]);
00092    
00093   // draw the sphere
00094   set_color(colorIndex);
00095 
00096   fprintf(outfile, "color%d sphere ball\n0\n0\n4 %4f %4f %4f %4f\n",
00097           cur_color, ORDER(vec[0], vec[1], vec[2]), radius);
00098 }
00099 
00100 // draw a line (cylinder) from a to b
00101 void RadianceDisplayDevice::line(float *a, float*b) {
00102   int i, j, test;
00103   float dirvec[3], unitdirvec[3];
00104   float from[3], to[3], tmp1[3], tmp2[3];
00105 
00106   if (lineStyle == ::SOLIDLINE) {
00107     // transform the world coordinates
00108     (transMat.top()).multpoint3d(a, from);
00109     (transMat.top()).multpoint3d(b, to);
00110     
00111     // draw the cylinder
00112     set_color(colorIndex);
00113     fprintf(outfile, "color%d cylinder cyl\n0\n0\n7 ", cur_color);
00114     fprintf(outfile, "%4f %4f %4f ", 
00115             ORDER(from[0], from[1], from[2])); // first point
00116     fprintf(outfile, "%4f %4f %4f ", 
00117             ORDER(to[0], to[1], to[2])); // second point
00118     fprintf(outfile, "%4f\n", float(lineWidth)*DEFAULT_RADIUS); // radius
00119         
00120   } else if (lineStyle == ::DASHEDLINE) {
00121     // transform the world coordinates
00122     (transMat.top()).multpoint3d(a, tmp1);
00123     (transMat.top()).multpoint3d(b, tmp2);
00124 
00125     // how to create a dashed line
00126     vec_sub(dirvec, tmp2, tmp1);  // vector from a to b
00127     vec_copy(unitdirvec, dirvec);
00128     vec_normalize(unitdirvec);    // unit vector from a to b
00129     test = 1;
00130     i = 0;
00131     while (test == 1) {
00132       for (j=0; j<3; j++) {
00133         from[j] = (float) (tmp1[j] + (2*i    )*DASH_LENGTH*unitdirvec[j]);
00134           to[j] = (float) (tmp1[j] + (2*i + 1)*DASH_LENGTH*unitdirvec[j]);
00135       }
00136       if (fabsf(tmp1[0] - to[0]) >= fabsf(dirvec[0])) {
00137         vec_copy(to, tmp2);
00138         test = 0;
00139       }
00140 
00141       // draw the cylinder
00142       set_color(colorIndex);
00143       fprintf(outfile, "color%d cylinder cyl\n0\n0\n7 ", cur_color);
00144       // first point
00145       fprintf(outfile, "%4f %4f %4f ", ORDER(from[0], from[1], from[2]));
00146       // second point
00147       fprintf(outfile, "%4f %4f %4f ", ORDER(to[0], to[1], to[2])); 
00148       // radius
00149       fprintf(outfile, "%4f\n", float(lineWidth)*DEFAULT_RADIUS);
00150       i++;
00151     }
00152   } else {
00153     msgErr << "RadianceDisplayDevice: Unknown line style " << lineStyle << sendmsg;
00154   }
00155 }
00156 
00157 // draw a cylinder
00158 void RadianceDisplayDevice::cylinder(float *a, float *b, float r,int /*filled*/) {
00159 
00160   float vec1[3], vec2[3];
00161   
00162   // transform the world coordinates
00163   (transMat.top()).multpoint3d(a, vec1);
00164   (transMat.top()).multpoint3d(b, vec2);
00165     
00166   // draw the cylinder
00167 
00168   set_color(colorIndex);
00169 
00170   fprintf(outfile, "color%d cylinder cyl\n0\n0\n7 ", cur_color);
00171   // first point
00172   fprintf(outfile, "%4f %4f %4f ", 
00173     ORDER(vec1[0], vec1[1], vec1[2]));
00174   // second point
00175   fprintf(outfile, "%4f %4f %4f ", 
00176     ORDER(vec2[0], vec2[1], vec2[2])); 
00177   // radius
00178   fprintf(outfile, "%4f\n", scale_radius(r));
00179 
00180   // and fill in the ends
00181   float normal[3];
00182   vec_sub(normal, vec1, vec2);
00183   vec_normalize(normal);
00184 
00185   // one end
00186   set_color(colorIndex);
00187 
00188   fprintf(outfile, "color%d ring cyl_end\n0\n0\n8 ", cur_color);
00189   fprintf(outfile, "%4f %4f %4f ",         // location
00190     ORDER(vec1[0], vec1[1], vec1[2]));
00191   fprintf(outfile, "%4f %4f %4f ",         // normal
00192     ORDER(normal[0], normal[1], normal[2]));
00193   fprintf(outfile, "0 %4f\n", scale_radius(r)); // radii
00194 
00195   // the other end
00196   normal[0] = -normal[0];
00197   normal[1] = -normal[1];
00198   normal[2] = -normal[2];
00199   set_color(colorIndex);
00200 
00201   fprintf(outfile, "color%d ring cyl_end\n0\n0\n8 ", cur_color);
00202   fprintf(outfile, "%4f %4f %4f ",         // location
00203     ORDER(vec2[0], vec2[1], vec2[2]));
00204   fprintf(outfile, "%4f %4f %4f ",         // normal
00205     ORDER(normal[0], normal[1], normal[2]));
00206   fprintf(outfile, "0 %4f\n", scale_radius(r)); // radii
00207   
00208 }
00209 
00210 // draw a single radius cone
00211 void RadianceDisplayDevice::cone(float *a, float *b, float r) {
00212   cone(a, b, r, 0.0);
00213 }
00214 
00215 // draw a two radius cone
00216 void RadianceDisplayDevice::cone(float *a, float *b, float rad1, float rad2) {
00217 
00218   float vec1[3], vec2[3];
00219   
00220   // transform the world coordinates
00221   (transMat.top()).multpoint3d(a, vec1);
00222   (transMat.top()).multpoint3d(b, vec2);
00223     
00224   set_color(colorIndex);
00225 
00226   fprintf(outfile, "color%d cone a_cone\n0\n0\n8 ", cur_color);
00227   // first point
00228   fprintf(outfile, "%4f %4f %4f ", 
00229     ORDER(vec1[0], vec1[1], vec1[2]));
00230   // second point
00231   fprintf(outfile, "%4f %4f %4f ", 
00232     ORDER(vec2[0], vec2[1], vec2[2])); 
00233   // radius
00234   fprintf(outfile, "%4f %4f\n", scale_radius(rad1), scale_radius(rad2));
00235 }
00236 
00237 // draw a triangle
00238 void RadianceDisplayDevice::triangle(const float *a, const float *b, const float *c, const float *, const float *, const float *) {
00239 
00240   float vec1[3], vec2[3], vec3[3];
00241   
00242   // transform the world coordinates
00243   (transMat.top()).multpoint3d(a, vec1);
00244   (transMat.top()).multpoint3d(b, vec2);
00245   (transMat.top()).multpoint3d(c, vec3);
00246 
00247   // draw the triangle
00248 
00249   set_color(colorIndex);
00250 
00251   fprintf(outfile, "color%d polygon poly\n0\n0\n9 ", cur_color); // triangle
00252   fprintf(outfile, "%4f %4f %4f ", 
00253     ORDER(vec1[0], vec1[1], vec1[2])); // point one
00254   fprintf(outfile, "%4f %4f %4f ", 
00255     ORDER(vec2[0], vec2[1], vec2[2])); // point two
00256   fprintf(outfile, "%4f %4f %4f\n", 
00257     ORDER(vec3[0], vec3[1], vec3[2])); // point three
00258 }
00259 
00260 // draw a square
00261 void RadianceDisplayDevice::square(float *, float *a, float *b, float *c, float *d) {
00262   
00263   float vec1[3], vec2[3], vec3[3], vec4[3];
00264   
00265   // transform the world coordinates
00266   (transMat.top()).multpoint3d(a, vec1);
00267   (transMat.top()).multpoint3d(b, vec2);
00268   (transMat.top()).multpoint3d(c, vec3);
00269   (transMat.top()).multpoint3d(d, vec4);
00270 
00271   // draw the square
00272 
00273   set_color(colorIndex);
00274 
00275   fprintf(outfile, "color%d polygon poly\n0\n0\n12 ", cur_color); // triangle
00276   fprintf(outfile, "%4f %4f %4f ", 
00277     ORDER(vec1[0], vec1[1], vec1[2])); // point one
00278   fprintf(outfile, "%4f %4f %4f ", 
00279     ORDER(vec2[0], vec2[1], vec2[2])); // point two
00280   fprintf(outfile, "%4f %4f %4f ", 
00281     ORDER(vec3[0], vec3[1], vec3[2])); // point three
00282   fprintf(outfile, "%4f %4f %4f\n", 
00283     ORDER(vec4[0], vec4[1], vec4[2])); // point four
00284 
00285 }
00286 
00288 
00289 void RadianceDisplayDevice::set_color(int cIndex)
00290 {
00291   int num = red.num();
00292   int i;
00293 
00294   float r = matData[cIndex][0],
00295         g = matData[cIndex][0 + 1],
00296         b = matData[cIndex][0 + 2],
00297 #if 0  /// XXX
00298         t = 1.0f - matData[cIndex][ALPHA_INDEX];
00299 #else
00300         t = 1.0f;
00301 #endif
00302 
00303   for (i = 0; i < num; i++) {
00304     if (r == red[i] && g == green[i] && b == blue[i] && t == trans[i]) {
00305       break;
00306     }
00307   }
00308 
00309   if (i == num) { // create a new color category
00310     red.append(r);
00311     green.append(g);
00312     blue.append(b);
00313     trans.append(t);
00314     // define it for radiance
00315     if (t != 0) {
00316       fprintf(outfile, "void trans color%d\n0\n0\n7 ", i);
00317       fprintf(outfile, "%f %f %f .05 .00 %f 1.0\n", r, g, b, t);
00318     }
00319     else {
00320       fprintf(outfile, "void plastic color%d\n0\n0\n5 ", i);
00321       fprintf(outfile, "%f %f %f .05 .05\n", r, g, b);
00322     }
00323   }
00324   //else {
00325   //  // the color is 'i' so print it
00326   //  fprintf(outfile, "color%d ", i);
00327   //}
00328 
00329   // Save the current color
00330   cur_color = i;
00331 }
00332        
00333 
00334 // write comment to file
00335 void RadianceDisplayDevice::comment(const char *s) {
00336   fprintf (outfile, "# %s\n", s);
00337 }
00338 
00340 
00341 // initialize the file for output
00342 void RadianceDisplayDevice::write_header() {
00343     int i;
00344 
00345     // clear out the r/g/b/t arrays
00346     red.clear();
00347     green.clear();
00348     blue.clear();
00349     trans.clear();
00350 
00351     fprintf(outfile, "#\n");
00352     fprintf(outfile, "# Radiance input script: %s\n",my_filename);
00353     fprintf(outfile, "#\n");
00354 
00355 
00356     // write the light sources
00357     fprintf(outfile, "void dielectric invisible\n0\n0\n5 1 1 1 1 0\n");
00358     fprintf(outfile, "void illum bright\n1 invisible\n0\n"
00359             "3 10000 10000 10000\n");
00360     
00361     // do this instead of the right way (see later)
00362     // fprintf(outfile, "bright sphere fixture\n0\n0\n4  -10 0 0  .01\n");
00363     
00364     // background color is black until I figure out how to set it
00365     // interactively.  I'm thinking of having a glowing sphere or plane
00366 
00367     for (i = 0; i < DISP_LIGHTS; i++) {
00368         if (lightState[i].on) {
00369             float vec[3];
00370 
00371             (transMat.top()).multpoint3d(lightState[i].pos, vec);
00372 
00373             fprintf(outfile,
00374                     "bright sphere fixture\n0\n0\n4 %f %f %f .01\n",
00375                     ORDER(10 * vec[0], 10 * vec[1], 10 * vec[2]));
00376         }
00377     }
00378 }
00379 
00380     
00381 // clean up after yourself
00382 void RadianceDisplayDevice::write_trailer() {
00383   msgInfo << "Radiance file generation finished" << sendmsg;
00384   reset_vars(); // reset state variables
00385 }
00386 
00387 
00388 

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