コード例 #1
0
ファイル: Dict.cpp プロジェクト: Afr0/idtech4.net
/*
================
idDict::Copy

  copy all key value pairs without removing existing key/value pairs not present in the other dict
================
*/
void idDict::Copy( const idDict &other ) {
	int i, n, *found;
	idKeyValue kv;

	// check for assignment to self
	if ( this == &other ) {
		return;
	}

	n = other.args.Num();

	if ( args.Num() ) {
		found = (int *) _alloca16( other.args.Num() * sizeof( int ) );
        for ( i = 0; i < n; i++ ) {
			found[i] = FindKeyIndex( other.args[i].GetKey() );
		}
	} else {
		found = NULL;
	}

	for ( i = 0; i < n; i++ ) {
		if ( found && found[i] != -1 ) {
			// first set the new value and then free the old value to allow proper self copying
			const idPoolStr *oldValue = args[found[i]].value;
			args[found[i]].value = globalValues.CopyString( other.args[i].value );
			globalValues.FreeString( oldValue );
		} else {
			kv.key = globalKeys.CopyString( other.args[i].key );
			kv.value = globalValues.CopyString( other.args[i].value );
			argHash.Add( argHash.GenerateKey( kv.GetKey(), false ), args.Append( kv ) );
		}
	}
}
コード例 #2
0
bool ApplyInterpolator(float aTarget[], int aWidth, int aCount, const float aKeys[], float aTime, int &aHint)
{
	// get stride
	const int aStride = aWidth + 1;

	// get the key index
	int index = FindKeyIndex(aStride, aCount, aKeys, aTime, aHint);
	if (index < 0)
		return false;

	// update hint index
	aHint = index;

	// interpolate the value
	const float * __restrict key = aKeys + index * aStride;
	const float time0 = key[0];
	const float * __restrict data0 = &key[1];
	const float time1 = key[aStride];
	const float * __restrict data1 = &key[aStride + 1];
	const float t = (aTime - time0) / (time1 - time0 + FLT_EPSILON);
	for (int element = 0; element < aWidth; element++)
	{
		aTarget[element] = Lerp(data0[element], data1[element], t);
	}
	return true;
}
コード例 #3
0
ファイル: Dict.cpp プロジェクト: revelator/Revelator-Doom3
/*
================
idDict::Set
================
*/
void idDict::Set( const char *key, const char *value )
{
    int i;
    idKeyValue kv;

    if ( key == NULL || key[0] == '\0' )
    {
        return;
    }

    i = FindKeyIndex( key );
    if ( i != -1 )
    {
        // first set the new value and then free the old value to allow proper self copying
        const idPoolStr *oldValue = args[i].value;
        args[i].value = globalValues.AllocString( value );
        globalValues.FreeString( oldValue );
    }
    else
    {
        kv.key = globalKeys.AllocString( key );
        kv.value = globalValues.AllocString( value );
        argHash.Add( argHash.GenerateKey( kv.GetKey(), false ), args.Append( kv ) );
    }
}
コード例 #4
0
bool ApplyInterpolatorConstant(float aTarget[], int aWidth, int aCount, const float aKeys[], float aTime, int &aHint)
{
	// get stride
	const int aStride = aWidth + 1;

	// get the key index
	int index = FindKeyIndex(aStride, aCount, aKeys, aTime, aHint);
	if (index < 0)
		return false;

	// update hint index
	aHint = index;

	// use the first value
	const float * __restrict key = aKeys + index * aStride;
	const float * __restrict data0 = &key[1];
	for (int element = 0; element < aWidth; element++)
	{
		aTarget[element] = data0[element];
	}
	return true;
}
コード例 #5
0
ファイル: Dict.cpp プロジェクト: AliKalkandelen/quake4
/*
================
idDict::Set
================
*/
void idDict::Set( const char *key, const char *value ) {
	int i;
	idKeyValue kv;
// RAVEN BEGIN
// jnewquist: Tag scope and callees to track allocations using "new".
	MEM_SCOPED_TAG(tag,MA_STRING);
// RAVEN END

	if ( key == NULL || key[0] == '\0' ) {
		return;
	}

	i = FindKeyIndex( key );
	if ( i != -1 ) {
		// first set the new value and then free the old value to allow proper self copying
		const idPoolStr *oldValue = args[i].value;
		args[i].value = globalValues.AllocString( value );
		globalValues.FreeString( oldValue );
	} else {
		kv.key = globalKeys.AllocString( key );
		kv.value = globalValues.AllocString( value );
		argHash.Add( argHash.GenerateKey( kv.GetKey(), false ), args.Append( kv ) );
	}
}
コード例 #6
0
/**
 * Reconstructs a bone atom from key-reduced tracks.
 */
