Skip to content

Commit 6055621

Browse files
chore: interpolation implementation
1 parent 3732d3c commit 6055621

2 files changed

Lines changed: 188 additions & 31 deletions

File tree

FreeFrame/Components/Shapes/Shape.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public Shape()
4545
/// </summary>
4646
public virtual void Draw(Vector2i clientSize)
4747
{
48-
Console.WriteLine("Draw {0}, {1}, {2}", GetType().Name, Id, GetHashCode());
48+
//Console.WriteLine("Draw {0}, {1}, {2}", GetType().Name, Id, GetHashCode());
4949
foreach (VertexArrayObject vao in Vaos)
5050
vao.Draw(clientSize, Color, this);
5151
}

FreeFrame/Window.cs

Lines changed: 187 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ protected override void OnLoad()
6666
{
6767
base.OnLoad();
6868

69-
Helper.EnableDebugMode();
69+
//Helper.EnableDebugMode();
7070

7171
GL.ClearColor(0.1f, 0.1f, 0.1f, 1.0f); // TODO: Magic value
7272
GL.Enable(EnableCap.Multisample);
@@ -122,17 +122,17 @@ protected override void OnRenderFrame(FrameEventArgs e)
122122

123123
if (KeyboardState.IsKeyDown(Keys.Q))
124124
{
125-
//Console.WriteLine("Draw me please");
126-
foreach (KeyValuePair<int, List<Shape>> shapes in _timeline)
127-
{
128-
foreach (Shape shape in shapes.Value)
129-
{
130-
shape.ImplementObject();
131-
shape.Draw(ClientSize);
132-
}
133-
}
134-
if (_selectedShape != null)
135-
_selectedShape.ImplementObject(); // Reset VAOS for selected shape
125+
////Console.WriteLine("Draw me please");
126+
//foreach (KeyValuePair<int, List<Shape>> shapes in _timeline)
127+
//{
128+
// foreach (Shape shape in shapes.Value)
129+
// {
130+
// shape.ImplementObject();
131+
// shape.Draw(ClientSize);
132+
// }
133+
//}
134+
//if (_selectedShape != null)
135+
// _selectedShape.ImplementObject(); // Reset VAOS for selected shape
136136
}
137137

138138
if (KeyboardState.IsKeyDown(Keys.Escape))
@@ -173,7 +173,12 @@ protected override void OnRenderFrame(FrameEventArgs e)
173173
//GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
174174
foreach (Shape shape in _shapes)
175175
{
176+
177+
//if (_selectedShape != null)
178+
// _selectedShape.ImplementObject(); // Reset VAOS for selected shape
179+
176180
//shape.ImplementObject(); // Reset VAOs
181+
//shape.ImplementObject();
177182
shape.Draw(ClientSize);
178183
}
179184

@@ -204,6 +209,22 @@ protected override void OnRenderFrame(FrameEventArgs e)
204209
_selectedShape.Angle = _ioAngle;
205210
_selectedShape.CornerRadius = _ioCornerRadius;
206211

212+
if (_timeline.ContainsKey(_ioTimeline) == true && _timeline[_ioTimeline] != null)
213+
{
214+
Shape? shape = _timeline[_ioTimeline].Find(x => x.Id == _selectedShape.Id);
215+
if (shape != null)
216+
{
217+
Console.WriteLine("There is a shape like meee");
218+
shape.X = _selectedShape.X;
219+
shape.Y = _selectedShape.Y;
220+
shape.Width = _selectedShape.Width;
221+
shape.Height = _selectedShape.Height;
222+
shape.Angle = _selectedShape.Angle;
223+
shape.CornerRadius = _selectedShape.CornerRadius;
224+
shape.Color = _selectedShape.Color;
225+
}
226+
}
227+
207228
_selectedShape.ImplementObject();
208229
_selector.Select(_selectedShape);
209230
}
@@ -392,6 +413,13 @@ public void OnLeftMouseEnter() // TODO: Rename this
392413
x = _mouseOriginalState.X;
393414
}
394415
_selectedShape.Move(new Vector2i((int)x, (int)y));
416+
417+
if (_timeline.ContainsKey(_ioTimeline) == true && _timeline[_ioTimeline] != null)
418+
{
419+
Shape? shape = _timeline[_ioTimeline].Find(x => x.Id == _selectedShape.Id);
420+
if (shape != null)
421+
shape.Move(new Vector2i((int)x, (int)y));
422+
}
395423
_selector.Select(_selectedShape);
396424
UpdateIO_UI();
397425
}
@@ -410,6 +438,14 @@ public void OnLeftMouseEnter() // TODO: Rename this
410438
width = height;
411439
}
412440
_selectedShape.Resize(new Vector2i((int)width, (int)height));
441+
442+
if (_timeline.ContainsKey(_ioTimeline) == true && _timeline[_ioTimeline] != null)
443+
{
444+
Shape? shape = _timeline[_ioTimeline].Find(x => x.Id == _selectedShape.Id);
445+
if (shape != null)
446+
shape.Resize(new Vector2i((int)width, (int)height));
447+
}
448+
413449
_selector.Select(_selectedShape);
414450
UpdateIO_UI();
415451
}
@@ -518,6 +554,45 @@ public void ShowUIDebug()
518554
}
519555
ImGui.End();
520556
}
557+
public int Interpolate(int x, int x1, int x2, int y1, int y2)
558+
{
559+
float y;
560+
if (x1 < x2)
561+
{
562+
if (y1 < y2)
563+
y = y1 + (x - x1) * ((y2 - y1) / (x2 - x1));
564+
else
565+
y = y2 + (x - x1) * ((y1 - y2) / (x2 - x1));
566+
}
567+
else
568+
{
569+
if (y1 < y2)
570+
y = y1 + (x - x2) * ((y2 - y1) / (x1 - x2));
571+
else
572+
y = y2 + (x - x2) * ((y1 - y2) / (x1 - x2));
573+
}
574+
575+
576+
if (y1 < y2)
577+
{
578+
Console.WriteLine("input({0}) min({1}) max({2}) === {3}", y, y1, y2, Math.Clamp(y, y1, y2));
579+
return (int)Math.Clamp(y, y1, y2);
580+
581+
}
582+
else
583+
{
584+
Console.WriteLine("input({0}) min({1}) max({2}) === {3}", y, y2, y1, Math.Clamp(y, y2, y1));
585+
return (int)Math.Clamp(y, y2, y1);
586+
}
587+
}
588+
public Color4 InterpolateColor(int x, int x1, int x2, Color4 y1, Color4 y2)
589+
{
590+
int r = Interpolate(x, x1, x2, (int)(y1.R * 255), (int)(y2.R * 255));
591+
int g = Interpolate(x, x1, x2, (int)(y1.G * 255), (int)(y2.G * 255));
592+
int b = Interpolate(x, x1, x2, (int)(y1.B * 255), (int)(y2.B * 255));
593+
int a = Interpolate(x, x1, x2, (int)(y1.A * 255), (int)(y2.A * 255));
594+
return new Color4(r / 255f, g / 255f, b / 255f, a / 255f);
595+
}
521596
public void ShowUI()
522597
{
523598
// ImGui settings
@@ -775,23 +850,6 @@ public void ShowUI()
775850
}
776851
}
777852

