diff --git a/scripts/__polygon/__polygon.gml b/scripts/__polygon/__polygon.gml index d64ce3edc..bbda92b8f 100644 --- a/scripts/__polygon/__polygon.gml +++ b/scripts/__polygon/__polygon.gml @@ -5,16 +5,16 @@ function polygon_simplify(points, tolerance = 4) { #region for( var i = 0; i < len; i++ ) { var _px0 = points[i].x; var _py0 = points[i].y; - var _px1 = points[safe_mod(i + 1, len)].x; - var _py1 = points[safe_mod(i + 1, len)].y; - var _px2 = points[safe_mod(i + 2, len)].x; - var _py2 = points[safe_mod(i + 2, len)].y; + var _px1 = points[(i + 1) % len].x; + var _py1 = points[(i + 1) % len].y; + var _px2 = points[(i + 2) % len].x; + var _py2 = points[(i + 2) % len].y; var dir0 = point_direction(_px0, _py0, _px1, _py1); var dir1 = point_direction(_px1, _py1, _px2, _py2); - if(abs(dir0 - dir1) <= tolerance) - ds_stack_push(remSt, safe_mod(i + 1, len)); + if((_px0 == _px1 && _py0 == _py1) || abs(dir0 - dir1) <= tolerance) + ds_stack_push(remSt, (i + 1) % len); } while(!ds_stack_empty(remSt)) { @@ -44,22 +44,23 @@ function polygon_points_classify(points) { #region var side, _side = 0; var convexs = []; var reflects = []; - var startindex = safe_mod(maxindex - 1 + len, len); + var startindex = (maxindex - 1 + len) % len; for( var i = 0; i < len; i++ ) { - var index = safe_mod(startindex + i, len); + var index = (startindex + i) % len; var _px0 = points[index].x; var _py0 = points[index].y; - var _px1 = points[safe_mod(index + 1, len)].x; - var _py1 = points[safe_mod(index + 1, len)].y; - var _px2 = points[safe_mod(index + 2, len)].x; - var _py2 = points[safe_mod(index + 2, len)].y; + var _px1 = points[(index + 1) % len].x; + var _py1 = points[(index + 1) % len].y; + var _px2 = points[(index + 2) % len].x; + var _py2 = points[(index + 2) % len].y; var side = cross_product(_px0, _py0, _px1, _py1, _px2, _py2); + if(_side != 0 && sign(_side) != sign(side)) - array_push(reflects, safe_mod(index + 1, len)); + array_push(reflects, (index + 1) % len); else { - array_push(convexs, safe_mod(index + 1, len)); + array_push(convexs, (index + 1) % len); _side = sign(side); } } @@ -83,25 +84,28 @@ function polygon_triangulate_convex(points) { #region return triangles; } #endregion -function polygon_triangulate(points, tolerance = 4) { #region - points = polygon_simplify(points, tolerance); +function polygon_triangulate(points, tolerance = 4) { #region // ear clipping + if(array_length(points) < 3) return [ [], points ]; + + if(tolerance > 0) points = polygon_simplify(points, tolerance); + if(array_length(points) < 3) return [ [], points ]; + var classes = polygon_points_classify(points); var convexes = classes[0]; var reflected = classes[1]; var checkSide = classes[2]; if(array_length(reflected) == 0) - return polygon_triangulate_convex(points); - - var pointInd = array_create(array_length(points)); - for( var i = 0, n = array_length(points); i < n; i++ ) - pointInd[i] = i; + return [ polygon_triangulate_convex(points), points ]; + var pointInd = array_create_ext(array_length(points), function(i) /*=>*/ { return i; }); var triangles = []; - var repeated = 0; + var repeated = 0; + + //print($"Ear cutting : {array_length(points)} verticies"); while(array_length(pointInd) > 3) { - if(array_length(convexes) == 0) return triangles; + if(array_length(convexes) == 0) return [ triangles, points ]; var len = array_length(pointInd); var c0 = convexes[0]; @@ -117,9 +121,7 @@ function polygon_triangulate(points, tolerance = 4) { #region var isEar = true; for( var i = 0; i < len; i++ ) { var ind = pointInd[i]; - if(ind == c0) continue; - if(ind == c1) continue; - if(ind == c2) continue; + if(ind == c0 || ind == c1 || ind == c2) continue; var p = points[ind]; if(point_in_triangle(p.x, p.y, p0.x, p0.y, p1.x, p1.y, p2.x, p2.y)) { @@ -171,16 +173,16 @@ function polygon_triangulate(points, tolerance = 4) { #region array_push(convexes, c0); if(repeated++ > len) { - //print("mesh error") + noti_warning("Mesh error"); break; } } } if(array_length(pointInd) == 3) - array_push(triangles, [points[pointInd[0]], points[pointInd[1]], points[pointInd[2]]]); + array_push(triangles, [ points[pointInd[0]], points[pointInd[1]], points[pointInd[2]] ]); - return triangles; + return [ triangles, points ]; } #endregion function polygon_triangulate_convex_fan(points) { #region diff --git a/scripts/canvas_freeform/canvas_freeform.gml b/scripts/canvas_freeform/canvas_freeform.gml index db1cf7eb6..c8a1dde11 100644 --- a/scripts/canvas_freeform/canvas_freeform.gml +++ b/scripts/canvas_freeform/canvas_freeform.gml @@ -26,7 +26,7 @@ function canvas_freeform_step(active, _x, _y, _s, _mx, _my, _draw) { #region surface_reset_target(); if(array_length(freeform_shape) > 3) { - var _triangles = polygon_triangulate(freeform_shape, 1); + var _triangles = polygon_triangulate(freeform_shape, 1)[0]; var temp_surface = surface_create(_dim[0], _dim[1]); diff --git a/scripts/node_mesh_create_path/node_mesh_create_path.gml b/scripts/node_mesh_create_path/node_mesh_create_path.gml index 8f394c943..f5ea0a253 100644 --- a/scripts/node_mesh_create_path/node_mesh_create_path.gml +++ b/scripts/node_mesh_create_path/node_mesh_create_path.gml @@ -46,7 +46,7 @@ function Node_Mesh_Create_Path(_x, _y, _group = noone) : Node(_x, _y, _group) co var triangles = []; switch(_algo) { - case 0 : triangles = polygon_triangulate(points); break; + case 0 : triangles = polygon_triangulate(points)[0]; break; case 1 : triangles = polygon_triangulate_convex_fan(points); break; case 2 : triangles = delaunay_triangulation(points); break; } diff --git a/scripts/node_path/node_path.gml b/scripts/node_path/node_path.gml index 8bc2f6304..5847fb28c 100644 --- a/scripts/node_path/node_path.gml +++ b/scripts/node_path/node_path.gml @@ -57,13 +57,13 @@ function Node_Path(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { ]; #region ---- path ---- - path_loop = false; - anchors = []; - segments = []; - lengths = []; - lengthAccs = []; - lengthTotal = 0; - boundary = new BoundingBox(); + path_loop = false; + anchors = []; + segments = []; + lengths = []; + lengthAccs = []; + lengthTotal = 0; + boundary = new BoundingBox(); cached_pos = ds_map_create(); #endregion @@ -568,7 +568,7 @@ function Node_Path(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { for( var i = 0, n = array_length(segments); i < n; i++ ) { #region draw path var _seg = segments[i]; - var _ox = 0, _oy = 0, _nx = 0, _ny = 0, p = 0; + var _ox = 0, _oy = 0, _nx = 0, _ny = 0, p = 0; for( var j = 0, m = array_length(_seg); j < m; j++ ) { _nx = _x + _seg[j][0] * _s; @@ -801,12 +801,13 @@ function Node_Path(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { } #endregion static updateLength = function() { #region - boundary = new BoundingBox(); - segments = []; - lengths = []; - lengthAccs = []; - lengthTotal = 0; + boundary = new BoundingBox(); + segments = []; + lengths = []; + lengthAccs = []; + lengthTotal = 0; + var _index = 0; var loop = getInputData(1); var sample = PREFERENCES.path_resolution; var ansize = ds_list_size(inputs) - input_fix_len; diff --git a/scripts/node_shape/node_shape.gml b/scripts/node_shape/node_shape.gml index f6b202e96..1ae385700 100644 --- a/scripts/node_shape/node_shape.gml +++ b/scripts/node_shape/node_shape.gml @@ -109,12 +109,52 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con ]; temp_surface = [ noone ]; + use_path = false; + path_points = []; + point_simp = []; + triangles = []; attribute_surface_depth(); static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) { #region - var _path = getInputData(14); - if(_path != noone && struct_has(_path, "getPointRatio")) return; + if(use_path) { + draw_set_text(f_p3, fa_center, fa_top); + draw_set_color(COLORS._main_accent); + var ox, oy, nx, ny; + + for (var i = 0, n = array_length(point_simp); i < n; i++) { + var p = point_simp[i]; + nx = _x + p.x * _s; + ny = _y + p.y * _s; + + if(i) draw_line(ox, oy, nx, ny); + // draw_circle(nx, ny, 3, false); + // draw_text(nx, ny + 8, i); + + ox = nx; + oy = ny; + } + + // draw_set_color(c_red); + // for( var i = 0, n = array_length(triangles); i < n; i++ ) { + // var tri = triangles[i]; + // var p0 = tri[0]; + // var p1 = tri[1]; + // var p2 = tri[2]; + + // var p0x = _x + p0.x * _s; + // var p0y = _y + p0.y * _s; + // var p1x = _x + p1.x * _s; + // var p1y = _y + p1.y * _s; + // var p2x = _x + p2.x * _s; + // var p2y = _y + p2.y * _s; + + // draw_line(p0x, p0y, p1x, p1y); + // draw_line(p0x, p0y, p2x, p2y); + // draw_line(p1x, p1y, p2x, p2y); + // } + return; + } var _type = getInputData(15); @@ -186,8 +226,9 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con inputs[| 15].setVisible(true); _outSurf = surface_verify(_outSurf, _dim[0], _dim[1], attrDepth()); + use_path = _path != noone && struct_has(_path, "getPointRatio"); - if(_path != noone && struct_has(_path, "getPointRatio")) { #region + if(use_path) { #region inputs[| 3].setVisible(false); inputs[| 4].setVisible(false); inputs[| 5].setVisible(false); @@ -201,20 +242,19 @@ function Node_Shape(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con if(_bg) draw_clear_alpha(0, 1); else DRAW_CLEAR - var points = []; var segCount = _path.getSegmentCount(); if(segCount) { var quality = 8; - var sample = quality * segCount; + var sample = quality * segCount; + var _step = 1 / sample; - for( var i = 0; i < sample; i++ ) { - var t = i / sample; - var pos = _path.getPointRatio(t); + path_points = array_verify(path_points, sample); + for( var i = 0; i < sample; i++ ) + path_points[i] = _path.getPointRatio(i * _step, array_safe_get(path_points, i, undefined)); - array_push(points, pos); - } - - var triangles = polygon_triangulate(points); + var tri = polygon_triangulate(path_points); + triangles = tri[0]; + point_simp = tri[1]; draw_set_color(_color); draw_primitive_begin(pr_trianglelist); diff --git a/scripts/node_shape_polygon/node_shape_polygon.gml b/scripts/node_shape_polygon/node_shape_polygon.gml index e2d0045fd..4da0694ae 100644 --- a/scripts/node_shape_polygon/node_shape_polygon.gml +++ b/scripts/node_shape_polygon/node_shape_polygon.gml @@ -195,7 +195,7 @@ function Node_Shape_Polygon(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr var shapes = []; for( var i = 0, n = array_length(points); i < n; i++ ) { if(points[i].type == SHAPE_TYPE.points) - shapes[i] = polygon_triangulate(points[i].points); + shapes[i] = polygon_triangulate(points[i].points)[0]; else if(points[i].type == SHAPE_TYPE.triangles) shapes[i] = points[i].triangles;