void UAnimSequence::ReconstructBoneAtom(FBoneAtom& OutAtom,
										const FTranslationTrack& TranslationTrack,
										const FRotationTrack& RotationTrack,
										FLOAT SequenceLength,
										FLOAT Time,
										UBOOL bLooping)
{
	OutAtom.Scale = 1.f;

	// Bail out (with rather wacky data) if data is empty for some reason.
	if( TranslationTrack.PosKeys.Num() == 0 || TranslationTrack.Times.Num() == 0 || 
		RotationTrack.RotKeys.Num() == 0 || RotationTrack.Times.Num() == 0 )
	{
		//debugf( TEXT("UAnimSequence::ReconstructBoneAtom(reduced) : No anim data in AnimSequence!") );
		OutAtom.Rotation = FQuat::Identity;
		OutAtom.Translation = FVector(0.f, 0.f, 0.f);
		return;
	}

	// Check for before-first-frame case.
	if( Time <= 0.f )
	{
		OutAtom.Translation = TranslationTrack.PosKeys(0);
		OutAtom.Rotation	= RotationTrack.RotKeys(0);
		return;
	}

	// Check for after-last-frame case.
	const INT LastPosIndex	= TranslationTrack.PosKeys.Num() - 1;
	const INT LastRotIndex	= RotationTrack.RotKeys.Num() - 1;
	if( Time >= SequenceLength )
	{
		OutAtom.Translation = TranslationTrack.PosKeys(LastPosIndex);
		OutAtom.Rotation	= RotationTrack.RotKeys(LastRotIndex);
		return;
	}

	// Find the "starting" key indices.
	const INT PosIndex0 = FindKeyIndex( Time, TranslationTrack.Times );
	const INT RotIndex0 = FindKeyIndex( Time, RotationTrack.Times );

	///////////////////////
	// Translation.

	INT PosIndex1;
	FLOAT PosAlpha;

	// If we have gone over the end, do different things in case of looping.
	if ( PosIndex0 == LastPosIndex )
	{
		// If looping, interpolate between last and first frame.
		if( bLooping )
		{
			PosIndex1 = 0;
			// @todo DB: handle looping with variable-length keys.
			PosAlpha = 0.5f;
		}
		// If not looping - hold the last frame.
		else
		{
			PosIndex1 = PosIndex0;
			PosAlpha = 1.f;
		}
	}
	else
	{
		// Find the "ending" key index and alpha.
		PosIndex1 = PosIndex0+1;
		const FLOAT DeltaTime = TranslationTrack.Times(PosIndex1) - TranslationTrack.Times(PosIndex0);
		PosAlpha = (Time - TranslationTrack.Times(PosIndex0))/DeltaTime;
	}

	OutAtom.Translation = Lerp( TranslationTrack.PosKeys(PosIndex0), TranslationTrack.PosKeys(PosIndex1), PosAlpha );

	///////////////////////
	// Rotation.

	INT RotIndex1;
	FLOAT RotAlpha;

	// If we have gone over the end, do different things in case of looping.
	if ( RotIndex0 == LastRotIndex )
	{
		// If looping, interpolate between last and first frame.
		if( bLooping )
		{
			RotIndex1 = 0;
			 // @todo DB: handle looping with variable-length keys.
			RotAlpha = 0.5f;
		}
		// If not looping - hold the last frame.
		else
		{
			RotIndex1 = RotIndex0;
			RotAlpha = 1.f;
		}
	}
	else
	{
		// Find the "ending" key index and alpha.
		RotIndex1 = RotIndex0+1;
		const FLOAT DeltaTime = RotationTrack.Times(RotIndex1) - RotationTrack.Times(RotIndex0);
		RotAlpha = (Time - RotationTrack.Times(RotIndex0))/DeltaTime;
	}

#if !USE_SLERP
	// Fast linear quaternion interpolation.
	// To ensure the 'shortest route', we make sure the dot product between the two keys is positive.
	if( (RotationTrack.RotKeys(RotIndex0) | RotationTrack.RotKeys(RotIndex1)) < 0.f )
	{
		// To clarify the code here: a slight optimization of inverting the parametric variable as opposed to the quaternion.
		OutAtom.Rotation = (RotationTrack.RotKeys(RotIndex0) * (1.f-RotAlpha)) + (RotationTrack.RotKeys(RotIndex1) * -RotAlpha);
	}
	else
	{
		OutAtom.Rotation = (RotationTrack.RotKeys(RotIndex0) * (1.f-RotAlpha)) + (RotationTrack.RotKeys(RotIndex1) * RotAlpha);
	}
#else
	OutAtom.Rotation = SlerpQuat( RotationTrack.RotKeys(RotIndex0), RotationTrack.RotKeys(RotIndex1), RotAlpha );
#endif

	OutAtom.Rotation.Normalize();
}