engine/src/HalibutAnimation/HalibutAnimation.cpp
2013-02-05 20:17:58 +00:00

501 lines
13 KiB
C++

#include "include/Engine.h"
#include "boost/assign.hpp"
namespace SE
{
THalibutAnimObject::THalibutAnimObject(const std::string& texName, vec2 posFrom, vec2 posTo)
: TexName(texName)
, TotalAnimTime(0)
, CurrentAnimTime(0)
, CurrentAnimFrame(0)
{
TRenderParams renderParams;
renderParams.SamplerMap[CONST_STRING_TEXTURE_UNIFORM] = texName;
renderParams.FloatMap[CONST_STRING_TRANSPARENCY_UNIFORM] = 1.f;
TriangleListVector.push_back(std::pair<TRenderParams, TTriangleList>(renderParams, MakeTriangleList(posFrom, posTo)));
LeftBottomPos = posFrom;
}
void THalibutAnimObject::RefreshTriangleListVector()
{
vec2 tex1 = AnimShotArr[CurrentAnimFrame].TexCoordFrom;
vec2 tex2 = vec2(AnimShotArr[CurrentAnimFrame].TexCoordFrom.v[0], AnimShotArr[CurrentAnimFrame].TexCoordTo.v[1]);
vec2 tex3 = AnimShotArr[CurrentAnimFrame].TexCoordTo;
vec2 tex4 = vec2(AnimShotArr[CurrentAnimFrame].TexCoordTo.v[0], AnimShotArr[CurrentAnimFrame].TexCoordFrom.v[1]);
TTriangleList& triangleList = TriangleListVector.begin()->second;
triangleList.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][0] = tex1;
triangleList.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][1] = tex2;
triangleList.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][2] = tex3;
triangleList.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][3] = tex3;
triangleList.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][4] = tex4;
triangleList.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][5] = tex1;
triangleList.RefreshBuffer();
}
void THalibutAnimObject::AddAnimShot(vec2 texCoordFrom, vec2 texCoordTo, cardinal timePassedFromStart)
{
AnimShotArr.push_back(TAnimShot(texCoordFrom, texCoordTo, timePassedFromStart));
CalcTotalAnimTime(); //Not rational but prevents a lot of stupid mistakes :(
}
void THalibutAnimObject::CalcTotalAnimTime()
{
if (AnimShotArr.size() == 0)
{
TotalAnimTime = 0;
}
else
{
std::vector<TAnimShot>::iterator i = AnimShotArr.end();
i--;
TotalAnimTime = i->TimePassedFromStart;
}
}
void THalibutAnimObject::Update(cardinal dt)
{
if (AnimShotArr.size() == 0)
{
return;
}
//cardinal prevCurrentAnimTime = CurrentAnimTime;
CurrentAnimTime += dt;
cardinal prevCurrentAnimFrame = CurrentAnimFrame;
while (CurrentAnimTime > AnimShotArr[CurrentAnimFrame].TimePassedFromStart)
{
CurrentAnimFrame++;
if (CurrentAnimFrame == AnimShotArr.size())
{
CurrentAnimFrame = 0;
CurrentAnimTime -= TotalAnimTime;
}
}
if (prevCurrentAnimFrame != CurrentAnimFrame)
{
RefreshTriangleListVector();
}
}
void THalibutAnimObject::Reset()
{
CurrentAnimFrame = 0;
CurrentAnimTime = 0;
RefreshTriangleListVector();
}
void THalibutAnimObject::Serialize(boost::property_tree::ptree& propertyTree)
{
Clear();
TexName = propertyTree.get<std::string>("Animation.TexName");
vec2 posFrom, posTo;
posFrom.v[0] = propertyTree.get<float>("Animation.PosFrom.<xmlattr>.x");
posFrom.v[1] = propertyTree.get<float>("Animation.PosFrom.<xmlattr>.y");
posTo.v[0] = propertyTree.get<float>("Animation.PosTo.<xmlattr>.x");
posTo.v[1] = propertyTree.get<float>("Animation.PosTo.<xmlattr>.y");
TRenderParams renderParams;
renderParams.SamplerMap[CONST_STRING_TEXTURE_UNIFORM] = TexName;
renderParams.FloatMap[CONST_STRING_TRANSPARENCY_UNIFORM] = 1.f;
TriangleListVector.push_back(std::pair<TRenderParams, TTriangleList>(renderParams, MakeTriangleList(posFrom, posTo)));
BOOST_FOREACH(boost::property_tree::ptree::value_type &v, propertyTree.get_child("Animation.Frames"))
{
vec2 texCoordFrom, texCoordTo;
texCoordFrom.v[0] = v.second.get<float>("TexCoordFrom.<xmlattr>.x");
texCoordFrom.v[1] = v.second.get<float>("TexCoordFrom.<xmlattr>.y");
texCoordTo.v[0] = v.second.get<float>("TexCoordTo.<xmlattr>.x");
texCoordTo.v[1] = v.second.get<float>("TexCoordTo.<xmlattr>.y");
cardinal timePassedFromStart = v.second.get<cardinal>("TimePassed");
AddAnimShot(texCoordFrom, texCoordTo, timePassedFromStart);
}
}
void THalibutAnimObject::Clear()
{
AnimShotArr.clear();
TriangleListVector.clear();
TotalAnimTime = 0;
CurrentAnimTime = 0;
CurrentAnimFrame = 0;
}
//==================================================
THalibutExternalAnimObject::THalibutExternalAnimObject(TRenderPairList::iterator renderPairIter, cardinal rectFrom, cardinal rectCount)
: RectCount(rectCount)
, RectFrom(rectFrom)
, TotalAnimTime(0)
, CurrentAnimTime(0)
, CurrentAnimFrame(0)
, RenderPairIter(renderPairIter)
{
}
THalibutExternalAnimObject::THalibutExternalAnimObject(const THalibutExternalAnimObject& copyFrom)
: CurrentAnimTime(copyFrom.CurrentAnimTime)
, TotalAnimTime(copyFrom.TotalAnimTime)
, CurrentAnimFrame(copyFrom.CurrentAnimFrame)
, AnimShotArr(copyFrom.AnimShotArr)
, RenderPairIter(copyFrom.RenderPairIter)
, RectCount(copyFrom.RectCount)
, RectFrom(copyFrom.RectFrom)
{
}
THalibutExternalAnimObject& THalibutExternalAnimObject::operator=(const THalibutExternalAnimObject& copyFrom)
{
//Self-assignment is ok
CurrentAnimTime = copyFrom.CurrentAnimTime;
TotalAnimTime = copyFrom.TotalAnimTime;
CurrentAnimFrame = copyFrom.CurrentAnimFrame;
AnimShotArr = copyFrom.AnimShotArr;
RenderPairIter = copyFrom.RenderPairIter;
RectCount = copyFrom.RectCount;
RectFrom = copyFrom.RectFrom;
return *this;
}
THalibutExternalAnimObject::~THalibutExternalAnimObject()
{
}
void THalibutExternalAnimObject::ReplaceAnimObject(TRenderPairList::iterator renderPairIter, cardinal rectFrom)
{
RectFrom = rectFrom;
RenderPairIter = renderPairIter;
}
void THalibutExternalAnimObject::RefreshTriangleListVector()
{
vec2 tex1 = AnimShotArr[CurrentAnimFrame].TexCoordFrom;
vec2 tex2 = vec2(AnimShotArr[CurrentAnimFrame].TexCoordFrom.v[0], AnimShotArr[CurrentAnimFrame].TexCoordTo.v[1]);
vec2 tex3 = AnimShotArr[CurrentAnimFrame].TexCoordTo;
vec2 tex4 = vec2(AnimShotArr[CurrentAnimFrame].TexCoordTo.v[0], AnimShotArr[CurrentAnimFrame].TexCoordFrom.v[1]);
for (cardinal i = RectFrom; i<RectFrom+RectCount; i++)
{
RenderPairIter->second.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][i*6+0] = tex1;
RenderPairIter->second.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][i*6+1] = tex2;
RenderPairIter->second.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][i*6+2] = tex3;
RenderPairIter->second.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][i*6+3] = tex3;
RenderPairIter->second.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][i*6+4] = tex4;
RenderPairIter->second.Data.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB][i*6+5] = tex1;
}
RenderPairIter->second.RefreshBuffer();
}
void THalibutExternalAnimObject::AddAnimShot(vec2 texCoordFrom, vec2 texCoordTo, cardinal timePassedFromStart)
{
AnimShotArr.push_back(TAnimShot(texCoordFrom, texCoordTo, timePassedFromStart));
CalcTotalAnimTime(); //Not rational but prevents a lot of stupid mistakes :(
}
void THalibutExternalAnimObject::CalcTotalAnimTime()
{
if (AnimShotArr.size() == 0)
{
TotalAnimTime = 0;
}
else
{
std::vector<TAnimShot>::iterator i = AnimShotArr.end();
i--;
TotalAnimTime = i->TimePassedFromStart;
}
}
void THalibutExternalAnimObject::Update(cardinal dt)
{
if (AnimShotArr.size() == 0)
{
return;
}
//cardinal prevCurrentAnimTime = CurrentAnimTime;
CurrentAnimTime += dt;
cardinal prevCurrentAnimFrame = CurrentAnimFrame;
while (CurrentAnimTime > AnimShotArr[CurrentAnimFrame].TimePassedFromStart)
{
CurrentAnimFrame++;
if (CurrentAnimFrame == AnimShotArr.size())
{
CurrentAnimFrame = 0;
CurrentAnimTime -= TotalAnimTime;
}
}
if (prevCurrentAnimFrame != CurrentAnimFrame)
{
RefreshTriangleListVector();
}
}
void THalibutExternalAnimObject::Reset()
{
CurrentAnimFrame = 0;
CurrentAnimTime = 0;
RefreshTriangleListVector();
}
void THalibutExternalAnimObject::Serialize(boost::property_tree::ptree& propertyTree)
{
//*Console<<"Halibut external anim object serialize\n";
Clear();
BOOST_FOREACH(boost::property_tree::ptree::value_type &v, propertyTree.get_child("Animation.Frames"))
{
vec2 texCoordFrom, texCoordTo;
texCoordFrom.v[0] = v.second.get<float>("TexCoordFrom.<xmlattr>.x");
texCoordFrom.v[1] = v.second.get<float>("TexCoordFrom.<xmlattr>.y");
texCoordTo.v[0] = v.second.get<float>("TexCoordTo.<xmlattr>.x");
texCoordTo.v[1] = v.second.get<float>("TexCoordTo.<xmlattr>.y");
cardinal timePassedFromStart = v.second.get<cardinal>("TimePassed");
AddAnimShot(texCoordFrom, texCoordTo, timePassedFromStart);
}
}
void THalibutExternalAnimObject::Clear()
{
//*Console<<"Halibut external anim object clear\n";
AnimShotArr.clear();
TotalAnimTime = 0;
CurrentAnimTime = 0;
CurrentAnimFrame = 0;
}
//==================================================
THalibutAnimationManager::~THalibutAnimationManager()
{
*Console<<"HalibutAnimationManager deleting...";
}
std::vector<THalibutAnimObjectRecord>::iterator THalibutAnimationManager::FindAnimObjectByName(const std::string& name)
{
std::vector<THalibutAnimObjectRecord>::iterator i;
for (i = HalibutAnimObjectArr.begin(); i != HalibutAnimObjectArr.end(); ++i)
{
if (i->Name == name)
{
return i;
}
}
//throw ErrorToLog("ERROR: Animation not found: " + name + "\n");
return HalibutAnimObjectArr.end();
}
void THalibutAnimationManager::ReplaceAnimationObject(const std::string& animName, TRenderPairList::iterator renderPairIter, cardinal rectFrom)
{
std::vector<THalibutAnimObjectRecord>::iterator i = FindAnimObjectByName(animName);
if (i == HalibutAnimObjectArr.end())
{
throw ErrorToLog("ERROR: Animation not found: " + animName);
}
i->HalibutAnimObject.ReplaceAnimObject(renderPairIter, rectFrom);
}
void THalibutAnimationManager::AddAnimationObject(const std::string& animName, THalibutExternalAnimObject halibutExternalAnimObject)
{
if (FindAnimObjectByName(animName) == HalibutAnimObjectArr.end())
{
HalibutAnimObjectArr.push_back(THalibutAnimObjectRecord(animName, halibutExternalAnimObject, THalibutAnimObjectRecord::AS_STOP));
}
}
void THalibutAnimationManager::DeleteAnimationObject(const std::string& animName)
{
std::vector<THalibutAnimObjectRecord>::iterator i = FindAnimObjectByName(animName);
if (i != HalibutAnimObjectArr.end())
{
HalibutAnimObjectArr.erase(i);
}
}
bool THalibutAnimationManager::AnimationExists(const std::string& animName)
{
return FindAnimObjectByName(animName) != HalibutAnimObjectArr.end();
}
void THalibutAnimationManager::Update(cardinal dt)
{
std::vector<THalibutAnimObjectRecord>::iterator i;
for (i = HalibutAnimObjectArr.begin(); i != HalibutAnimObjectArr.end(); ++i)
{
if (i->AnimState == THalibutAnimObjectRecord::AS_PLAY)
{
i->HalibutAnimObject.Update(dt);
}
}
}
void THalibutAnimationManager::StartAnimation(const std::string& animName)
{
std::vector<THalibutAnimObjectRecord>::iterator i = FindAnimObjectByName(animName);
if (FindAnimObjectByName(animName) == HalibutAnimObjectArr.end())
{
return;
}
i->AnimState = THalibutAnimObjectRecord::AS_PLAY;
}
void THalibutAnimationManager::StopAnimation(const std::string& animName)
{
std::vector<THalibutAnimObjectRecord>::iterator i = FindAnimObjectByName(animName);
if (FindAnimObjectByName(animName) == HalibutAnimObjectArr.end())
{
return;
}
i->AnimState = THalibutAnimObjectRecord::AS_STOP;
i->HalibutAnimObject.Reset();
}
void THalibutAnimationManager::PauseAnimation(const std::string& animName)
{
std::vector<THalibutAnimObjectRecord>::iterator i = FindAnimObjectByName(animName);
i->AnimState = THalibutAnimObjectRecord::AS_STOP;
}
/*
void THalibutAnimationManager::HideAnimation(const std::string& animName)
{
std::vector<THalibutAnimObjectRecord>::iterator i = FindAnimObjectByName(animName);
i->Visible = false;
}
void THalibutAnimationManager::ShowAnimation(const std::string& animName)
{
std::vector<THalibutAnimObjectRecord>::iterator i = FindAnimObjectByName(animName);
i->Visible = true;
}*/
void THalibutAnimationManager::PrintAnimationList()
{
static std::map<THalibutAnimObjectRecord::TAnimState, std::string> mapAnimState = boost::assign::map_list_of(THalibutAnimObjectRecord::AS_PLAY, "AS_PLAY")(THalibutAnimObjectRecord::AS_STOP, "AS_STOP");
std::vector<THalibutAnimObjectRecord>::iterator i;
Console->PrintImmediate("==========> ANIMATION LIST <==========");
for (i = HalibutAnimObjectArr.begin(); i != HalibutAnimObjectArr.end(); ++i)
{
Console->PrintImmediate(i->Name + " " + mapAnimState[i->AnimState]);
}
}
void THalibutAnimationManager::BindFunctions()
{
//*Console<<"Bind functions in THalibutAnimationManager\n";
ResourceManager->ScriptManager.AddFunction("pal", TScriptInfo("PrintAnimationList"), *this, &THalibutAnimationManager::PrintAnimationList);
}
} //namespace SE