FKeyHandle FRichCurve::UpdateOrAddKey(float InTime, float InValue, const bool bUnwindRotation) { // Search for a key that already exists at the time and if found, update its value for (int32 KeyIndex = 0; KeyIndex < Keys.Num(); ++KeyIndex) { float KeyTime = Keys[KeyIndex].Time; if (KeyTime > InTime) { // All the rest of the keys exist after the key we want to add // so there is no point in searching break; } if (FMath::IsNearlyEqual(KeyTime, InTime)) { Keys[KeyIndex].Value = InValue; return GetKeyHandle(KeyIndex); } } // A key wasnt found, add it now return AddKey(InTime, InValue, bUnwindRotation); }
FKeyHandle FRichCurve::FindKey( float KeyTime ) const { int32 Start = 0; int32 End = Keys.Num()-1; // Binary search since the keys are in sorted order while( Start <= End ) { int32 TestPos = Start + (End-Start) / 2; float TestKeyTime = Keys[TestPos].Time; if( TestKeyTime == KeyTime ) { return GetKeyHandle( TestPos ); } else if( TestKeyTime < KeyTime ) { Start = TestPos+1; } else { End = TestPos-1; } } return FKeyHandle(); }
FKeyHandle FIntegralCurve::FindKeyBeforeOrAt( float KeyTime ) const { // If there are no keys or the time is before the first key return an invalid handle. if ( Keys.Num() == 0 || KeyTime < Keys[0].Time ) { return FKeyHandle(); } // If the time is after or at the last key return the last key. if ( KeyTime >= Keys[Keys.Num() - 1].Time ) { return GetKeyHandle(Keys.Num() - 1); } // Otherwise binary search to find the handle of the nearest key at or before the time. int32 Start = 0; int32 End = Keys.Num() - 1; int32 FoundIndex = -1; while ( FoundIndex < 0 ) { int32 TestPos = (Start + End) / 2; float TestKeyTime = Keys[TestPos].Time; float NextTestKeyTime = Keys[TestPos + 1].Time; if ( TestKeyTime <= KeyTime ) { if( NextTestKeyTime > KeyTime ) { FoundIndex = TestPos; } else { Start = TestPos + 1; } } else { End = TestPos; } } return GetKeyHandle(FoundIndex); }
FKeyHandle FRichCurve::GetPreviousKey(FKeyHandle KeyHandle) const { int32 KeyIndex = GetIndex(KeyHandle); KeyIndex--; if (Keys.IsValidIndex(KeyIndex)) { return GetKeyHandle(KeyIndex); } return FKeyHandle(); }
FKeyHandle FRichCurve::GetNextKey(FKeyHandle KeyHandle) const { int32 KeyIndex = GetIndex(KeyHandle); KeyIndex++; if (Keys.IsValidIndex(KeyIndex)) { return GetKeyHandle(KeyIndex); } else { return FKeyHandle(); } }
FKeyHandle FIntegralCurve::AddKey( float InTime, int32 InValue, FKeyHandle InKeyHandle ) { int32 Index = 0; for(; Index < Keys.Num() && Keys[Index].Time < InTime; ++Index); Keys.Insert(FIntegralKey(InTime, InValue), Index); for (auto It = KeyHandlesToIndices.CreateIterator(); It; ++It) { const FKeyHandle& KeyHandle = It.Key(); int32& KeyIndex = It.Value(); if (KeyIndex >= Index) {++KeyIndex;} } KeyHandlesToIndices.Add(InKeyHandle, Index); return GetKeyHandle(Index); }
FKeyHandle FNameCurve::AddKey(float InTime, const FName& InValue, FKeyHandle KeyHandle) { int32 Index = 0; // insert key for(; Index < Keys.Num() && Keys[Index].Time < InTime; ++Index); Keys.Insert(FNameCurveKey(InTime, InValue), Index); // update key indices for ( auto It = KeyHandlesToIndices.CreateIterator(); It; ++It) { int32& KeyIndex = It.Value(); if (KeyIndex >= Index) {++KeyIndex;} } KeyHandlesToIndices.Add(KeyHandle, Index); return GetKeyHandle(Index); }
FKeyHandle FRichCurve::AddKey( const float InTime, const float InValue, const bool bUnwindRotation, FKeyHandle NewHandle ) { int32 Index = 0; for(; Index < Keys.Num() && Keys[Index].Time < InTime; ++Index); Keys.Insert(FRichCurveKey(InTime, InValue), Index); // If we were asked to treat this curve as a rotation value and to unwindow the rotation, then // we'll look at the previous key and modify the key's value to use a rotation angle that is // continuous with the previous key while retaining the exact same rotation angle, if at all necessary if( Index > 0 && bUnwindRotation ) { const float OldValue = Keys[ Index - 1 ].Value; float NewValue = Keys[ Index ].Value; while( NewValue - OldValue > 180.0f ) { NewValue -= 360.0f; } while( NewValue - OldValue < -180.0f ) { NewValue += 360.0f; } Keys[Index].Value = NewValue; } for ( auto It = KeyHandlesToIndices.CreateIterator(); It; ++It) { const FKeyHandle& KeyHandle = It.Key(); int32& KeyIndex = It.Value(); if (KeyIndex >= Index) {++KeyIndex;} } KeyHandlesToIndices.Add(NewHandle, Index); return GetKeyHandle(Index); }
FKeyHandle FIntegralCurve::UpdateOrAddKey( float Time, int32 Value ) { for( int32 KeyIndex = 0; KeyIndex < Keys.Num(); ++KeyIndex ) { float KeyTime = Keys[KeyIndex].Time; if( KeyTime > Time ) { // All the rest of the keys exist after the key we want to add // so there is no point in searching break; } if( KeyTime == Time ) { Keys[KeyIndex].Value = Value; return GetKeyHandle(KeyIndex); } } // A key wasnt found, add it now return AddKey( Time, Value ); }