summaryrefslogtreecommitdiff
path: root/src/layer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/layer.cpp')
-rw-r--r--src/layer.cpp154
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);