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: Animation.C,v $ 00013 * $Author: johns $ $Locker: $ $State: Exp $ 00014 * $Revision: 1.51 $ $Date: 2008/03/27 19:36:34 $ 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 // constructor 00038 Animation::Animation(VMDApp *app_) 00039 : UIObject(app_), mlist(*app->moleculeList) { 00040 00041 lastTime = time_of_day(); // get the current time for determining speed 00042 speed(1.0); // set initial speed to maximum 00043 skip(1); // don't skip any frames yet 00044 anim_dir(ANIM_PAUSE); // not yet animating 00045 anim_style(ANIM_LOOP); // loop back to beginning when end reached 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) theframe = 0; 00055 else if (fr == -2) theframe = m->numframes(); 00056 m->override_current_frame(theframe); 00057 m->change_ts(); 00058 } 00059 } 00060 } 00061 00062 // update the animation list based on current mode; return if curr frame change 00063 int Animation::check_event() { 00064 // if we're paused, do nothing 00065 if (animDir == ANIM_PAUSE) return 0; 00066 00067 // other animation modes depend on the delay. Check if a sufficient 00068 // delay has elapsed. 00069 double curTime = time_of_day(); 00070 double dt = curTime - lastTime; 00071 if (dt <= (SPEED_FACTOR - Speed)) return 0; 00072 00073 00074 // time to update frames. Cache the current time before proceeding. 00075 lastTime = curTime; 00076 int curframe = frame(); 00077 int n = num(); 00078 00079 // nothing to do if there are fewer than two frames 00080 if (n < 2) return 0; 00081 00082 // skip the current frame ahead the proper amount 00083 for (int i=0; i < frameSkip; i++) { 00084 if (animDir == ANIM_REVERSE || animDir == ANIM_REVERSE1) { 00085 if (curframe <= 0) { 00086 if (animStyle == ANIM_LOOP || animDir == ANIM_REVERSE1) { 00087 curframe = n-1; 00088 } else if (animStyle == ANIM_ROCK) { 00089 animDir = ANIM_FORWARD; 00090 } else if (animStyle == ANIM_ONCE) { 00091 animDir = ANIM_PAUSE; 00092 } 00093 } else { 00094 --curframe; 00095 } 00096 00097 } else if (animDir == ANIM_FORWARD || animDir == ANIM_FORWARD1) { 00098 if (curframe >= n-1) { 00099 if (animStyle == ANIM_LOOP || animDir == ANIM_FORWARD1) { 00100 curframe = 0; 00101 } else if (animStyle == ANIM_ROCK) { 00102 animDir = ANIM_REVERSE; 00103 } else if (animStyle == ANIM_ONCE) { 00104 animDir = ANIM_PAUSE; 00105 } 00106 } else { 00107 ++curframe; 00108 } 00109 } 00110 } 00111 goto_frame(curframe); 00112 // we generated an event, so let other UIs know about it. 00113 runcommand(new CmdAnimNewFrame); 00114 00115 // these two modes stop after one action 00116 if (animDir == ANIM_FORWARD1 || animDir == ANIM_REVERSE1) 00117 animDir = ANIM_PAUSE; 00118 00119 return 1; 00120 } 00121 00122 void Animation::skip(int newsk) { 00123 frameSkip = ( newsk >= 1 ? newsk : 1); 00124 } 00125 00126 float Animation::speed(float newsp) { 00127 if (newsp < 0.0) 00128 Speed = 0.0; 00129 else if (newsp > 1.0) 00130 Speed = SPEED_FACTOR; 00131 else 00132 Speed = newsp*SPEED_FACTOR; 00133 00134 return Speed; 00135 } 00136 00137 void Animation::anim_style(AnimStyle as) 00138 { 00139 animStyle = as; 00140 }
1.2.14 written by Dimitri van Heesch,
© 1997-2002