778-
779-
780-
i = 0;
781-
ImGui.TableNextRow();
782-
ImGui.TableSetColumnIndex(i);
783-
ImGui.Text("Color");
784-
foreach (KeyValuePair<int, List<Shape>> timeline in _timeline)
785-
{
786-
i++;
787-
Shape? sibling = timeline.Value.Find(x => x.Id == shape.Id);
788-
if (sibling != null)
789-
{
790-
ImGui.TableSetColumnIndex(i);
791-
ImGui.Text(String.Format("RGBA({0}, {1}, {2}, {3})", sibling.Color.R, sibling.Color.G, sibling.Color.B, sibling.Color.A));
792-
}
793-
}
794-
795853
if (shape.IsAngleChangeable)
796854
{
797855
i = 0;
@@ -828,6 +886,20 @@ public void ShowUI()
828886
}
829887
}
830888

889+
i = 0;
890+
ImGui.TableNextRow();
891+
ImGui.TableSetColumnIndex(i);
892+
ImGui.Text("Color");
893+
foreach (KeyValuePair<int, List<Shape>> timeline in _timeline)
894+
{
895+
i++;
896+
Shape? sibling = timeline.Value.Find(x => x.Id == shape.Id);
897+
if (sibling != null)
898+
{
899+
ImGui.TableSetColumnIndex(i);
900+
ImGui.Text(String.Format("RGBA({0}, {1}, {2}, {3})", sibling.Color.R, sibling.Color.G, sibling.Color.B, sibling.Color.A));
901+
}
902+
}
831903

