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

DispCmds.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2008 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: DispCmds.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.84 $       $Date: 2008/06/09 04:13:09 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *
00019  * DispCmds - different display commands which take data and put it in
00020  *      a storage space provided by a given VMDDisplayList object.
00021  *
00022  * Notes:
00023  *      1. All coordinates are stored as 3 points (x,y,z), even if meant
00024  * for a 2D object.  The 3rd coord for 2D objects will be ignored.
00025  ***************************************************************************/
00026 
00027 #include <string.h>
00028 #include <stdlib.h>
00029 #include <stdio.h>
00030 #include <math.h>
00031 
00032 #ifdef VMDACTC
00033 extern "C" {
00034 // XXX 
00035 // The regular ACTC distribution compiles as plain C, need to send 
00036 // a header file fix to Brad Grantham so C++ codes don't need this.
00037 #include <tc.h>
00038 }
00039 #endif
00040 
00041 #include "DispCmds.h"
00042 #include "utilities.h"
00043 #include "Matrix4.h"
00044 #include "VMDDisplayList.h"
00045 #include "Inform.h"
00046 #include "VMDApp.h" // needed for texture serial numbers
00047 
00048 //*************************************************************
00049 
00050 // Pass a block o data to the command list.
00051 #ifdef VMDCAVE
00052 void DispCmdDataBlock::putdata(float *d, int n, VMDDisplayList *dobj) {
00053   void *ptr = dobj->append(DDATABLOCK, n*sizeof(float));
00054   if (ptr == NULL)
00055     return;
00056   memcpy(ptr, d, n*sizeof(float));
00057 }
00058 #else
00059 void DispCmdDataBlock::putdata(float *d, int, VMDDisplayList *dobj) {
00060   void *ptr = dobj->append(DDATABLOCK, sizeof(DispCmdDataBlock));
00061   if (ptr == NULL)
00062     return;
00063   data = d;
00064   memcpy(ptr, this, sizeof(DispCmdDataBlock));
00065 }
00066 #endif
00067 
00068 //*************************************************************
00069 
00070 // plot a point at the given position
00071 void DispCmdPoint::putdata(const float *newpos, VMDDisplayList *dobj) {
00072   DispCmdPoint *ptr = (DispCmdPoint *)(dobj->append(DPOINT, 
00073                                        sizeof(DispCmdPoint)));
00074   if (ptr == NULL)
00075     return;
00076   ptr->pos[0]=newpos[0];
00077   ptr->pos[1]=newpos[1];
00078   ptr->pos[2]=newpos[2];
00079 }
00080 
00081 //*************************************************************
00082 
00083 // plot a sphere of specified radius at the given position
00084 void DispCmdSphere::putdata(float *newpos, float radius, VMDDisplayList *dobj) {
00085   DispCmdSphere *ptr = (DispCmdSphere *)(dobj->append(DSPHERE, 
00086                                          sizeof(DispCmdSphere)));
00087   if (ptr == NULL)
00088     return;
00089   ptr->pos_r[0]=newpos[0];
00090   ptr->pos_r[1]=newpos[1];
00091   ptr->pos_r[2]=newpos[2];
00092   ptr->pos_r[3]=radius; 
00093 } 
00094 
00095 void DispCmdSphereIndex::putdata(int newpos, float newrad, VMDDisplayList *dobj) {
00096   DispCmdSphereIndex *ptr = (DispCmdSphereIndex *)(dobj->append(DSPHERE_I, 
00097                                          sizeof(DispCmdSphereIndex)));
00098   if (ptr == NULL)
00099     return;
00100   ptr->pos=newpos;
00101   ptr->rad=newrad;
00102 }
00103 
00104 void DispCmdSphereArray::putdata(const float * spcenters,
00105                                 const float * spradii,
00106                                 const float * spcolors,
00107                                 int num_spheres,
00108                                 int sphere_res,
00109                                 VMDDisplayList * dobj) {
00110 
00111   DispCmdSphereArray *ptr = (DispCmdSphereArray *) dobj->append(DSPHEREARRAY, 
00112                            sizeof(DispCmdSphereArray) +
00113                            sizeof(float) * num_spheres * 3 +
00114                            sizeof(float) * num_spheres + 
00115                            sizeof(float) * num_spheres * 3 +
00116                            sizeof(int) * 2);
00117   if (ptr == NULL)
00118     return;
00119   ptr->numspheres = num_spheres;
00120   ptr->sphereres = sphere_res;
00121 
00122   float *centers;
00123   float *radii;
00124   float *colors;
00125   ptr->getpointers(centers, radii, colors);
00126 
00127   memcpy(centers, spcenters, sizeof(float) * num_spheres * 3);
00128   memcpy(radii, spradii, sizeof(float) * num_spheres);
00129   memcpy(colors, spcolors, sizeof(float) * num_spheres * 3);
00130 }
00131 
00132 //*************************************************************
00133 
00134 void DispCmdPointArray::putdata(const float * pcenters,
00135                                 const float * pcolors,
00136                                 float psize,
00137                                 int num_points,
00138                                 VMDDisplayList * dobj) {
00139 
00140   DispCmdPointArray *ptr = (DispCmdPointArray *) dobj->append(DPOINTARRAY, 
00141                            sizeof(DispCmdPointArray) +
00142                            sizeof(float) * num_points * 3 +
00143                            sizeof(float) * num_points * 3 +
00144                            sizeof(float) +
00145                            sizeof(int));
00146   if (ptr == NULL)
00147     return;
00148   ptr->size = psize;
00149   ptr->numpoints = num_points;
00150 
00151   float *centers;
00152   float *colors;
00153   ptr->getpointers(centers, colors);
00154 
00155   memcpy(centers, pcenters, sizeof(float) * num_points * 3);
00156   memcpy(colors, pcolors, sizeof(float) * num_points * 3);
00157 }
00158 
00159 //*************************************************************
00160 
00161 void DispCmdLitPointArray::putdata(const float * pcenters,
00162                                    const float * pnormals,
00163                                    const float * pcolors,
00164                                    float psize,
00165                                    int num_points,
00166                                    VMDDisplayList * dobj) {
00167 
00168   DispCmdLitPointArray *ptr = (DispCmdLitPointArray *) dobj->append(DLITPOINTARRAY, 
00169                            sizeof(DispCmdLitPointArray) +
00170                            sizeof(float) * num_points * 3 +
00171                            sizeof(float) * num_points * 3 +
00172                            sizeof(float) * num_points * 3 +
00173                            sizeof(float) +
00174                            sizeof(int));
00175   if (ptr == NULL)
00176     return;
00177   ptr->size = psize;
00178   ptr->numpoints = num_points;
00179 
00180   float *centers;
00181   float *normals;
00182   float *colors;
00183   ptr->getpointers(centers, normals, colors);
00184 
00185   memcpy(centers, pcenters, sizeof(float) * num_points * 3);
00186   memcpy(normals, pnormals, sizeof(float) * num_points * 3);
00187   memcpy(colors, pcolors, sizeof(float) * num_points * 3);
00188 }
00189 
00190 //*************************************************************
00191 
00192 // plot a line at the given position
00193 void DispCmdLine::putdata(float *newpos1, float *newpos2, VMDDisplayList *dobj) {
00194   DispCmdLine *ptr = (DispCmdLine *)(dobj->append(DLINE, 
00195                                          sizeof(DispCmdLine)));
00196   if (ptr == NULL)
00197     return;
00198   memcpy(ptr->pos1, newpos1, 3*sizeof(float));
00199   memcpy(ptr->pos2, newpos2, 3*sizeof(float));
00200 }
00201 
00202 // draw a series of independent lines, (v0 v1), (v2 v3), (v4 v5)
00203 void DispCmdLineArray::putdata(float *v, int n, VMDDisplayList *dobj) {
00204   void *ptr = dobj->append(DLINEARRAY, (1+6*n)*sizeof(float));
00205   if (ptr == NULL)
00206     return;
00207   float *fltptr = (float *)ptr;
00208   *fltptr = (float)n;
00209   memcpy(fltptr+1, v, 6*n*sizeof(float));
00210 }
00211 
00212 // draw a series of connected polylines, (v0 v1 v2 v3 v4 v5)
00213 void DispCmdPolyLineArray::putdata(float *v, int n, VMDDisplayList *dobj) {
00214   void *ptr = dobj->append(DPOLYLINEARRAY, (1+3*n)*sizeof(float));
00215   if (ptr == NULL)
00216     return;
00217   float *fltptr = (float *)ptr;
00218   *fltptr = (float)n;
00219   memcpy(fltptr+1, v, 3*n*sizeof(float));
00220 }
00221 
00222 //*************************************************************
00223 // draw a triangle
00224 
00225 // set up the data for the DTRIANGLE drawing command
00226 void DispCmdTriangle::set_array(const float *p1,const float *p2,const float *p3,
00227   const float *n1, const float *n2, const float *n3, VMDDisplayList *dobj) {
00228   DispCmdTriangle *ptr = (DispCmdTriangle *)(dobj->append(DTRIANGLE, 
00229                                          sizeof(DispCmdTriangle)));
00230   if (ptr == NULL)
00231     return;
00232   memcpy(ptr->pos1,p1,3*sizeof(float)); 
00233   memcpy(ptr->pos2,p2,3*sizeof(float)); 
00234   memcpy(ptr->pos3,p3,3*sizeof(float)); 
00235   memcpy(ptr->norm1,n1,3*sizeof(float)); 
00236   memcpy(ptr->norm2,n2,3*sizeof(float)); 
00237   memcpy(ptr->norm3,n3,3*sizeof(float)); 
00238 }
00239 
00240 // put in new data, and put the command
00241 void DispCmdTriangle::putdata(const float *p1, const float *p2, 
00242                               const float *p3, VMDDisplayList *dobj) {
00243   int i;
00244   float tmp1[3], tmp2[3], tmp3[3];  // precompute the normal for
00245   for (i=0; i<3; i++) {             //   faster drawings later
00246      tmp1[i] = p2[i] - p1[i];
00247      tmp2[i] = p3[i] - p2[i];
00248   }
00249   cross_prod( tmp3, tmp1, tmp2);  
00250   vec_normalize(tmp3);
00251   set_array(p1, p2, p3, tmp3, tmp3, tmp3, dobj);
00252 }
00253 void DispCmdTriangle::putdata(const float *p1, const float *p2,const float *p3,
00254                               const float *n1, const float *n2,const float *n3,
00255                               VMDDisplayList *dobj) {
00256   set_array(p1,p2,p3,n1,n2,n3,dobj);
00257 }
00258 
00259 //*************************************************************
00260 
00261 // draw a square, given 3 of four points
00262 void DispCmdSquare::putdata(float *p1, float *p2,float *p3,VMDDisplayList *dobj) {
00263   DispCmdSquare *ptr = (DispCmdSquare *)(dobj->append(DSQUARE, 
00264                                          sizeof(DispCmdSquare)));
00265   if (ptr == NULL)
00266     return;
00267   int i;
00268   float tmp1[3], tmp2[3];           // precompute the normal for
00269   for (i=0; i<3; i++) {             //   faster drawings later
00270      tmp1[i] = p2[i] - p1[i];
00271      tmp2[i] = p3[i] - p2[i];
00272   }
00273   cross_prod( ptr->norml, tmp1, tmp2);  
00274   vec_normalize(ptr->norml);
00275 
00276   memcpy(ptr->pos1,p1,3*sizeof(float));
00277   memcpy(ptr->pos2,p2,3*sizeof(float));
00278   memcpy(ptr->pos3,p3,3*sizeof(float));
00279   for (i=0; i<3; i++)
00280     ptr->pos4[i] = p1[i] + tmp2[i];  // compute the fourth point
00281 }
00282 
00283 
00284 
00285 //*************************************************************
00286 
00287 // draw a mesh consisting of vertices, facets, colors, normals etc.
00288 void DispCmdTriMesh::putdata(const float * vertices,
00289                              const float * normals,
00290                              const float * colors,
00291                              int num_verts,
00292                              const int * facets,
00293                              int num_facets, 
00294                              int enablestrips,
00295                              VMDDisplayList * dobj) {
00296   int builtstrips = 0; 
00297 
00298 #if defined(VMDACTC) 
00299   if (enablestrips)  {
00300     // Rearrange face data into triangle strips
00301     ACTCData *tc = actcNew();  // intialize ACTC stripification library
00302     int fsize = num_facets * 3;
00303     int i, ind, ii;
00304     int iPrimCount = 0;
00305     int iCurrPrimSize;
00306 
00307     // XXX over-allocate the vertex and facet buffers to prevent an
00308     //     apparent bug in ACTC 1.1 from crashing VMD.  This was causing
00309     //     Surf surfaces to crash ACTC at times.
00310     int *p_iPrimSize = new int[fsize + 6];  // num vertices in a primitive 
00311     unsigned int *f2 = new uint[fsize + 6];
00312     
00313     if (tc == NULL) {
00314       msgErr << "ACTC initialization failed, using triangle mesh." << sendmsg;
00315     } else {
00316       msgInfo << "Performing ACTC Triangle Consolidation..." << sendmsg;
00317  
00318       // only produce strips, not fans, give a ridiculously high min value.
00319       actcParami(tc, ACTC_OUT_MIN_FAN_VERTS, 2147483647);
00320 
00321       // disabling honoring vertex winding order might allow ACTC to
00322       // consolidate more triangles into strips, but this is only useful
00323       // if VMD has two-sided lighting enabled.
00324       // actcParami(tc, ACTC_OUT_HONOR_WINDING, ACTC_TRUE);
00325         
00326       // send triangle data over to ACTC library
00327       actcBeginInput(tc);
00328       for (ii=0; ii < num_facets; ii++) {
00329         ind = ii * 3;
00330         if ((actcAddTriangle(tc, facets[ind], facets[ind + 1], facets[ind + 2])) != ACTC_NO_ERROR) {
00331           msgInfo << "ACTC Add Triangle Error." << sendmsg;
00332         }
00333       }
00334       actcEndInput(tc);
00335         
00336       // get triangle strips back from ACTC, loop through once to get sizes
00337       actcBeginOutput(tc);
00338       i = 0;
00339       while ((actcStartNextPrim(tc, &f2[i], &f2[i+1]) != ACTC_DATABASE_EMPTY)) {
00340         iCurrPrimSize = 2;  // if we're here, we got 2 vertices
00341         i+=2;               // increment array position
00342         while (actcGetNextVert(tc, &f2[i]) != ACTC_PRIM_COMPLETE) {
00343           iCurrPrimSize++;  // increment number of vertices for this primitive
00344           i++;              // increment array position
00345         }
00346 
00347         p_iPrimSize[iPrimCount] = iCurrPrimSize;  // save vertex count
00348         iPrimCount++;       // increment primitive counter
00349       }
00350       actcEndOutput(tc);
00351       msgInfo << "ACTC: Created " << iPrimCount << " triangle strips" << sendmsg;
00352       msgInfo << "ACTC: Average vertices per strip = " << i / iPrimCount  << sendmsg;
00353 
00354       // Draw triangle strips, uses double-sided lighting until we change
00355       // things to allow the callers to specify the desired lighting 
00356       // explicitly.
00357       DispCmdTriStrips::putdata(vertices, normals, colors, num_verts, p_iPrimSize, iPrimCount, f2, i, 1, dobj);
00358           
00359       // delete temporary memory
00360       delete [] f2;
00361       delete [] p_iPrimSize;
00362 
00363       // delete ACTC handle
00364       actcDelete(tc);
00365 
00366       builtstrips = 1; // don't generate a regular triangle mesh
00367     }  
00368   } 
00369 #endif
00370 
00371   if (!builtstrips) {
00372     // make a triangle mesh (no strips)
00373     DispCmdTriMesh *ptr = (DispCmdTriMesh *) 
00374                   (dobj->append(DTRIMESH, sizeof(DispCmdTriMesh) +
00375                                           sizeof(float) * num_verts * 10 +
00376                                           sizeof(int) * num_facets * 3));
00377     if (ptr == NULL)
00378       return;
00379     ptr->numverts=num_verts;
00380     ptr->numfacets=num_facets;
00381     float *cnv;
00382     int *f;
00383     ptr->getpointers(cnv, f);
00384 
00385     int i, ind, ind2;
00386     for (i=0; i<num_verts; i++) {
00387       ind = i * 10;
00388       ind2 = i * 3;
00389       cnv[ind    ] =   colors[ind2    ];
00390       cnv[ind + 1] =   colors[ind2 + 1]; 
00391       cnv[ind + 2] =   colors[ind2 + 2]; 
00392       cnv[ind + 3] =   1.0; 
00393       cnv[ind + 4] =  normals[ind2    ];
00394       cnv[ind + 5] =  normals[ind2 + 1];
00395       cnv[ind + 6] =  normals[ind2 + 2];
00396       cnv[ind + 7] = vertices[ind2    ];
00397       cnv[ind + 8] = vertices[ind2 + 1];
00398       cnv[ind + 9] = vertices[ind2 + 2];
00399     } 
00400 
00401     memcpy(f, facets, ptr->numfacets * 3 * sizeof(int));
00402   }
00403 }
00404 
00405 //*************************************************************
00406 
00407 // draw a set of triangle strips
00408 void DispCmdTriStrips::putdata(const float * vertices,
00409                                const float * normals,
00410                                const float * colors,
00411                                int num_verts,
00412                                const int * verts_per_strip,
00413                                int num_strips,
00414                                const unsigned int * strip_data,
00415                                const int num_strip_verts,
00416                                int double_sided_lighting,
00417                                VMDDisplayList * dobj) {
00418 
00419   DispCmdTriStrips *ptr = (DispCmdTriStrips *) (dobj->append(DTRISTRIP, 
00420                                          sizeof(DispCmdTriStrips) +
00421                                          sizeof(int *) * num_strips +
00422                                          sizeof(float) * num_verts * 10 +
00423                                          sizeof(int) * num_strip_verts +
00424                                          sizeof(int) * num_strips));
00425   if (ptr == NULL) 
00426     return;
00427   ptr->numverts=num_verts;
00428   ptr->numstrips=num_strips;
00429   ptr->numstripverts=num_strip_verts;
00430   ptr->doublesided=double_sided_lighting;
00431 
00432   float *cnv;
00433   int *f;
00434   int *vertsperstrip;
00435   ptr->getpointers(cnv, f, vertsperstrip);
00436 
00437   // copy vertex,color,normal data
00438   int i, ind, ind2;
00439   for (i=0; i<num_verts; i++) {
00440     ind = i * 10;
00441     ind2 = i * 3;
00442     cnv[ind    ] =   colors[ind2    ];
00443     cnv[ind + 1] =   colors[ind2 + 1];
00444     cnv[ind + 2] =   colors[ind2 + 2];
00445     cnv[ind + 3] =   1.0;
00446     cnv[ind + 4] =  normals[ind2    ];
00447     cnv[ind + 5] =  normals[ind2 + 1];
00448     cnv[ind + 6] =  normals[ind2 + 2];
00449     cnv[ind + 7] = vertices[ind2    ];
00450     cnv[ind + 8] = vertices[ind2 + 1];
00451     cnv[ind + 9] = vertices[ind2 + 2];
00452   }
00453 
00454   // copy vertices per strip data
00455   for (i=0; i<num_strips; i++) {
00456     vertsperstrip[i] = verts_per_strip[i];
00457   }
00458 
00459   // copy face (triangle) data
00460   for (i=0; i<num_strip_verts; i++) {
00461     f[i] = strip_data[i];
00462   }
00463 }
00464 
00465 
00466 //*************************************************************
00467 
00468 void DispCmdWireMesh::putdata(const float * vertices,
00469                              const float * normals,
00470                              const float * colors,
00471                              int num_verts,
00472                              const int * lines,
00473                              int num_lines, VMDDisplayList * dobj) {
00474  
00475   DispCmdWireMesh *ptr = (DispCmdWireMesh *) (dobj->append(DWIREMESH, 
00476                                          sizeof(DispCmdWireMesh) +
00477                                          sizeof(float) * num_verts * 10 +
00478                                          sizeof(int) * num_lines * 3));
00479   if (ptr == NULL) 
00480     return;
00481   ptr->numverts=num_verts;
00482   ptr->numlines=num_lines;
00483 
00484   float *cnv;
00485   int *l;
00486   ptr->getpointers(cnv, l);
00487 
00488   int i, ind, ind2;
00489   for (i=0; i<num_verts; i++) {
00490     ind = i * 10;
00491     ind2 = i * 3;
00492     cnv[ind    ] =   colors[ind2    ];
00493     cnv[ind + 1] =   colors[ind2 + 1]; 
00494     cnv[ind + 2] =   colors[ind2 + 2]; 
00495     cnv[ind + 3] =   1.0; 
00496     cnv[ind + 4] =  normals[ind2    ];
00497     cnv[ind + 5] =  normals[ind2 + 1];
00498     cnv[ind + 6] =  normals[ind2 + 2];
00499     cnv[ind + 7] = vertices[ind2    ];
00500     cnv[ind + 8] = vertices[ind2 + 1];
00501     cnv[ind + 9] = vertices[ind2 + 2];
00502   } 
00503 
00504   memcpy(l, lines, ptr->numlines * 2 * sizeof(int));
00505 }
00506 
00507 //*************************************************************
00508 // plot a cylinder at the given position
00509 // this is used to precalculate the cylinder data for speedup
00510 // in renderers without hardware cylinders.  For example, the GL
00511 // library.  There are res number of edges (with a norm, and two points)
00512 
00513 DispCmdCylinder::DispCmdCylinder(void) {
00514   lastres = 0;
00515 }
00516 
00517 void DispCmdCylinder::putdata(const float *pos1, const float *pos2, float rad, 
00518                       int res, int filled, VMDDisplayList *dobj) {
00519 
00520   float lenaxis[3];
00521   vec_sub(lenaxis, pos1, pos2);  // check that it's valid
00522   if (dot_prod(lenaxis,lenaxis) == 0.0 || res <= 0) return;
00523 
00524   if (lastres != res ) {
00525     rot[0] = cosf( (float) VMD_TWOPI / (float) res);
00526     rot[1] = sinf( (float) VMD_TWOPI / (float) res);
00527   }
00528   lastres = res;
00529   size_t size = (9 + res*3*3)*sizeof(float);
00530 
00531   float *pos = (float *)(dobj->append(DCYLINDER, size));
00532   if (pos == NULL) 
00533     return;
00534 
00535   memcpy(pos,pos1,3*sizeof(float));
00536   memcpy(pos+3,pos2,3*sizeof(float));
00537   pos[6] = rad;
00538   pos[7] = (float)res;
00539   pos[8] = (float)filled;
00540 
00541   float axis[3];
00542   vec_sub(axis, pos1, pos2);
00543   vec_normalize(axis);
00544   int i;  // find an axis not aligned with the cylinder
00545   if (fabs(axis[0]) < fabs(axis[1]) &&
00546       fabs(axis[0]) < fabs(axis[2])) {
00547      i = 0;
00548   } else if (fabs(axis[1]) < fabs(axis[2])) {
00549      i = 1;
00550   } else {
00551      i = 2;
00552   }
00553   float perp[3];
00554   perp[i] = 0;                    // this is not aligned with the cylinder
00555   perp[(i+1)%3] = axis[(i+2)%3];
00556   perp[(i+2)%3] = -axis[(i+1)%3];
00557   vec_normalize(perp);
00558   float perp2[3];
00559   cross_prod(perp2, axis, perp); // find a normal to the cylinder
00560 
00561   float *posptr = pos+9;
00562   float m = rot[0], n = rot[1];
00563   for (int h=0; h<res; h++) {
00564     float tmp0, tmp1, tmp2;
00565     
00566     tmp0 = m*perp[0] + n*perp2[0]; // add the normal
00567     tmp1 = m*perp[1] + n*perp2[1];
00568     tmp2 = m*perp[2] + n*perp2[2];
00569 
00570     posptr[0] = tmp0; // add the normal
00571     posptr[1] = tmp1;
00572     posptr[2] = tmp2;
00573 
00574     posptr[3] = pos2[0] + rad * tmp0; // start
00575     posptr[4] = pos2[1] + rad * tmp1;
00576     posptr[5] = pos2[2] + rad * tmp2;
00577 
00578     posptr[6] = posptr[3] + lenaxis[0];  // and end of the edge
00579     posptr[7] = posptr[4] + lenaxis[1];
00580     posptr[8] = posptr[5] + lenaxis[2];
00581     posptr += 9;
00582     // use angle addition formulae:
00583     // cos(A+B) = cos A cos B - sin A sin B
00584     // sin(A+B) = cos A sin B + sin A cos B
00585     float mtmp = rot[0]*m - rot[1]*n;
00586     float ntmp = rot[0]*n + rot[1]*m; 
00587     m = mtmp;
00588     n = ntmp;
00589   }
00590 }
00591  
00592 //*************************************************************
00593 
00594 void DispCmdCone::putdata(float *p1,float *p2,float newrad,float newrad2,int newres,
00595                           VMDDisplayList *dobj) {
00596   DispCmdCone *ptr = (DispCmdCone *)(dobj->append(DCONE, 
00597                                          sizeof(DispCmdCone)));
00598   if (ptr == NULL) 
00599     return;
00600   memcpy(ptr->pos1,p1,3*sizeof(float));
00601   memcpy(ptr->pos2,p2,3*sizeof(float));
00602   ptr->radius=newrad;
00603   ptr->radius2=newrad2;
00604   ptr->res=newres;
00605 }
00606 
00607 // put in new data, and put the command
00608 void DispCmdColorIndex::putdata(int newcol, VMDDisplayList *dobj) {
00609   DispCmdColorIndex *ptr = (DispCmdColorIndex *)(dobj->append(DCOLORINDEX, 
00610                                          sizeof(DispCmdColorIndex)));
00611   if (ptr == NULL) 
00612     return;
00613   ptr->color = newcol;
00614 }
00615 
00616 //*************************************************************
00617 
00618 // display text at the given text coordinates
00619 void DispCmdText::putdata(const float *c, const char *s, VMDDisplayList *dobj) {
00620   if (s != NULL) {
00621     size_t len = strlen(s)+1;
00622     char *buf = (char *)(dobj->append(DTEXT, len+3*sizeof(float)));
00623     if (buf == NULL) 
00624       return;
00625     ((float *)buf)[0] = c[0];
00626     ((float *)buf)[1] = c[1];
00627     ((float *)buf)[2] = c[2];
00628     memcpy(buf+3*sizeof(float),s,len);
00629   }
00630 }
00631 
00632 void DispCmdTextOffset::putdata(float ox, float oy, VMDDisplayList *dobj) {
00633   DispCmdTextOffset *cmd = (DispCmdTextOffset *)(dobj->append(DTEXTOFFSET,
00634         sizeof(DispCmdTextOffset)));
00635   cmd->x = ox;
00636   cmd->y = oy;
00637 }
00638 
00639 //*************************************************************
00640 // include comments in the display list, useful for Token Rendering
00641 void DispCmdComment::putdata(const char *newtxt, VMDDisplayList *dobj) {
00642   char *buf = (char *) dobj->append(DCOMMENT, strlen(newtxt)+1);
00643   if (buf == NULL)
00644     return;
00645   memcpy(buf, newtxt, strlen(newtxt)+1);
00646 }
00647 
00648 //*************************************************************
00649 
00650 void DispCmdTextSize::putdata(float size1, VMDDisplayList *dobj) {
00651   DispCmdTextSize *ptr  = (DispCmdTextSize *)dobj->append(DTEXTSIZE,
00652                            sizeof(DispCmdTextSize));
00653   if (ptr == NULL)
00654     return;
00655   ptr->size = size1;
00656 }
00657 
00658 //*************************************************************
00659 
00660 void DispCmdVolSlice::putdata(int mode, const float *pnormal, const float *verts, 
00661     const float *texs, VMDDisplayList *dobj) {
00662 
00663   DispCmdVolSlice *cmd = (DispCmdVolSlice *) dobj->append(DVOLSLICE, 
00664                                        sizeof(DispCmdVolSlice));
00665   if (cmd == NULL)
00666     return;
00667 
00668   cmd->texmode = mode;
00669   memcpy(cmd->normal, pnormal, 3*sizeof(float));
00670   memcpy(cmd->v, verts, 12*sizeof(float));
00671   memcpy(cmd->t, texs,  12*sizeof(float));
00672 }
00673 
00674 //*************************************************************
00675 
00676 
00677 void DispCmdVolumeTexture::putdata(unsigned long texID, 
00678     const int size[3], unsigned char *texptr, const float pv0[3], 
00679     const float pv1[3], const float pv2[3], const float pv3[3], 
00680     VMDDisplayList *dobj) {
00681 
00682   DispCmdVolumeTexture *cmd = (DispCmdVolumeTexture *) dobj->append(DVOLUMETEXTURE,
00683       sizeof(DispCmdVolumeTexture));
00684 
00685   if (cmd == NULL) return;
00686 
00687   cmd->ID = texID;
00688   cmd->xsize = size[0];
00689   cmd->ysize = size[1];
00690   cmd->zsize = size[2];
00691   cmd->texmap = texptr;
00692   memcpy(cmd->v0, pv0, 3*sizeof(float));
00693   memcpy(cmd->v1, pv1, 3*sizeof(float));
00694   memcpy(cmd->v2, pv2, 3*sizeof(float));
00695   memcpy(cmd->v3, pv3, 3*sizeof(float));
00696 }
00697 
00698 //*************************************************************
00699 // put in new data, and put the command
00700 void DispCmdSphereRes::putdata(int newres, VMDDisplayList *dobj) {
00701   DispCmdSphereRes *ptr  = (DispCmdSphereRes *)dobj->append(DSPHERERES,
00702                            sizeof(DispCmdSphereRes));
00703   if (ptr == NULL)
00704     return;
00705   ptr->res = newres;
00706 }
00707 
00708 //*************************************************************
00709 
00710 // put in new data, and put the command
00711 void DispCmdSphereType::putdata(int newtype, VMDDisplayList *dobj) {
00712   DispCmdSphereType *ptr  = (DispCmdSphereType *)dobj->append(DSPHERETYPE,
00713                            sizeof(DispCmdSphereType));
00714   if (ptr == NULL)
00715     return;
00716   ptr->type = newtype;
00717 }
00718 
00719 //*************************************************************
00720 
00721 // put in new data, and put the command
00722 void DispCmdLineType::putdata(int newtype, VMDDisplayList *dobj) {
00723   DispCmdLineType* ptr  = (DispCmdLineType *)dobj->append(DLINESTYLE,
00724                            sizeof(DispCmdLineType));
00725   if (ptr == NULL)
00726     return;
00727   ptr->type = newtype;
00728 }
00729 
00730 //*************************************************************
00731 
00732 void DispCmdLineWidth::putdata(int newwidth, VMDDisplayList *dobj) {
00733   DispCmdLineWidth * ptr  = (DispCmdLineWidth *)dobj->append(DLINEWIDTH,
00734                            sizeof(DispCmdLineWidth));
00735   if (ptr == NULL)
00736     return;
00737   ptr->width = newwidth;
00738 }
00739 
00740 //*************************************************************
00741 
00742 void DispCmdPickPoint::putdata(float *pos, int newtag, VMDDisplayList *dobj) {
00743   DispCmdPickPoint *ptr = (DispCmdPickPoint *)(dobj->append(DPICKPOINT, 
00744                                                sizeof(DispCmdPickPoint)));
00745   if (ptr == NULL)
00746     return;
00747   memcpy(ptr->postag,pos,3*sizeof(float));
00748   ptr->tag=newtag;
00749 }
00750 
00751 //*************************************************************
00752 
00753 // put in new data, and put the command
00754 void DispCmdPickPointIndex::putdata(int newpos, int newtag, VMDDisplayList *dobj) {
00755   DispCmdPickPointIndex *ptr = (DispCmdPickPointIndex *)(dobj->append(
00756                                  DPICKPOINT_I, sizeof(DispCmdPickPointIndex)));
00757   if (ptr == NULL)
00758     return;
00759   ptr->pos=newpos;
00760   ptr->tag=newtag;
00761 }
00762 
00763 //*************************************************************
00764 
00765 // put in new data, and put the command
00766 void DispCmdPickPointIndexArray::putdata(int num, int numsel, int *onoff, VMDDisplayList *dobj) {
00767   if (numsel < 1)
00768     return;
00769 
00770   int i;
00771   DispCmdPickPointIndexArray *ptr;
00772 
00773   if (num == numsel) {
00774     // if all indices in a contiguous block are enabled (e.g. "all" selection)
00775     // then there's no need to actually store the pick point indices
00776     ptr = (DispCmdPickPointIndexArray *) (dobj->append(DPICKPOINT_IARRAY, 
00777                                    sizeof(DispCmdPickPointIndexArray)));
00778   } else {
00779     // if only some of the indices are selected, then we allocate storage
00780     // for the list of indices to be copied in.
00781     ptr = (DispCmdPickPointIndexArray *) (dobj->append(DPICKPOINT_IARRAY, 
00782                                    sizeof(DispCmdPickPointIndexArray) + 
00783                                    sizeof(int) * numsel));
00784   }
00785 
00786   if (ptr == NULL)
00787     return;
00788 
00789   ptr->numpicks = numsel;
00790 
00791   if (num == numsel) {
00792     // if all indices are selected note it, and we're done.
00793     ptr->allselected = 1;
00794   } else {
00795     // if only some indices are selected, copy in the selected ones
00796     ptr->allselected = 0;
00797     int *tags;
00798     ptr->getpointers(tags);
00799 
00800     // copy tags for selected/enabled indices
00801     int cp=0;
00802     for (i=0; i<num; i++) {
00803       if (onoff[i]) {
00804         tags[cp] = i;
00805         cp++;
00806       }
00807     }
00808   }
00809 }
00810 
00811 //*************************************************************
00812 
00813 // put in new data, and put the command
00814 void DispCmdPickPointIndexArray::putdata(int num, int *indices, VMDDisplayList *dobj) {
00815   DispCmdPickPointIndexArray *ptr;
00816 
00817   ptr = (DispCmdPickPointIndexArray *) (dobj->append(DPICKPOINT_IARRAY, 
00818                                    sizeof(DispCmdPickPointIndexArray) + 
00819                                    sizeof(int) * num));
00820 
00821   if (ptr == NULL)
00822     return;
00823 
00824   ptr->numpicks = num;
00825   ptr->allselected = 0; // use the index array entries
00826   int *tags;
00827   ptr->getpointers(tags);
00828   memcpy(tags, indices, num * sizeof(int));
00829 }
00830 

Generated on Fri Aug 29 01:26:52 2008 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002