153 lines
3.8 KiB
C++
153 lines
3.8 KiB
C++
/* -----------------------------------------------------------------------------
|
|
GSFramework
|
|
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
|
----------------------------------------------------------------------------- */
|
|
|
|
|
|
#ifndef __PLATFORM_IOS__
|
|
#include <malloc.h>
|
|
#endif
|
|
#include "automation/automation_player.h"
|
|
#include "automation/automation_source.h"
|
|
#include "platform_config.h"
|
|
|
|
using namespace GS::Automation;
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
Motion *Player::GetMotion(const char *id) const
|
|
{
|
|
ListForeachPtr(Motion *, i, motions)
|
|
if (!String::Compare(i->name, id))
|
|
return i;
|
|
return NULL;
|
|
}
|
|
Motion *Player::GetMotionFromIndex(uint index) const
|
|
{ return motions.ObjectAt(index); }
|
|
bool Player::AddMotion(Motion *motion)
|
|
{ return asbool(motions.Add(motion)); }
|
|
void Player::RemoveMotion(Motion *motion)
|
|
{ motions.Remove(motion); }
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
Source *Player::StartAutomation(Source *source, float _blend, AddSourceMode mode, float _weight)
|
|
{
|
|
if (!source)
|
|
return NULL;
|
|
|
|
// Source blend.
|
|
switch (mode)
|
|
{
|
|
case SourceSet: // Dispose of all current sources.
|
|
ListForeachPtr(Source *, s, sources)
|
|
s->Dispose(_blend);
|
|
break;
|
|
|
|
default: break;
|
|
}
|
|
|
|
// Blend in source.
|
|
source->SetWeight(_weight, _blend);
|
|
sources.Add(source);
|
|
|
|
switch (source->GetType())
|
|
{
|
|
case Source::TypeMotion:
|
|
source->relative = flags.IsSet(FlagRelativeMotion);
|
|
break;
|
|
|
|
default: break;
|
|
}
|
|
return source;
|
|
}
|
|
void Player::Evaluate(const GS::Time &dt_time)
|
|
{
|
|
if (!sources.GetCount() || property_provider.IsNull())
|
|
return;
|
|
|
|
// Allocate weight table from stack.
|
|
weight_table = (float *)alloca(sizeof(float) * MotionChannel::Last);
|
|
for (int n = 0; n < MotionChannel::Last; ++n)
|
|
weight_table[n] = 0;
|
|
|
|
// Update sources.
|
|
ListForeachPtr(Source *, s, sources)
|
|
{
|
|
s->Update(dt_time);
|
|
if (s->CanDispose())
|
|
sources.Remove(s);
|
|
}
|
|
|
|
// Mix rotation.
|
|
float w = 0;
|
|
Quaternion q, source_q = property_provider->GetRotation();
|
|
|
|
ListForeachPtr(Source *, s, sources)
|
|
if (s->GetWeight() > 0.01)
|
|
if (s->EvaluateRotation(source_q))
|
|
{
|
|
if (w > 0.01)
|
|
q = Quaternion::Slerp(w / (w + s->GetWeight()), source_q, q);
|
|
else q = source_q;
|
|
|
|
w += s->GetWeight();
|
|
}
|
|
|
|
if (w > 0)
|
|
property_provider->SetRotation(q);
|
|
|
|
// Mix sources.
|
|
ListForeachPtr(Source *, s, sources)
|
|
if (s->GetWeight())
|
|
s->Evaluate(*this);
|
|
|
|
// Drop weight table.
|
|
weight_table = NULL;
|
|
}
|
|
void Player::BlendAutomatedProperty(MotionChannel::Type type, float _v, float _w)
|
|
{
|
|
if (!_w || !weight_table)
|
|
return;
|
|
|
|
float v, *w = &weight_table[(uint)type];
|
|
|
|
if (property_provider->GetProperty(type, v))
|
|
{
|
|
v = (v * *w + _v * _w) / (*w + _w);
|
|
*w += _w;
|
|
property_provider->SetProperty(type, v);
|
|
}
|
|
}
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
bool Player::IsAutomated() const
|
|
{ return asbool(sources.GetCount()); }
|
|
bool Player::IsAutomationDone() const
|
|
{
|
|
ListForeachPtr(Source *, s, GetSourceList())
|
|
if (!s->IsDone())
|
|
return false;
|
|
return true;
|
|
}
|
|
bool Player::GetAutomationActive() const
|
|
{ return active; }
|
|
void Player::SetAutomationActive(bool _active)
|
|
{ active = _active; }
|
|
void Player::DisposeAutomationSources()
|
|
{ sources.Clear(); }
|
|
//------------------------------------------------------------------------------
|
|
|
|
//------------------------------------------------------------------------------
|
|
Player::Player()
|
|
{
|
|
active = true;
|
|
weight_table = NULL;
|
|
}
|
|
Player::~Player()
|
|
{
|
|
DisposeAutomationSources();
|
|
}
|
|
//------------------------------------------------------------------------------
|