// Filename: animInterface.I // Created by: drose (20Sep05) // //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // // All use of this software is subject to the terms of the revised BSD // license. You should have received a copy of this license along // with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// // Function: AnimInterface::play // Access: Published // Description: Runs the entire animation from beginning to end and // stops. //////////////////////////////////////////////////////////////////// INLINE void AnimInterface:: play() { play(0, get_num_frames() - 1); } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::play // Access: Published // Description: Runs the animation from the frame "from" to and // including the frame "to", at which point the // animation is stopped. Both "from" and "to" frame // numbers may be outside the range (0, // get_num_frames()) and the animation will follow the // range correctly, reporting numbers modulo // get_num_frames(). For instance, play(0, // get_num_frames() * 2) will play the animation twice // and then stop. //////////////////////////////////////////////////////////////////// INLINE void AnimInterface:: play(double from, double to) { { CDWriter cdata(_cycler); cdata->play(from, to); } animation_activated(); } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::loop // Access: Published // Description: Starts the entire animation looping. If restart is // true, the animation is restarted from the beginning; // otherwise, it continues from the current frame. //////////////////////////////////////////////////////////////////// INLINE void AnimInterface:: loop(bool restart) { loop(restart, 0, get_num_frames() - 1); } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::loop // Access: Published // Description: Loops the animation from the frame "from" to and // including the frame "to", indefinitely. If restart // is true, the animation is restarted from the // beginning; otherwise, it continues from the current // frame. //////////////////////////////////////////////////////////////////// INLINE void AnimInterface:: loop(bool restart, double from, double to) { { CDWriter cdata(_cycler); cdata->loop(restart, from, to); } animation_activated(); } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::pingpong // Access: Published // Description: Starts the entire animation bouncing back and forth // between its first frame and last frame. If restart // is true, the animation is restarted from the // beginning; otherwise, it continues from the current // frame. //////////////////////////////////////////////////////////////////// INLINE void AnimInterface:: pingpong(bool restart) { pingpong(restart, 0, get_num_frames() - 1); } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::pingpong // Access: Published // Description: Loops the animation from the frame "from" to and // including the frame "to", and then back in the // opposite direction, indefinitely. //////////////////////////////////////////////////////////////////// INLINE void AnimInterface:: pingpong(bool restart, double from, double to) { { CDWriter cdata(_cycler); cdata->pingpong(restart, from, to); } animation_activated(); } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::stop // Access: Published // Description: Stops a currently playing or looping animation right // where it is. The animation remains posed at the // current frame. //////////////////////////////////////////////////////////////////// INLINE void AnimInterface:: stop() { CDWriter cdata(_cycler); cdata->pose(cdata->get_full_fframe()); // Don't call animation_activated() here; stopping an animation // should not activate it. } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::pose // Access: Published // Description: Sets the animation to the indicated frame and holds // it there. //////////////////////////////////////////////////////////////////// INLINE void AnimInterface:: pose(double frame) { { CDWriter cdata(_cycler); cdata->pose(frame); } animation_activated(); } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::set_play_rate // Access: Published // Description: Changes the rate at which the animation plays. 1.0 // is the normal speed, 2.0 is twice normal speed, and // 0.5 is half normal speed. 0.0 is legal to pause the // animation, and a negative value will play the // animation backwards. //////////////////////////////////////////////////////////////////// INLINE void AnimInterface:: set_play_rate(double play_rate) { CDWriter cdata(_cycler); cdata->internal_set_rate(cdata->_frame_rate, play_rate); } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::get_play_rate // Access: Published // Description: Returns the rate at which the animation plays. See // set_play_rate(). //////////////////////////////////////////////////////////////////// INLINE double AnimInterface:: get_play_rate() const { CDReader cdata(_cycler); return cdata->_play_rate; } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::get_frame_rate // Access: Published // Description: Returns the native frame rate of the animation. This // is the number of frames per second that will elapse // when the play_rate is set to 1.0. It is a fixed // property of the animation and may not be adjusted by // the user. //////////////////////////////////////////////////////////////////// INLINE double AnimInterface:: get_frame_rate() const { CDReader cdata(_cycler); return cdata->_frame_rate; } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::get_frame // Access: Published // Description: Returns the current integer frame number. // This number will be in the range 0 <= f < // get_num_frames(). //////////////////////////////////////////////////////////////////// INLINE int AnimInterface:: get_frame() const { int num_frames = get_num_frames(); if (num_frames <= 0) { return 0; } CDReader cdata(_cycler); return cmod(cdata->get_full_frame(0), num_frames); } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::get_next_frame // Access: Published // Description: Returns the current integer frame number + 1, // constrained to the range 0 <= f < get_num_frames(). // // If the play mode is PM_play, this will clamp to the // same value as get_frame() at the end of the // animation. If the play mode is any other value, this // will wrap around to frame 0 at the end of the // animation. //////////////////////////////////////////////////////////////////// INLINE int AnimInterface:: get_next_frame() const { int num_frames = get_num_frames(); if (num_frames <= 0) { return 0; } CDReader cdata(_cycler); return cmod(cdata->get_full_frame(1), num_frames); } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::get_frac // Access: Published // Description: Returns the fractional part of the current frame. // Normally, this is in the range 0.0 <= f < 1.0, but in // the one special case of an animation playing to its // end frame and stopping, it might exactly equal 1.0. // // It will always be true that get_full_frame() + // get_frac() == get_full_fframe(). //////////////////////////////////////////////////////////////////// INLINE double AnimInterface:: get_frac() const { CDReader cdata(_cycler); return cdata->get_frac(); } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::get_full_frame // Access: Published // Description: Returns the current integer frame number. // // Unlike the value returned by get_frame(), this frame // number may extend beyond the range of // get_num_frames() if the frame range passed to play(), // loop(), etc. did. // // Unlike the value returned by get_full_fframe(), this // return value will never exceed the value passed to // to_frame in the play() method. //////////////////////////////////////////////////////////////////// INLINE int AnimInterface:: get_full_frame() const { CDReader cdata(_cycler); return cdata->get_full_frame(0); } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::get_full_fframe // Access: Published // Description: Returns the current floating-point frame number. // // Unlike the value returned by get_frame(), this frame // number may extend beyond the range of // get_num_frames() if the frame range passed to play(), // loop(), etc. did. // // Unlike the value returned by get_full_frame(), this // return value may equal (to_frame + 1.0), when the // animation has played to its natural end. However, in // this case the return value of get_full_frame() will // be to_frame, not (to_frame + 1). //////////////////////////////////////////////////////////////////// INLINE double AnimInterface:: get_full_fframe() const { CDReader cdata(_cycler); return cdata->get_full_fframe(); } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::is_playing // Access: Published // Description: Returns true if the animation is currently playing, // false if it is stopped (e.g. because stop() or pose() // was called, or because it reached the end of the // animation after play() was called). //////////////////////////////////////////////////////////////////// INLINE bool AnimInterface:: is_playing() const { CDReader cdata(_cycler); return cdata->is_playing(); } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::set_frame_rate // Access: Protected // Description: Should be called by a derived class to specify the // native frame rate of the animation. It is legal to // call this after the animation has already started. //////////////////////////////////////////////////////////////////// INLINE void AnimInterface:: set_frame_rate(double frame_rate) { CDWriter cdata(_cycler); cdata->internal_set_rate(frame_rate, cdata->_play_rate); } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::set_num_frames // Access: Protected // Description: Should be called by a derived class to specify the // number of frames of the animation. It is legal to // call this after the animation has already started, // but doing so may suddenly change the apparent current // frame number. //////////////////////////////////////////////////////////////////// INLINE void AnimInterface:: set_num_frames(int num_frames) { _num_frames = num_frames; } //////////////////////////////////////////////////////////////////// // Function: AnimInterface::CData::get_frac // Access: Published // Description: Returns the fractional part of the current frame. // Normally, this is in the range 0.0 <= f < 1.0, but in // the one special case of an animation playing to its // end frame and stopping, it might exactly equal 1.0. // // It will always be true that get_full_frame() + // get_frac() == get_full_fframe(). //////////////////////////////////////////////////////////////////// INLINE double AnimInterface::CData:: get_frac() const { return get_full_fframe() - (double)get_full_frame(0); } INLINE ostream & operator << (ostream &out, const AnimInterface &ai) { ai.output(out); return out; }