diff options
Diffstat (limited to 'src/layer.cpp')
-rw-r--r-- | src/layer.cpp | 175 |
1 files changed, 161 insertions, 14 deletions
diff --git a/src/layer.cpp b/src/layer.cpp index b27935b..8bf6bef 100644 --- a/src/layer.cpp +++ b/src/layer.cpp @@ -1,3 +1,7 @@ +#if SPECIAL +#include "main.h" +#endif + static property_channel Property_InitFloat(real32 Val, real32 ScrubVal, real32 MinVal = PROPERTY_REAL_MIN, real32 MaxVal = PROPERTY_REAL_MAX, bool32 AlwaysInteger = 0); @@ -17,7 +21,7 @@ Layer_Init(project_data *File, memory *Memory) Layer->Block_String_Index = Memory_Block_AllocateNew(Memory, F_Strings); block_string *String = (block_string *)Memory_Block_AddressAtIndex(Memory, F_Strings, Layer->Block_String_Index, 0); sprintf(String->Char, "Layer %i", File->Layer_Count + 1); // CSbros... - History_Action_Swap(Memory, F_File, sizeof(String->Occupied), &String->Occupied); + History_Action_Swap(Memory, F_Strings, sizeof(String->Occupied), &String->Occupied); String->Occupied = 1; Layer->x = Property_InitFloat(0.0f, 1.0f); @@ -112,22 +116,17 @@ Layer_UpdateMasksEffects(project_state *State, block_layer *Layer, memory *Memor Arbitrary_Zero((uint8 *)Data, sizeof(nvg_point) * 128); layer_transforms T = Layer_GetTransforms(Layer); v2 Min = {}, Max = {}; - int ShapeWidth = 0, ShapeHeight = 0; - if (State->Interact_Active == interact_type_keyframe_move) { - NVG_FlattenPath(Memory, Shape, (nvg_point *)Data, State, T, 0, 0, Width, Height, 0, &Min, &Max); - ShapeWidth = Max.x - Min.x; - ShapeHeight = Max.y - Min.y; - } uint32 NumberOfVerts = NVG_FlattenPath(Memory, Shape, (nvg_point *)Data, - State, T, ShapeWidth, ShapeHeight, Width, Height, 1, &Min, &Max); + State, T, Shape->Width, Shape->Height, Width, Height, 1, &Min, &Max); void *Data_Stroke = Memory_PushScratch(Memory, sizeof(real32) * 4 * 256); uint32 StrokeCount = NVG_ExpandStroke(Memory, NumberOfVerts, Shape->Opt.StrokeWidth, Shape->Opt.LineCapType, Shape->Opt.LineJoinType, Shape->IsClosed, (nvg_point *)Data, (real32 *)Data_Stroke); void *Data_Fill = Memory_PushScratch(Memory, sizeof(real32) * 4 * NumberOfVerts); NVG_ExpandFill(Memory, NumberOfVerts, (nvg_point *)Data, (real32 *)Data_Fill); - GL_RasterizeShape(&TestL, &TestM, Data_Stroke, Data_Fill, StrokeCount, NumberOfVerts, T, - Width, Height, BytesPerPixel, EffectBitmapAddress, Shape->Width, Shape->Height, - Shape->Opt.StrokeCol, Shape->Opt.FillCol, Shape->Opt.Visibility); + Assert(0); + // GL_RasterizeShape(&TestL, &TestM, Data_Stroke, Data_Fill, StrokeCount, NumberOfVerts, T, + // Width, Height, BytesPerPixel, EffectBitmapAddress, Shape->Width, Shape->Height, + // Shape->Opt.StrokeCol, Shape->Opt.FillCol, Shape->Opt.Visibility); Memory_PopScratch(Memory, sizeof(real32) * 4 * NumberOfVerts); Memory_PopScratch(Memory, sizeof(real32) * 4 * 256); @@ -215,17 +214,18 @@ Layer_DeselectAll(project_data *File, project_state *State, memory *Memory) { State->MostRecentlySelectedLayer = -1; } +// TODO(fox): This function will be replaced once properties are reworked. // h: index of the total amount of properties and effects // c: index of the amount of properties in a given effect // p: prior property's keyframe count, so we can increment the sorted keyframe array properly static bool32 Layer_LoopChannels(project_state *State, memory *Memory, sorted_property_array **SortedProperty, uint16 **SortedKeyframe, block_layer *Layer, - property_channel **Property, block_effect **EffectOut, int *h, int *c, int *p) + property_channel **Property, block_effect **EffectOut, int *h, int *c, int *p, int LoopNumber) { - uint32 Amount = AmountOf(Layer->Property) + Layer->Block_Effect_Count; + uint32 Amount = LoopNumber + Layer->Block_Effect_Count; // Assert(Layer->Block_Effect_Count < 2); while (*h < Amount) { - if (*h < AmountOf(Layer->Property) && *c == 0) { + if (*h < LoopNumber && *c == 0) { *Property = &Layer->Property[*h]; if (*h != 0) { *SortedProperty += 1; @@ -367,6 +367,7 @@ Layer_TraverseForPoint(project_data *File, project_state *State, memory *Memory, return PointUV * V2(InnerWidth, InnerHeight); } +// TODO(fox): Precomps? static int32 Layer_TestSelection(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 PrincipalIndex) { @@ -420,6 +421,152 @@ Layer_TestSelection(memory *Memory, project_state *State, ui *UI, sorted_comp_ar return LayerIndex; } +static bool32 +Shape_TestBoxSelect(v2 Min, v2 Max, bezier_point *BezierPointData, uint32 BezierCount) +{ + v2 StartMin = V2(1000, 1000); + v2 StartMax = V2(-1000, -1000); + v2 ClosestPoint[4] = { StartMin, StartMax, V2(StartMin.x, StartMax.y), V2(StartMax.y, StartMin.x) }; + + for (int i = 0; i < BezierCount; i++) { + bezier_point *Point = &BezierPointData[i]; + if (i == 0 || Point->Type == interpolation_type_linear) { + if ((Point->Pos[0].x > Min.x) && (Point->Pos[0].x < Max.x) && + (Point->Pos[0].x > Min.y) && (Point->Pos[0].x < Max.y)) + Assert(0); + } else if (Point->Type == interpolation_type_bezier) { + Assert(0); + /* + bezier_point *Point_1 = &BezierPointData[i-1]; + v2 Pos[2] = { Point_1->Pos[0], Point->Pos[0] }; + PointPlayhead = (nvg_point *)Bezier_CubicCalcPoints(Pos[0], Pos[0] + Point_1->Pos[1], Pos[1] + Point->Pos[2], Pos[1], PointPlayhead, sizeof(nvg_point)); + */ + } else { + Assert(0); + } + } + return false; +} + +// v2 Bezier_LineClose + +// stPoint(v2 a, v2 b, v2 p); + + +// char get_line_intersection(float p0_x, float p0_y, float p1_x, float p1_y, +// float p2_x, float p2_y, float p3_x, float p3_y, float *i_x, float *i_y) +#if 0 +char T_TestLine(v2 Point[4]) +{ + /* + float s1_x, s1_y, s2_x, s2_y; + + s1_x = p1_x - p0_x; + s1_y = p1_y - p0_y; + s2_x = p3_x - p2_x; + s2_y = p3_y - p2_y; + */ + + v2 Vector0 = Point[1] - Point[0]; + v2 Vector1 = Point[3] - Point[2]; + + Vector1 * (Point[0] - Point[2]) / + Side0 = (-s1_y * (p0_x - p2_x) + s1_x * (p0_y - p2_y)) + + float s, t; + s = (-s1_y * (p0_x - p2_x) + s1_x * (p0_y - p2_y)) / (-s2_x * s1_y + s1_x * s2_y); + t = ( s2_x * (p0_y - p2_y) - s2_y * (p0_x - p2_x)) / (-s2_x * s1_y + s1_x * s2_y); + + if (s >= 0 && s <= 1 && t >= 0 && t <= 1) + { + // Collision detected + if (i_x != NULL) + *i_x = p0_x + (t * s1_x); + if (i_y != NULL) + *i_y = p0_y + (t * s1_y); + return 1; + } + + return 0; // No collision +} +#endif + +static bool32 +Transform_TestBox(block_layer *Layer, uint32 Width, uint32 Height, v2 Min, v2 Max) +{ + real32 Rad = (Layer->rotation.CurrentValue * (PI / 180)); + real32 s = Layer->scale.CurrentValue; + + v2 XAxis = (Width * s)*V2(cos(Rad), sin(Rad)); + v2 YAxis = (Height * -s)*V2(sin(Rad), -cos(Rad)); + + real32 AnchorX = Layer->ax.CurrentValue; + real32 AnchorY = Layer->ay.CurrentValue; + + v2 Pos = {Layer->x.CurrentValue, Layer->y.CurrentValue}; + v2 Origin = Pos - (XAxis * AnchorX) - (YAxis * AnchorY); + + real32 XLengthSq = 1.0f / LengthSq(XAxis); + real32 YLengthSq = 1.0f / LengthSq(YAxis); + + v2 Box[4] = { Min, V2(Min.x, Max.y), Max, V2(Max.x, Min.y) }; + v2 Point[4] = {Origin, Origin + YAxis, Origin + XAxis + YAxis, Origin + XAxis }; + if (Length((Max - Min)) < 2.0f) + return false; + v2 *P1_B = &Box[3]; + v2 *P2_B = &Box[0]; + for (int x = 0; x < 4; x++) { + v2 *P1 = &Point[3]; + v2 *P2 = &Point[0]; + for (int i = 0; i < 4; i++) { + // v2 ClosestLayer = Bezier_LineClosestPoint(*P1, *P2, *P1_B); + // v2 ClosestBox = Bezier_LineClosestPoint(*P1_B, *P2_B, *P1); + // if (abs(ClosestLayer.x - ClosestBox.x) < 1.0f && + // abs(ClosestLayer.y - ClosestBox.y) < 1.0f) + // return true; + // P1 = P2++; + } + P1_B = P2_B++; + } + return false; +} + + +static void +Layer_TestBoxSelect(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, + uint16 PrincipalIndex, v2 MinPos, v2 MaxPos) +{ + block_composition *Comp = (block_composition *)Memory_Block_AddressAtIndex(Memory, F_Precomps, PrincipalIndex); + sorted_comp_array SortedCompStart = SortedCompArray[PrincipalIndex]; + sorted_layer_array *SortedLayerStart = Sorted_GetLayerStart(SortedLayerArray, SortedCompArray, PrincipalIndex); + for (int i = SortedCompStart.LayerCount - 1; i >= 0; i--) { + sorted_layer_array SortEntry = SortedLayerStart[i]; + uint32 Index_Physical = SortEntry.Block_Layer_Index; + block_layer *Layer = (block_layer *)Memory_Block_AddressAtIndex(Memory, F_Layers, Index_Physical); + if (Layer->IsShapeLayer) { + shape_layer *Shape = &Layer->Shape; + int Width = Shape->Width, Height = Shape->Height; + layer_transforms T = Layer_GetTransforms(Layer); + v2 MinUV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Width, Height, MinPos); + v2 MaxUV = T_CompUVToLayerUV(T, Comp->Width, Comp->Height, Width, Height, MaxPos); + + bezier_point *BezierPointData = (bezier_point *)Memory_PushScratch(Memory, sizeof(bezier_point) * 128); + uint32 BezierCount = Bezier_Shape_Sort(Memory, Shape, BezierPointData, + State, T, Width, Height, + Comp->Width, Comp->Height, 0); + + Shape_TestBoxSelect(MinPos, MaxPos, BezierPointData, BezierCount); + + Memory_PopScratch(Memory, sizeof(bezier_point) * 128); + } else { + int Width, Height; + Layer_GetDimensions(Memory, Layer, &Width, &Height); + if (Transform_TestBox(Layer, Width, Height, MinPos, MaxPos)) + Layer->IsSelected = true; + } + } +} + static void Layer_RecursiveDeselect(memory *Memory, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, uint16 TargetIndex, uint16 PrincipalIndex) { |