diff options
Diffstat (limited to 'src/layer.cpp')
-rw-r--r-- | src/layer.cpp | 154 |
1 files changed, 86 insertions, 68 deletions
diff --git a/src/layer.cpp b/src/layer.cpp index 8bf6bef..d21ab0e 100644 --- a/src/layer.cpp +++ b/src/layer.cpp @@ -421,75 +421,35 @@ 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]) +// TODO(fox): learn this; stop stealing from stackoverflow +bool32 Line_TestIntersect(real32 p0_x, real32 p0_y, real32 p1_x, real32 p1_y, + real32 p2_x, real32 p2_y, real32 p3_x, real32 p3_y) { - /* - float s1_x, s1_y, s2_x, s2_y; + real32 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]; + real32 b = (-s2_x * s1_y + s1_x * s2_y); + if (b == 0) + return 0; - Vector1 * (Point[0] - Point[2]) / - Side0 = (-s1_y * (p0_x - p2_x) + s1_x * (p0_y - p2_y)) + real32 s, t; + s = (-s1_y * (p0_x - p2_x) + s1_x * (p0_y - p2_y)) / b; + t = ( s2_x * (p0_y - p2_y) - s2_y * (p0_x - p2_x)) / b; - 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) { + int a = 0; + } 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) @@ -519,18 +479,77 @@ Transform_TestBox(block_layer *Layer, uint32 Width, uint32 Height, v2 Min, v2 Ma 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++; + if (Line_TestIntersect(P1->x, P1->y, P2->x, P2->y, P1_B->x, P1_B->y, P2_B->x, P2_B->y)) + return true; + P1 = P2++; } P1_B = P2_B++; } return false; } +// TODO(fox): It would probably be faster to transform the box into layer space +// and test that way. Don't know how to do the UV test though. + +static bool32 +Shape_TestBoxSelect(layer_transforms T, uint32 CompWidth, uint32 CompHeight, uint32 ShapeWidth, uint32 ShapeHeight, v2 Box[4], + nvg_point *Point, uint16 PointCount) +{ + // v2 BoxLocal[4] = {}; + // for (int x = 0; x < 4; x++) { + // BoxLocal[x] = T_CompPosToLayerPos(T, CompWidth, CompHeight, ShapeHeight, ShapeWidth, Box[x].x, Box[x].y); + // } + Assert(Box[0].x < Box[2].x && Box[0].y < Box[2].y); +#if 1 + for (int i = 0; i < PointCount; i++) { + nvg_point *P0 = &Point[i]; + v2 Pos0 = TransformPoint(T, ShapeWidth, ShapeHeight, V2(P0->x, P0->y)); + if (Pos0.x > Box[0].x && Pos0.x < Box[2].x && + Pos0.y > Box[0].y && Pos0.y < Box[2].y) + return true; + P0->x = Pos0.x; + P0->y = Pos0.y; + } + nvg_point *P0 = &Point[PointCount-1]; + nvg_point *P1 = &Point[0]; + for (int i = 0; i < PointCount; i++) { + if (Line_TestIntersect(P0->x, P0->y, P1->x, P1->y, Box[0].x, Box[0].y, Box[1].x, Box[1].y)) + return true; + if (Line_TestIntersect(P0->x, P0->y, P1->x, P1->y, Box[1].x, Box[1].y, Box[2].x, Box[2].y)) + return true; + if (Line_TestIntersect(P0->x, P0->y, P1->x, P1->y, Box[2].x, Box[2].y, Box[3].x, Box[3].y)) + return true; + if (Line_TestIntersect(P0->x, P0->y, P1->x, P1->y, Box[3].x, Box[3].y, Box[0].x, Box[0].y)) + return true; + P0 = P1++; + } + return false; +#else + v2 *P0_B = &Box[3]; + v2 *P1_B = &Box[0]; + for (int x = 0; x < 4; x++) { + nvg_point *P0 = &Point[PointCount-1]; + v2 Pos0 = TransformPoint(T, ShapeWidth, ShapeHeight, V2(P0->x, P0->y)); + if (Pos0.x > Box[0].x && Pos0.x < Box[2].x && + Pos0.y > Box[0].y && Pos0.y < Box[2].y) + return true; + P0->x = Pos0.x; + P0->y = Pos0.y; + nvg_point *P1 = &Point[0]; + for (int i = 0; i < PointCount; i++) { + v2 Pos1 = TransformPoint(T, ShapeWidth, ShapeHeight, V2(P1->x, P1->y)); + if (Pos1.x > Box[0].x && Pos1.x < Box[2].x && + Pos1.y > Box[0].y && Pos1.y < Box[2].y) + return true; + if (Line_TestIntersect(P0->x, P0->y, P1->x, P1->y, P0_B->x, P0_B->y, P1_B->x, P1_B->y)) + return true; + P0 = P1++; + } + P0_B = P1_B++; + } + return false; +#endif +} static void Layer_TestBoxSelect(memory *Memory, project_state *State, ui *UI, sorted_comp_array *SortedCompArray, sorted_layer_array *SortedLayerArray, @@ -547,17 +566,16 @@ Layer_TestBoxSelect(memory *Memory, project_state *State, ui *UI, sorted_comp_ar 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); + nvg_point *NVGPointData = (nvg_point *)Memory_PushScratch(Memory, sizeof(nvg_point) * 1024); + v2 ShapeMin = {}, ShapeMax = {}; + uint32 NumberOfVerts = NVG_FlattenPath(Memory, Shape, NVGPointData, + State, T, Shape->Width, Shape->Height, Comp->Width, Comp->Height, 1, &ShapeMin, &ShapeMax); + v2 Box[4] = { MinPos, V2(MinPos.x, MaxPos.y), MaxPos, V2(MaxPos.x, MinPos.y) }; + if (Shape_TestBoxSelect(T, Comp->Width, Comp->Height, Shape->Height, Shape->Width, Box, NVGPointData, NumberOfVerts)) + Layer->IsSelected = true; - Memory_PopScratch(Memory, sizeof(bezier_point) * 128); + Memory_PopScratch(Memory, sizeof(nvg_point) * 1024); } else { int Width, Height; Layer_GetDimensions(Memory, Layer, &Width, &Height); |