//////////////////////////////////////////////////////////////////////////////
/// \file CooneyAnimatedMesh.h
///
/// Contains AnimatedMesh:
/// Simple animation scheme that allows mesh animation by doing mesh-to-mesh
/// interpolation. This is faster than using a full skeleton, but requires
/// more memory and is less dynamic.
///
/// Stephen Timothy Cooney, 2009
//////////////////////////////////////////////////////////////////////////////
#ifndef COONEYANIMATEDMESH_H
#define COONEYANIMATEDMESH_H
#include "CooneyMesh.h"
#include <map>
namespace Cooney
{
/// Simple animation scheme that allows mesh animation by doing mesh-to-mesh
/// interpolation. This is faster than using a full skeleton, but requires
/// more memory and is less dynamic.
class AnimatedMesh
{
protected:
std::map<float, Cooney::Mesh*> keys; /// key meshes tied to time(the float)
std::vector<Cooney::Mesh*> keymeshes; /// container of all unique owned meshes, for memory management. NOT for direct use.
float timeRate; /// rate at which time passes ( default 1.0f )
bool bLoop; /// if true, starts at the beginning once at the end...
bool bPlaying; /// if true, the mesh is currently animating.
float currentTime; /// the local mesh-time of where the animation is.
Cooney::Mesh interpolatedMesh; // the up-to-date animated mesh.
public:
AnimatedMesh();
~AnimatedMesh();
/// Return a reference to teh deformed/animating mesh.
Cooney::Mesh& Mesh(){return interpolatedMesh;}
/// Add a keyframe by loading a mesh file. Attaches
/// this loaded mesh to a time. The animated mesh will
/// manage the memory created when loading from the file.
bool AddKey(float time, const char* filename);
/// Connects a mesh to a time. If connected with this
/// function, the AnimatedMesh is NOT responsible for
/// the memory of the mesh. Memory management is not
/// necessary since this only contains references for
/// animation.
bool AddKey(float time, Cooney::Mesh* mesh);
/// Removes a keyframe at a point in the timeline.
bool DeleteKey(float time);
/// Remove keyframes between a start and an endtime.
bool DeleteKeys(float lowTime, float highTime);
/// Set the current local animation time to a point in
/// the local timeline.
bool SetTime(float time);
/// Begins playing the mesh if it is not already playing.
bool Play(bool bShouldLoop = true, float timePlayRate = 1.0f);
/// Stop playing the mesh animation.
void Stop(bool bReset = false);
/// Reset the animation to the start of the timeline.
void Reset();
/// Increment the timeline, stop or loop if at the end.
void Update(float timeStep);
/// Update the local version of the deformed mesh. This should
/// be called before rendering the deformed/animating mesh.
void UpdateMesh();
/// Render the deformed/animating mesh.
void PushGL(bool bPositions=true, bool bNormals=false, bool bTangents=false, bool bColors=false, bool bTexCoords=false);
/// Load an animation from file.
bool Load(const char* filePath);
/// Save the current animation to file.
bool Save(const char* filePath);
/// Load an animation from a data-stream.
void StreamInAnimatedMesh(std::istream& inStream);
/// Save the current animation to a datastream.
void StreamOutAnimatedMesh(std::ostream& outStream);
};
/// Utility function used for mesh deformation/animation.
/// Interpolates from meshA to meshB by interp value into
/// meshOut. It is assumed that meshA and B are of the same
/// data-topology.
void Interp(Cooney::Mesh &meshA, Cooney::Mesh &meshB, float interp, Cooney::Mesh &meshOut);
};
#endif