00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #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
00038
00039
00040
00041 #define ORDER(x,y,z) -z, -x, y
00042
00044
00045
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