//===========================================================================//
// File:	AnimInterp.cpp                                                 
// Project: MechWarrior 4
// Contents: 
//			
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 07/06/98  JSE  Initial coding, 
//---------------------------------------------------------------------------//
// Copyright (C) 1998, Fasa Interactive, Inc.
// All Rights reserved worldwide
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL
//===========================================================================//



#include <MW4\MW4AnimationSystem.hpp>


using namespace MW4Animation;
using namespace Stuff;

//
//#############################################################################
//#############################################################################
//
Stuff::Point3D 
	MW4Animation::Point3DSnapInterpolator(
		BaseKeyframe *keyframe_from, 
		BaseKeyframe *keyframe_to,
		BaseKeyframeTime *keyframe_from_time, 
		BaseKeyframeTime *keyframe_to_time, 
		Stuff::Scalar time)
{

	return ((Point3DLinearKey*)keyframe_from)->valueOfKey;
	
}
//
//#############################################################################
//#############################################################################
//
Stuff::Point3D 
	MW4Animation::Point3DVelPosSnapInterpolator(
		BaseKeyframe *keyframe_from, 
		BaseKeyframe *keyframe_to, 
		BaseKeyframeTime *keyframe_from_time, 
		BaseKeyframeTime *keyframe_to_time,
		Stuff::Scalar time)
{

	return ((VelocityLinearKey*)keyframe_from)->velocityOfKey;
	
}

//
//#############################################################################
//#############################################################################
//
Stuff::Vector3D 
	MW4Animation::AngularVelocitySnapInterpolator(
		BaseKeyframe *keyframe_from, 
		BaseKeyframe *keyframe_to, 
		BaseKeyframeTime *keyframe_from_time, 
		BaseKeyframeTime *keyframe_to_time,
		Stuff::Scalar time)
{

	return ((AngularVelocityLinearKey*)keyframe_from)->velocityOfKey;
	
}


//
//#############################################################################
//#############################################################################
//
Stuff::UnitQuaternion
	MW4Animation::QuaternionSnapInterpolator(
		BaseKeyframe *keyframe_from, 
		BaseKeyframe *keyframe_to, 
		BaseKeyframeTime *keyframe_from_time, 
		BaseKeyframeTime *keyframe_to_time,
		Stuff::Scalar time)
{

	return ((QuaternionLinearKey*)keyframe_from)->valueOfKey;

}

//
//#############################################################################
//#############################################################################
//
Stuff::Point3D 
	MW4Animation::Point3DLinearInterpolator(
		BaseKeyframe *keyframe_from, 
		BaseKeyframe *keyframe_to, 
		BaseKeyframeTime *keyframe_from_time, 
		BaseKeyframeTime *keyframe_to_time,
		Stuff::Scalar time)
{

	if (time > keyframe_to_time->timeOfFrame)
	{
		return ((Point3DLinearKey*)keyframe_to)->valueOfKey;
	}


	Verify(time >= keyframe_from_time->timeOfFrame);
	Verify(time <= keyframe_to_time->timeOfFrame);
	Verify(keyframe_from_time->timeOfFrame != keyframe_to_time->timeOfFrame);

	if (time == keyframe_from_time->timeOfFrame)
	{
		return ((Point3DLinearKey*)keyframe_from)->valueOfKey;
	}

	if (Close_Enough(keyframe_to_time->timeOfFrame, keyframe_from_time->timeOfFrame, 1e-4f))
	{
		return ((Point3DLinearKey*)keyframe_from)->valueOfKey;
	}

	Scalar percent = (time - keyframe_from_time->timeOfFrame)
		/(keyframe_to_time->timeOfFrame - keyframe_from_time->timeOfFrame);
		
	Point3D new_val;
	new_val.Lerp(((Point3DLinearKey*)keyframe_from)->valueOfKey, ((Point3DLinearKey*)keyframe_to)->valueOfKey, percent);

	return new_val;
}

//
//#############################################################################
//#############################################################################
//
Stuff::Point3D 
	MW4Animation::Point3DVelPosLinearInterpolator(
		BaseKeyframe *keyframe_from, 
		BaseKeyframe *keyframe_to, 
		BaseKeyframeTime *keyframe_from_time, 
		BaseKeyframeTime *keyframe_to_time,
		Stuff::Scalar time)
{

	return ((VelocityLinearKey*)keyframe_to)->velocityOfKey;
#if 0
	if (time > keyframe_to_time->timeOfFrame)
	{
		return ((VelocityLinearKey*)keyframe_to)->velocityOfKey;
	}

	Verify(time >= keyframe_from_time->timeOfFrame);
	Verify(time <= keyframe_to_time->timeOfFrame);
	Verify(keyframe_from_time->timeOfFrame != keyframe_to_time->timeOfFrame);

	if (time == keyframe_from_time->timeOfFrame)
	{
		return ((VelocityLinearKey*)keyframe_from)->velocityOfKey;
	}

	if (Close_Enough(keyframe_to_time->timeOfFrame, keyframe_from_time->timeOfFrame, 1e-4f))
	{
		return ((VelocityLinearKey*)keyframe_from)->velocityOfKey;
	}

	Scalar percent = (time - keyframe_from_time->timeOfFrame)
		/(keyframe_to_time->timeOfFrame - keyframe_from_time->timeOfFrame);
		
	Point3D new_val;
	new_val.Lerp(((VelocityLinearKey*)keyframe_from)->velocityOfKey, ((VelocityLinearKey*)keyframe_to)->velocityOfKey, percent);

	return new_val;
#endif
}
//
//#############################################################################
//#############################################################################
//
Stuff::Vector3D 
	MW4Animation::AngularVelocityLinearInterpolator(
		BaseKeyframe *keyframe_from, 
		BaseKeyframe *keyframe_to, 
		BaseKeyframeTime *keyframe_from_time, 
		BaseKeyframeTime *keyframe_to_time,
		Stuff::Scalar time)
{

	return ((AngularVelocityLinearKey*)keyframe_to)->velocityOfKey;

#if 0

	if (time > keyframe_to_time->timeOfFrame)
	{
		return ((AngularVelocityLinearKey*)keyframe_to)->velocityOfKey;
	}

	Verify(time >= keyframe_from_time->timeOfFrame);
	Verify(time <= keyframe_to_time->timeOfFrame);
	Verify(keyframe_from_time->timeOfFrame != keyframe_to_time->timeOfFrame);

	if (time == keyframe_from_time->timeOfFrame)
	{
		return ((AngularVelocityLinearKey*)keyframe_from)->velocityOfKey;
	}

	if (Close_Enough(keyframe_to_time->timeOfFrame, keyframe_from_time->timeOfFrame, 1e-4f))
	{
		return ((AngularVelocityLinearKey*)keyframe_from)->velocityOfKey;
	}

	Scalar percent = (time - keyframe_from_time->timeOfFrame)
		/(keyframe_to_time->timeOfFrame - keyframe_from_time->timeOfFrame);
		
	Point3D new_val;
	new_val.Lerp(((AngularVelocityLinearKey*)keyframe_from)->velocityOfKey, ((AngularVelocityLinearKey*)keyframe_to)->velocityOfKey, percent);

	return new_val;
#endif
}


