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

VMDTitle.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2011 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: VMDTitle.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.58 $       $Date: 2011/03/05 17:14:51 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *
00019  * A flashy title object which is displayed when the program starts up,
00020  * until a molecule is loaded.
00021  *
00022  ***************************************************************************/
00023 #include <math.h>
00024 #include "VMDTitle.h"
00025 #include "DisplayDevice.h"
00026 #include "config.h"
00027 #include "utilities.h"
00028 #include "Scene.h"
00029 
00030 // functions which put V, M, and D on the display list
00031 // The max height is y+1 (and the min is y+0, since they
00032 // are all capital letters).  The leftmost (on x)
00033 // graphics starts at x.  However, different letters
00034 // are different widths.
00035 //  The width of a stroke is STROKE_WIDTH.
00036 #define STROKE_WIDTH (0.2f + 0.0f)
00037 
00038 
00039 // given the front surface coordinates(4) in counter clockwise direction
00040 // draw the solid box that goes around the box with that
00041 // surface, and a depth of 0.25 deep
00042 // The optional field requests that the ends also be covered
00043 static void draw_outsides(float c[8][3], VMDDisplayList *disp, int draw_ends) {
00044   float zoffset[3] = { 0, 0, 0.25}; // make the other 4 coords
00045   for (int i=0; i<4; i++)
00046     vec_sub(c[i+4], c[i], zoffset);
00047 
00048   DispCmdTriangle tri;
00049   // draw the front parallegram
00050   tri.putdata(c[0], c[1], c[2], disp);
00051   tri.putdata(c[2], c[3], c[0], disp);
00052 
00053   // draw the rear parallegram
00054   tri.putdata(c[5], c[4], c[6], disp);
00055   tri.putdata(c[6], c[4], c[7], disp);
00056   
00057   // draw the left face
00058   tri.putdata(c[0], c[3], c[7], disp);
00059   tri.putdata(c[7], c[4], c[0], disp);
00060 
00061   // draw the right face
00062   tri.putdata(c[1], c[5], c[6], disp);
00063   tri.putdata(c[6], c[2], c[1], disp);
00064 
00065   if (!draw_ends)
00066     return;
00067     
00068   // draw the top face
00069   tri.putdata(c[0], c[5], c[4], disp);
00070   tri.putdata(c[5], c[0], c[1], disp);
00071   
00072   // draw the bottom face
00073   tri.putdata(c[2], c[7], c[3], disp);
00074   tri.putdata(c[7], c[2], c[6], disp);
00075 }
00076 
00077 
00078 // draw a parallelpiped from start to end
00079 //  the top and bottoms are flat
00080 //  the front parallegram marks out the regions
00081 //   (startx-STROKE_WIDTH/2, starty) to 
00082 //   (startx+STROKE_WIDTH/2, starty) to 
00083 //   (endx-STROKE_WIDTH/2, endy) to 
00084 //   (endx+STROKE_WIDTH/2, endy) and back
00085 static void draw_stroke(float startx, float starty, float endx, float endy, 
00086                         VMDDisplayList *disp) {
00087   float c[8][3];
00088   c[0][0] = startx - (STROKE_WIDTH+0.0f)/(2.0f);
00089   c[0][1] = starty; 
00090   c[0][2] = 0;
00091   c[1][0] = startx + (STROKE_WIDTH+0.0f)/(2.0f);
00092   c[1][1] = starty; 
00093   c[1][2] = 0;
00094   c[2][0] = endx + (STROKE_WIDTH+0.0f)/(2.0f);
00095   c[2][1] = endy; 
00096   c[2][2] = 0;
00097   c[3][0] = endx - (STROKE_WIDTH+0.0f)/(2.0f);
00098   c[3][1] = endy; 
00099   c[3][2] = 0;
00100   draw_outsides(c, disp, TRUE);
00101 }
00102 
00103 static void draw_letter_V(float x, float y, VMDDisplayList *disp) {
00104   // draw the down stroke (note the order, this is because of the 
00105   //  way I define the coordinates in the draw_stroke routine for width)
00106   draw_stroke(x+STROKE_WIDTH*(1.5f), y+0, x+STROKE_WIDTH/2.0f, y+1.0f, disp);
00107   // and the up stroke   
00108   draw_stroke(x+STROKE_WIDTH*(1.5f), y+0, x+STROKE_WIDTH*2.5f, y+1.0f, disp);
00109 }
00110 
00111 static float letter_V_width(void) {
00112  return STROKE_WIDTH*2.0;
00113 }
00114 
00115 static void draw_letter_M(float x, float y, VMDDisplayList *disp) {
00116   // up
00117   draw_stroke(x+STROKE_WIDTH/2.0f, y, x+STROKE_WIDTH*1.5f, y+1.0f, disp);
00118   // down
00119   draw_stroke(x+STROKE_WIDTH*2.5f, y, x+STROKE_WIDTH*1.5f, y+1.0f, disp);
00120   // up
00121   draw_stroke(x+STROKE_WIDTH*2.5f, y, 
00122               x+STROKE_WIDTH*3.5f, y+1.0f, disp);
00123   // down
00124   draw_stroke(x+STROKE_WIDTH*4.5f, y,
00125               x+STROKE_WIDTH*3.5f, y+1.0f, disp);
00126 }
00127 
00128 static float letter_M_width(void) {
00129   return STROKE_WIDTH*5.0f;
00130 }
00131 
00132 // given the angle and the major/minor radii for the ellipse
00133 //   angle = 0 => along major axis
00134 //   increasing angle is in the clockwise direction
00135 // find the x, y point of the axis at that angle (with z=0)
00136 static void find_ellipse_coords(float angle, float major, float minor, float *data) {
00137   data[0] = minor * sinf(angle);
00138   data[1] = major * cosf(angle);
00139   data[2] = 0;
00140 }
00141 
00142 
00143 // This one is tricky
00144 static void draw_letter_D(float x, float y, VMDDisplayList *disp) {
00145   // up
00146   draw_stroke(x+STROKE_WIDTH/2.0f, y, x+STROKE_WIDTH/2.0f, y+1.0f, disp);
00147   // and the curve
00148   float stepsize = (float) VMD_PI/60.0f;
00149   float offset[3] = {STROKE_WIDTH, 0.5f, 0.0f};
00150   offset[0] += x;
00151   offset[1] += y;
00152   float c[8][3];
00153   int i, j;
00154   for (i=0; i<60; i++) {
00155     // inside coords
00156     find_ellipse_coords(stepsize*i, 0.5f - STROKE_WIDTH, STROKE_WIDTH, c[1]);
00157     find_ellipse_coords(stepsize*(i+1), 0.5f - STROKE_WIDTH, STROKE_WIDTH, c[2]);
00158     // outside coords
00159     find_ellipse_coords(stepsize * i, 0.5 , STROKE_WIDTH * 2, c[0]);
00160     find_ellipse_coords(stepsize * (i+1), 0.5 , STROKE_WIDTH * 2, c[3]);
00161     // add the offsets
00162     for (j=0; j<4; j++)
00163       vec_add(c[j], c[j], offset);
00164     draw_outsides(c, disp, FALSE);
00165   }
00166 }
00167 
00169 VMDTitle::VMDTitle(DisplayDevice *d, Displayable *par) 
00170 : Displayable(par), disp(d) {
00171   // displayable characteristics
00172   rot_off();
00173   scale_off();
00174   glob_trans_off();
00175   cent_trans_off();
00176   letterson = TRUE;
00177   redraw_list();
00178   
00179   glob_trans_on();
00180   set_glob_trans(-0.1f, 0.65f, 0.10f);
00181   glob_trans_off();
00182   starttime = time_of_day();
00183 }
00184 
00185 void VMDTitle::redraw_list(void) {
00186   reset_disp_list();
00187   float x;  // offset to center VMD
00188   x = letter_V_width() + STROKE_WIDTH/2.0f + 
00189       letter_M_width() + STROKE_WIDTH/2.0f +
00190       letter_V_width(); // same width as 'V'
00191   x=x/2.0f; // center on the screen
00192 
00193   append(DMATERIALON);
00194   color.putdata(REGRED, cmdList);
00195   draw_letter_V(-x, -0.4f, cmdList);
00196   color.putdata(REGGREEN, cmdList);
00197   draw_letter_M(-x + STROKE_WIDTH/2.0f + letter_V_width(), -0.4f, cmdList);
00198   color.putdata(REGBLUE, cmdList);
00199   draw_letter_D(-x + STROKE_WIDTH/2.0f + letter_V_width() +
00200                      STROKE_WIDTH/2.0f + letter_M_width(), -0.4f, cmdList);
00201   append(DMATERIALOFF);
00202 
00203   if (letterson) {
00204     color.putdata(REGWHITE, cmdList);
00205     float pos[3];
00206     pos[0] = -x + 0.2f;
00207     pos[1] = -0.6f; 
00208     pos[2] =  0.0f;
00209 
00210     DispCmdText txt;
00211     DispCmdTextSize txtsize;
00212     txtsize.putdata(0.8f, cmdList);
00213     txt.putdata(pos, "Theoretical and Computational Biophysics Group", 1.0f, cmdList);
00214     pos[1] -= 0.1f;
00215     txt.putdata(pos, "NIH Resource for Macromolecular Modeling and Bioinformatics", 1.0f, cmdList);
00216     pos[1] -= 0.1f;
00217     txt.putdata(pos, "University of Illinois at Urbana-Champaign", 1.0f, cmdList);
00218     pos[1] -= 0.1f;
00219     txt.putdata(pos, VMD_AUTHORS_LINE1, 1.0f, cmdList);
00220     pos[1] -= 0.1f;
00221     txt.putdata(pos, VMD_AUTHORS_LINE2, 1.0f, cmdList);
00222     pos[1] -= 0.1f;
00223     txt.putdata(pos, VMD_AUTHORS_LINE3, 1.0f, cmdList);
00224   }
00225 }
00226 
00227 // simply fits a 2rd degree polynomial so that v(d=0)=0=v(d=t)
00228 // and x(d=0)=start and x(d=t)=end
00229 static float solve_position(float d, float t, float start, float end) {
00230   float a = 6.0f*(end-start)/(t*t*t);
00231   return a*d*d*(t/2.0f-d/3.0f)+start;
00232 }
00233 
00234 void VMDTitle::prepare() {
00235   double elapsed = time_of_day() - starttime;
00236   double delta;
00237 
00238   // Prevent the title screen from hogging the CPU/GPU when there's
00239   // nothing else going on.  This is particularly important for users
00240   // that start VMD and immediately start using Multiseq with no structure
00241   // data loaded at all.
00242   vmd_msleep(1); // sleep for 1 millisecond or more
00243 
00244   if (elapsed < 5 + 3) {  // display the title screen, no animation
00245     if (!letterson) {
00246       letterson = TRUE;
00247       redraw_list();
00248     }
00249     return;
00250   }
00251 
00252   elapsed -= 3;
00253   if (letterson) {
00254     letterson = FALSE;
00255     redraw_list();
00256   }
00257 
00258   if (elapsed < 30) { // just spin the VMD logo
00259     delta = elapsed - 5;
00260     rot_on();
00261     set_rot(solve_position((float) delta, 25.0f, 0.0f, 360.0f*8.0f), 'y');
00262     rot_off();
00263   }
00264 
00265   if (elapsed < 15) { 
00266     delta = elapsed - 5;
00267     scale_on();
00268     set_scale( 1.0f/(1.0f+ ((float) delta)/3.0f)); // and getting smaller
00269     scale_off();
00270     glob_trans_on();
00271 
00272     // and moving up
00273     set_glob_trans(0, 0.5f, solve_position((float) delta, 10.0f, 0.0f, 0.5f)); 
00274     glob_trans_off();
00275     return;
00276   }
00277 
00278   if (elapsed < 20) {
00279     return;
00280   }
00281 
00282   // I am at          ( 0  ,  0.5, 0.5)
00283   // I want to get to ( -.7  ,  0.9  , 0.5) in 10 secs
00284   if (elapsed < 30) {
00285     delta = elapsed - 20;
00286     glob_trans_on();
00287     set_glob_trans(
00288        solve_position((float) delta, 10.0f, 0.0f, -0.6f * disp->aspect()),
00289        solve_position((float) delta, 10.0f, 0.5f, 0.8f),
00290        solve_position((float) delta, 10.0f, 0.5f, 0.5f));
00291     glob_trans_off();
00292     scale_on();
00293     set_scale(solve_position((float) delta, 10.0f, 1.0f/(1.0f+10.0f/3.0f), 0.25f));
00294     scale_off();
00295     return;
00296   }
00297 
00298   if (elapsed < 35) 
00299     return;
00300 
00301   // just spin the VMD logo
00302   delta = elapsed - 35;
00303   rot_on();
00304   set_rot((float) delta * 360.0f / 6.0f, 'y');  
00305   rot_off();
00306 }
00307 

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