/* ----------------------------------------------------------------------------- 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); } //------------------------------------------------------------------------------