00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include "utilities.h"
00027 #include "DispCmds.h"
00028 #include "FileRenderer.h"
00029 #include "VMDDisplayList.h"
00030 #include "Inform.h"
00031 #include "Scene.h"
00032 #include "Hershey.h"
00033
00034
00035 FileRenderer::FileRenderer(const char *public_name,
00036 const char *public_pretty_name,
00037 const char *default_file_name,
00038 const char *default_command_line) :
00039 DisplayDevice(public_name), transMat(10)
00040 {
00041
00042 publicName = stringdup(public_name);
00043 publicPrettyName = stringdup(public_pretty_name);
00044 defaultFilename = stringdup(default_file_name);
00045 defaultCommandLine = stringdup(default_command_line);
00046 execCmd = stringdup(defaultCommandLine);
00047 has_aa = 0;
00048 aasamples = -1;
00049 aosamples = -1;
00050 has_imgsize = 0;
00051 imgwidth = imgheight = 0;
00052 aspectratio = 0.0f;
00053 curformat = -1;
00054 warningflags = FILERENDERER_NOWARNINGS;
00055
00056
00057 outfile = NULL;
00058 isOpened = FALSE;
00059 my_filename = NULL;
00060
00061
00062 sph_nverts = 0;
00063 sph_verts = NULL;
00064 }
00065
00066
00067 FileRenderer::~FileRenderer(void) {
00068
00069 if (sph_verts && sph_nverts)
00070 free(sph_verts);
00071
00072 close_file();
00073 delete [] my_filename;
00074 delete [] publicName;
00075 delete [] publicPrettyName;
00076 delete [] defaultFilename;
00077 delete [] defaultCommandLine;
00078 delete [] execCmd;
00079 }
00080
00081 int FileRenderer::do_define_light(int n, float *color, float *position) {
00082 if (n < 0 || n >= DISP_LIGHTS)
00083 return FALSE;
00084
00085 for (int i=0; i<3; i++) {
00086 lightState[n].color[i] = color[i];
00087 lightState[n].pos[i] = position[i];
00088 }
00089 return TRUE;
00090 }
00091
00092 int FileRenderer::do_activate_light(int n, int turnon) {
00093 if (n < 0 || n >= DISP_LIGHTS)
00094 return FALSE;
00095
00096 lightState[n].on = turnon;
00097 return TRUE;
00098 }
00099
00100 int FileRenderer::do_define_adv_light(int n, float *color,
00101 float *position,
00102 float constant, float linear, float quad,
00103 float *spotdir, float fallstart,
00104 float fallend, int spoton) {
00105 if(n < 0 || n >= DISP_LIGHTS)
00106 return FALSE;
00107
00108 for (int i=0; i < 3; i++) {
00109 advLightState[n].color[i] = color[i];
00110 advLightState[n].pos[i] = position[i];
00111 advLightState[n].spotdir[i] = spotdir[i];
00112 }
00113 advLightState[n].constfactor = constant;
00114 advLightState[n].linearfactor = linear;
00115 advLightState[n].quadfactor = quad;
00116 advLightState[n].fallstart = fallstart;
00117 advLightState[n].fallend = fallend;
00118 advLightState[n].spoton = spoton;
00119 return TRUE;
00120 }
00121
00122 int FileRenderer::do_activate_adv_light(int n, int turnon) {
00123 if (n < 0 || n >= DISP_LIGHTS)
00124 return FALSE;
00125
00126 advLightState[n].on = turnon;
00127 return TRUE;
00128 }
00129
00130
00131
00132 void FileRenderer::do_use_colors() {
00133 for (int i=0; i<MAXCOLORS; i++) {
00134 matData[i][0] = colorData[3L*i ];
00135 matData[i][1] = colorData[3L*i+1];
00136 matData[i][2] = colorData[3L*i+2];
00137 }
00138 }
00139
00140 int FileRenderer::set_imagesize(int *w, int *h) {
00141 if (*w < 0 || *h < 0) return FALSE;
00142 if (*w == imgwidth && *h == imgheight) return TRUE;
00143 if (!aspectratio) {
00144 if (*w) imgwidth = *w;
00145 if (*h) imgheight = *h;
00146 } else {
00147 if (*w) {
00148 imgwidth = *w;
00149 imgheight = (int)(*w / aspectratio);
00150 } else if (*h) {
00151 imgwidth = (int)(*h * aspectratio);
00152 imgheight = *h;
00153 } else {
00154 if (imgwidth || imgheight) {
00155 int wtmp = imgwidth, htmp = imgheight;
00156 set_imagesize(&wtmp, &htmp);
00157 }
00158 }
00159 }
00160 update_exec_cmd();
00161 *w = imgwidth;
00162 *h = imgheight;
00163 return TRUE;
00164 }
00165
00166 float FileRenderer::set_aspectratio(float aspect) {
00167 if (aspect >= 0) aspectratio = aspect;
00168 int w=0, h=0;
00169 set_imagesize(&w, &h);
00170 return aspectratio;
00171 }
00172
00173 int FileRenderer::nearest_index(float r, float g, float b) const {
00174 const float *rcol = matData[BEGREGCLRS];
00175 float lsq = r - rcol[0]; lsq *= lsq;
00176 float tmp = g - rcol[1]; lsq += tmp * tmp;
00177 tmp = b - rcol[2]; lsq += tmp * tmp;
00178 float best = lsq;
00179 int bestidx = BEGREGCLRS;
00180 for (int n=BEGREGCLRS+1; n < (BEGREGCLRS + REGCLRS + MAPCLRS); n++) {
00181 rcol = matData[n];
00182 lsq = r - rcol[0]; lsq *= lsq;
00183 tmp = g - rcol[1]; lsq += tmp * tmp;
00184 tmp = b - rcol[2]; lsq += tmp * tmp;
00185 if (lsq < best) {
00186 best = lsq;
00187 bestidx = n;
00188 }
00189 }
00190 return bestidx;
00191 }
00192
00193 void FileRenderer::set_background(const float * bg) {
00194 backColor[0] = bg[0];
00195 backColor[1] = bg[1];
00196 backColor[2] = bg[2];
00197 }
00198
00199 void FileRenderer::set_backgradient(const float *top, const float *bot) {
00200 vec_copy(backgradienttopcolor, top);
00201 vec_copy(backgradientbotcolor, bot);
00202 }
00203
00204
00205
00206 int FileRenderer::open_file(const char *filename) {
00207 if (isOpened) {
00208 close_file();
00209 }
00210 if ((outfile = fopen(filename, "w")) == NULL) {
00211 msgErr << "Could not open file " << filename
00212 << " in current directory for writing!" << sendmsg;
00213 return FALSE;
00214 }
00215 my_filename = stringdup(filename);
00216 isOpened = TRUE;
00217 reset_state();
00218 return TRUE;
00219 }
00220
00221 void FileRenderer::reset_state(void) {
00222
00223 transMat.clear();
00224
00225
00226 colorIndex = -1;
00227 materialIndex = -1;
00228 lineWidth = 1;
00229 lineStyle = ::SOLIDLINE;
00230 pointSize = 1;
00231 sphereResolution = 4;
00232 sphereStyle = 1;
00233 materials_on = 0;
00234 }
00235
00236
00237
00238 void FileRenderer::close_file(void) {
00239 if (outfile) {
00240 fclose(outfile);
00241 outfile = NULL;
00242 }
00243 delete [] my_filename;
00244 my_filename = NULL;
00245 isOpened = FALSE;
00246 }
00247
00248
00249 int FileRenderer::prepare3D(int) {
00250
00251
00252
00253 int i;
00254 float lookat[3];
00255 for (i=0; i<3; i++)
00256 lookat[i] = eyePos[i] + eyeDir[i];
00257
00258 switch (whichEye) {
00259 case LEFTEYE:
00260 for (i=0; i<3; i++)
00261 eyePos[i] -= eyeSepDir[i];
00262
00263 for (i=0; i<3; i++)
00264 eyeDir[i] = lookat[i] - eyePos[i];
00265 break;
00266
00267 case RIGHTEYE:
00268 for (i=0; i<3; i++)
00269 eyePos[i] += eyeSepDir[i];
00270
00271 for (i=0; i<3; i++)
00272 eyeDir[i] = lookat[i] - eyePos[i];
00273 break;
00274
00275 case NOSTEREO:
00276 break;
00277 }
00278
00279 if (isOpened) {
00280 write_header();
00281 }
00282
00283 return TRUE;
00284 }
00285
00287
00288 void FileRenderer::render(const VMDDisplayList *cmdList) {
00289 if (!cmdList) return;
00290 int tok, i;
00291 char *cmdptr;
00292
00293
00294
00295
00296 transMat.clear();
00297 Matrix4 m;
00298 transMat.push(m);
00299 super_multmatrix(cmdList->mat.mat);
00300
00301 colorIndex = 0;
00302 materialIndex = 0;
00303 pointSize = 1;
00304 lineWidth = 1;
00305 lineStyle = ::SOLIDLINE;
00306 sphereResolution = 4;
00307 sphereStyle = 1;
00308
00309
00310 super_set_material(cmdList->materialtag);
00311 mat_ambient = cmdList->ambient;
00312 mat_specular = cmdList->specular;
00313 mat_diffuse = cmdList->diffuse;
00314 mat_shininess = cmdList->shininess;
00315 mat_mirror = cmdList->mirror;
00316 mat_opacity = cmdList->opacity;
00317 mat_outline = cmdList->outline;
00318 mat_outlinewidth = cmdList->outlinewidth;
00319 mat_transmode = cmdList->transmode;
00320
00321 for (i=0; i<VMD_MAX_CLIP_PLANE; i++) {
00322 clip_mode[i] = cmdList->clipplanes[i].mode;
00323 memcpy(&clip_center[i][0], &cmdList->clipplanes[i].center, 3L*sizeof(float));
00324 memcpy(&clip_normal[i][0], &cmdList->clipplanes[i].normal, 3L*sizeof(float));
00325 memcpy(&clip_color[i][0], &cmdList->clipplanes[i].color, 3L*sizeof(float));
00326 }
00327 start_clipgroup();
00328
00329
00330 ResizeArray<Matrix4> pbcImages;
00331 find_pbc_images(cmdList, pbcImages);
00332 int npbcimages = pbcImages.num();
00333
00334
00335 ResizeArray<Matrix4> instanceImages;
00336 find_instance_images(cmdList, instanceImages);
00337 int ninstances = instanceImages.num();
00338
00339 for (int pbcimage = 0; pbcimage < npbcimages; pbcimage++) {
00340 transMat.dup();
00341 super_multmatrix(pbcImages[pbcimage].mat);
00342
00343 for (int instanceimage = 0; instanceimage < ninstances; instanceimage++) {
00344 transMat.dup();
00345 super_multmatrix(instanceImages[instanceimage].mat);
00346
00347 VMDDisplayList::VMDLinkIter cmditer;
00348 cmdList->first(&cmditer);
00349 while ((tok = cmdList->next(&cmditer, cmdptr)) != DLASTCOMMAND) {
00350 switch (tok) {
00351 case DPOINT:
00352 point(((DispCmdPoint *)cmdptr)->pos);
00353 break;
00354
00355 case DPOINTARRAY:
00356 {
00357 DispCmdPointArray *pa = (DispCmdPointArray *)cmdptr;
00358 float *centers, *colors;
00359 pa->getpointers(centers, colors);
00360 point_array(pa->numpoints, pa->size, centers, colors);
00361 }
00362 break;
00363
00364 case DLITPOINTARRAY:
00365 {
00366 DispCmdLitPointArray *pa = (DispCmdLitPointArray *)cmdptr;
00367 float *centers, *normals, *colors;
00368 pa->getpointers(centers, normals, colors);
00369 point_array_lit(pa->numpoints, pa->size, centers, normals, colors);
00370 }
00371 break;
00372
00373 case DSPHERE:
00374 sphere((float *)cmdptr);
00375 break;
00376
00377 case DSPHEREARRAY:
00378 {
00379 DispCmdSphereArray *sa = (DispCmdSphereArray *)cmdptr;
00380 float *centers, *radii, *colors;
00381 sa->getpointers(centers, radii, colors);
00382 sphere_array(sa->numspheres, sa->sphereres, centers, radii, colors);
00383 }
00384 break;
00385
00386 #ifdef VMDLATTICECUBES
00387 case DCUBEARRAY:
00388 {
00389 DispCmdLatticeCubeArray *ca = (DispCmdLatticeCubeArray *)cmdptr;
00390 float *centers, *radii, *colors;
00391 ca->getpointers(centers, radii, colors);
00392 cube_array(ca->numcubes, centers, radii, colors);
00393 }
00394 break;
00395 #endif
00396
00397 case DLINE:
00398
00399 if (memcmp(cmdptr, cmdptr+3L*sizeof(float), 3L*sizeof(float))) {
00400 line((float *)cmdptr, ((float *)cmdptr) + 3);
00401 }
00402 break;
00403
00404 case DLINEARRAY:
00405 {
00406 float *v = (float *) cmdptr;
00407 int nlines = (int)v[0];
00408 v++;
00409 line_array(nlines, (float) lineWidth, v);
00410 }
00411 break;
00412
00413 case DPOLYLINEARRAY:
00414 {
00415 float *v = (float *) cmdptr;
00416 int nlines = (int)v[0];
00417 v++;
00418 polyline_array(nlines, (float) lineWidth, v);
00419 }
00420 break;
00421
00422 case DCYLINDER:
00423 if (memcmp(cmdptr, cmdptr+3L*sizeof(float), 3L*sizeof(float))) {
00424 cylinder((float *)cmdptr, ((float *)cmdptr) + 3, ((float *)cmdptr)[6],
00425 ((int) ((float *) cmdptr)[8]));
00426 }
00427 break;
00428
00429 #if defined(VMDOPTIXRTRT)
00430 case DCYLINDERARRAY:
00431 {
00432 DispCmdCylinderArray *ca = (DispCmdCylinderArray *)cmdptr;
00433 float *points, *radii, *colors;
00434 ca->getpointers(points, radii, colors);
00435 cylinder_array(ca->numcylinders, ca->cylinderres, ca->cylindercaps,
00436 points, radii, colors);
00437 }
00438 break;
00439 #endif
00440
00441 case DCONE:
00442 {
00443 DispCmdCone *cmd = (DispCmdCone *)cmdptr;
00444 if (memcmp(cmd->pos1, cmd->pos2, 3L*sizeof(float)))
00445 cone_trunc(cmd->pos1, cmd->pos2, cmd->radius, cmd->radius2, cmd->res);
00446 }
00447 break;
00448
00449 case DTRIANGLE:
00450 {
00451 DispCmdTriangle *cmd = (DispCmdTriangle *)cmdptr;
00452 triangle(cmd->pos1,cmd->pos2,cmd->pos3,
00453 cmd->norm1, cmd->norm2, cmd->norm3);
00454 }
00455 break;
00456
00457 case DTRIMESH_C3F_N3F_V3F:
00458 {
00459 DispCmdTriMesh *cmd = (DispCmdTriMesh *) cmdptr;
00460 float *c=NULL, *n=NULL, *v=NULL;
00461
00462 if (cmd->pervertexcolors) {
00463 cmd->getpointers(c, n, v);
00464 trimesh_c3f_n3f_v3f(c, n, v, cmd->numfacets);
00465 } else if (cmd->pervertexnormals) {
00466 cmd->getpointers(n, v);
00467 trimesh_n3f_v3f(n, v, cmd->numfacets);
00468 } else {
00469 cmd->getpointers(n, v);
00470 trimesh_n3fopt_v3f(n, v, cmd->numfacets);
00471 }
00472 }
00473 break;
00474
00475 case DTRIMESH_C4F_N3F_V3F:
00476 {
00477 DispCmdTriMesh *cmd = (DispCmdTriMesh *) cmdptr;
00478 float *cnv=NULL;
00479 int *f=NULL;
00480 cmd->getpointers(cnv, f);
00481 trimesh_c4n3v3(cmd->numverts, cnv, cmd->numfacets, f);
00482 }
00483 break;
00484
00485 case DTRIMESH_C4U_N3F_V3F:
00486 {
00487 DispCmdTriMesh *cmd = (DispCmdTriMesh *) cmdptr;
00488 unsigned char *c=NULL;
00489 float *n=NULL, *v=NULL;
00490
00491 if (cmd->pervertexcolors) {
00492 cmd->getpointers(c, n, v);
00493 trimesh_c4u_n3f_v3f(c, n, v, cmd->numfacets);
00494 } else {
00495 cmd->getpointers(n, v);
00496 trimesh_n3f_v3f(n, v, cmd->numfacets);
00497 }
00498 }
00499 break;
00500
00501 case DTRIMESH_C4U_N3B_V3F:
00502 {
00503 DispCmdTriMesh *cmd = (DispCmdTriMesh *) cmdptr;
00504 unsigned char *c=NULL;
00505 signed char *n=NULL;
00506 float *v=NULL;
00507
00508 if (cmd->pervertexcolors) {
00509 cmd->getpointers(c, n, v);
00510 trimesh_c4u_n3b_v3f(c, n, v, cmd->numfacets);
00511 } else {
00512 cmd->getpointers(n, v);
00513 trimesh_n3b_v3f(n, v, cmd->numfacets);
00514 }
00515 }
00516 break;
00517
00518 case DTRISTRIP:
00519 {
00520 DispCmdTriStrips *cmd = (DispCmdTriStrips *) cmdptr;
00521 float *cnv=NULL;
00522 int *f=NULL;
00523 int *vertsperstrip;
00524 cmd->getpointers(cnv, f, vertsperstrip);
00525 tristrip(cmd->numverts, cnv, cmd->numstrips, vertsperstrip, f);
00526 }
00527 break;
00528
00529 case DWIREMESH:
00530 {
00531 DispCmdWireMesh *cmd = (DispCmdWireMesh *) cmdptr;
00532 float *cnv=NULL;
00533 int *l=NULL;
00534 cmd->getpointers(cnv, l);
00535 wiremesh(cmd->numverts, cnv, cmd->numlines, l);
00536 }
00537 break;
00538
00539 case DSQUARE:
00540 {
00541 DispCmdSquare *cmd = (DispCmdSquare *)cmdptr;
00542 square(cmd->norml, cmd->pos1, cmd->pos2, cmd->pos3, cmd->pos4);
00543 }
00544 break;
00545
00546
00548 case DLINEWIDTH:
00549 lineWidth = ((DispCmdLineWidth *)cmdptr)->width;
00550 set_line_width(lineWidth);
00551 break;
00552
00553 case DLINESTYLE:
00554 lineStyle = ((DispCmdLineType *)cmdptr)->type;
00555 set_line_style(lineStyle);
00556 break;
00557
00558 case DSPHERERES:
00559 sphereResolution = ((DispCmdSphereRes *)cmdptr)->res;
00560 set_sphere_res(sphereResolution);
00561 break;
00562
00563 case DSPHERETYPE:
00564 sphereStyle = ((DispCmdSphereType *)cmdptr)->type;
00565 set_sphere_style(sphereStyle);
00566 break;
00567
00568 case DMATERIALON:
00569 super_materials(1);
00570 break;
00571
00572 case DMATERIALOFF:
00573 super_materials(0);
00574 break;
00575
00576 case DCOLORINDEX:
00577 super_set_color(((DispCmdColorIndex *)cmdptr)->color);
00578 break;
00579
00580 case DTEXT:
00581 {
00582 float *pos = (float *)cmdptr;
00583 float textsize = pos[4];
00584 #if 0
00585
00586 float textoffset_x = pos[5];
00587 float textoffset_y = pos[6];
00588 #endif
00589 text(pos, textsize, pos[3], (char *) (pos+7));
00590 }
00591 break;
00592
00593 case DBEGINREPGEOMGROUP:
00594 beginrepgeomgroup((char *)cmdptr);
00595 break;
00596
00597 case DCOMMENT:
00598 comment((char *)cmdptr);
00599 break;
00600
00601 case DPICKPOINT_ARRAY:
00602 {
00603 int i;
00604 DispCmdPickPointArray *cmd = ((DispCmdPickPointArray *)cmdptr);
00605 float *crds=NULL;
00606 int *indices=NULL;
00607 cmd->getpointers(crds, indices);
00608 if (cmd->allselected) {
00609 for (i=0; i<cmd->numpicks; i++) {
00610 pick_point(crds + i*3L, i);
00611 }
00612 } else {
00613 for (i=0; i<cmd->numpicks; i++) {
00614 pick_point(crds + i*3L, indices[i]);
00615 }
00616 }
00617 }
00618 break;
00619
00620
00621 #if 0
00622 case DSTRIPETEXON:
00623 case DSTRIPETEXOFF:
00624 #endif
00625 case DVOLUMETEXTURE:
00626 {
00627 DispCmdVolumeTexture *cmd = (DispCmdVolumeTexture *)cmdptr;
00628 float xplaneeq[4];
00629 float yplaneeq[4];
00630 float zplaneeq[4];
00631 int i;
00632
00633
00634
00635 for (i=0; i<3; i++) {
00636 xplaneeq[i] = cmd->v1[i];
00637 yplaneeq[i] = cmd->v2[i];
00638 zplaneeq[i] = cmd->v3[i];
00639 }
00640 xplaneeq[3] = cmd->v0[0];
00641 yplaneeq[3] = cmd->v0[1];
00642 zplaneeq[3] = cmd->v0[2];
00643
00644
00645 define_volume_texture(cmd->ID, cmd->xsize, cmd->ysize, cmd->zsize,
00646 xplaneeq, yplaneeq, zplaneeq,
00647 cmd->texmap);
00648 volume_texture_on(1);
00649 }
00650 break;
00651
00652 case DVOLSLICE:
00653 {
00654
00655
00656 super_materials(0);
00657 DispCmdVolSlice *cmd = (DispCmdVolSlice *)cmdptr;
00658 volume_texture_on(1);
00659 square(cmd->normal, cmd->v, cmd->v + 3, cmd->v + 6, cmd->v + 9);
00660 volume_texture_off();
00661 super_materials(1);
00662 }
00663 break;
00664
00665 case DVOLTEXON:
00666 volume_texture_on(0);
00667 break;
00668
00669 case DVOLTEXOFF:
00670 volume_texture_off();
00671 break;
00672
00673 #if 0
00674
00675 default:
00676 warningflags |= FILERENDERER_NOMISCFEATURE;
00677 break;
00678 #endif
00679 }
00680 }
00681
00682 transMat.pop();
00683 }
00684
00685 transMat.pop();
00686 }
00687
00688 end_clipgroup();
00689 }
00690
00692
00693
00694
00695 void FileRenderer::super_set_color(int color_index) {
00696 if (colorIndex != color_index) {
00697 colorIndex = color_index;
00698 set_color(color_index);
00699 }
00700 }
00701
00702
00703 void FileRenderer::super_set_material(int material_index) {
00704 if (materialIndex != material_index) {
00705 materialIndex = material_index;
00706 set_material(material_index);
00707 }
00708 }
00709
00710
00711 void FileRenderer::super_materials(int on_or_off) {
00712 if (on_or_off) {
00713 materials_on = 1;
00714 activate_materials();
00715 } else {
00716 materials_on = 0;
00717 deactivate_materials();
00718 }
00719 }
00720
00721
00723
00724 void FileRenderer::super_load(float *cmdptr) {
00725 Matrix4 tmp(cmdptr);
00726 (transMat.top()).loadmatrix(tmp);
00727 load(tmp);
00728 }
00729 void FileRenderer::super_multmatrix(const float *cmdptr) {
00730 Matrix4 tmp(cmdptr);
00731 (transMat.top()).multmatrix(tmp);
00732 multmatrix(tmp);
00733 }
00734
00735 void FileRenderer::super_translate(float *cmdptr) {
00736 (transMat.top()).translate( cmdptr[0], cmdptr[1], cmdptr[2]);
00737 translate( cmdptr[0], cmdptr[1], cmdptr[2]);
00738 }
00739
00740 void FileRenderer::super_rot(float * cmdptr) {
00741 (transMat.top()).rot( cmdptr[0], 'x' + (int) (cmdptr[1]) );
00742 rot( cmdptr[0], 'x' + (int) (cmdptr[1]) );
00743 }
00744
00745 void FileRenderer::super_scale(float *cmdptr) {
00746 (transMat.top()).scale( cmdptr[0], cmdptr[1], cmdptr[2] );
00747 scale( cmdptr[0], cmdptr[1], cmdptr[2] );
00748 }
00749
00750 void FileRenderer::super_scale(float s) {
00751 transMat.top().scale(s,s,s);
00752 scale(s,s,s);
00753 }
00754
00755
00756 float FileRenderer::scale_factor(void) {
00757
00758
00759
00760 float scaleFactor;
00761
00762 float *mat = &transMat.top().mat[0];
00763 scaleFactor = (sqrtf(mat[0]*mat[0] + mat[4]*mat[4] + mat[ 8]*mat[ 8]) +
00764 sqrtf(mat[1]*mat[1] + mat[5]*mat[5] + mat[ 9]*mat[ 9]) +
00765 sqrtf(mat[2]*mat[2] + mat[6]*mat[6] + mat[10]*mat[10])) / 3.0f;
00766
00767 return scaleFactor;
00768 }
00769
00770
00771 float FileRenderer::scale_radius(float r) {
00772 float scaleFactor = scale_factor();
00773 if (r < 0.0) {
00774 msgErr << "FileRenderer: Error, Negative radius" << sendmsg;
00775 r = -r;
00776 }
00777 r = r * scaleFactor;
00778 return r;
00779 }
00780
00781
00783 void FileRenderer::set_exec_string(const char *extstr) {
00784 delete [] execCmd;
00785 execCmd = stringdup(extstr);
00786 }
00787
00788
00789
00790 void FileRenderer::cone_trunc(float *base, float *apex, float radius, float radius2, int numsides) {
00791 int h;
00792 float theta, incTheta, cosTheta, sinTheta;
00793 float axis[3], temp[3], perp[3], perp2[3];
00794 float vert0[3], vert1[3], vert2[3], edge0[3], edge1[3], face0[3], face1[3], norm0[3], norm1[3];
00795
00796 axis[0] = base[0] - apex[0];
00797 axis[1] = base[1] - apex[1];
00798 axis[2] = base[2] - apex[2];
00799 vec_normalize(axis);
00800
00801
00802 temp[0] = axis[0] - 1.0f;
00803 temp[1] = 1.0f;
00804 temp[2] = 1.0f;
00805
00806
00807 cross_prod(perp, axis, temp);
00808 vec_normalize(perp);
00809 cross_prod(perp2, axis, perp);
00810
00811
00812 incTheta = (float) VMD_TWOPI / numsides;
00813 theta = 0.0;
00814
00815
00816
00817 if (radius2 > 0) {
00818 float negaxis[3], offsetL[3], offsetT[3], vert3[3];
00819 int filled=1;
00820 vec_negate(negaxis, axis);
00821 memset(vert0, 0, sizeof(vert0));
00822 memset(vert1, 0, sizeof(vert1));
00823 memset(norm0, 0, sizeof(norm0));
00824
00825 for (h=0; h <= numsides+3; h++) {
00826
00827
00828 sincosf(theta, &sinTheta, &cosTheta);
00829 offsetL[0] = radius2 * (cosTheta*perp[0] + sinTheta*perp2[0]);
00830 offsetL[1] = radius2 * (cosTheta*perp[1] + sinTheta*perp2[1]);
00831 offsetL[2] = radius2 * (cosTheta*perp[2] + sinTheta*perp2[2]);
00832 offsetT[0] = radius * (cosTheta*perp[0] + sinTheta*perp2[0]);
00833 offsetT[1] = radius * (cosTheta*perp[1] + sinTheta*perp2[1]);
00834 offsetT[2] = radius * (cosTheta*perp[2] + sinTheta*perp2[2]);
00835
00836
00837 vec_copy(vert2, vert0);
00838 vec_copy(vert3, vert1);
00839 vec_copy(norm1, norm0);
00840
00841
00842 vec_add(vert0, base, offsetT);
00843 vec_add(vert1, apex, offsetL);
00844
00845
00846 edge0[0] = vert0[0] - vert1[0];
00847 edge0[1] = vert0[1] - vert1[1];
00848 edge0[2] = vert0[2] - vert1[2];
00849 edge1[0] = vert0[0] - vert2[0];
00850 edge1[1] = vert0[1] - vert2[1];
00851 edge1[2] = vert0[2] - vert2[2];
00852
00853
00854 cross_prod(norm0, edge1, edge0);
00855 vec_normalize(norm0);
00856
00857 if (h > 2) {
00858
00859 triangle(vert0, vert3, vert1, norm0, norm1, norm0);
00860 triangle(vert3, vert0, vert2, norm1, norm0, norm1);
00861
00862
00863 if (filled & CYLINDER_LEADINGCAP) {
00864 triangle(vert1, vert3, apex, axis, axis, axis);
00865 }
00866 if (filled & CYLINDER_TRAILINGCAP) {
00867 triangle(vert0, vert2, base, negaxis, negaxis, negaxis);
00868 }
00869 }
00870
00871 theta += incTheta;
00872 }
00873 } else {
00874
00875 for (h=0; h < numsides+3; h++) {
00876
00877
00878 sincosf(theta, &sinTheta, &cosTheta);
00879 vert0[0] = base[0] + radius * (cosTheta*perp[0] + sinTheta*perp2[0]);
00880 vert0[1] = base[1] + radius * (cosTheta*perp[1] + sinTheta*perp2[1]);
00881 vert0[2] = base[2] + radius * (cosTheta*perp[2] + sinTheta*perp2[2]);
00882
00883
00884 edge0[0] = vert0[0] - apex[0];
00885 edge0[1] = vert0[1] - apex[1];
00886 edge0[2] = vert0[2] - apex[2];
00887
00888 if (h > 0) {
00889
00890 cross_prod(face0, edge1, edge0);
00891 vec_normalize(face0);
00892
00893 if (h > 1) {
00894
00895 norm0[0] = (face1[0] + face0[0]) * 0.5f;
00896 norm0[1] = (face1[1] + face0[1]) * 0.5f;
00897 norm0[2] = (face1[2] + face0[2]) * 0.5f;
00898 vec_normalize(norm0);
00899
00900 if (h > 2) {
00901
00902 triangle(vert2, vert1, apex, norm1, norm0, face1);
00903 triangle(vert2, vert1, base, axis, axis, axis);
00904 }
00905
00906 }
00907
00908
00909 memcpy(norm1, norm0, 3L*sizeof(float));
00910 memcpy(vert2, vert1, 3L*sizeof(float));
00911 memcpy(face1, face0, 3L*sizeof(float));
00912 }
00913 memcpy(vert1, vert0, 3L*sizeof(float));
00914 memcpy(edge1, edge0, 3L*sizeof(float));
00915
00916 theta += incTheta;
00917 }
00918 }
00919 }
00920
00921
00922
00923 void FileRenderer::cylinder(float *base, float *apex, float radius, int filled) {
00924 const int numsides = 20;
00925 int h;
00926 float theta, incTheta, cosTheta, sinTheta;
00927 float axis[3], negaxis[3], temp[3], perp[3], perp2[3], offset[3];
00928
00929 axis[0] = base[0] - apex[0];
00930 axis[1] = base[1] - apex[1];
00931 axis[2] = base[2] - apex[2];
00932 vec_normalize(axis);
00933 vec_negate(negaxis, axis);
00934
00935
00936 temp[0] = axis[0] - 1.0f;
00937 temp[1] = 1.0f;
00938 temp[2] = 1.0f;
00939
00940
00941 cross_prod(perp, axis, temp);
00942 vec_normalize(perp);
00943 cross_prod(perp2, axis, perp);
00944
00945
00946 incTheta = (float) VMD_TWOPI / numsides;
00947 theta = 0.0;
00948
00949 const int stripsz = (2L*numsides) * 6L;
00950 float *stripnv = new float[stripsz];
00951 memset(stripnv, 0, sizeof(float) * stripsz);
00952
00953 const int capsz = numsides+1;
00954 float *lcapnv = new float[capsz*6L];
00955 memset(lcapnv, 0, sizeof(float)*capsz*6L);
00956 vec_copy(&lcapnv[0], negaxis);
00957 vec_copy(&lcapnv[3], apex);
00958
00959 float *tcapnv = new float[capsz*6L];
00960 memset(tcapnv, 0, sizeof(float)*capsz*6L);
00961 vec_copy(&tcapnv[0], axis);
00962 vec_copy(&tcapnv[3], base);
00963
00964 for (h=0; h < numsides; h++) {
00965
00966
00967 sincosf(theta, &sinTheta, &cosTheta);
00968 offset[0] = radius * (cosTheta*perp[0] + sinTheta*perp2[0]);
00969 offset[1] = radius * (cosTheta*perp[1] + sinTheta*perp2[1]);
00970 offset[2] = radius * (cosTheta*perp[2] + sinTheta*perp2[2]);
00971
00972
00973 float lvert[3], tvert[3];
00974 vec_add(lvert, apex, offset);
00975 vec_add(tvert, base, offset);
00976 vec_copy(&stripnv[((2L*h)*6L)+9L], lvert);
00977 vec_copy(&stripnv[((2L*h)*6L)+3L], tvert);
00978 vec_copy(&lcapnv[((1L+h)*6L)+3L], lvert);
00979 vec_copy(&tcapnv[((1L+h)*6L)+3L], tvert);
00980
00981
00982 vec_normalize(offset);
00983 vec_copy(&stripnv[((2L*h)*6L) ], offset);
00984 vec_copy(&stripnv[((2L*h)*6L)+6], offset);
00985 vec_copy(&lcapnv[((1+h)*6L)], negaxis);
00986 vec_copy(&tcapnv[((1+h)*6L)], axis);
00987
00988 theta += incTheta;
00989 }
00990
00991 const int vertsperstrip = (numsides + 1)*2L;
00992 int *stripfaces = new int[vertsperstrip];
00993 memset(stripfaces, 0, sizeof(float) * vertsperstrip);
00994 for (h=0; h < vertsperstrip-2; h++) {
00995 stripfaces[h] = h;
00996 }
00997 stripfaces[h ] = 0;
00998 stripfaces[h+1] = 1;
00999
01000 tristrip_singlecolor(2L*numsides, &stripnv[0],
01001 1, &colorIndex, &vertsperstrip, &stripfaces[0]);
01002 delete [] stripfaces;
01003
01004
01005 if (filled & CYLINDER_LEADINGCAP) {
01006 const int vertsperfan = capsz+1;
01007 int *fanfaces = new int[vertsperfan];
01008 memset(fanfaces, 0, sizeof(float) * vertsperfan);
01009 fanfaces[0] = 0;
01010 for (h=1; h < capsz; h++) {
01011 fanfaces[h] = capsz-h;
01012 }
01013 fanfaces[h] = capsz-1;
01014 trifan_singlecolor(capsz-1, &lcapnv[0],
01015 1, &colorIndex, &vertsperfan, &fanfaces[0]);
01016 delete [] fanfaces;
01017 }
01018 if (filled & CYLINDER_TRAILINGCAP) {
01019 const int vertsperfan = capsz+1;
01020 int *fanfaces = new int[vertsperfan];
01021 memset(fanfaces, 0, sizeof(float) * vertsperfan);
01022 fanfaces[0] = 0;
01023 for (h=1; h < capsz; h++) {
01024 fanfaces[h] = h;
01025 }
01026 fanfaces[h] = 1;
01027 trifan_singlecolor(capsz-1, &tcapnv[0],
01028 1, &colorIndex, &vertsperfan, &fanfaces[0]);
01029 delete [] fanfaces;
01030 }
01031
01032 delete [] stripnv;
01033 delete [] lcapnv;
01034 delete [] tcapnv;
01035 }
01036
01037
01038 #if defined(VMDOPTIXRTRT)
01039
01040
01041
01042
01043 void FileRenderer::cylinder_array(int cylnum, int cylres, int cylcaps,
01044 float *points, float *radii, float *colors) {
01045
01046 int i, ind3, ind6;
01047 for (i=0,ind3=0,ind6=0; i<cylnum; i++,ind3+=3,ind6+=6) {
01048 super_set_color(nearest_index(colors[ind3], colors[ind3+1], colors[ind3+2]));
01049 cylinder(points + ind6, points + ind6+3, radii[i], cylcaps);
01050 }
01051 }
01052
01053 #endif
01054
01055
01056
01057 void FileRenderer::line(float * a, float * b) {
01058
01059 int i, j, test;
01060 float dirvec[3], unitdirvec[3];
01061 float from[3], to[3];
01062
01063 if (lineStyle == ::SOLIDLINE) {
01064 cylinder(a, b, lineWidth * 0.1f, 0);
01065 } else if (lineStyle == ::DASHEDLINE) {
01066 vec_sub(dirvec, b, a);
01067 vec_copy(unitdirvec, dirvec);
01068 vec_normalize(unitdirvec);
01069 test = 1;
01070 i = 0;
01071 while (test == 1) {
01072 for (j=0; j<3; j++) {
01073 from[j] = (float) (a[j] + (2*i )* 0.05 * unitdirvec[j]);
01074 to[j] = (float) (a[j] + (2*i + 1)* 0.05 * unitdirvec[j]);
01075 }
01076 if (fabsf(a[0] - to[0]) >= fabsf(dirvec[0])) {
01077 vec_copy(to, b);
01078 test = 0;
01079 }
01080 cylinder(from, to, lineWidth * 0.1f, 0);
01081 i++;
01082 }
01083 }
01084 }
01085
01086
01087 void FileRenderer::line_array(int num, float thickness, float *points) {
01088 float *v = points;
01089 for (int i=0; i<num; i++) {
01090
01091 if (memcmp(v, v+3, 3L*sizeof(float))) {
01092 line(v, v+3);
01093 }
01094 v += 6;
01095 }
01096 }
01097
01098
01099 void FileRenderer::polyline_array(int num, float thickness, float *points) {
01100 float *v = points;
01101 for (int i=0; i<num-1; i++) {
01102
01103 if (memcmp(v, v+3, 3L*sizeof(float))) {
01104 line(v, v+3);
01105 }
01106 v += 3;
01107 }
01108 }
01109
01110
01111
01112 void FileRenderer::sphere(float * xyzr) {
01113 float c[3], r;
01114 int pi, ni;
01115 int i;
01116 int sph_iter = -1;
01117 int sph_desired_iter = 0;
01118
01119
01120 vec_copy(c, xyzr);
01121 r = xyzr[3];
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131 const int sph_iter_table[] = {
01132 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,
01133 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4 };
01134
01135 if (sphereResolution < 0)
01136 return;
01137 else if (sphereResolution < 32)
01138 sph_desired_iter = sph_iter_table[sphereResolution];
01139 else
01140 sph_desired_iter = (int) (0.8f * sqrtf((float) sphereResolution));
01141
01142
01143
01144
01145 if (!sph_verts || !sph_nverts || sph_iter != sph_desired_iter) {
01146 float a[3], b[3], c[3];
01147 float *newverts;
01148 float *oldverts;
01149 int nverts, ntris;
01150 int level;
01151
01152
01153 if (sph_verts && sph_nverts) free(sph_verts);
01154
01155 newverts = (float *) malloc(sizeof(float) * 36L);
01156 nverts = 12;
01157 ntris = 4;
01158
01159
01160
01161
01162 newverts[0] = -1; newverts[1] = 0; newverts[2] = 0;
01163 newverts[3] = 0; newverts[4] = 1; newverts[5] = 0;
01164 newverts[6] = 0; newverts[7] = 0; newverts[8] = 1;
01165
01166
01167 newverts[9] = 0; newverts[10] = 0; newverts[11] = 1;
01168 newverts[12] = 0; newverts[13] = 1; newverts[14] = 0;
01169 newverts[15] = 1; newverts[16] = 0; newverts[17] = 0;
01170
01171
01172 newverts[18] = 0; newverts[19] = 0; newverts[20] = 1;
01173 newverts[21] = 1; newverts[22] = 0; newverts[23] = 0;
01174 newverts[24] = 0; newverts[25] = -1; newverts[26] = 0;
01175
01176
01177 newverts[27] = 0; newverts[28] = 0; newverts[29] = 1;
01178 newverts[30] = 0; newverts[31] = -1; newverts[32] = 0;
01179 newverts[33] = -1; newverts[34] = 0; newverts[35] = 0;
01180
01181 for (level = 1; level < sph_desired_iter; level++) {
01182 oldverts = newverts;
01183
01184
01185
01186 newverts = (float *) malloc(sizeof(float) * 12L * nverts);
01187 if (!newverts) {
01188
01189 sph_iter = -1;
01190 sph_nverts = 0;
01191 sph_verts = NULL;
01192 free(oldverts);
01193 msgErr << "FileRenderer::sphere(): Out of memory. Some "
01194 << "objects were not drawn." << sendmsg;
01195 return;
01196 }
01197
01198 pi = 0;
01199 ni = 0;
01200 for (i = 0; i < ntris; i++) {
01201
01202 a[0] = (oldverts[pi ] + oldverts[pi + 6]) / 2;
01203 a[1] = (oldverts[pi + 1] + oldverts[pi + 7]) / 2;
01204 a[2] = (oldverts[pi + 2] + oldverts[pi + 8]) / 2;
01205 vec_normalize(a);
01206 b[0] = (oldverts[pi ] + oldverts[pi + 3]) / 2;
01207 b[1] = (oldverts[pi + 1] + oldverts[pi + 4]) / 2;
01208 b[2] = (oldverts[pi + 2] + oldverts[pi + 5]) / 2;
01209 vec_normalize(b);
01210 c[0] = (oldverts[pi + 3] + oldverts[pi + 6]) / 2;
01211 c[1] = (oldverts[pi + 4] + oldverts[pi + 7]) / 2;
01212 c[2] = (oldverts[pi + 5] + oldverts[pi + 8]) / 2;
01213 vec_normalize(c);
01214
01215
01216 memcpy(&newverts[ni ], &oldverts[pi], sizeof(float) * 3L);
01217 memcpy(&newverts[ni + 3 ], b, sizeof(float) * 3L);
01218 memcpy(&newverts[ni + 6 ], a, sizeof(float) * 3L);
01219
01220 memcpy(&newverts[ni + 9 ], b, sizeof(float) * 3L);
01221 memcpy(&newverts[ni + 12], &oldverts[pi + 3], sizeof(float) * 3L);
01222 memcpy(&newverts[ni + 15], c, sizeof(float) * 3L);
01223
01224 memcpy(&newverts[ni + 18], a, sizeof(float) * 3L);
01225 memcpy(&newverts[ni + 21], b, sizeof(float) * 3L);
01226 memcpy(&newverts[ni + 24], c, sizeof(float) * 3L);
01227
01228 memcpy(&newverts[ni + 27], a, sizeof(float) * 3L);
01229 memcpy(&newverts[ni + 30], c, sizeof(float) * 3L);
01230 memcpy(&newverts[ni + 33], &oldverts[pi + 6], sizeof(float) * 3L);
01231
01232 pi += 9;
01233 ni += 36;
01234 }
01235
01236 free(oldverts);
01237 nverts *= 4;
01238 ntris *= 4;
01239 }
01240
01241 sph_iter = sph_desired_iter;
01242 sph_nverts = nverts;
01243 sph_verts = newverts;
01244 }
01245
01246
01247
01248
01249 pi = 0;
01250 for (i = 0; i < sph_nverts / 3; i++) {
01251 float v0[3], v1[3], v2[3];
01252 float n0[3], n1[3], n2[3];
01253
01254
01255 v0[0] = r * sph_verts[pi ] + c[0];
01256 v0[1] = r * sph_verts[pi + 1] + c[1];
01257 v0[2] = r * sph_verts[pi + 2] + c[2];
01258 v1[0] = r * sph_verts[pi + 3] + c[0];
01259 v1[1] = r * sph_verts[pi + 4] + c[1];
01260 v1[2] = r * sph_verts[pi + 5] + c[2];
01261 v2[0] = r * sph_verts[pi + 6] + c[0];
01262 v2[1] = r * sph_verts[pi + 7] + c[1];
01263 v2[2] = r * sph_verts[pi + 8] + c[2];
01264
01265
01266 vec_copy(n0, &sph_verts[pi ]);
01267 vec_copy(n1, &sph_verts[pi + 3]);
01268 vec_copy(n2, &sph_verts[pi + 6]);
01269
01270
01271 triangle(v0, v2, v1, n0, n2, n1);
01272
01273
01274 v0[2] = (-r * sph_verts[pi + 2]) + c[2];
01275 v1[2] = (-r * sph_verts[pi + 5]) + c[2];
01276 v2[2] = (-r * sph_verts[pi + 8]) + c[2];
01277
01278
01279 n0[2] = -n0[2];
01280 n1[2] = -n1[2];
01281 n2[2] = -n2[2];
01282
01283
01284 triangle(v0, v1, v2, n0, n1, n2);
01285
01286 pi += 9;
01287 }
01288 }
01289
01290
01291
01292
01293
01294 void FileRenderer::sphere_array(int spnum, int spres,
01295 float *centers, float *radii, float *colors) {
01296 int i, ind;
01297 set_sphere_res(spres);
01298 ind = 0;
01299 for (i=0; i<spnum; i++) {
01300 float xyzr[4];
01301 xyzr[0]=centers[ind ];
01302 xyzr[1]=centers[ind + 1];
01303 xyzr[2]=centers[ind + 2];
01304 xyzr[3]=radii[i];
01305
01306 super_set_color(nearest_index(colors[ind], colors[ind+1], colors[ind+2]));
01307 sphere(xyzr);
01308 ind += 3;
01309 }
01310 }
01311
01312
01313
01314
01315
01316 void FileRenderer::cube_array(int cbnum, float *centers, float *radii, float *colors) {
01317 int i, ind;
01318 ind = 0;
01319 for (i=0; i<cbnum; i++) {
01320 float xyzr[4];
01321 xyzr[0]=centers[ind ];
01322 xyzr[1]=centers[ind + 1];
01323 xyzr[2]=centers[ind + 2];
01324 xyzr[3]=radii[i];
01325
01326 super_set_color(nearest_index(colors[ind], colors[ind+1], colors[ind+2]));
01327 cube(xyzr);
01328 ind += 3;
01329 }
01330 }
01331
01332
01333
01334
01335 void FileRenderer::point_array(int num, float size, float *xyz, float *colors) {
01336 int i, ind;
01337
01338 pointSize = (int) size;
01339
01340
01341 for (ind=0,i=0; i<num; i++) {
01342 super_set_color(nearest_index(colors[ind], colors[ind+1], colors[ind+2]));
01343 point(&xyz[ind]);
01344 ind += 3;
01345 }
01346
01347 pointSize = 1;
01348 }
01349
01350
01351
01352
01353 void FileRenderer::point_array_lit(int num, float size,
01354 float *xyz, float *norms, float *colors) {
01355
01356
01357 point_array(num, size, xyz, colors);
01358 }
01359
01360
01361
01362
01363 void FileRenderer::start_clipgroup() {
01364 int i;
01365
01366 for (i=0; i<VMD_MAX_CLIP_PLANE; i++) {
01367 if (clip_mode[i]) {
01368 warningflags |= FILERENDERER_NOCLIP;
01369 break;
01370 }
01371 }
01372 }
01373
01374
01375 void FileRenderer::text(float *pos, float size, float thickness, const char *str) {
01376 #if 1
01377
01378
01379 warningflags |= FILERENDERER_NOTEXT;
01380 #else
01381 hersheyhandle hh;
01382 float lm, rm, x, y, ox, oy;
01383 int draw, odraw;
01384
01385 Matrix4 m;
01386 transMat.push(m);
01387
01388 while (*str != '\0') {
01389 hersheyDrawInitLetter(&hh, *str, &lm, &rm);
01390 (transMat.top()).translate(-lm, 0, 0);
01391 ox=0;
01392 oy=0;
01393 odraw=0;
01394 while (!hersheyDrawNextLine(&hh, &draw, &x, &y)) {
01395 if (draw && odraw) {
01396 float a[3], b[3];
01397 a[0] = ox;
01398 a[1] = oy;
01399 a[2] = 0;
01400 b[0] = x;
01401 b[1] = y;
01402 b[2] = 0;
01403
01404
01405 line(a, b);
01406 }
01407
01408 ox=x;
01409 oy=y;
01410 odraw=draw;
01411 }
01412 (transMat.top()).translate(rm, 0, 0);
01413
01414 str++;
01415 }
01416
01417 transMat.pop();
01418 #endif
01419 }
01420
01421