summaryrefslogtreecommitdiff
path: root/src/bezier.cpp
diff options
context:
space:
mode:
authorFox Caminiti <fox@foxcam.net>2023-01-06 23:11:49 -0500
committerFox Caminiti <fox@foxcam.net>2023-01-06 23:11:49 -0500
commit1d0d8549411e23394059f420f053cc3ee28dacfb (patch)
treec4486e5632c09d11acfae5634dceb3db6d6dba97 /src/bezier.cpp
parent84d04d391bc4bf9481106d4f5ac4d3dd8f27ed87 (diff)
more shape code
Diffstat (limited to 'src/bezier.cpp')
-rw-r--r--src/bezier.cpp55
1 files changed, 44 insertions, 11 deletions
diff --git a/src/bezier.cpp b/src/bezier.cpp
index 1585495..b90e146 100644
--- a/src/bezier.cpp
+++ b/src/bezier.cpp
@@ -34,20 +34,53 @@ Bezier_SolveYForX(v2 Point_P0, v2 Point_P1, v2 Point_P2, v2 Point_P3, real32 Tar
return Y;
}
+// All the extra inputs on the second line are for when we need to take
+// interactive mode into account.
// TODO(fox): Incorporate sorting for non-continuous shapes.
static uint32
-Bezier_Shape_Sort(memory *Memory, shape_layer *Shape, bezier_point *PointData)
+Bezier_Shape_Sort(memory *Memory, shape_layer *Shape, bezier_point *PointData,
+ project_state *State, layer_transforms T, int Width, int Height,
+ int CompWidth, int CompHeight, bool32 Interact)
{
real32 Radius = Shape->Opt.Roundness;
bezier_point *PointStart = PointData;
for (int i = 0; i < Shape->Point_Count; i++) {
- bezier_point *Point = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, i, 1);
- if (Radius <= 0 && Point->Type == interpolation_type_linear) {
- v2 Pos = Point->Pos[0];
+ bezier_point Point = *Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, i, 1);
+ if (State->Interact_Active == interact_type_keyframe_move && Interact && Point.IsSelected) {
+ v2 Pos = Point.Pos[0];
+ Pos = TransformPoint(T, Width, Height, Pos);
+ Pos.x += State->Interact_Offset[0];
+ Pos.y += State->Interact_Offset[1];
+ Pos = T_CompPosToLayerPos(T, CompWidth, CompHeight, Width, Height, Pos.x, Pos.y);
+ Point.Pos[0] = Pos;
+ }
+ // Corner rounder
+ if ((Radius > 0 && Point.Type == interpolation_type_linear) &&
+ (Shape->IsClosed || (i != 0 && i != (Shape->Point_Count - 1)) )) {
+ v2 Pos = Point.Pos[0];
int Index_Prev = (i != 0) ? i-1 : Shape->Point_Count-1;
int Index_Next = (i != Shape->Point_Count-1) ? i+1 : 0;
- v2 Pos_Prev = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, Index_Prev, 1)->Pos[0];
- v2 Pos_Next = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, Index_Next, 1)->Pos[0];
+ bezier_point *Point_Prev = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, Index_Prev, 1);
+ bezier_point *Point_Next = Bezier_LookupAddress(Memory, Shape->Block_Bezier_Index, Index_Next, 1);
+ v2 Pos_Prev = Point_Prev->Pos[0];
+ v2 Pos_Next = Point_Next->Pos[0];
+ // TODO(fox): debloat
+ if (State->Interact_Active == interact_type_keyframe_move && Interact && Point_Prev->IsSelected) {
+ v2 Pos = Pos_Prev;
+ Pos = TransformPoint(T, Width, Height, Pos);
+ Pos.x += State->Interact_Offset[0];
+ Pos.y += State->Interact_Offset[1];
+ Pos = T_CompPosToLayerPos(T, CompWidth, CompHeight, Width, Height, Pos.x, Pos.y);
+ Pos_Prev = Pos;
+ }
+ if (State->Interact_Active == interact_type_keyframe_move && Interact && Point_Next->IsSelected) {
+ v2 Pos = Pos_Next;
+ Pos = TransformPoint(T, Width, Height, Pos);
+ Pos.x += State->Interact_Offset[0];
+ Pos.y += State->Interact_Offset[1];
+ Pos = T_CompPosToLayerPos(T, CompWidth, CompHeight, Width, Height, Pos.x, Pos.y);
+ Pos_Next = Pos;
+ }
v2 Vector_Prev = Pos - Pos_Prev;
v2 Vector_Next = Pos - Pos_Next;
real32 Length_Prev = sqrtf(LengthSq(Vector_Prev));
@@ -56,10 +89,10 @@ Bezier_Shape_Sort(memory *Memory, shape_layer *Shape, bezier_point *PointData)
// real32 RadAngle = acos(Inner(Vector_Prev, VectorR) / (LengthL * LengthR)) * PI / 180;
// real32 AngleKappa = (4.f/3) * tan(RadAngle * 1/4);
- real32 Ratio_Prev = Radius / Length_Prev;
+ real32 Ratio_Prev = Min(Radius / Length_Prev, 0.5);
real32 Ratio_Prev_Inv = 1.0f - Ratio_Prev;
- real32 Ratio_Next = Radius / Length_Next;
+ real32 Ratio_Next = Min(Radius / Length_Next, 0.5);
real32 Ratio_Next_Inv = 1.0f - Ratio_Next;
v2 Point_1 = Pos_Prev + V2(Vector_Prev.x * Ratio_Prev_Inv, (Vector_Prev.y * Ratio_Prev_Inv));
@@ -67,10 +100,10 @@ Bezier_Shape_Sort(memory *Memory, shape_layer *Shape, bezier_point *PointData)
v2 Point_3 = Pos_Next + V2(Vector_Next.x * Ratio_Next_Inv, Vector_Next.y * Ratio_Next_Inv);
v2 Point_4 = Vector_Next * Ratio_Next * (1-KAPPA);
- *PointData++ = { 1, { Point_1, Point_2, V2(0, 0) }, interpolation_type_bezier, 0 };
- *PointData++ = { 1, { Point_3, V2(0, 0), Point_4 }, interpolation_type_bezier, 0 };
+ *PointData++ = { 1, { Point_1, Point_2, V2(0, 0) }, interpolation_type_bezier, Point.IsSelected };
+ *PointData++ = { 1, { Point_3, V2(0, 0), Point_4 }, interpolation_type_bezier, Point.IsSelected };
} else {
- *PointData++ = *Point;
+ *PointData++ = Point;
}
}
return PointData - PointStart;