From fc8040d695644aaca4596adebeca4ea1369ef630 Mon Sep 17 00:00:00 2001 From: Fox Caminiti Date: Fri, 22 Jul 2022 20:45:08 -0400 Subject: first --- keyframes.cpp | 383 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 383 insertions(+) create mode 100644 keyframes.cpp (limited to 'keyframes.cpp') diff --git a/keyframes.cpp b/keyframes.cpp new file mode 100644 index 0000000..a7ff37a --- /dev/null +++ b/keyframes.cpp @@ -0,0 +1,383 @@ +internal keyframe* +KeyframeLookupMemory(property_channel *Property, int16 i) { + int16 b = i / MAX_KEYFRAMES_PER_BLOCK; + int16 k = i - b*MAX_KEYFRAMES_PER_BLOCK; + return &Property->KeyframeBlock[b]->Keyframe[k]; +} + +internal keyframe* +KeyframeLookupIndex(property_channel *Property, int16 a) { + int16 i = Property->SortedIndex[a]; + int16 b = i / MAX_KEYFRAMES_PER_BLOCK; + int16 k = i - b*MAX_KEYFRAMES_PER_BLOCK; + return &Property->KeyframeBlock[b]->Keyframe[k]; +} + +internal keyframe* +PushKeyframe(property_channel *Property) { + int16 i = Property->NumberOfTotalKeyframes; + int16 b = i / MAX_KEYFRAMES_PER_BLOCK; + int16 k = i - b*MAX_KEYFRAMES_PER_BLOCK; + return &Property->KeyframeBlock[b]->Keyframe[k]; +} + +// (extremely bad) +internal temp_keyframe_list +GetSelectedKeyframes(project_data *File) +{ + temp_keyframe_list KeyframeList; + int z = 0; + for (int i = 0; i < File->NumberOfLayers; i++) { + for (int a = 0; a < AmountOf(File->Layer[i]->Property); a++) { + for (int l = 0; l < File->Layer[i]->Property[a].NumberOfTotalKeyframes; l++) { + keyframe *Keyframe = KeyframeLookupMemory(&File->Layer[i]->Property[a], l); + if (Keyframe->IsSelected) { + KeyframeList.SelectedKeyframe[z] = Keyframe; + z++; + } + } + } + } + KeyframeList.Amount = z; + return KeyframeList; +} + +internal int32 +KeyframeMemoryToIndex(property_channel *Property, int32 a) +{ + int32 Result = -1; + for (int l = 0; l < Property->NumberOfTotalKeyframes; l++) { + if (Property->SortedIndex[l] == a) { + Result = l; + break; + } + } + Assert(Result > -1); + return Result; +} + +internal void +SelectKeyframe(project_data *File, project_layer *Layer, property_channel *Property, keyframe *Keyframe) +{ + Layer->IsSelected = true; + File->NumberOfSelectedLayers++; + Property->NumberOfSelectedKeyframes++; + Keyframe->IsSelected = true; +} + +internal void +DeselectKeyframe(project_data *File, project_layer *Layer, property_channel *Property, keyframe *Keyframe) +{ + Layer->IsSelected = true; + File->NumberOfSelectedLayers++; + Property->NumberOfSelectedKeyframes++; + Keyframe->IsSelected = true; +} + +internal void +CheckKeyframeSort(property_channel *Property, int32 Increment, int32 b) +{ + int32 i = KeyframeMemoryToIndex(Property, b); + if (Increment > 0) { + if (i+1 != Property->NumberOfTotalKeyframes) { + keyframe *CurrentKeyframe = KeyframeLookupIndex(Property, i); + keyframe *NextKeyframe = KeyframeLookupIndex(Property, i + 1); + if (NextKeyframe->FrameNumber < CurrentKeyframe->FrameNumber) { + uint16 Temp = Property->SortedIndex[i]; + Property->SortedIndex[i] = Property->SortedIndex[i + 1]; + Property->SortedIndex[i + 1] = Temp; + } + } + } else { + if (i != 0) { + keyframe *CurrentKeyframe = KeyframeLookupIndex(Property, i); + keyframe *LastKeyframe = KeyframeLookupIndex(Property, i - 1); + if (CurrentKeyframe->FrameNumber < LastKeyframe->FrameNumber) { + uint16 Temp = Property->SortedIndex[i]; + Property->SortedIndex[i] = Property->SortedIndex[i - 1]; + Property->SortedIndex[i - 1] = Temp; + } + } + } +} + +internal void +ShiftKeyframeIndex(property_channel *Property, int16 Increment, int16 StopAt) { + if (Increment > 0) { + int16 i = Property->NumberOfTotalKeyframes - 1; + while (i > StopAt) { + Property->SortedIndex[i + Increment] = Property->SortedIndex[i]; + i--; + } + } else { + int16 i = StopAt; + while (i < Property->NumberOfTotalKeyframes - 1) { + Property->SortedIndex[i] = Property->SortedIndex[i + Increment]; + i++; + } + } +} + +internal void +DeleteKeyframeFromMemory(property_channel *Property, int16 Increment, int16 StopAt) { + if (Increment > 0) { + int16 i = Property->NumberOfTotalKeyframes - 1; + while (i > StopAt) { + keyframe *CurrentKeyframe = KeyframeLookupMemory(Property, i); + keyframe *NextKeyframe = KeyframeLookupMemory(Property, i + Increment); + *NextKeyframe = *CurrentKeyframe; + i--; + } + Property->NumberOfTotalKeyframes += Increment; + } else { + int16 i = StopAt; + while (i < Property->NumberOfTotalKeyframes - 1) { + keyframe *CurrentKeyframe = KeyframeLookupMemory(Property, i); + keyframe *NextKeyframe = KeyframeLookupMemory(Property, i - Increment); + *CurrentKeyframe = *NextKeyframe; + i++; + } + Property->NumberOfTotalKeyframes += Increment; + } +} + +internal void +ResortPropertyChannel(property_channel *Property) { + for (int16 i = 0; i < Property->NumberOfTotalKeyframes; i++) + { + Property->SortedIndex[i] = i; + } + for (;;) { + int16 Swaps = 0; + for (int16 i = 0; i < Property->NumberOfTotalKeyframes - 1; i++) + { + keyframe *Keyframe = KeyframeLookupIndex(Property, i); + keyframe *NextKeyframe = KeyframeLookupIndex(Property, i + 1); + if (Keyframe->FrameNumber > NextKeyframe->FrameNumber) { + uint16 Temp = Property->SortedIndex[i]; + Property->SortedIndex[i] = Property->SortedIndex[i + 1]; + Property->SortedIndex[i + 1] = Temp; + Swaps++; + } + } + if (Swaps == 0) + break; + } +} + +internal void +DeleteSelectedKeyframes(project_data *File, memory *Memory) +{ + for (int i = 0; i < File->NumberOfLayers; i++) { + for (int a = 0; a < AmountOf(File->Layer[i]->Property); a++) { + property_channel *Property = &File->Layer[i]->Property[a]; + for (int l = 0; l < Property->NumberOfTotalKeyframes; l++) { + keyframe *Keyframe = KeyframeLookupMemory(Property, l); + if (Keyframe->IsSelected) { + int16 ToShift = 1; + bool32 Until = true; + while (Until) { + keyframe *KeyframeN = KeyframeLookupMemory(Property, l + ToShift); + if (KeyframeN->IsSelected) { + ToShift += 1; + } else { + Until = false; + } + } + DeleteKeyframeFromMemory(Property, -ToShift, l); + } + } + ResortPropertyChannel(Property); + } + } +} + +internal void +CalculatePropertyMinMax(property_channel *Property) { + Property->LocalMaxVal = Property->MinVal; + Property->LocalMinVal = Property->MaxVal; + for (int16 i = 0; i < Property->NumberOfTotalKeyframes; i++) { + keyframe *Keyframe = KeyframeLookupMemory(Property, i); + Property->LocalMinVal.f = Ceil(Property->LocalMinVal.f, Keyframe->Value.f); + Property->LocalMaxVal.f = Floor(Property->LocalMaxVal.f, Keyframe->Value.f); + } + if (Property->LocalMinVal.f == Property->LocalMaxVal.f) + { + Property->LocalMaxVal.f += 1; + } +} + + +internal void +IncrementKeyframes(property_channel *Property, int16 Increment) +{ + for (int i = 0; i < Property->NumberOfTotalKeyframes; i++) { + keyframe *Keyframe = KeyframeLookupIndex(Property, i); + Keyframe->FrameNumber += Increment; + } +} + +internal void +IncrementKeyframesInLayer(project_layer *Layer, int16 Increment) +{ + for (int a = 0; a < AmountOf(Layer->Property); a++) + IncrementKeyframes(&Layer->Property[a], Increment); + for (int e = 0; e < Layer->NumberOfEffects; e++) + for (int a = 0; a < Layer->Effect[e]->NumberOfProperties; a++) + IncrementKeyframes(&Layer->Effect[e]->Property[a], Increment); +} + +internal void +CreateKeyframeBlock(property_channel *, memory *); + +// dir 0 left, 1 right +internal void +ClampKeyframeHandles(property_channel *Property, int16 b, int16 dir) { + if (dir == 0) { + if (b > 0) { + keyframe *Keyframe = KeyframeLookupIndex(Property, b - 1); + keyframe *NextKeyframe = KeyframeLookupIndex(Property, b); + real32 XSpan = NextKeyframe->FrameNumber - Keyframe->FrameNumber; + if (abs(NextKeyframe->TangentLeft.x) > XSpan) + NextKeyframe->TangentLeft.x = -XSpan; + if (NextKeyframe->TangentLeft.x > 0) + NextKeyframe->TangentLeft.x = 0; + } + } + if (dir == 1) { + if (b < Property->NumberOfTotalKeyframes - 1) { + keyframe *Keyframe = KeyframeLookupIndex(Property, b); + keyframe *NextKeyframe = KeyframeLookupIndex(Property, b + 1); + real32 XSpan = NextKeyframe->FrameNumber - Keyframe->FrameNumber; + if (Keyframe->TangentRight.x > XSpan) + Keyframe->TangentRight.x = XSpan; + if (Keyframe->TangentRight.x < 0) + Keyframe->TangentRight.x = 0; + } + } +} + +internal void +ClampSurroundingKeyframeHandles(property_channel *Property, int16 b) { + ClampKeyframeHandles(Property, b, 0); + ClampKeyframeHandles(Property, b, 1); + if (b > 0) { + ClampKeyframeHandles(Property, b-1, 0); + ClampKeyframeHandles(Property, b-1, 1); + } + if (b < Property->NumberOfTotalKeyframes - 1) { + ClampKeyframeHandles(Property, b+1, 0); + ClampKeyframeHandles(Property, b+1, 1); + } +} + + + +internal void +ManualKeyframeInsertF(property_channel *Property, memory *Memory, int32 CurrentFrame, real32 Val) +{ + if (!(Property->NumberOfTotalKeyframes % MAX_KEYFRAMES_PER_BLOCK)) { + CreateKeyframeBlock(Property, Memory); + } + keyframe *Keyframe = NULL; + if (Property->NumberOfTotalKeyframes == 0) { + Keyframe = &Property->KeyframeBlock[0]->Keyframe[0]; + Property->NumberOfTotalKeyframes++; + } else if (Property->NumberOfTotalKeyframes == 1) { + Keyframe = &Property->KeyframeBlock[0]->Keyframe[0]; + if (CurrentFrame != Keyframe->FrameNumber) { + if (CurrentFrame > Keyframe->FrameNumber) { + Property->SortedIndex[1] = 1; + } else { + Property->SortedIndex[0] = 1; + } + Property->NumberOfTotalKeyframes++; + } + Keyframe = &Property->KeyframeBlock[0]->Keyframe[1]; + } else { + keyframe *LastKeyframe = KeyframeLookupIndex(Property, Property->NumberOfTotalKeyframes-1); + if (LastKeyframe->FrameNumber < CurrentFrame) { + Property->SortedIndex[Property->NumberOfTotalKeyframes] = Property->NumberOfTotalKeyframes; + } else { + for (int16 i = 0; i < Property->NumberOfTotalKeyframes; i++) { + keyframe *CurrentKeyframe = KeyframeLookupIndex(Property, i); + if (CurrentKeyframe->FrameNumber > CurrentFrame) { + ShiftKeyframeIndex(Property, 1, i - 1); + Property->SortedIndex[i] = Property->NumberOfTotalKeyframes; + break; + } + } + } + Keyframe = PushKeyframe(Property); + Property->NumberOfTotalKeyframes++; + } + Assert(!(Keyframe == NULL)) + Keyframe->FrameNumber = CurrentFrame; + Keyframe->Value.f = Val; + Keyframe->Type = bezier; + Keyframe->TangentLeft = V2(-1, 0); + Keyframe->TangentRight = V2(1, 0); + CalculatePropertyMinMax(Property); +} + + +internal void +CalculateKeyframesLinearly(uint16 CurrentFrame, struct property_channel *Property) +{ + + keyframe *FirstKeyframe = KeyframeLookupIndex(Property, 0); + + keyframe *LastKeyframe = KeyframeLookupIndex(Property, Property->NumberOfTotalKeyframes - 1); + if (Property->NumberOfTotalKeyframes == 0) { + // do nothing + } + // check if current frame is before first keyframe or after last + else if (Property->NumberOfTotalKeyframes == 1 || + CurrentFrame < FirstKeyframe->FrameNumber) { + Property->CurrentValue = FirstKeyframe->Value; + } + else if (CurrentFrame > LastKeyframe->FrameNumber) { + Property->CurrentValue = LastKeyframe->Value; + } + else if (Property->NumberOfTotalKeyframes > 1) { + for (int i = 0; i < (Property->NumberOfTotalKeyframes - 1); i++) { + keyframe *Keyframe = KeyframeLookupIndex(Property, i); + keyframe *NextKeyframe = KeyframeLookupIndex(Property, i+1); + if (CurrentFrame >= Keyframe->FrameNumber && + CurrentFrame <= NextKeyframe->FrameNumber) + { + real32 FakeVelocity = ((CurrentFrame - Keyframe->FrameNumber) / + (NextKeyframe->FrameNumber - + (real32)Keyframe->FrameNumber)); + real32 t = FakeVelocity; + // real32 u = 1.0f - t; + // real32 w1 = u * u * u; + // real32 w2 = 3 * u * u * t; + // real32 w3 = 3 * u * t * t; + // real32 w4 = t * t * t; + real32 t2 = t * t; + real32 t3 = t2 * t; + real32 mt = 1-t; + real32 mt2 = mt * mt; + real32 mt3 = mt2 * mt; + if (Property->VarType == type_real ) { + real32 OldValue = Property->CurrentValue.f; + real32 CurrentVal = Keyframe->Value.f; + real32 CurrentTan = CurrentVal + Keyframe->TangentRight.y; + real32 NextVal = NextKeyframe->Value.f; + real32 NextTan = NextVal + NextKeyframe->TangentLeft.y; + // Property->CurrentValue.f = w1 * CurrentVal + w2 * CurrentTan + w3 * NextTan + w4 * NextVal; + Property->CurrentValue.f = CurrentVal*mt3 + 3*CurrentTan*mt2*t + 3*NextTan*mt*t2 + NextVal*t3; + //Property->CurrentValue.f = CurrentVal + ((NextVal - CurrentVal) * FakeVelocity); + } + else if (Property->VarType == type_color) { + v4 OldValue = Property->CurrentValue.col; + v4 CurrentVal = Keyframe->Value.col; + v4 NextVal = NextKeyframe->Value.col; + Property->CurrentValue.col = CurrentVal + ((NextVal - CurrentVal) * FakeVelocity); + } + break; + } + } + } +} -- cgit v1.2.3