00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <string.h>
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <math.h>
00027 #include "TachyonDisplayDevice.h"
00028 #include "Matrix4.h"
00029 #include "DispCmds.h"
00030 #include "Inform.h"
00031 #include "utilities.h"
00032 #include "config.h"
00033 #include "Hershey.h"
00034
00035 #define DEFAULT_RADIUS 0.002f
00036 #define DASH_LENGTH 0.02f
00037
00038 #if defined(_MSC_VER) || defined(WIN32)
00039 #define TACHYON_RUN_STRING " -aasamples 12 %s -format BMP -o %s.bmp"
00040 #else
00041 #define TACHYON_RUN_STRING " -aasamples 12 %s -format TARGA -o %s.tga"
00042 #endif
00043
00044 static char tachyon_run_string[2048];
00045
00046 static char * get_tachyon_run_string() {
00047 char *tbin;
00048 strcpy(tachyon_run_string, "tachyon");
00049
00050 if ((tbin=getenv("TACHYON_BIN")) != NULL) {
00051 sprintf(tachyon_run_string, "\"%s\"", tbin);
00052 }
00053 strcat(tachyon_run_string, TACHYON_RUN_STRING);
00054
00055 return tachyon_run_string;
00056 }
00057
00058 void TachyonDisplayDevice::update_exec_cmd() {
00059 const char *tbin;
00060 if ((tbin = getenv("TACHYON_BIN")) == NULL)
00061 tbin = "tachyon";
00062
00063 switch(curformat) {
00064 case 0:
00065 sprintf(tachyon_run_string,
00066 "\"%s\" -aasamples %d %%s -format %s -o %%s.%s", tbin, aasamples, "BMP", "bmp");
00067 break;
00068
00069 case 1:
00070 sprintf(tachyon_run_string,
00071 "\"%s\" -aasamples %d %%s -format %s -o %%s.%s", tbin, aasamples, "PPM", "ppm");
00072 break;
00073
00074 case 2:
00075 sprintf(tachyon_run_string,
00076 "\"%s\" -aasamples %d %%s -format %s -o %%s.%s", tbin, aasamples, "PPM48", "ppm");
00077 break;
00078
00079 case 3:
00080 sprintf(tachyon_run_string,
00081 "\"%s\" -aasamples %d %%s -format %s -o %%s.%s", tbin, aasamples, "PSD48", "psd");
00082 break;
00083
00084 case 4:
00085 sprintf(tachyon_run_string,
00086 "\"%s\" -aasamples %d %%s -format %s -o %%s.%s", tbin, aasamples, "RGB", "rgb");
00087 break;
00088
00089 case 5:
00090 default:
00091 sprintf(tachyon_run_string,
00092 "\"%s\" -aasamples %d %%s -format %s -o %%s.%s", tbin, aasamples, "TARGA", "tga");
00093 break;
00094 }
00095 delete [] execCmd;
00096 execCmd = stringdup(tachyon_run_string);
00097 }
00098
00100
00101
00102
00103 TachyonDisplayDevice::TachyonDisplayDevice() : FileRenderer ("Tachyon", "Tachyon", "vmdscene.dat", get_tachyon_run_string()) {
00104
00105 formats.add_name("BMP", 0);
00106 formats.add_name("PPM", 0);
00107 formats.add_name("PPM48", 0);
00108 formats.add_name("PSD48", 0);
00109 formats.add_name("RGB", 0);
00110 formats.add_name("TGA", 0);
00111
00112
00113 has_aa = TRUE;
00114 aasamples = 12;
00115 aosamples = 12;
00116
00117 reset_vars();
00118
00119
00120 #if defined(_MSC_VER) || defined(WIN32)
00121 curformat = 0;
00122 #else
00123 curformat = 5;
00124 #endif
00125 }
00126
00127
00128 TachyonDisplayDevice::~TachyonDisplayDevice(void) { }
00129
00131
00132 void TachyonDisplayDevice::reset_vars(void) {
00133 enablemirrorspecular = (getenv("VMDTACHYONMIRRORSPECULAR") != NULL);
00134 phongspecularthresh = 256.0f;
00135 if (getenv("VMDTACHYONPHONGSPECTHRESH")) {
00136 sscanf(getenv("VMDTACHYONPHONGSPECTHRESH"), "%f", &phongspecularthresh);
00137 }
00138 inclipgroup = 0;
00139 involtex = 0;
00140 voltexID = -1;
00141 memset(xplaneeq, 0, sizeof(xplaneeq));
00142 memset(yplaneeq, 0, sizeof(xplaneeq));
00143 memset(zplaneeq, 0, sizeof(xplaneeq));
00144 }
00145
00146
00147
00148 void TachyonDisplayDevice::comment(const char *s) {
00149 fprintf(outfile, "# %s\n", s);
00150 }
00151
00152
00153 void TachyonDisplayDevice::text(float *pos, float size, float thickness,
00154 const char *str) {
00155 float textpos[3];
00156 float textsize, textthickness;
00157 hersheyhandle hh;
00158
00159
00160 (transMat.top()).multpoint3d(pos, textpos);
00161 textsize = size * 1.5f;
00162 textthickness = thickness*DEFAULT_RADIUS;
00163
00164 while (*str != '\0') {
00165 float lm, rm, x, y, ox, oy;
00166 int draw, odraw;
00167 ox=oy=x=y=0.0f;
00168 draw=odraw=0;
00169
00170 hersheyDrawInitLetter(&hh, *str, &lm, &rm);
00171 textpos[0] -= lm * textsize;
00172
00173 while (!hersheyDrawNextLine(&hh, &draw, &x, &y)) {
00174 float oldpt[3], newpt[3];
00175 if (draw) {
00176 newpt[0] = textpos[0] + textsize * x;
00177 newpt[1] = textpos[1] + textsize * y;
00178 newpt[2] = textpos[2];
00179
00180 if (odraw) {
00181
00182 oldpt[0] = textpos[0] + textsize * ox;
00183 oldpt[1] = textpos[1] + textsize * oy;
00184 oldpt[2] = textpos[2];
00185
00186 fprintf(outfile, "FCylinder\n");
00187 fprintf(outfile, " Base %g %g %g\n", oldpt[0], oldpt[1], -oldpt[2]);
00188 fprintf(outfile, " Apex %g %g %g\n", newpt[0], newpt[1], -newpt[2]);
00189 fprintf(outfile, " Rad %g \n", textthickness);
00190 write_cindexmaterial(colorIndex, materialIndex);
00191
00192 fprintf(outfile, "Sphere \n");
00193 fprintf(outfile, " Center %g %g %g \n", newpt[0], newpt[1], -newpt[2]);
00194 fprintf(outfile, " Rad %g \n", textthickness);
00195 write_cindexmaterial(colorIndex, materialIndex);
00196 } else {
00197
00198 fprintf(outfile, "Sphere \n");
00199 fprintf(outfile, " Center %g %g %g \n", newpt[0], newpt[1], -newpt[2]);
00200 fprintf(outfile, " Rad %g \n", textthickness);
00201 write_cindexmaterial(colorIndex, materialIndex);
00202 }
00203 }
00204
00205 ox=x;
00206 oy=y;
00207 odraw=draw;
00208 }
00209 textpos[0] += rm * textsize;
00210
00211 str++;
00212 }
00213 }
00214
00215
00216
00217 void TachyonDisplayDevice::point(float * spdata) {
00218 float vec[3];
00219
00220 (transMat.top()).multpoint3d(spdata, vec);
00221
00222
00223 fprintf(outfile, "Sphere \n");
00224 fprintf(outfile, " Center %g %g %g \n ", vec[0], vec[1], -vec[2]);
00225 fprintf(outfile, " Rad %g \n", float(lineWidth)*DEFAULT_RADIUS);
00226 write_cindexmaterial(colorIndex, materialIndex);
00227 }
00228
00229
00230
00231 void TachyonDisplayDevice::sphere(float * spdata) {
00232 float vec[3];
00233 float radius;
00234
00235
00236 (transMat.top()).multpoint3d(spdata, vec);
00237 radius = scale_radius(spdata[3]);
00238
00239
00240 fprintf(outfile, "Sphere \n");
00241 fprintf(outfile, " Center %g %g %g \n ", vec[0], vec[1], -vec[2]);
00242 fprintf(outfile, " Rad %g \n", radius );
00243 write_cindexmaterial(colorIndex, materialIndex);
00244 }
00245
00246
00247
00248 void TachyonDisplayDevice::sphere_array(int spnum, int spres, float *centers, float *radii, float *colors) {
00249 float vec[3];
00250 float radius;
00251 int i, ind;
00252
00253 ind = 0;
00254 for (i=0; i<spnum; i++) {
00255
00256 (transMat.top()).multpoint3d(¢ers[ind], vec);
00257 radius = scale_radius(radii[i]);
00258
00259
00260 fprintf(outfile, "Sphere \n");
00261 fprintf(outfile, " Center %g %g %g \n ", vec[0], vec[1], -vec[2]);
00262 fprintf(outfile, " Rad %g \n", radius );
00263 write_colormaterial(&colors[ind], materialIndex);
00264 ind += 3;
00265 }
00266
00267
00268 ind=(spnum-1)*3;
00269 super_set_color(nearest_index(colors[ind], colors[ind+1], colors[ind+2]));
00270 }
00271
00272
00273
00274 void TachyonDisplayDevice::line(float *a, float*b) {
00275 int i, j, test;
00276 float dirvec[3], unitdirvec[3];
00277 float from[3], to[3], tmp1[3], tmp2[3];
00278
00279 if (lineStyle == ::SOLIDLINE) {
00280
00281 (transMat.top()).multpoint3d(a, from);
00282 (transMat.top()).multpoint3d(b, to);
00283
00284
00285 fprintf(outfile, "FCylinder\n");
00286 fprintf(outfile, " Base %g %g %g\n", from[0], from[1], -from[2]);
00287 fprintf(outfile, " Apex %g %g %g\n", to[0], to[1], -to[2]);
00288 fprintf(outfile, " Rad %g \n", float(lineWidth)*DEFAULT_RADIUS);
00289 write_cindexmaterial(colorIndex, materialIndex);
00290
00291 } else if (lineStyle == ::DASHEDLINE) {
00292
00293 (transMat.top()).multpoint3d(a, tmp1);
00294 (transMat.top()).multpoint3d(b, tmp2);
00295
00296
00297 vec_sub(dirvec, tmp2, tmp1);
00298 vec_copy(unitdirvec, dirvec);
00299 vec_normalize(unitdirvec);
00300 test = 1;
00301 i = 0;
00302 while (test == 1) {
00303 for (j=0; j<3; j++) {
00304 from[j] = (float) (tmp1[j] + (2*i )*DASH_LENGTH*unitdirvec[j]);
00305 to[j] = (float) (tmp1[j] + (2*i + 1)*DASH_LENGTH*unitdirvec[j]);
00306 }
00307 if (fabsf(tmp1[0] - to[0]) >= fabsf(dirvec[0])) {
00308 vec_copy(to, tmp2);
00309 test = 0;
00310 }
00311
00312
00313 fprintf(outfile, "FCylinder\n");
00314 fprintf(outfile, " Base %g %g %g\n", from[0], from[1], -from[2]);
00315 fprintf(outfile, " Apex %g %g %g\n", to[0], to[1], -to[2]);
00316 fprintf(outfile, " Rad %g \n", float(lineWidth)*DEFAULT_RADIUS);
00317 write_cindexmaterial(colorIndex, materialIndex);
00318 i++;
00319 }
00320 } else {
00321 msgErr << "TachyonDisplayDevice: Unknown line style "
00322 << lineStyle << sendmsg;
00323 }
00324 }
00325
00326
00327
00328
00329
00330 void TachyonDisplayDevice::cylinder(float *a, float *b, float r, int filled) {
00331 float from[3], to[3], norm[3];
00332 float radius;
00333 filled = filled;
00334
00335
00336 (transMat.top()).multpoint3d(a, from);
00337 (transMat.top()).multpoint3d(b, to);
00338 radius = scale_radius(r);
00339
00340
00341
00342 fprintf(outfile, "FCylinder\n");
00343 fprintf(outfile, " Base %g %g %g\n", from[0], from[1], -from[2]);
00344 fprintf(outfile, " Apex %g %g %g\n", to[0], to[1], -to[2]);
00345 fprintf(outfile, " Rad %g\n", radius);
00346 write_cindexmaterial(colorIndex, materialIndex);
00347
00348
00349 if (filled) {
00350 float div;
00351
00352 norm[0] = to[0] - from[0];
00353 norm[1] = to[1] - from[1];
00354 norm[2] = to[2] - from[2];
00355
00356 div = 1.0f / sqrtf(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]);
00357 norm[0] *= div;
00358 norm[1] *= div;
00359 norm[2] *= div;
00360
00361 if (filled & CYLINDER_TRAILINGCAP) {
00362 fprintf(outfile, "Ring\n");
00363 fprintf(outfile, "Center %g %g %g \n", from[0], from[1], -from[2]);
00364 fprintf(outfile, "Normal %g %g %g \n", norm[0], norm[1], -norm[2]);
00365 fprintf(outfile, "Inner 0.0 Outer %g \n", radius);
00366 write_cindexmaterial(colorIndex, materialIndex);
00367 }
00368
00369 if (filled & CYLINDER_LEADINGCAP) {
00370 fprintf(outfile, "Ring\n");
00371 fprintf(outfile, "Center %g %g %g \n", to[0], to[1], -to[2]);
00372 fprintf(outfile, "Normal %g %g %g \n", -norm[0], -norm[1], norm[2]);
00373 fprintf(outfile, "Inner 0.0 Outer %g \n", radius);
00374 write_cindexmaterial(colorIndex, materialIndex);
00375 }
00376 }
00377 }
00378
00379
00380
00381 void TachyonDisplayDevice::triangle(const float *a, const float *b, const float *c, const float *n1, const float *n2, const float *n3) {
00382 float vec1[3], vec2[3], vec3[3];
00383 float norm1[3], norm2[3], norm3[3];
00384
00385
00386
00387 (transMat.top()).multpoint3d(a, vec1);
00388 (transMat.top()).multpoint3d(b, vec2);
00389 (transMat.top()).multpoint3d(c, vec3);
00390
00391
00392 (transMat.top()).multnorm3d(n1, norm1);
00393 (transMat.top()).multnorm3d(n2, norm2);
00394 (transMat.top()).multnorm3d(n3, norm3);
00395
00396
00397 fprintf(outfile, "STri\n");
00398 fprintf(outfile, " V0 %g %g %g\n", vec1[0], vec1[1], -vec1[2]);
00399 fprintf(outfile, " V1 %g %g %g\n", vec2[0], vec2[1], -vec2[2]);
00400 fprintf(outfile, " V2 %g %g %g\n", vec3[0], vec3[1], -vec3[2]);
00401 fprintf(outfile, " N0 %g %g %g\n", -norm1[0], -norm1[1], norm1[2]);
00402 fprintf(outfile, " N1 %g %g %g\n", -norm2[0], -norm2[1], norm2[2]);
00403 fprintf(outfile, " N2 %g %g %g\n", -norm3[0], -norm3[1], norm3[2]);
00404 write_cindexmaterial(colorIndex, materialIndex);
00405 }
00406
00407
00408 void TachyonDisplayDevice::tricolor(const float * xyz1, const float * xyz2, const float * xyz3,
00409 const float * n1, const float * n2, const float * n3,
00410 const float *c1, const float *c2, const float *c3) {
00411 float vec1[3], vec2[3], vec3[3];
00412 float norm1[3], norm2[3], norm3[3];
00413
00414
00415 (transMat.top()).multpoint3d(xyz1, vec1);
00416 (transMat.top()).multpoint3d(xyz2, vec2);
00417 (transMat.top()).multpoint3d(xyz3, vec3);
00418
00419
00420 (transMat.top()).multnorm3d(n1, norm1);
00421 (transMat.top()).multnorm3d(n2, norm2);
00422 (transMat.top()).multnorm3d(n3, norm3);
00423
00424
00425 if (!involtex) {
00426 fprintf(outfile, "VCSTri\n");
00427 } else {
00428 fprintf(outfile, "STri\n");
00429 }
00430 fprintf(outfile, " V0 %g %g %g\n", vec1[0], vec1[1], -vec1[2]);
00431 fprintf(outfile, " V1 %g %g %g\n", vec2[0], vec2[1], -vec2[2]);
00432 fprintf(outfile, " V2 %g %g %g\n", vec3[0], vec3[1], -vec3[2]);
00433
00434 fprintf(outfile, " N0 %g %g %g\n", -norm1[0], -norm1[1], norm1[2]);
00435 fprintf(outfile, " N1 %g %g %g\n", -norm2[0], -norm2[1], norm2[2]);
00436 fprintf(outfile, " N2 %g %g %g\n", -norm3[0], -norm3[1], norm3[2]);
00437
00438 if (!involtex) {
00439 fprintf(outfile, " C0 %g %g %g\n", c1[0], c1[1], c1[2]);
00440 fprintf(outfile, " C1 %g %g %g\n", c2[0], c2[1], c2[2]);
00441 fprintf(outfile, " C2 %g %g %g\n", c3[0], c3[1], c3[2]);
00442 }
00443
00444 if (materials_on) {
00445 float myspecular = 0.0f;
00446 if (enablemirrorspecular && (mat_shininess >= phongspecularthresh))
00447 myspecular=mat_specular;
00448 fprintf(outfile, " Ambient %g Diffuse %g Specular %g Opacity %g\n",
00449 mat_ambient, mat_diffuse, myspecular, mat_opacity);
00450 } else {
00451 fprintf(outfile, " Ambient %g Diffuse %g Specular %g Opacity %g\n",
00452 1.0, 0.0, 0.0, mat_opacity);
00453 }
00454
00455 if (mat_transmode != 0) {
00456 fprintf(outfile, " TransMode R3D ");
00457 }
00458 if (mat_outline > 0.0) {
00459 fprintf(outfile, " Outline %g Outline_Width %g ",
00460 mat_outline, mat_outlinewidth);
00461 }
00462 fprintf(outfile, " Phong Plastic %g Phong_size %g ", mat_specular,
00463 mat_shininess);
00464 fprintf(outfile, "VCST\n\n");
00465 }
00466
00467
00468
00469
00470 void TachyonDisplayDevice::trimesh_c4n3v3(int numverts, float * cnv,
00471 int numfacets, int * facets) {
00472 int i;
00473 float vec1[3];
00474 float norm1[3];
00475
00476 fprintf(outfile, "VertexArray");
00477 fprintf(outfile, " Numverts %d\n", numverts);
00478
00479 fprintf(outfile, "\nCoords\n");
00480 for (i=0; i<numverts; i++) {
00481 (transMat.top()).multpoint3d(cnv + i*10 + 7, vec1);
00482 fprintf(outfile, "%g %g %g\n", vec1[0], vec1[1], -vec1[2]);
00483 }
00484
00485 fprintf(outfile, "\nNormals\n");
00486 for (i=0; i<numverts; i++) {
00487 (transMat.top()).multnorm3d(cnv + i*10 + 4, norm1);
00488 fprintf(outfile, "%g %g %g\n", -norm1[0], -norm1[1], norm1[2]);
00489 }
00490
00491
00492 if (!involtex) {
00493 fprintf(outfile, "\nColors\n");
00494 for (i=0; i<numverts; i++) {
00495 int idx = i * 10;
00496 fprintf(outfile, "%g %g %g\n", cnv[idx], cnv[idx+1], cnv[idx+2]);
00497 }
00498 }
00499
00500
00501 write_cindexmaterial(colorIndex, materialIndex);
00502
00503
00504 fprintf(outfile, "\nTriMesh %d\n", numfacets);
00505 for (i=0; i<numfacets*3; i+=3) {
00506 fprintf(outfile, "%d %d %d\n", facets[i], facets[i+1], facets[i+2]);
00507 }
00508
00509
00510 fprintf(outfile, "\nEnd_VertexArray\n");
00511 }
00512
00513
00514 void TachyonDisplayDevice::tristrip(int numverts, const float * cnv,
00515 int numstrips, const int *vertsperstrip,
00516 const int *facets) {
00517 int i, strip, v=0;
00518 float vec1[3];
00519 float norm1[3];
00520
00521 fprintf(outfile, "VertexArray");
00522 fprintf(outfile, " Numverts %d\n", numverts);
00523
00524 fprintf(outfile, "\nCoords\n");
00525 for (i=0; i<numverts; i++) {
00526 (transMat.top()).multpoint3d(cnv + i*10 + 7, vec1);
00527 fprintf(outfile, "%g %g %g\n", vec1[0], vec1[1], -vec1[2]);
00528 }
00529
00530 fprintf(outfile, "\nNormals\n");
00531 for (i=0; i<numverts; i++) {
00532 (transMat.top()).multnorm3d(cnv + i*10 + 4, norm1);
00533 fprintf(outfile, "%g %g %g\n", -norm1[0], -norm1[1], norm1[2]);
00534 }
00535
00536
00537 if (!involtex) {
00538 fprintf(outfile, "\nColors\n");
00539 for (i=0; i<numverts; i++) {
00540 int idx = i * 10;
00541 fprintf(outfile, "%g %g %g\n", cnv[idx], cnv[idx+1], cnv[idx+2]);
00542 }
00543 }
00544
00545
00546 write_cindexmaterial(colorIndex, materialIndex);
00547
00548
00549 v=0;
00550 for (strip=0; strip < numstrips; strip++) {
00551 fprintf(outfile, "\nTriStrip %d\n", vertsperstrip[strip]);
00552
00553
00554 for (i = 0; i < vertsperstrip[strip]; i++) {
00555 fprintf(outfile, "%d ", facets[v]);
00556 v++;
00557 }
00558 }
00559
00560
00561 fprintf(outfile, "\nEnd_VertexArray\n");
00562 }
00563
00564
00565
00566 void TachyonDisplayDevice::define_volume_texture(int ID,
00567 int xs, int ys, int zs,
00568 const float *xpq,
00569 const float *ypq,
00570 const float *zpq,
00571 unsigned char *texmap) {
00572 voltexID = ID;
00573
00574 memcpy(xplaneeq, xpq, sizeof(xplaneeq));
00575 memcpy(yplaneeq, ypq, sizeof(yplaneeq));
00576 memcpy(zplaneeq, zpq, sizeof(zplaneeq));
00577
00578 fprintf(outfile, "# VMD volume texture definition: ID %d\n", ID);
00579 fprintf(outfile, "# Res: %d %d %d\n", xs, ys, zs);
00580 fprintf(outfile, "# xplaneeq: %g %g %g %g\n",
00581 xplaneeq[0], xplaneeq[1], xplaneeq[2], xplaneeq[3]);
00582 fprintf(outfile, "# yplaneeq: %g %g %g %g\n",
00583 yplaneeq[0], yplaneeq[1], yplaneeq[2], yplaneeq[3]);
00584 fprintf(outfile, "# zplaneeq: %g %g %g %g\n",
00585 zplaneeq[0], zplaneeq[1], zplaneeq[2], zplaneeq[3]);
00586
00587 fprintf(outfile, "ImageDef ::VMDVolTex%d\n", ID);
00588 fprintf(outfile, " Format RGB24\n");
00589 fprintf(outfile, " Resolution %d %d %d\n", xs, ys, zs);
00590 fprintf(outfile, " Encoding Hex\n");
00591
00592 int x, y, z;
00593 for (z=0; z<zs; z++) {
00594 for (y=0; y<ys; y++) {
00595 int addr = (z * xs * ys) + (y * xs);
00596 for (x=0; x<xs; x++) {
00597 int addr2 = (addr + x) * 3;
00598 fprintf(outfile, "%02x%02x%02x ",
00599 texmap[addr2 ],
00600 texmap[addr2 + 1],
00601 texmap[addr2 + 2]);
00602 }
00603 fprintf(outfile, "\n");
00604 }
00605 fprintf(outfile, "\n");
00606 }
00607 fprintf(outfile, "\n");
00608 fprintf(outfile, "# End of volume texture ::VMDVolTex%d\n", ID);
00609 fprintf(outfile, "\n");
00610 fprintf(outfile, "\n");
00611 }
00612
00613
00614
00615 void TachyonDisplayDevice::volume_texture_on(int texmode) {
00616 involtex = 1;
00617 }
00618
00619
00620
00621 void TachyonDisplayDevice::volume_texture_off(void) {
00622 involtex = 0;
00623 }
00624
00625
00626 void TachyonDisplayDevice::start_clipgroup(void) {
00627 int i;
00628 int planesenabled = 0;
00629
00630 for (i=0; i<VMD_MAX_CLIP_PLANE; i++) {
00631 if (clip_mode[i] > 0) {
00632 planesenabled++;
00633 if (clip_mode[i] > 1)
00634 warningflags |= FILERENDERER_NOCLIP;
00635 }
00636 }
00637
00638 if (planesenabled > 0) {
00639 fprintf(outfile, "Start_ClipGroup\n");
00640 fprintf(outfile, " NumPlanes %d\n", planesenabled);
00641 for (i=0; i<VMD_MAX_CLIP_PLANE; i++) {
00642 if (clip_mode[i] > 0) {
00643 float tachyon_clip_center[3];
00644 float tachyon_clip_normal[3];
00645 float tachyon_clip_distance;
00646
00647 inclipgroup = 1;
00648
00649
00650 (transMat.top()).multpoint3d(clip_center[i], tachyon_clip_center);
00651 (transMat.top()).multnorm3d(clip_normal[i], tachyon_clip_normal);
00652 vec_negate(tachyon_clip_normal, tachyon_clip_normal);
00653
00654
00655
00656 tachyon_clip_distance = dot_prod(tachyon_clip_normal, tachyon_clip_center);
00657
00658 fprintf(outfile, "%g %g %g %g\n", tachyon_clip_normal[0],
00659 tachyon_clip_normal[1], -tachyon_clip_normal[2],
00660 tachyon_clip_distance);
00661 }
00662 }
00663 fprintf(outfile, "\n");
00664 } else {
00665 inclipgroup = 0;
00666 }
00667 }
00668
00669
00671
00672
00673 void TachyonDisplayDevice::write_header() {
00674 fprintf(outfile, "# \n");
00675 fprintf(outfile, "# Molecular graphics exported from VMD %s\n", VMDVERSION);
00676 fprintf(outfile, "# http://www.ks.uiuc.edu/Research/vmd/\n");
00677 fprintf(outfile, "# \n");
00678 fprintf(outfile, "# Requires Tachyon version 0.99.0 or newer\n");
00679 fprintf(outfile, "# \n");
00680 fprintf(outfile, "# Default tachyon rendering command for this scene:\n");
00681 fprintf(outfile, "# tachyon %s\n", TACHYON_RUN_STRING);
00682 fprintf(outfile, "# \n");
00683
00684
00685
00686
00687
00688
00689 fprintf(outfile, "Begin_Scene\n");
00690 fprintf(outfile, "Resolution %d %d\n", (int) xSize, (int) ySize);
00691
00692
00693
00694 fprintf(outfile, "Shader_Mode ");
00695
00696
00697
00698 if (shadows_enabled() || ao_enabled()) {
00699 fprintf(outfile, "Full\n");
00700 } else {
00701 fprintf(outfile, "Medium\n");
00702 }
00703
00704
00705
00706
00707
00708 fprintf(outfile, " Trans_VMD\n");
00709 fprintf(outfile, " Fog_VMD\n");
00710
00711
00712 if (ao_enabled()) {
00713 fprintf(outfile, " Ambient_Occlusion\n");
00714 fprintf(outfile, " Ambient_Color %g %g %g\n",
00715 get_ao_ambient(), get_ao_ambient(), get_ao_ambient());
00716 fprintf(outfile, " Rescale_Direct %g\n", get_ao_direct());
00717 fprintf(outfile, " Samples %d\n", aosamples);
00718 }
00719 fprintf(outfile, "End_Shader_Mode\n");
00720
00721 write_camera();
00722 write_lights();
00723 write_materials();
00724 }
00725
00726
00727 void TachyonDisplayDevice::end_clipgroup(void) {
00728 if (inclipgroup) {
00729 fprintf(outfile, "End_ClipGroup\n");
00730 inclipgroup = 0;
00731 }
00732 }
00733
00734
00735 void TachyonDisplayDevice::write_trailer(void){
00736 fprintf(outfile, "End_Scene \n");
00737 if (inclipgroup) {
00738 msgErr << "TachyonDisplayDevice clipping group still active at end of scene\n" << sendmsg;
00739 }
00740 msgInfo << "Tachyon file generation finished" << sendmsg;
00741
00742 reset_vars();
00743 }
00744
00745
00746
00748
00749 void TachyonDisplayDevice::write_camera(void) {
00750 int raydepth = 50;
00751
00752
00753
00754
00755
00756 switch (projection()) {
00757
00758 case DisplayDevice::ORTHOGRAPHIC:
00759 fprintf(outfile, "Camera\n");
00760 fprintf(outfile, " Projection Orthographic\n");
00761 fprintf(outfile, " Zoom %g\n", 1.0 / (vSize / 2.0));
00762 fprintf(outfile, " Aspectratio %g\n", 1.0f);
00763 fprintf(outfile, " Antialiasing %d\n", aasamples);
00764 fprintf(outfile, " Raydepth %d\n", raydepth);
00765 fprintf(outfile, " Center %g %g %g\n", eyePos[0], eyePos[1], -eyePos[2]);
00766 fprintf(outfile, " Viewdir %g %g %g\n", eyeDir[0], eyeDir[1], -eyeDir[2]);
00767 fprintf(outfile, " Updir %g %g %g\n", upDir[0], upDir[1], -upDir[2]);
00768 fprintf(outfile, "End_Camera\n");
00769 break;
00770
00771 case DisplayDevice::PERSPECTIVE:
00772 default:
00773 fprintf(outfile, "Camera\n");
00774 fprintf(outfile, " Zoom %g\n", (eyePos[2] - zDist) / vSize);
00775 fprintf(outfile, " Aspectratio %g\n", 1.0f);
00776 fprintf(outfile, " Antialiasing %d\n", aasamples);
00777 fprintf(outfile, " Raydepth %d\n", raydepth);
00778 fprintf(outfile, " Center %g %g %g\n", eyePos[0], eyePos[1], -eyePos[2]);
00779 fprintf(outfile, " Viewdir %g %g %g\n", eyeDir[0], eyeDir[1], -eyeDir[2]);
00780 fprintf(outfile, " Updir %g %g %g\n", upDir[0], upDir[1], -upDir[2]);
00781 fprintf(outfile, "End_Camera\n");
00782 break;
00783
00784 }
00785 }
00786
00787
00788 void TachyonDisplayDevice::write_lights(void) {
00789
00790 int i;
00791 int lightcount = 0;
00792 for (i=0; i<DISP_LIGHTS; i++) {
00793 if (lightState[i].on) {
00794
00795 fprintf(outfile, "Directional_Light Direction %g %g %g ",
00796 -lightState[i].pos[0],
00797 -lightState[i].pos[1],
00798 lightState[i].pos[2]);
00799 fprintf(outfile, "Color %g %g %g\n",
00800 lightState[i].color[0], lightState[i].color[1], lightState[i].color[2]);
00801 lightcount++;
00802 }
00803 }
00804
00805 #if 1
00806 for (i=0; i<DISP_LIGHTS; i++) {
00807 if (advLightState[i].on) {
00808 float pos[3];
00809
00810
00811 vec_copy(pos, advLightState[i].pos);
00812
00813 if (advLightState[i].spoton) {
00814 fprintf(outfile, "# SpotLight not implemented yet ...\n");
00815 } else {
00816
00817 fprintf(outfile, "Light Center %g %g %g Rad 0.0 ",
00818 pos[0], pos[1], -pos[2]);
00819
00820
00821 if (advLightState[i].constfactor != 1.0f ||
00822 advLightState[i].linearfactor != 0.0f ||
00823 advLightState[i].quadfactor != 0.0f) {
00824 fprintf(outfile, "Attenuation Constant %g Linear %g Quadratic %g\n",
00825 advLightState[i].constfactor,
00826 advLightState[i].linearfactor,
00827 advLightState[i].quadfactor);
00828 }
00829
00830 fprintf(outfile, "Color %g %g %g\n",
00831 lightState[i].color[0], lightState[i].color[1], lightState[i].color[2]);
00832 }
00833
00834 lightcount++;
00835 }
00836 }
00837 #endif
00838
00839 if (lightcount < 1) {
00840 msgInfo << "Warning: no lights defined in exported scene!!" << sendmsg;
00841 }
00842 }
00843
00844 void TachyonDisplayDevice::write_materials(void) {
00845
00846 fprintf(outfile, "\nBackground %g %g %g\n",
00847 backColor[0], backColor[1], backColor[2]);
00848
00849
00850
00851 if (backgroundmode == 1) {
00852 float bspheremag = 0.5f;
00853
00854
00855 switch (projection()) {
00856 case DisplayDevice::ORTHOGRAPHIC:
00857
00858
00859
00860
00861 bspheremag = vSize / 4.0f;
00862 break;
00863
00864 case DisplayDevice::PERSPECTIVE:
00865 default:
00866
00867
00868
00869
00870 bspheremag = (vSize / 2.0f) / (eyePos[2] - zDist);
00871 if (bspheremag > 1.0f)
00872 bspheremag = 1.0f;
00873 break;
00874 }
00875
00876
00877 fprintf(outfile, "Background_Gradient ");
00878 if (projection() == DisplayDevice::ORTHOGRAPHIC)
00879 fprintf(outfile, "Sky_Ortho_Plane\n");
00880 else
00881 fprintf(outfile, "Sky_Sphere\n");
00882 fprintf(outfile, " UpDir %g %g %g\n", 0.0f, 1.0f, 0.0f);
00883 fprintf(outfile, " TopVal %g\n", bspheremag);
00884 fprintf(outfile, " BottomVal %g\n", -bspheremag);
00885 fprintf(outfile, " TopColor %g %g %g\n", backgradienttopcolor[0],
00886 backgradienttopcolor[1], backgradienttopcolor[2]);
00887 fprintf(outfile, " BottomColor %g %g %g\n", backgradientbotcolor[0],
00888 backgradientbotcolor[1], backgradientbotcolor[2]);
00889 }
00890
00891
00892 if (cueingEnabled) {
00893 switch (cueMode) {
00894 case CUE_LINEAR:
00895 fprintf(outfile,
00896 "Fog Linear Start %g End %g Density %g Color %g %g %g\n",
00897 get_cue_start(), get_cue_end(), 1.0f,
00898 backColor[0], backColor[1], backColor[2]);
00899 break;
00900
00901 case CUE_EXP:
00902 fprintf(outfile,
00903 "Fog Exp Start %g End %g Density %g Color %g %g %g\n",
00904 0.0, get_cue_end(), get_cue_density(),
00905 backColor[0], backColor[1], backColor[2]);
00906 break;
00907
00908 case CUE_EXP2:
00909 fprintf(outfile,
00910 "Fog Exp2 Start %g End %g Density %g Color %g %g %g\n",
00911 0.0, get_cue_end(), get_cue_density(),
00912 backColor[0], backColor[1], backColor[2]);
00913 break;
00914
00915 case NUM_CUE_MODES:
00916
00917 break;
00918 }
00919 }
00920 }
00921
00922 void TachyonDisplayDevice::write_cindexmaterial(int cindex, int material) {
00923 write_colormaterial((float *) &matData[cindex], material);
00924 }
00925
00926
00927 void TachyonDisplayDevice::write_colormaterial(float *rgb, int ) {
00928 fprintf(outfile, "Texture\n");
00929 if (materials_on) {
00930 float myspecular = 0.0f;
00931 if (enablemirrorspecular && (mat_shininess >= phongspecularthresh))
00932 myspecular=mat_specular;
00933 fprintf(outfile, " Ambient %g Diffuse %g Specular %g Opacity %g\n",
00934 mat_ambient, mat_diffuse, myspecular, mat_opacity);
00935 } else {
00936 fprintf(outfile, " Ambient %g Diffuse %g Specular %g Opacity %g\n",
00937 1.0, 0.0, 0.0, mat_opacity);
00938 }
00939
00940 if (mat_transmode != 0) {
00941 fprintf(outfile, " TransMode R3D ");
00942 }
00943 if (mat_outline > 0.0) {
00944 fprintf(outfile, " Outline %g Outline_Width %g ",
00945 mat_outline, mat_outlinewidth);
00946 }
00947 fprintf(outfile, " Phong Plastic %g Phong_size %g ", mat_specular,
00948 mat_shininess);
00949 fprintf(outfile, "Color %g %g %g ", rgb[0], rgb[1], rgb[2]);
00950
00952 if (!involtex) {
00954 fprintf(outfile, "TexFunc 0\n\n");
00955 } else {
00957 float voluaxs[3];
00958 float volvaxs[3];
00959 float volwaxs[3];
00960 float volcent[3];
00961
00962
00963
00964 (transMat.top()).multplaneeq3d(xplaneeq, voluaxs);
00965 (transMat.top()).multplaneeq3d(yplaneeq, volvaxs);
00966 (transMat.top()).multplaneeq3d(zplaneeq, volwaxs);
00967
00968
00969 float invscale = 1.0f / scale_radius(1.0f);
00970 int i;
00971 for (i=0; i<3; i++) {
00972 voluaxs[i] *= invscale;
00973 volvaxs[i] *= invscale;
00974 volwaxs[i] *= invscale;
00975 }
00976
00977
00978
00979
00980 float volorgmol[3] = {0,0,0};
00981 volorgmol[0] = -xplaneeq[3] / norm(xplaneeq);
00982 volorgmol[1] = -yplaneeq[3] / norm(yplaneeq);
00983 volorgmol[2] = -zplaneeq[3] / norm(zplaneeq);
00984
00985
00986 (transMat.top()).multpoint3d(volorgmol, volcent);
00987
00988
00989 fprintf(outfile, "\n TexFunc 10 ::VMDVolTex%d\n", voltexID);
00990 fprintf(outfile, " Center %g %g %g\n", volcent[0], volcent[1], -volcent[2]);
00991 fprintf(outfile, " Rotate 0 0 0\n");
00992 fprintf(outfile, " Scale 1 1 1\n");
00993 fprintf(outfile, " Uaxis %g %g %g\n", voluaxs[0], voluaxs[1], -voluaxs[2]);
00994 fprintf(outfile, " Vaxis %g %g %g\n", volvaxs[0], volvaxs[1], -volvaxs[2]);
00995 fprintf(outfile, " Waxis %g %g %g\n", volwaxs[0], volwaxs[1], -volwaxs[2]);
00996 fprintf(outfile, "\n");
00997 }
00998 }
00999
01000
01001
01002