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

VMDTitle.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2019 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.61 $       $Date: 2019/09/26 04:58:39 $
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     float size = 0.8f;
00212     txt.putdata(pos, "Theoretical and Computational Biophysics Group", 1.0f, size, 0, 0, cmdList);
00213     pos[1] -= 0.1f;
00214     txt.putdata(pos, "NIH Resource for Macromolecular Modeling and Bioinformatics", 1.0f, size, 0, 0, cmdList);
00215     pos[1] -= 0.1f;
00216     txt.putdata(pos, "University of Illinois at Urbana-Champaign", 1.0f, size, 0, 0, cmdList);
00217     pos[1] -= 0.1f;
00218     txt.putdata(pos, VMD_AUTHORS_LINE1, 1.0f, size, 0, 0, cmdList);
00219     pos[1] -= 0.1f;
00220     txt.putdata(pos, VMD_AUTHORS_LINE2, 1.0f, size, 0, 0, cmdList);
00221     pos[1] -= 0.1f;
00222     txt.putdata(pos, VMD_AUTHORS_LINE3, 1.0f, size, 0, 0, cmdList);
00223   }
00224 }
00225 
00226 // simply fits a 2rd degree polynomial so that v(d=0)=0=v(d=t)
00227 // and x(d=0)=start and x(d=t)=end
00228 static float solve_position(float d, float t, float start, float end) {
00229   float a = 6.0f*(end-start)/(t*t*t);
00230   return a*d*d*(t/2.0f-d/3.0f)+start;
00231 }
00232 
00233 void VMDTitle::prepare() {
00234   double elapsed = time_of_day() - starttime;
00235   double delta;
00236 
00237   // Prevent the title screen from hogging the CPU/GPU when there's
00238   // nothing else going on.  This is particularly important for users
00239   // that start VMD and immediately start using Multiseq with no structure
00240   // data loaded at all.
00241   vmd_msleep(1); // sleep for 1 millisecond or more
00242 
00243   if (elapsed < 5 + 3) {  // display the title screen, no animation
00244     if (!letterson) {
00245       letterson = TRUE;
00246       redraw_list();
00247     }
00248     return;
00249   }
00250 
00251   elapsed -= 3;
00252   if (letterson) {
00253     letterson = FALSE;
00254     redraw_list();
00255   }
00256 
00257   if (elapsed < 30) { // just spin the VMD logo
00258     delta = elapsed - 5;
00259     rot_on();
00260     set_rot(solve_position((float) delta, 25.0f, 0.0f, 360.0f*8.0f), 'y');
00261     rot_off();
00262   }
00263 
00264   if (elapsed < 15) { 
00265     delta = elapsed - 5;
00266     scale_on();
00267     set_scale( 1.0f/(1.0f+ ((float) delta)/3.0f)); // and getting smaller
00268     scale_off();
00269     glob_trans_on();
00270 
00271     // and moving up
00272     set_glob_trans(0, 0.5f, solve_position((float) delta, 10.0f, 0.0f, 0.5f)); 
00273     glob_trans_off();
00274     return;
00275   }
00276 
00277   if (elapsed < 20) {
00278     return;
00279   }
00280 
00281   // I am at          ( 0  ,  0.5, 0.5)
00282   // I want to get to ( -.7  ,  0.9  , 0.5) in 10 secs
00283   if (elapsed < 30) {
00284     delta = elapsed - 20;
00285     glob_trans_on();
00286     set_glob_trans(
00287        solve_position((float) delta, 10.0f, 0.0f, -0.6f * disp->aspect()),
00288        solve_position((float) delta, 10.0f, 0.5f, 0.8f),
00289        solve_position((float) delta, 10.0f, 0.5f, 0.5f));
00290     glob_trans_off();
00291     scale_on();
00292     set_scale(solve_position((float) delta, 10.0f, 1.0f/(1.0f+10.0f/3.0f), 0.25f));
00293     scale_off();
00294     return;
00295   }
00296 
00297   if (elapsed < 35) 
00298     return;
00299 
00300   // just spin the VMD logo
00301   delta = elapsed - 35;
00302   rot_on();
00303   set_rot((float) delta * 360.0f / 6.0f, 'y');  
00304   rot_off();
00305 }
00306 

Generated on Fri Apr 19 02:45:34 2024 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002