//
//#############################################################################
//#############################################################################
//
Stuff::UnitQuaternion 
	MW4Animation::QuaternionLinearInterpolator(
		BaseKeyframe *keyframe_from, 
		BaseKeyframe *keyframe_to, 
		BaseKeyframeTime *keyframe_from_time, 
		BaseKeyframeTime *keyframe_to_time,
		Stuff::Scalar time)
{
	if (time > keyframe_to_time->timeOfFrame)
	{
		return ((QuaternionLinearKey*)keyframe_to)->valueOfKey;
	}

	Verify(time >= keyframe_from_time->timeOfFrame);
	Verify(time <= keyframe_to_time->timeOfFrame);
	Verify(keyframe_from_time->timeOfFrame != keyframe_to_time->timeOfFrame);

	if (time == keyframe_from_time->timeOfFrame)
	{
		return ((QuaternionLinearKey*)keyframe_from)->valueOfKey;
	}

	if (Close_Enough(keyframe_to_time->timeOfFrame, keyframe_from_time->timeOfFrame, 1e-4f))
	{
		return ((QuaternionLinearKey*)keyframe_from)->valueOfKey;
	}

	Scalar percent = (time - keyframe_from_time->timeOfFrame)
		/(keyframe_to_time->timeOfFrame - keyframe_from_time->timeOfFrame);
		
	//DEBUG_STREAM << "*" << percent << endl;
	UnitQuaternion new_val;
	
	//UnitQuaternion from_frame = ((QuaternionLinearKey*)keyframe_from)->valueOfKey;
	//UnitQuaternion to_frame = ((QuaternionLinearKey*)keyframe_to)->valueOfKey;
	//from_frame.Normalize();
	//to_frame.Normalize();
	//new_val.Slerp(from_frame, to_frame, percent);

	new_val.FastLerp(((QuaternionLinearKey*)keyframe_from)->valueOfKey, ((QuaternionLinearKey*)keyframe_to)->valueOfKey, percent);

	return new_val;
}
//
//#############################################################################
//#############################################################################
//
Stuff::UnitQuaternion 
	MW4Animation::QuaternionLinearInterpolatorSlow(
		BaseKeyframe *keyframe_from, 
		BaseKeyframe *keyframe_to, 
		BaseKeyframeTime *keyframe_from_time, 
		BaseKeyframeTime *keyframe_to_time,
		Stuff::Scalar time)
{
	if (time > keyframe_to_time->timeOfFrame)
	{
		return ((QuaternionLinearKey*)keyframe_to)->valueOfKey;
	}

	Verify(time >= keyframe_from_time->timeOfFrame);
	Verify(time <= keyframe_to_time->timeOfFrame);
	Verify(keyframe_from_time->timeOfFrame != keyframe_to_time->timeOfFrame);

	if (time == keyframe_from_time->timeOfFrame)
	{
		return ((QuaternionLinearKey*)keyframe_from)->valueOfKey;
	}

	if (Close_Enough(keyframe_to_time->timeOfFrame, keyframe_from_time->timeOfFrame, 1e-4f))
	{
		return ((QuaternionLinearKey*)keyframe_from)->valueOfKey;
	}

	Scalar percent = (time - keyframe_from_time->timeOfFrame)
		/(keyframe_to_time->timeOfFrame - keyframe_from_time->timeOfFrame);
		
	//DEBUG_STREAM << "*" << percent << endl;
	UnitQuaternion new_val;
	
	UnitQuaternion from_frame = ((QuaternionLinearKey*)keyframe_from)->valueOfKey;
	UnitQuaternion to_frame = ((QuaternionLinearKey*)keyframe_to)->valueOfKey;
	from_frame.Normalize();
	to_frame.Normalize();
	new_val.Lerp(from_frame, to_frame, percent);

	return new_val;
}

//
//#############################################################################
//#############################################################################
//
int
	MW4Animation::TriggerSnapInterpolator(
		BaseKeyframe *keyframe_from, 
		BaseKeyframe *keyframe_to, 
		BaseKeyframeTime *keyframe_from_time, 
		BaseKeyframeTime *keyframe_to_time,
		Stuff::Scalar time)
{
	return ((TriggerLinearKey*)keyframe_from)->valueOfKey;
}
//
//#############################################################################
//#############################################################################
//
