Files
Webcam/include/engine/motion/motion_automation_source.cpp

144 lines
3.2 KiB
C++

/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include "motion/motion_automation_source.h"
#include "motion/motion.h"
#include "automation/automation_source_group.h"
#include "automation/automation_player.h"
using namespace GS::Automation;
//------------------------------------------------------------------------------
void MotionSource::Evaluate(Player &target)
{
if (motion == NULL)
return;
ListForeachPtr(MotionChannel *, channel, motion->GetChannelList())
{
if (channel->GetPointCount() == 0)
continue;
// Skip rotation channels if using quaternion.
if (motion->GetUseQuaternion())
switch (channel->type)
{
case MotionChannel::XRot:
case MotionChannel::YRot:
case MotionChannel::ZRot:
continue;
default: break;
}
// Evaluate channel.
float v;
channel->Evaluate(time, &v, loop_mode, loop_start, loop_end);
// Relative mode.
switch (channel->type)
{
case MotionChannel::XPos:
case MotionChannel::YPos:
case MotionChannel::ZPos:
{
float _v = v, s;
if (relative && target.property_provider->GetProperty(channel->type, s))
v = s + v - p_pos[channel->type - MotionChannel::XPos];
p_pos[channel->type - MotionChannel::XPos] = _v;
}
break;
case MotionChannel::XRot:
case MotionChannel::YRot:
case MotionChannel::ZRot:
{
float _v = v, s;
if (relative && target.property_provider->GetProperty(channel->type, s))
v = s + v - p_euler[channel->type - MotionChannel::XRot];
p_euler[channel->type - MotionChannel::XRot] = _v;
}
break;
default: break;
}
target.BlendAutomatedProperty(channel->type, v, GetWeight());
}
}
bool MotionSource::EvaluateRotation(GS::Quaternion &q)
{
if (!motion->GetUseQuaternion())
return false;
Quaternion s = q;
motion->GetQuaternion().Evaluate(time, q, loop_mode, loop_start, loop_end);
Quaternion _q = q;
if (relative)
q = (q * p_quat.Inverse()) * s;
p_quat = _q;
return true;
}
bool MotionSource::IsDone() const
{
if (!motion)
return true;
switch (loop_mode)
{
case Curve::Repeat:
case Curve::OffsetAndRepeat:
case Curve::Oscillate:
break;
default:
if (time_scale > 0)
{
if (time > loop_end)
return true;
}
else
if (time < loop_start)
return true;
break;
}
return false;
}
MotionSource::MotionSource(Motion *_motion, SourceGroup *_group)
{
type = TypeMotion;
motion = _motion;
loop_mode = Curve::Constant;
if (motion)
{
TimeRange range = motion->GetTimeRange();
loop_start = range.start;
loop_end = range.end;
}
else
{
loop_start = Time::Inf;
loop_end = Time::Inf;
}
// Evaluate relative position/euler.
relative = false;
motion->EvaluatePosition(loop_start, p_pos, loop_mode);
if (motion->GetUseQuaternion())
motion->GetQuaternion().Evaluate(loop_start, p_quat, loop_mode);
else motion->EvaluateRotation(loop_start, p_euler, loop_mode);
group = _group;
if (group)
group->source_list.Add(this, true, false);
}
//------------------------------------------------------------------------------