/******************************************************************************
void IFXKeyTrack::Filter(F32 deltatime)

remove track entries too close in time

******************************************************************************/
void IFXKeyTrack::Filter(F32 deltatime)
{
	//I32 original=GetNumberElements();

	IFXListContext basecontext,nextcontext;
	IFXKeyFrame *base,*next;

	ToHead(basecontext);
	while((base=GetCurrent(basecontext)) != NULL)
	{
		nextcontext=basecontext;
		PostIncrement(nextcontext);

		if(IsAtTail(nextcontext))
			break;

		next=GetCurrent(nextcontext);

		if( (next->Time()-base->Time()) < deltatime )
		{
			Delete(next);
		}
		else
		{
			PostIncrement(basecontext);
		}
	}
}
void IFXKeyTrack::Compress(F32 deltaposition,F32 deltarotation,F32 deltascale)
{
	//I32 original=GetNumberElements();

	IFXListContext basecontext,midcontext,leapcontext;
	IFXKeyFrame *base,*mid,*leap;

	ToHead(basecontext);
	while((base=GetCurrent(basecontext)) != NULL)
	{
		midcontext=basecontext;
		PostIncrement(midcontext);
		leapcontext=midcontext;
		PostIncrement(leapcontext);

		if(IsAtTail(leapcontext))
			break;

		mid=GetCurrent(midcontext);
		leap=GetCurrent(leapcontext);

		F32 fraction=(mid->Time()-base->Time())/(leap->Time()-base->Time());

		IFXVector3 intervector;
		intervector.Interpolate(fraction,base->LocationConst(),
			leap->LocationConst());

		IFXQuaternion interquat;
		interquat.Interpolate(fraction,base->RotationConst(),
			leap->RotationConst());
		IFXVector3 interscale;
		interscale.Interpolate(fraction,base->ScaleConst(),
			leap->ScaleConst());



		if(mid->LocationConst().IsApproximately(intervector,deltaposition) &&
			mid->RotationConst().IsApproximately(interquat,deltarotation) &&
			mid->ScaleConst().IsApproximately(interscale,deltascale) )
		{
			//* watch out for spans close to 180 degrees
			F32 radians;
			IFXVector3 axis;
			IFXQuaternion inverse,span;
			inverse.Invert(base->RotationConst());
			span.Multiply(inverse,leap->RotationConst());
			span.ComputeAngleAxis(radians,axis);

			if(radians<170.0*IFXTO_RAD)
				Delete(mid);
			else
				PostIncrement(basecontext);
		}
		else
		{
			PostIncrement(basecontext);
		}
	}
}
int Multilign_object::SetIndexSeq(size_t indexSeq) {
    // the first seq is the index seq; no need to make any change
    if(!--indexSeq) return 0;
    // the indexSeq is out of range
    if(indexSeq < 0 || indexSeq >= inputList.size()) return 5005;
    // move the indicated index seq to the beginning of the vectors by rotating
    ToHead(inputList.begin(), inputList.begin() + indexSeq);
    return 0;
}
/**
	move context to node just after time
*/
void IFXKeyTrack::Sync(F32 time, IFXListContext* context) const
{
	IFXKeyFrame *frame=GetCurrent(*context);

	if(!frame)
	{
		if(IsAtTail(*context))
			frame=ToTail(*context);
		else
			frame=ToHead(*context);
	}

	while(frame && frame->Time()>time)
		frame=PreDecrement(*context);

	while(frame && frame->Time()<time)
		frame=PreIncrement(*context);
}