// // SuperTuxKart - a fun racing game with go-kart // Copyright (C) 2009-2015 Joerg Henrichs // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 3 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "animations/animation_base.hpp" #include "animations/ipo.hpp" #include "io/file_manager.hpp" #include "io/xml_node.hpp" #include "utils/vs.hpp" #include #include AnimationBase::AnimationBase(const XMLNode &node) { float fps=25; node.get("fps", &fps); for(unsigned int i=0; igetName() == "animated-texture") continue; Ipo *ipo = new Ipo(*node.getNode(i), fps); m_all_ipos.push_back(ipo); } m_playing = true; m_anim_type = ATT_CYCLIC; if (m_all_ipos.size() == 0) // this will happen for some separate but non-animated objects { m_playing = false; } reset(); } // AnimationBase // ---------------------------------------------------------------------------- /** Special constructor which takes one IPO (or curve). This is used by the */ AnimationBase::AnimationBase(Ipo *ipo) { m_anim_type = ATT_CYCLIC_ONCE; m_playing = true; m_all_ipos.push_back(ipo); reset(); } // AnimationBase(Ipo) // ---------------------------------------------------------------------------- /** Stores the initial transform (in the IPOs actually). This is necessary * for relative IPOs. * \param xyz Position of the object. * \param hpr Rotation of the object. */ void AnimationBase::setInitialTransform(const Vec3 &xyz, const Vec3 &hpr) { for_var_in(Ipo*, curr, m_all_ipos) { curr->setInitialTransform(xyz, hpr); } } // setTransform // ---------------------------------------------------------------------------- /** Resets all IPOs for this animation. */ void AnimationBase::reset() { m_current_time = 0; for_var_in(Ipo*, curr, m_all_ipos) { curr->reset(); } } // reset // ---------------------------------------------------------------------------- /** Updates the time, position and rotation. Called once per frame. * \param dt Time since last call. * \param xyz Position to be updated. * \param hpr Rotation to be updated. */ void AnimationBase::update(float dt, Vec3 *xyz, Vec3 *hpr, Vec3 *scale) { assert(!std::isnan(m_current_time)); // Don't do anything if the animation is disabled if(!m_playing) return; m_current_time += dt; assert(!std::isnan(m_current_time)); for_var_in (Ipo*, curr, m_all_ipos) { curr->update(m_current_time, xyz, hpr, scale); } } // update // ---------------------------------------------------------------------------- /** Return the time, position and rotation at the specified time. It does not * update the internal timer as update() does. * \param dt Time since last call. * \param xyz Position to be updated. * \param hpr Rotation to be updated. */ void AnimationBase::getAt(float time, Vec3 *xyz, Vec3 *hpr, Vec3 *scale) { assert(!std::isnan(time)); // Don't do anything if the animation is disabled if (!m_playing) return; for_var_in(Ipo*, curr, m_all_ipos) { curr->update(time, xyz, hpr, scale); } } // getAt // ---------------------------------------------------------------------------- /** Returns the derivative at the specified point. * \param time The time for which to determine the derivative. * \param xyz Float pointer to store the result. */ void AnimationBase::getDerivativeAt(float time, Vec3 *xyz) { for_var_in(Ipo*, curr, m_all_ipos) { curr->getDerivative(time, xyz); } xyz->normalize(); }