832904
ImGui.EndTable();
833905
}
@@ -846,7 +918,92 @@ public void ShowUI()
846918
ImGui.SetWindowPos(new System.Numerics.Vector2(ClientSize.X / 2, ClientSize.Y - ImGui.GetWindowHeight()));
847919
ImGui.Text("Timeline");
848920
ImGui.Spacing();
849-
ImGui.SliderInt("(seconds)", ref _ioTimeline, 0, 60);
921+
if (ImGui.SliderInt("(seconds)", ref _ioTimeline, 0, 60))
922+
{
923+
foreach (Shape shape in _shapes)
924+
{
925+
if (_timeline.ContainsKey(_ioTimeline) == true && _timeline[_ioTimeline] != null && _timeline[_ioTimeline].Any(x => x.Id == shape.Id))
926+
{
927+
// Draw the current one in this list
928+
Shape sibling = _timeline[_ioTimeline].Find(x => x.Id == shape.Id)!;
929+
930+
shape.X = sibling.X;
931+
shape.Y = sibling.Y;
932+
shape.Width = sibling.Width;
933+
shape.Height = sibling.Height;
934+
shape.Angle = sibling.Angle;
935+
shape.CornerRadius = sibling.CornerRadius;
936+
shape.Color = sibling.Color;
937+
shape.ImplementObject();
938+
}
939+
else // Doesn't exist in the list
940+
{
941+
if (_timeline.Any(i => i.Value.Any(j => j.Id == shape.Id))) // If exist somewhere else but not here
942+
{
943+
List<int> keys = _timeline.Where(pair => pair.Value.Any(x => x.Id == shape.Id)).Select(pair => pair.Key).ToList(); // Key key everywhere it exist
944+
945+
// Find two nearest
946+
(int first, int second) nearest = (int.MaxValue, int.MaxValue);
947+
foreach (int key in keys)
948+
{
949+
int delta = Math.Abs(key - _ioTimeline);
950+
if (delta < nearest.first) // First nearest
951+
nearest.first = key;
952+
else if (delta < nearest.second) // Second nearest
953+
nearest.second = key;
954+
}
955+
if (nearest.second != int.MaxValue && nearest.first < _ioTimeline && _ioTimeline < nearest.second) // If need to interpolate
956+
{
957+
Shape first = _timeline[nearest.first].Find(x => x.Id == shape.Id)!; // can't be null
958+
Shape second = _timeline[nearest.second].Find(x => x.Id == shape.Id)!; // can't be null
959+
960+
Console.WriteLine("X vv");
961+
// Interpolate every properties
962+
shape.X = Interpolate(_ioTimeline, nearest.first, nearest.second, first.X, second.X);
963+
Console.WriteLine(Environment.NewLine);
964+
Console.WriteLine("Y vv");
965+
shape.Y = Interpolate(_ioTimeline, nearest.first, nearest.second, first.Y, second.Y);
966+
Console.WriteLine(Environment.NewLine);
967+
Console.WriteLine("Width vv");
968+
shape.Width = Interpolate(_ioTimeline, nearest.first, nearest.second, first.Width, second.Width);
969+
Console.WriteLine(Environment.NewLine);
970+
Console.WriteLine("Height vv");
971+
shape.Height = Interpolate(_ioTimeline, nearest.first, nearest.second, first.Height, second.Height);
972+
Console.WriteLine(Environment.NewLine);
973+
Console.WriteLine("Angle vv");
974+
shape.Angle = Interpolate(_ioTimeline, nearest.first, nearest.second, first.Angle, second.Angle);
975+
Console.WriteLine(Environment.NewLine);
976+
Console.WriteLine("CornerRadius vv");
977+
shape.CornerRadius = Interpolate(_ioTimeline, nearest.first, nearest.second, first.CornerRadius, second.CornerRadius);
978+
Console.WriteLine(Environment.NewLine);
979+
Console.WriteLine("Color vv");
980+
shape.Color = InterpolateColor(_ioTimeline, nearest.first, nearest.second, first.Color, second.Color);
981+
982+
shape.ImplementObject();
983+
}
984+
else // Just draw the first nearest
985+
{
986+
Shape first = _timeline[nearest.first].Find(x => x.Id == shape.Id)!; // can't be null
987+
988+
shape.X = first.X;
989+
shape.Y = first.Y;
990+
shape.Width = first.Width;
991+
shape.Height = first.Height;
992+
shape.Angle = first.Angle;
993+
shape.CornerRadius = first.CornerRadius;
994+
shape.Color = first.Color;
995+
shape.ImplementObject();
996+
}
997+
}
998+
else
999+
{
1000+
// doesnt exist somewhere else, so just draw the one on the screen.
1001+
shape.ImplementObject();
1002+
}
1003+
}
1004+
}
1005+
ResetSelection();
1006+
}
8501007
if (_selectedShape != null)
8511008
{
8521009
if (ImGui.Button(String.Format("Create keyframe for {0}", _selectedShape.GetType().Name)))

0 commit comments

Comments
 (0)