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