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: Animation.C,v $ 00013 * $Author: johns $ $Locker: $ $State: Exp $ 00014 * $Revision: 1.55 $ $Date: 2010/12/16 04:08:01 $ 00015 * 00016 *************************************************************************** 00017 * DESCRIPTION: 00018 * 00019 * The Animation class, which stores a list of pointers to Timestep objects 00020 * that contain 3D coordinates and other data that varies with time. 00021 * 00022 ***************************************************************************/ 00023 00024 #include "Animation.h" 00025 #include "VMDApp.h" 00026 #include "CmdAnimate.h" 00027 #include <stdio.h> 00028 00029 // strings describing animation styles 00030 const char *animationStyleName[Animation::ANIM_TOTAL_STYLES] = { 00031 "Once", "Loop", "Rock" 00032 }; 00033 const char *animationDirName[Animation::ANIM_TOTAL_DIRS] = { 00034 "forward", "next", "reverse", "prev", "pause" 00035 }; 00036 00037 00038 // constructor 00039 Animation::Animation(VMDApp *app_) : UIObject(app_), mlist(*app->moleculeList) { 00040 lastTime = time_of_day(); // get the current time for determining speed 00041 speed(1.0); // set initial speed to maximum 00042 skip(1); // don't skip any frames yet 00043 anim_dir(ANIM_PAUSE); // not yet animating 00044 anim_style(ANIM_LOOP); // loop back to beginning when end reached 00045 } 00046 00047 00048 void Animation::goto_frame(int fr) { 00049 for (int i=0; i<mlist.num(); i++) { 00050 Molecule *m = mlist.molecule(i); 00051 if (m->active) { 00052 // XXX backward compatibility lameness 00053 int theframe = fr; 00054 if (fr == -1) 00055 theframe = 0; 00056 else if (fr == -2) 00057 theframe = m->numframes(); 00058 m->override_current_frame(theframe); 00059 m->change_ts(); 00060 } 00061 } 00062 } 00063 00064 00065 // update the animation list based on current mode; return if curr frame change 00066 int Animation::check_event() { 00067 // if we're paused, do nothing 00068 if (animDir == ANIM_PAUSE) 00069 return 0; 00070 00071 // other animation modes depend on the delay. Check if a sufficient 00072 // delay has elapsed. 00073 double curTime = time_of_day(); 00074 double dt = curTime - lastTime; 00075 if (dt <= (SPEED_FACTOR - Speed)) 00076 return 0; 00077 00078 // time to update frames. Cache the current time before proceeding. 00079 lastTime = curTime; 00080 int curframe = frame(); 00081 int n = num(); 00082 00083 // nothing to do if there are fewer than two frames 00084 if (n < 2) 00085 return 0; 00086 00087 // skip the current frame ahead the proper amount 00088 for (int i=0; i < frameSkip; i++) { 00089 if (animDir == ANIM_REVERSE || animDir == ANIM_REVERSE1) { 00090 if (curframe <= 0) { 00091 if (animStyle == ANIM_LOOP) { 00092 curframe = n-1; 00093 } else if (animStyle == ANIM_ROCK) { 00094 animDir = ANIM_FORWARD; 00095 } else if (animStyle == ANIM_ONCE) { 00096 animDir = ANIM_PAUSE; 00097 } 00098 } else { 00099 --curframe; 00100 } 00101 } else if (animDir == ANIM_FORWARD || animDir == ANIM_FORWARD1) { 00102 if (curframe >= n-1) { 00103 if (animStyle == ANIM_LOOP) { 00104 curframe = 0; 00105 } else if (animStyle == ANIM_ROCK) { 00106 animDir = ANIM_REVERSE; 00107 } else if (animStyle == ANIM_ONCE) { 00108 animDir = ANIM_PAUSE; 00109 } 00110 } else { 00111 ++curframe; 00112 } 00113 } 00114 } 00115 00116 goto_frame(curframe); 00117 // we generated an event, so let other UIs know about it. 00118 runcommand(new CmdAnimNewFrame); 00119 00120 // these two modes stop after one action 00121 if (animDir == ANIM_FORWARD1 || animDir == ANIM_REVERSE1) 00122 animDir = ANIM_PAUSE; 00123 00124 return 1; 00125 } 00126 00127 00128 void Animation::skip(int newsk) { 00129 frameSkip = ( newsk >= 1 ? newsk : 1); 00130 } 00131 00132 00133 float Animation::speed(float newsp) { 00134 if (newsp < 0.0) 00135 Speed = 0.0; 00136 else if (newsp > 1.0) 00137 Speed = SPEED_FACTOR; 00138 else 00139 Speed = newsp*SPEED_FACTOR; 00140 00141 return Speed; 00142 } 00143 00144 00145 void Animation::anim_style(AnimStyle as) { 00146 animStyle = as; 00147 } 00148 00149 00150 00151 00152 00153 00154
1.2.14 written by Dimitri van Heesch,
© 1997-2002