From 147329f3d482b4be3647bbfcdfed0f740f7bf780 Mon Sep 17 00:00:00 2001 From: MakhamDev Date: Fri, 6 Oct 2023 16:51:11 +0700 Subject: [PATCH] Atlas datatype merging --- PixelComposer.resource_order | 5 +- PixelComposer.yyp | 4 +- datafiles/data/locale/en.zip | Bin 34087 -> 37338 bytes datafiles/data/locale/en/UI.json | 5 + datafiles/data/locale/en/words.json | 83 ++++ objects/o_dialog_preference/Create_0.gml | 2 +- objects/o_main/Draw_75.gml | 3 - scripts/__VFX/__VFX.gml | 70 ++-- scripts/__atlas/__atlas.gml | 10 - scripts/__rectangle/__rectangle.gml | 2 +- scripts/__surface/__surface.gml | 65 +++- .../_node_VFX_spawner/_node_VFX_spawner.gml | 70 ++-- scripts/draw_fit/draw_fit.gml | 2 +- .../draw_text_function/draw_text_function.gml | 1 + scripts/draw_tooltip/draw_tooltip.gml | 17 +- scripts/event_recorder/event_recorder.gml | 2 +- scripts/load_function/load_function.gml | 7 +- .../node_armature_bind/node_armature_bind.gml | 6 +- scripts/node_atlas_draw/node_atlas_draw.gml | 4 +- scripts/node_atlas_get/node_atlas_get.gml | 4 +- scripts/node_atlas_set/node_atlas_set.gml | 4 +- scripts/node_blend/node_blend.gml | 144 ++++--- scripts/node_collection/node_collection.gml | 24 +- .../node_color_adjustment.gml | 11 +- scripts/node_composite/node_composite.gml | 4 +- scripts/node_data/node_data.gml | 66 ++-- scripts/node_export/node_export.gml | 4 +- scripts/node_group_input/node_group_input.gml | 5 +- .../node_group_output/node_group_output.gml | 1 - .../node_group_thumbnail/node_group_input.yy | 12 + .../node_group_thumbnail.gml | 12 + .../node_group_thumbnail.yy} | 6 +- .../node_image_splice_sheet.gml | 6 +- .../node_pack_sprites/node_pack_sprites.gml | 15 +- scripts/node_processor/node_processor.gml | 103 +++-- scripts/node_registry/node_registry.gml | 25 +- .../node_render_sprite_sheet.gml | 14 +- .../node_rigid_object/node_rigid_object.gml | 357 ++++++++++-------- .../node_rigid_render/node_rigid_render.gml | 4 +- scripts/node_scatter/node_scatter.gml | 4 +- .../node_seperate_shapes.gml | 68 ++-- .../node_seperate_shapes.yy | 4 +- scripts/node_stack/node_stack.gml | 4 +- scripts/node_value/node_value.gml | 118 +++--- scripts/pack_best_fit/pack_best_fit.gml | 2 +- scripts/pack_skyline/pack_skyline.gml | 13 +- scripts/panel_inspector/panel_inspector.gml | 12 +- scripts/render_data/render_data.gml | 3 +- scripts/save_function/save_function.gml | 1 + scripts/struct_functions/struct_functions.gml | 1 - scripts/surfaceBox/surfaceBox.gml | 47 ++- .../surface_functions/surface_functions.gml | 74 ++-- shaders/sh_d3d_default/sh_d3d_default.fsh | 6 +- shaders/sh_d3d_geometry/sh_d3d_geometry.fsh | 1 + .../73969580-2c2a-4003-9463-a742cfdd83de.png | Bin 0 -> 1120 bytes .../3033c2a9-6e3d-4798-a3e1-de1cb30c0402.png | Bin 0 -> 1120 bytes .../s_node_group_thumbnail.yy | 74 ++++ 57 files changed, 1024 insertions(+), 587 deletions(-) delete mode 100644 scripts/__atlas/__atlas.gml create mode 100644 scripts/node_group_thumbnail/node_group_input.yy create mode 100644 scripts/node_group_thumbnail/node_group_thumbnail.gml rename scripts/{__atlas/__atlas.yy => node_group_thumbnail/node_group_thumbnail.yy} (56%) create mode 100644 sprites/s_node_group_thumbnail/73969580-2c2a-4003-9463-a742cfdd83de.png create mode 100644 sprites/s_node_group_thumbnail/layers/73969580-2c2a-4003-9463-a742cfdd83de/3033c2a9-6e3d-4798-a3e1-de1cb30c0402.png create mode 100644 sprites/s_node_group_thumbnail/s_node_group_thumbnail.yy diff --git a/PixelComposer.resource_order b/PixelComposer.resource_order index 900a028f8..9a4e9bfa2 100644 --- a/PixelComposer.resource_order +++ b/PixelComposer.resource_order @@ -100,6 +100,7 @@ {"name":"generator","order":5,"path":"folders/nodes/data/generator.yy",}, {"name":"noise","order":14,"path":"folders/nodes/data/generator/noise.yy",}, {"name":"pattern","order":15,"path":"folders/nodes/data/generator/pattern.yy",}, + {"name":"regions","order":23,"path":"folders/nodes/data/generator/regions.yy",}, {"name":"group","order":7,"path":"folders/nodes/data/group.yy",}, {"name":"network","order":16,"path":"folders/nodes/data/IO/network.yy",}, {"name":"iterate","order":10,"path":"folders/nodes/data/iterate.yy",}, @@ -713,7 +714,6 @@ {"name":"sh_d3d_ssao_blur","order":1,"path":"shaders/sh_d3d_ssao_blur/sh_d3d_ssao_blur.yy",}, {"name":"panel_addon","order":5,"path":"scripts/panel_addon/panel_addon.yy",}, {"name":"s_node_text_splice","order":6,"path":"sprites/s_node_text_splice/s_node_text_splice.yy",}, - {"name":"__atlas","order":6,"path":"scripts/__atlas/__atlas.yy",}, {"name":"__node_3d_transform","order":7,"path":"scripts/__node_3d_transform/__node_3d_transform.yy",}, {"name":"__d3d_gizmo","order":2,"path":"scripts/__d3d_gizmo/__d3d_gizmo.yy",}, {"name":"sh_draw_single_channel","order":3,"path":"shaders/sh_draw_single_channel/sh_draw_single_channel.yy",}, @@ -968,7 +968,6 @@ {"name":"sh_bloom_pass","order":2,"path":"shaders/sh_bloom_pass/sh_bloom_pass.yy",}, {"name":"fd_rectangle_draw_view","order":4,"path":"scripts/fd_rectangle_draw_view/fd_rectangle_draw_view.yy",}, {"name":"fd_rectangle_set_material_type","order":9,"path":"scripts/fd_rectangle_set_material_type/fd_rectangle_set_material_type.yy",}, - {"name":"node_seperate_shapes","order":4,"path":"scripts/node_seperate_shapes/node_seperate_shapes.yy",}, {"name":"node_fluid_domain_queue","order":9,"path":"scripts/node_fluid_domain_queue/node_fluid_domain_queue.yy",}, {"name":"node_sequence_to_anim","order":3,"path":"scripts/node_sequence_to_anim/node_sequence_to_anim.yy",}, {"name":"sh_blend_replace","order":50,"path":"shaders/sh_blend_replace/sh_blend_replace.yy",}, @@ -1435,6 +1434,7 @@ {"name":"button","order":2,"path":"scripts/button/button.yy",}, {"name":"s_node_3d_sphere","order":8,"path":"sprites/s_node_3d_sphere/s_node_3d_sphere.yy",}, {"name":"fd_rectangle_replace_velocity","order":16,"path":"scripts/fd_rectangle_replace_velocity/fd_rectangle_replace_velocity.yy",}, + {"name":"s_node_group_thumbnail","order":34,"path":"sprites/s_node_group_thumbnail/s_node_group_thumbnail.yy",}, {"name":"node_VFX_effector","order":6,"path":"scripts/node_VFX_effector/node_VFX_effector.yy",}, {"name":"node_path_shift","order":5,"path":"scripts/node_path_shift/node_path_shift.yy",}, {"name":"s_node_wav_file_write","order":17,"path":"sprites/s_node_wav_file_write/s_node_wav_file_write.yy",}, @@ -1556,6 +1556,7 @@ {"name":"node_noise_fbm","order":3,"path":"scripts/node_noise_fbm/node_noise_fbm.yy",}, {"name":"sh_channel_V","order":6,"path":"shaders/sh_channel_V/sh_channel_V.yy",}, {"name":"__shapes","order":3,"path":"scripts/__shapes/__shapes.yy",}, + {"name":"node_group_thumbnail","order":3,"path":"scripts/node_group_thumbnail/node_group_thumbnail.yy",}, {"name":"VCT","order":1,"path":"scripts/VCT/VCT.yy",}, {"name":"node_alpha_to_grey","order":3,"path":"scripts/node_alpha_to_grey/node_alpha_to_grey.yy",}, {"name":"shell_functions","order":20,"path":"scripts/shell_functions/shell_functions.yy",}, diff --git a/PixelComposer.yyp b/PixelComposer.yyp index 7bd7fc81e..de2826745 100644 --- a/PixelComposer.yyp +++ b/PixelComposer.yyp @@ -125,6 +125,7 @@ {"resourceType":"GMFolder","resourceVersion":"1.0","name":"generator","folderPath":"folders/nodes/data/generator.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"noise","folderPath":"folders/nodes/data/generator/noise.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"pattern","folderPath":"folders/nodes/data/generator/pattern.yy",}, + {"resourceType":"GMFolder","resourceVersion":"1.0","name":"regions","folderPath":"folders/nodes/data/generator/regions.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"group","folderPath":"folders/nodes/data/group.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"IO","folderPath":"folders/nodes/data/IO.yy",}, {"resourceType":"GMFolder","resourceVersion":"1.0","name":"network","folderPath":"folders/nodes/data/IO/network.yy",}, @@ -1316,7 +1317,6 @@ {"id":{"name":"sh_d3d_ssao_blur","path":"shaders/sh_d3d_ssao_blur/sh_d3d_ssao_blur.yy",},}, {"id":{"name":"panel_addon","path":"scripts/panel_addon/panel_addon.yy",},}, {"id":{"name":"s_node_text_splice","path":"sprites/s_node_text_splice/s_node_text_splice.yy",},}, - {"id":{"name":"__atlas","path":"scripts/__atlas/__atlas.yy",},}, {"id":{"name":"__node_3d_transform","path":"scripts/__node_3d_transform/__node_3d_transform.yy",},}, {"id":{"name":"__d3d_gizmo","path":"scripts/__d3d_gizmo/__d3d_gizmo.yy",},}, {"id":{"name":"sh_draw_single_channel","path":"shaders/sh_draw_single_channel/sh_draw_single_channel.yy",},}, @@ -2142,6 +2142,7 @@ {"id":{"name":"button","path":"scripts/button/button.yy",},}, {"id":{"name":"s_node_3d_sphere","path":"sprites/s_node_3d_sphere/s_node_3d_sphere.yy",},}, {"id":{"name":"fd_rectangle_replace_velocity","path":"scripts/fd_rectangle_replace_velocity/fd_rectangle_replace_velocity.yy",},}, + {"id":{"name":"s_node_group_thumbnail","path":"sprites/s_node_group_thumbnail/s_node_group_thumbnail.yy",},}, {"id":{"name":"node_VFX_effector","path":"scripts/node_VFX_effector/node_VFX_effector.yy",},}, {"id":{"name":"sh_blur_gaussian","path":"shaders/sh_blur_gaussian/sh_blur_gaussian.yy",},}, {"id":{"name":"node_path_shift","path":"scripts/node_path_shift/node_path_shift.yy",},}, @@ -2284,6 +2285,7 @@ {"id":{"name":"node_noise_fbm","path":"scripts/node_noise_fbm/node_noise_fbm.yy",},}, {"id":{"name":"sh_channel_V","path":"shaders/sh_channel_V/sh_channel_V.yy",},}, {"id":{"name":"__shapes","path":"scripts/__shapes/__shapes.yy",},}, + {"id":{"name":"node_group_thumbnail","path":"scripts/node_group_thumbnail/node_group_thumbnail.yy",},}, {"id":{"name":"VCT","path":"scripts/VCT/VCT.yy",},}, {"id":{"name":"node_alpha_to_grey","path":"scripts/node_alpha_to_grey/node_alpha_to_grey.yy",},}, {"id":{"name":"shell_functions","path":"scripts/shell_functions/shell_functions.yy",},}, diff --git a/datafiles/data/locale/en.zip b/datafiles/data/locale/en.zip index db106990807eddb42ad96aa4c71236a5bfa8bcc8..fca3840b7507ec64db94d53db701d3e65e4ebc98 100644 GIT binary patch literal 37338 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

FBg+>8+0moPpcO2GVb{!wMX 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 AM*si- literal 34087 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 diff --git a/datafiles/data/locale/en/UI.json b/datafiles/data/locale/en/UI.json index 42ea69410..7ce3edcbf 100644 --- a/datafiles/data/locale/en/UI.json +++ b/datafiles/data/locale/en/UI.json @@ -364,5 +364,10 @@ "widget_rotator_random_range": "Range", "widget_rotator_random_span": "Span", + "pref_clear_temp": "Clear temp file on close.", + "pref_connection_type": "Connection type", + "pref_use_alt": "Use ALT for", + "meta_old_version": "Created on an older version", + "" : "" } \ No newline at end of file diff --git a/datafiles/data/locale/en/words.json b/datafiles/data/locale/en/words.json index 5211aa53e..f736548fd 100644 --- a/datafiles/data/locale/en/words.json +++ b/datafiles/data/locale/en/words.json @@ -223,5 +223,88 @@ "system": "System", "text": "Text", + "3d_camera": "3D Camera", + "add_bones": "Add bones", + "add_node": "Add node", + "add_number": "Add number", + "add_vector2": "Add vector2", + "add_vector3": "Add vector3", + "add_vector4": "Add vector4", + "adjust_control_point": "Adjust control point", + "anchor_add_/_remove": "Anchor add / remove", + "anchor_remove": "Anchor remove", + "array": "Array", + "assetbox": "Assetbox", + "bg": "Bg", + "blend": "Blend", + "canvas_blend": "Canvas blend", + "canvas": "Canvas", + "circle_path": "Circle path", + "close_file": "Close file", + "collection": "Collection", + "color_picker": "Color picker", + "comb": "Comb", + "copy_property": "Copy property", + "delete_(break)": "Delete (break)", + "delete_(merge)": "Delete (merge)", + "delete_keys": "Delete keys", + "detach_bones": "Detach bones", + "dialog": "Dialog", + "draw_path": "Draw path", + "edit_control_point": "Edit control point", + "ellipse": "Ellipse", + "eraser": "Eraser", + "fill": "Fill", + "first_frame": "First frame", + "focus_content": "Focus content", + "full_panel": "Full panel", + "grab": "Grab", + "ik": "IK", + "import_image_array": "Import image array", + "import_image": "Import image", + "last_frame": "Last frame", + "main": "Main", + "mesh_edit": "Mesh edit", + "mesh_warp": "Mesh Warp", + "move_target": "Move Target", + "new_file": "New file", + "next_frame": "Next frame", + "open_notification": "Open notification", + "pan": "Pan", + "panel": "Panel", + "paste_property": "Paste property", + "path_anchor": "Path Anchor", + "pencil": "Pencil", + "pin_mesh": "Pin mesh", + "play/pause": "Play/Pause", + "preview_focusing_node": "Preview focusing node", + "preview_window": "Preview window", + "previous_frame": "Previous frame", + "push": "Push", + "rectangle_path": "Rectangle path", + "rectangle": "Rectangle", + "remove_bones": "Remove bones", + "render_all": "Render all", + "resume/pause": "Resume/Pause", + "rigid_object": "Rigid Object", + "rotate": "Rotate", + "rotation": "Rotation", + "save_all_current_frame": "Save all current frame", + "save_current_frame": "Save current frame", + "scrollbar": "Scrollbar", + "select_all": "Select all", + "selection": "Selection", + "shorten": "Shorten", + "strand_create": "Strand Create", + "stretch": "Stretch", + "surfaces": "Surfaces", + "toggle_animation": "Toggle animation", + "toggle_grid": "Toggle grid", + "toggle_preview": "Toggle preview", + "toggle_render": "Toggle render", + "transform_node": "Transform node", + "widget": "Widget", + "workshop": "Workshop", + "" : "" } \ No newline at end of file diff --git a/objects/o_dialog_preference/Create_0.gml b/objects/o_dialog_preference/Create_0.gml index 6a556a82f..ccc6b3010 100644 --- a/objects/o_dialog_preference/Create_0.gml +++ b/objects/o_dialog_preference/Create_0.gml @@ -78,7 +78,7 @@ event_inherited(); sect_title = string_replace(sect_title, "- ", ""); } - draw_text_add(_xx, yl + hs / 2, sect_title); + draw_text_add(_xx, yl + hs / 2, __txt(sect_title)); yl += hs; hh += hs; diff --git a/objects/o_main/Draw_75.gml b/objects/o_main/Draw_75.gml index d78e35daa..5a81ef841 100644 --- a/objects/o_main/Draw_75.gml +++ b/objects/o_main/Draw_75.gml @@ -73,9 +73,6 @@ if(OS == os_windows && gameframe_is_minimized()) exit; txt += " (groups: " + string(array_length(content)) + ")"; draw_tooltip_text("[" + txt + "]"); break; - case VALUE_TYPE.atlas : - draw_tooltip_atlas(content); - break; case VALUE_TYPE.buffer : draw_tooltip_buffer(content); break; diff --git a/scripts/__VFX/__VFX.gml b/scripts/__VFX/__VFX.gml index 032feb009..548dd5efc 100644 --- a/scripts/__VFX/__VFX.gml +++ b/scripts/__VFX/__VFX.gml @@ -42,7 +42,7 @@ function __part(_node) constructor { //wig_rot = new wiggleMap(seed, 1, PROJECT.animator.frames_total); //wig_dir = new wiggleMap(seed, 1, PROJECT.animator.frames_total); - boundary_data = -1; + atlas = noone; grav = 0; gravDir = -90; @@ -77,21 +77,32 @@ function __part(_node) constructor { ground_bounce = 0; ground_friction = 1; + static reset = function() { #region + gml_pragma("forceinline"); + + surf = noone; + atlas = noone; + + prevx = undefined; + prevy = undefined; + } #endregion + static create = function(_surf, _x, _y, _life) { #region + gml_pragma("forceinline"); + active = true; surf = _surf; x = _x; y = _y; - prevx = undefined; - prevy = undefined; - life = _life; life_total = life; node.onPartCreate(self); } #endregion static setPhysic = function(_sx, _sy, _ac, _g, _gDir, _turn, _turnSpd) { #region + gml_pragma("forceinline"); + speedx = _sx; speedy = _sy; accel = _ac; @@ -108,6 +119,8 @@ function __part(_node) constructor { } #endregion static setWiggle = function(wiggle_maps) { #region + gml_pragma("forceinline"); + //wig_psx.check(_wig_pos[0], _wig_pos[1], seed + 10); //wig_psy.check(_wig_pos[0], _wig_pos[1], seed + 20); //wig_rot.check(_wig_rot[0], _wig_rot[1], seed + 30); @@ -124,6 +137,8 @@ function __part(_node) constructor { } #endregion static setGround = function(_ground, _ground_offset, _ground_bounce, _ground_frict) { #region + gml_pragma("forceinline"); + ground = _ground; ground_y = y + _ground_offset; ground_bounce = _ground_bounce; @@ -131,6 +146,8 @@ function __part(_node) constructor { } #endregion static setTransform = function(_scx, _scy, _sct, _rot, _rots, _follow) { #region + gml_pragma("forceinline"); + sc_sx = _scx; sc_sy = _scy; sct = _sct; @@ -141,6 +158,8 @@ function __part(_node) constructor { } #endregion static setDraw = function(_col, _blend, _alp, _fade) { #region + gml_pragma("forceinline"); + col = _col; blend = _blend; alp = _alp; @@ -149,12 +168,16 @@ function __part(_node) constructor { } #endregion static kill = function() { #region + gml_pragma("forceinline"); + active = false; node.onPartDestroy(self); } #endregion static step = function() { #region + gml_pragma("forceinline"); + if(!active) return; x += speedx; @@ -214,8 +237,11 @@ function __part(_node) constructor { } #endregion static draw = function(exact, surf_w, surf_h) { #region + gml_pragma("forceinline"); + var ss = surf; - if(is_array(surf)) { + + if(surf != noone && is_array(surf)) { var ind = abs(round((life_total - life) * anim_speed)); var len = array_length(surf); @@ -234,8 +260,9 @@ function __part(_node) constructor { } } - var surface = node.surface_cache[$ ss]; - //print($"VFX: {surface} ({is_surface(surface)})") + var surface = atlas == noone? node.surface_cache[$ ss] : atlas.getSurface(); + //print($"VFX: {surface} ({is_surface(surface)}), {atlas}") + if(!is_surface(surface)) return; var lifeRat = 1 - life / life_total; @@ -247,22 +274,9 @@ function __part(_node) constructor { var s_w = surface_get_width_safe(surface) * scx; var s_h = surface_get_height_safe(surface) * scy; - if(boundary_data == -1) { - var _pp = point_rotate(-s_w / 2, -s_h / 2, 0, 0, rot); - _xx = drawx + _pp[0]; - _yy = drawy + _pp[1]; - } else { - var ww = boundary_data[2] + boundary_data[0]; - var hh = boundary_data[3] + boundary_data[1]; - - var cx = (boundary_data[0] + boundary_data[2]) / 2; - var cy = (boundary_data[1] + boundary_data[3]) / 2; - - var _pp = point_rotate(-cx, -cy, 0, 0, rot); - - _xx = drawx + cx + _pp[0] * scx; - _yy = drawy + cy + _pp[1] * scy; - } + var _pp = point_rotate(-s_w / 2, -s_h / 2, 0, 0, rot); + _xx = drawx + _pp[0]; + _yy = drawy + _pp[1]; if(exact) { _xx = round(_xx); @@ -284,15 +298,9 @@ function __part(_node) constructor { } #endregion static getPivot = function() { #region - if(boundary_data == -1) - return [x, y]; + gml_pragma("forceinline"); - var ww = (boundary_data[2] - boundary_data[0]) * scx; - var hh = (boundary_data[3] - boundary_data[1]) * scy; - var cx = x + boundary_data[0] + ww / 2; - var cy = y + boundary_data[1] + hh / 2; - - return [cx, cy]; + return [x, y]; } #endregion } diff --git a/scripts/__atlas/__atlas.gml b/scripts/__atlas/__atlas.gml deleted file mode 100644 index 1fb3422f7..000000000 --- a/scripts/__atlas/__atlas.gml +++ /dev/null @@ -1,10 +0,0 @@ -function spriteAtlasData(x = 0, y = 0, w = 1, h = 1, surface = noone, index = 0) constructor { - self.surface = surface; - self.index = index; - self.x = x; - self.y = y; - self.w = w; - self.h = h; - - static clone = function() { return new spriteAtlasData(x, y, w, h, surface, index); } -} \ No newline at end of file diff --git a/scripts/__rectangle/__rectangle.gml b/scripts/__rectangle/__rectangle.gml index beeee47b5..8b1f5d11a 100644 --- a/scripts/__rectangle/__rectangle.gml +++ b/scripts/__rectangle/__rectangle.gml @@ -1,4 +1,4 @@ -function Rectangle(x, y, w, h) constructor { +function Rectangle(x = 0, y = 0, w = 0, h = 0) constructor { self.x = x; self.y = y; self.w = w; diff --git a/scripts/__surface/__surface.gml b/scripts/__surface/__surface.gml index 8454afe92..2852b8241 100644 --- a/scripts/__surface/__surface.gml +++ b/scripts/__surface/__surface.gml @@ -1,22 +1,61 @@ -function SurfaceAtlas(surface, position = [ 0, 0 ], rotation = 0, scale = [ 1, 1 ], blend = c_white, alpha = 1) constructor { +function SurfaceAtlas(surface, _x = 0, _y = 0, rot = 0, sx = 1, sy = 1, blend = c_white, alpha = 1) constructor { self.surface = new Surface(surface); - self.position = position; - self.rotation = rotation; - self.scale = scale; + self.x = _x; + self.y = _y; + self.rotation = rot; + self.sx = sx; + self.sy = sy; self.blend = blend; self.alpha = alpha; + w = surface_get_width_safe(surface); + h = surface_get_height_safe(surface); + + oriSurf = noone; + oriSurf_w = w; + oriSurf_h = h; + + static setOrginalSurface = function(surf) { + gml_pragma("forceinline"); + + oriSurf = surf; + oriSurf_w = surface_get_width_safe(surf); + oriSurf_h = surface_get_height_safe(surf); + return self; + } + + static getSurface = function() { + gml_pragma("forceinline"); + + return surface.get(); + } + + static setSurface = function(surface) { + gml_pragma("forceinline"); + self.surface.set(surface); + + w = surface_get_width_safe(surface); + h = surface_get_height_safe(surface); + } + static draw = function() { - draw_surface_ext_safe(surface.get(), position[0], position[1], scale[0], scale[1], rotation, blend, alpha); + gml_pragma("forceinline"); + + draw_surface_ext_safe(surface.get(), x, y, sx, sy, rotation, blend, alpha); + return self; } static clone = function() { - return new SurfaceAtlas(surface.get(), position, rotation, scale, blend, alpha); + gml_pragma("forceinline"); + + return new SurfaceAtlas(getSurface(), x, y, rotation, sx, sy, blend, alpha); } } function Surface(surface) constructor { static set = function(surface) { + gml_pragma("forceinline"); + self.surface = surface; w = surface_get_width_safe(surface); h = surface_get_height_safe(surface); @@ -24,11 +63,13 @@ function Surface(surface) constructor { } set(surface); - static get = function() { return surface; } + static get = function() { gml_pragma("forceinline"); return surface; } - static isValid = function() { return is_surface(surface); } + static isValid = function() { gml_pragma("forceinline"); return is_surface(surface); } static resize = function(w, h) { + gml_pragma("forceinline"); + surface_resize(surface, w, h); self.w = w; self.h = h; @@ -36,22 +77,30 @@ function Surface(surface) constructor { } static draw = function(x, y, xs = 1, ys = 1, rot = 0, col = c_white, alpha = 1) { + gml_pragma("forceinline"); + draw_surface_ext_safe(surface, x, y, xs, ys, rot, col, alpha); return self; } static drawStretch = function(x, y, w = 1, h = 1, rot = 0, col = c_white, alpha = 1) { + gml_pragma("forceinline"); + draw_surface_stretched_ext(surface, x, y, w, h, col, alpha); return self; } static destroy = function() { + gml_pragma("forceinline"); + if(!isValid()) return; surface_free(surface); } } function Surface_get(surface) { + gml_pragma("forceinline"); + if(is_real(surface)) return surface; if(is_struct(surface) && struct_has(surface, "surface")) diff --git a/scripts/_node_VFX_spawner/_node_VFX_spawner.gml b/scripts/_node_VFX_spawner/_node_VFX_spawner.gml index c1cb5079c..933284af9 100644 --- a/scripts/_node_VFX_spawner/_node_VFX_spawner.gml +++ b/scripts/_node_VFX_spawner/_node_VFX_spawner.gml @@ -15,7 +15,7 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co inputs[| 4] = nodeValue("Spawn distribution", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0 ) .rejectArray() - .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Area", "Border", "Map", "Direct Data" ] ); + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Area", "Border", "Map", "Atlas" ] ); inputs[| 5] = nodeValue("Lifespan", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [ 20, 30 ] ) .setDisplay(VALUE_DISPLAY.range); @@ -78,7 +78,7 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co inputs[| 24] = nodeValue("Scatter", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1) .rejectArray() - .setDisplay(VALUE_DISPLAY.enum_button, [ "Uniform", "Random", "Data" ]); + .setDisplay(VALUE_DISPLAY.enum_button, [ "Uniform", "Random" ]); inputs[| 25] = nodeValue("Boundary data", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, []) .setVisible(false, true); @@ -99,8 +99,9 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co inputs[| 30] = nodeValue("Distribution map", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, 0) .rejectArray() - inputs[| 31] = nodeValue("Distribution data", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, []) - .setDisplay(VALUE_DISPLAY.vector); + inputs[| 31] = nodeValue("Atlas", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, [] ) + .setArrayDepth(1) + .rejectArray(); inputs[| 32] = nodeValue("Seed", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, irandom_range(100000, 999999)) .rejectArray(); @@ -148,12 +149,12 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co inputs[| 44] = nodeValue("Spawn", self, JUNCTION_CONNECT.input, VALUE_TYPE.trigger, false ) .setDisplay(VALUE_DISPLAY.button, { name: "Trigger", onClick: triggerSpawn, output: true }) .rejectArray(); - + input_len = ds_list_size(inputs); input_display_list = [ 32, - ["Sprite", false], 0, 22, 23, 26, - ["Spawn", true], 27, 16, 44, 1, 2, 3, 4, 30, 31, 24, 25, 5, + ["Sprite", false], 0, 31, 22, 23, 26, + ["Spawn", true], 27, 16, 44, 1, 2, 3, 4, 30, 24, 5, ["Movement", true], 29, 6, 18, ["Physics", true], 7, 19, 33, 34, 35, 36, ["Ground", true], 37, 38, 39, 40, @@ -195,14 +196,14 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co parts[i] = new __part(self); static spawn = function(_time = PROJECT.animator.current_frame, _pos = -1) { #region - var _inSurf = current_data[0]; + var _inSurf = current_data[ 0]; + var _atlas = current_data[31]; var _spawn_amount = current_data[ 2]; var _spawn_area = current_data[ 3]; var _distrib = current_data[ 4]; var _dist_map = current_data[30]; - var _dist_data = current_data[31]; var _scatter = current_data[24]; var _life = current_data[ 5]; @@ -244,6 +245,7 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co random_set_seed(seed); var _amo = irandom_range(_spawn_amount[0], _spawn_amount[1]); + //print($"Frame {_time}: Spawning {_amo} particles, seed {seed}, {irandom(99999999)}"); for( var i = 0; i < _amo; i++ ) { seed += 100; random_set_seed(seed); @@ -251,7 +253,7 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co parts_runner = clamp(parts_runner, 0, array_length(parts) - 1); var part = parts[parts_runner]; - //print($"Frame {_time}: Spawning particle {parts_runner}, seed {seed}, {irandom(99999999)}"); + part.reset(); var _spr = _inSurf, _index = 0; if(is_array(_inSurf)) { @@ -269,36 +271,23 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co var yy = 0; if(_pos == -1) { - if(_scatter == 2) { - var _b_data = current_data[25]; - if(!is_array(_b_data) || array_length(_b_data) <= 0) return; - var _b = _b_data[safe_mod(_index, array_length(_b_data))]; - if(!is_array(_b) || array_length(_b) != 4) return; - - xx = array_safe_get(_spawn_area, 0) - array_safe_get(_spawn_area, 2); - yy = array_safe_get(_spawn_area, 1) - array_safe_get(_spawn_area, 3); - - part.boundary_data = _b; - } else { - if(_distrib < 2) { - var sp = area_get_random_point(_spawn_area, _distrib, _scatter, spawn_index, _spawn_amount, seed); - xx = sp[0]; - yy = sp[1]; - - part.boundary_data = -1; - } else if(_distrib == 2) { - var sp = array_safe_get(_posDist, i); - if(!is_array(sp)) continue; + if(_distrib < 2) { + var sp = area_get_random_point(_spawn_area, _distrib, _scatter, spawn_index, _spawn_amount, seed); + xx = sp[0]; + yy = sp[1]; + } else if(_distrib == 2) { + var sp = array_safe_get(_posDist, i); + if(!is_array(sp)) continue; - xx = _spawn_area[0] + _spawn_area[2] * (sp[0] * 2 - 1.); - yy = _spawn_area[1] + _spawn_area[3] * (sp[1] * 2 - 1.); - } else if(_distrib == 3) { - sp = array_safe_get(_dist_data, spawn_index); - if(!is_array(sp)) continue; - - _x = sp[0]; - _y = sp[1]; - } + xx = _spawn_area[0] + _spawn_area[2] * (sp[0] * 2 - 1.); + yy = _spawn_area[1] + _spawn_area[3] * (sp[1] * 2 - 1.); + } else if(_distrib == 3) { + sp = array_safe_get(_atlas, spawn_index,, ARRAY_OVERFLOW.loop); + + if(!is_instanceof(sp, SurfaceAtlas)) continue; + xx = sp.x + sp.w / 2; + yy = sp.y + sp.h / 2; + part.atlas = sp; } } else { xx = _pos[0]; @@ -464,8 +453,9 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co inputs[| 6].setVisible(!_dirAng); - inputs[| 25].setVisible(_scatt == 2); + inputs[| 24].setVisible(_dist < 2); + inputs[| 0].setVisible(_dist != 3, _dist != 3); inputs[| 30].setVisible(_dist == 2, _dist == 2); inputs[| 31].setVisible(_dist == 3, _dist == 3); diff --git a/scripts/draw_fit/draw_fit.gml b/scripts/draw_fit/draw_fit.gml index 05648864e..8605be083 100644 --- a/scripts/draw_fit/draw_fit.gml +++ b/scripts/draw_fit/draw_fit.gml @@ -8,7 +8,7 @@ function draw_surface_fit(surf, xx, yy, w, h, color = c_white, alpha = 1) { draw_surface_ext_safe(surf, xx - surface_get_width_safe(surf) * ss / 2, yy - surface_get_height_safe(surf) * ss / 2, ss, ss,, color, alpha); } -function draw_surface_stretch_fit(surf, xx, yy, w, h, sw, sh) { +function draw_surface_stretch_fit(surf, xx, yy, w, h, sw = 1, sh = 1) { var ss = min(w / sw, h / sh); draw_surface_stretched_safe(surf, xx - sw * ss / 2, yy - sh * ss / 2, sw * ss, sh * ss); } diff --git a/scripts/draw_text_function/draw_text_function.gml b/scripts/draw_text_function/draw_text_function.gml index a474e4491..5765a4284 100644 --- a/scripts/draw_text_function/draw_text_function.gml +++ b/scripts/draw_text_function/draw_text_function.gml @@ -21,6 +21,7 @@ function draw_text_bbox(bbox, text) { draw_set_halign(fa_center); draw_set_valign(fa_center); + draw_text_cut(bbox.xc, bbox.yc, text, bbox.w, ss); } diff --git a/scripts/draw_tooltip/draw_tooltip.gml b/scripts/draw_tooltip/draw_tooltip.gml index e0e288030..3f81361a1 100644 --- a/scripts/draw_tooltip/draw_tooltip.gml +++ b/scripts/draw_tooltip/draw_tooltip.gml @@ -61,6 +61,11 @@ function draw_tooltip_gradient(clr) { } function draw_tooltip_surface_array(surf) { + if(is_instanceof(surf[0], SurfaceAtlas)) { + draw_tooltip_atlas(surf); + return; + } + var amo = array_length(surf); var col = ceil(sqrt(amo)); var row = ceil(amo / col); @@ -101,6 +106,12 @@ function draw_tooltip_surface(surf) { draw_tooltip_surface_array(array_spread(surf)) return; } + + if(is_instanceof(surf, SurfaceAtlas)) { + draw_tooltip_atlas(surf); + return; + } + if(!is_surface(surf)) return; var sw = surface_get_width_safe(surf); @@ -142,7 +153,7 @@ function draw_tooltip_atlas(atlas) { var _y = sy + i * ui(48 + 8); var atl = atlas[i]; - var surf = atl.surface.get(); + var surf = atl.getSurface(); if(!is_surface(surf)) continue; @@ -161,9 +172,9 @@ function draw_tooltip_atlas(atlas) { draw_text_add(sx + ui( 56), _y + ui(32), __txt("Scale")); draw_set_text(f_p3, fa_right, fa_top, COLORS._main_text); - draw_text_add(sx + ui(160), _y + ui( 0), atl.position); + draw_text_add(sx + ui(160), _y + ui( 0), $"{atl.x}, {atl.y}"); draw_text_add(sx + ui(160), _y + ui(16), atl.rotation); - draw_text_add(sx + ui(160), _y + ui(32), atl.scale); + draw_text_add(sx + ui(160), _y + ui(32), $"{atl.sx}, {atl.sy}"); } } diff --git a/scripts/event_recorder/event_recorder.gml b/scripts/event_recorder/event_recorder.gml index 3147b5f15..988dba9d8 100644 --- a/scripts/event_recorder/event_recorder.gml +++ b/scripts/event_recorder/event_recorder.gml @@ -1,6 +1,6 @@ globalvar UNDO_STACK, REDO_STACK; globalvar IS_UNDOING, UNDO_HOLDING; - + IS_UNDOING = false; UNDO_HOLDING = false; UNDO_STACK = ds_stack_create(); diff --git a/scripts/load_function/load_function.gml b/scripts/load_function/load_function.gml index 39f004d1f..d8ff4b800 100644 --- a/scripts/load_function/load_function.gml +++ b/scripts/load_function/load_function.gml @@ -133,6 +133,9 @@ function __LOAD_PATH(path, readonly = false, safe_mode = false, override = false if(struct_has(_load_content, "graphGrid")) PROJECT.graphGrid = _load_content.graphGrid; + if(struct_has(_load_content, "attributes")) + struct_override(PROJECT.attributes, _load_content.attributes); + try { if(struct_has(_load_content, "metadata")) METADATA.deserialize(_load_content.metadata); @@ -201,7 +204,7 @@ function __LOAD_PATH(path, readonly = false, safe_mode = false, override = false log_warning("LOAD, update", exception_print(e)); } - Render(, true); + Render(); if(!ds_queue_empty(CONNECTION_CONFLICT)) { var pass = 0; @@ -236,7 +239,7 @@ function __LOAD_PATH(path, readonly = false, safe_mode = false, override = false log_warning("LOAD, connect", exception_print(e)); } - RENDER_ALL_REORDER + Render(, true); LOADING = false; PROJECT.modified = false; diff --git a/scripts/node_armature_bind/node_armature_bind.gml b/scripts/node_armature_bind/node_armature_bind.gml index 97a2d3017..61a7997d6 100644 --- a/scripts/node_armature_bind/node_armature_bind.gml +++ b/scripts/node_armature_bind/node_armature_bind.gml @@ -20,7 +20,7 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); - outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.atlas, []) + outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []) .rejectArrayProcess(); outputs[| 2] = nodeValue("Bind data", self, JUNCTION_CONNECT.output, VALUE_TYPE.struct, []) @@ -810,7 +810,7 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr if(!vis) continue; var datInd = input_fix_len + i * data_length; - var _s = use_data? _bind[i].surface.get() : _data[datInd]; + var _s = use_data? _bind[i].getSurface() : _data[datInd]; if(!is_surface(_s)) continue; var _b = use_data? _bind[i].bone : inputs[| datInd].display_data.bone_id; @@ -847,7 +847,7 @@ function Node_Armature_Bind(_x, _y, _group = noone) : Node_Processor(_x, _y, _gr (_anc.y * _dsca) + _cen[1] + _mov[1] + _dpos[1] ]; - array_push(atlas_data, new SurfaceAtlas(_s, _pos, _rot, _sca)); + array_push(atlas_data, new SurfaceAtlas(_s, _pos[0], _pos[1], _rot, _sca[0], _sca[1])); array_push(bind_data, { surface: new Surface(_s), bone: _b.ID, diff --git a/scripts/node_atlas_draw/node_atlas_draw.gml b/scripts/node_atlas_draw/node_atlas_draw.gml index 159dd45fe..3353325a7 100644 --- a/scripts/node_atlas_draw/node_atlas_draw.gml +++ b/scripts/node_atlas_draw/node_atlas_draw.gml @@ -5,7 +5,7 @@ function Node_Atlas_Draw(_x, _y, _group = noone) : Node(_x, _y, _group) construc inputs[| 0] = nodeValue("Dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, DEF_SURF) .setDisplay(VALUE_DISPLAY.vector); - inputs[| 1] = nodeValue("Atlas", self, JUNCTION_CONNECT.input, VALUE_TYPE.atlas, noone) + inputs[| 1] = nodeValue("Atlas", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone) .setVisible(true, true); outputs[| 0] = nodeValue("Surface", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); @@ -28,7 +28,7 @@ function Node_Atlas_Draw(_x, _y, _group = noone) : Node(_x, _y, _group) construc surface_set_shader(outSurf,,, BLEND.alpha); for( var i = 0, n = array_length(atl); i < n; i++ ) { - shader_set_interpolation(atl[i].surface.get()) + shader_set_interpolation(atl[i].getSurface()) atl[i].draw(); } surface_reset_shader(); diff --git a/scripts/node_atlas_get/node_atlas_get.gml b/scripts/node_atlas_get/node_atlas_get.gml index 8fbcbb286..a2782545e 100644 --- a/scripts/node_atlas_get/node_atlas_get.gml +++ b/scripts/node_atlas_get/node_atlas_get.gml @@ -2,7 +2,7 @@ function Node_Atlas_Get(_x, _y, _group = noone) : Node(_x, _y, _group) construct name = "Atlas Get"; previewable = true; - inputs[| 0] = nodeValue("Atlas", self, JUNCTION_CONNECT.input, VALUE_TYPE.atlas, noone) + inputs[| 0] = nodeValue("Atlas", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone) .setVisible(true, true); outputs[| 0] = nodeValue("Surface", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []) @@ -42,7 +42,7 @@ function Node_Atlas_Get(_x, _y, _group = noone) : Node(_x, _y, _group) construct var alph = []; for( var i = 0, n = array_length(atl); i < n; i++ ) { - surf[i] = atl[i].surface.get(); + surf[i] = atl[i].getSurface(); posi[i] = atl[i].position; rota[i] = atl[i].rotation; scal[i] = atl[i].scale; diff --git a/scripts/node_atlas_set/node_atlas_set.gml b/scripts/node_atlas_set/node_atlas_set.gml index ffe43f273..7cddd0a7b 100644 --- a/scripts/node_atlas_set/node_atlas_set.gml +++ b/scripts/node_atlas_set/node_atlas_set.gml @@ -2,7 +2,7 @@ function Node_Atlas_Set(_x, _y, _group = noone) : Node(_x, _y, _group) construct name = "Atlas Set"; previewable = true; - inputs[| 0] = nodeValue("Atlas", self, JUNCTION_CONNECT.input, VALUE_TYPE.atlas, noone) + inputs[| 0] = nodeValue("Atlas", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone) .setVisible(true, true); inputs[| 1] = nodeValue("Surface", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, []) @@ -25,7 +25,7 @@ function Node_Atlas_Set(_x, _y, _group = noone) : Node(_x, _y, _group) construct inputs[| 6] = nodeValue("Alpha", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, []) .setArrayDepth(1); - outputs[| 0] = nodeValue("Atlas", self, JUNCTION_CONNECT.output, VALUE_TYPE.atlas, noone); + outputs[| 0] = nodeValue("Atlas", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); static update = function(frame = PROJECT.animator.current_frame) { var atl = getInputData(0); diff --git a/scripts/node_blend/node_blend.gml b/scripts/node_blend/node_blend.gml index 1b4850ee9..700e8f4dc 100644 --- a/scripts/node_blend/node_blend.gml +++ b/scripts/node_blend/node_blend.gml @@ -5,6 +5,8 @@ function Node_create_Blend(_x, _y, _group = noone, _param = {}) { function Node_Blend(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor { name = "Blend"; + atlas_index = 1; + manage_atlas = false; inputs[| 0] = nodeValue("Background", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); inputs[| 1] = nodeValue("Foreground", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); @@ -48,7 +50,24 @@ function Node_Blend(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con attribute_surface_depth(); - temp_surface = [ surface_create(1, 1) ]; + temp_surface = [ surface_create(1, 1), surface_create(1, 1) ]; + blend_temp_surface = temp_surface[1]; + + static step = function() { #region + var _back = getSingleValue(0); + var _fore = getSingleValue(1); + var _fill = getSingleValue(5); + var _outp = getSingleValue(6); + + var _atlas = is_instanceof(_fore, SurfaceAtlas); + + inputs[| 5].editWidget.data_list = _atlas? [ "None", "Stretch" ] : [ "None", "Stretch", "Tile" ]; + inputs[| 6].editWidget.data_list = _atlas? [ "Background", "Forground" ] : [ "Background", "Forground", "Mask", "Maximum", "Constant" ]; + inputs[| 7].setVisible(_outp == 4); + + inputs[| 10].setVisible(_fill == 0 && !_atlas); + inputs[| 11].setVisible(_fill == 0 && !_atlas); + } #endregion static processData = function(_outSurf, _data, _output_index, _array_index) { #region var _back = _data[0]; @@ -56,7 +75,7 @@ function Node_Blend(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con var _type = _data[2]; var _opacity = _data[3]; var _mask = _data[4]; - var _tile = _data[5]; + var _fill = _data[5]; var _outp = _data[6]; var _out_dim = _data[7]; @@ -66,64 +85,28 @@ function Node_Blend(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con var _valign = _data[11]; var cDep = attrDepth(); - inputs[| 7].setVisible(_outp == 4); - var ww = 1, hh = 1; - var _foreDraw = _fore; + var ww = 1, hh = 1; + var _backDraw = _back; + var _foreDraw = _fore; - inputs[| 10].setVisible(_tile == 0); - inputs[| 11].setVisible(_tile == 0); + var _atlas = is_instanceof(_fore, SurfaceAtlas); - if(_tile == 0 && is_surface(_fore)) { - ww = surface_get_width_safe(_back); - hh = surface_get_height_safe(_back); - - var fw = surface_get_width_safe(_fore); - var fh = surface_get_height_safe(_fore); - - temp_surface[0] = surface_verify(temp_surface[0], ww, hh, cDep); - _foreDraw = temp_surface[0]; - - var sx = 0; - var sy = 0; - - switch(_halign) { - case 0 : sx = 0; break; - case 1 : sx = ww / 2 - fw / 2; break; - case 2 : sx = ww - fw; break; - } - - switch(_valign) { - case 0 : sy = 0; break; - case 1 : sy = hh / 2 - fh / 2; break; - case 2 : sy = hh - fh; break; - } - - surface_set_target(temp_surface[0]); - DRAW_CLEAR - BLEND_OVERRIDE - draw_surface_safe(_fore, sx, sy); - BLEND_NORMAL - surface_reset_target(); - } - - switch(_outp) { + switch(_outp) { // Dimension case 0 : ww = surface_get_width_safe(_back); hh = surface_get_height_safe(_back); break; case 1 : - if(is_surface(_foreDraw)) { - ww = surface_get_width_safe(_foreDraw); - hh = surface_get_height_safe(_foreDraw); - } + ww = surface_get_width_safe(_fore); + hh = surface_get_height_safe(_fore); break; case 2 : ww = surface_get_width_safe(_mask); hh = surface_get_height_safe(_mask); break; case 3 : - ww = max(surface_get_width_safe(_back), is_surface(_fore)? surface_get_width_safe(_fore) : 1, surface_get_width_safe(_mask)); - hh = max(surface_get_height_safe(_back), is_surface(_fore)? surface_get_height_safe(_fore) : 1, surface_get_height_safe(_mask)); + ww = max(surface_get_width_safe(_back), surface_get_width_safe(_fore), surface_get_width_safe(_mask)); + hh = max(surface_get_height_safe(_back), surface_get_height_safe(_fore), surface_get_height_safe(_mask)); break; case 4 : ww = _out_dim[0]; @@ -131,12 +114,69 @@ function Node_Blend(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) con break; } - _outSurf = surface_verify(_outSurf, ww, hh, cDep); + if(_fill == 0) { // Direct placement + for( var i = 0; i < 2; i++ ) + temp_surface[i] = surface_verify(temp_surface[i], ww, hh, cDep); + + _foreDraw = temp_surface[1]; + + if(_atlas) { + if(_outp == 0) { + surface_set_shader(_foreDraw, noone,, BLEND.over); + draw_surface_safe(_fore.getSurface(), _fore.x, _fore.y); + surface_reset_shader(); + } else if(_outp == 1) { + _backDraw = temp_surface[0]; + + surface_set_shader(_foreDraw, noone,, BLEND.over); + draw_surface_safe(_fore, 0, 0); + surface_reset_shader(); + + surface_set_shader(_backDraw, noone,, BLEND.over); + draw_surface_safe(_back, -_fore.x, -_fore.y); + surface_reset_shader(); + } + } else if(is_surface(_fore)) { + var sx = 0; + var sy = 0; + + var fw = surface_get_width_safe(_fore); + var fh = surface_get_height_safe(_fore); + + switch(_halign) { + case 0 : sx = 0; break; + case 1 : sx = ww / 2 - fw / 2; break; + case 2 : sx = ww - fw; break; + } + + switch(_valign) { + case 0 : sy = 0; break; + case 1 : sy = hh / 2 - fh / 2; break; + case 2 : sy = hh - fh; break; + } + + surface_set_shader(_foreDraw, noone,, BLEND.over); + draw_surface_safe(_fore, sx, sy); + surface_reset_shader(); + } + } - surface_set_target(_outSurf); - DRAW_CLEAR - draw_surface_blend(_back, _foreDraw, _type, _opacity, _pre_alp, _mask, max(0, _tile - 1)); - surface_reset_target(); + var _output = noone; + + if(is_instanceof(_outSurf, SurfaceAtlas)) + _output = surface_verify(_outSurf.surface.surface, ww, hh, cDep); + else + _output = surface_verify(_outSurf, ww, hh, cDep); + + surface_set_shader(_output, noone); + draw_surface_blend(_backDraw, _foreDraw, _type, _opacity, _pre_alp, _mask, _fill == 2); + surface_reset_shader(); + + if(_atlas) { + var _newAtl = _fore.clone(); + _newAtl.surface.set(_output); + return _newAtl; + } return _outSurf; } #endregion diff --git a/scripts/node_collection/node_collection.gml b/scripts/node_collection/node_collection.gml index 32361ba2e..0d9e8817f 100644 --- a/scripts/node_collection/node_collection.gml +++ b/scripts/node_collection/node_collection.gml @@ -324,13 +324,6 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc PATCH_STATIC - //static triggerRender = function() { - // for(var i = custom_input_index; i < ds_list_size(inputs); i++) { - // var jun_node = inputs[| i].from; - // jun_node.triggerRender(); - // } - //} - static preConnect = function() { #region sortIO(); deserialize(load_map, load_scale); @@ -468,6 +461,23 @@ function Node_Collection(_x, _y, _group = noone) : Node(_x, _y, _group) construc panel.addContext(self); } #endregion + static getGraphPreviewSurface = function() { #region + var _output_junc = outputs[| preview_channel]; + for( var i = 0, n = ds_list_size(nodes); i < n; i++ ) { + if(!nodes[| i].active) continue; + if(is_instanceof(nodes[| i], Node_Group_Thumbnail)) + _output_junc = nodes[| i].inputs[| 0]; + } + + switch(_output_junc.type) { + case VALUE_TYPE.surface : + case VALUE_TYPE.dynaSurface : + return _output_junc.getValue(); + } + + return noone; + } #endregion + static processSerialize = function(_map) { #region _map[? "instance_base"] = instanceBase? instanceBase.node_id : noone; } #endregion diff --git a/scripts/node_color_adjustment/node_color_adjustment.gml b/scripts/node_color_adjustment/node_color_adjustment.gml index 94f2f5f2a..04acf124f 100644 --- a/scripts/node_color_adjustment/node_color_adjustment.gml +++ b/scripts/node_color_adjustment/node_color_adjustment.gml @@ -139,11 +139,7 @@ function Node_Color_adjust(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro return _col; } - surface_set_target(_baseSurf); - DRAW_CLEAR - BLEND_OVERRIDE; - - shader_set(shader); + surface_set_shader(_baseSurf, shader); shader_set_uniform_i(uniform_mask_use, _m != DEF_SURFACE); texture_set_stage(uniform_mask, surface_get_texture(_m)); @@ -161,10 +157,7 @@ function Node_Color_adjust(_x, _y, _group = noone) : Node_Processor(_x, _y, _gro draw_surface_safe(_surf, 0, 0); gpu_set_colorwriteenable(1, 1, 1, 1); draw_surface_ext_safe(_surf, 0, 0, 1, 1, 0, c_white, _alp); - shader_reset(); - - BLEND_NORMAL; - surface_reset_target(); + surface_reset_shader(); return _outSurf; } #endregion diff --git a/scripts/node_composite/node_composite.gml b/scripts/node_composite/node_composite.gml index 91864d1da..29723b676 100644 --- a/scripts/node_composite/node_composite.gml +++ b/scripts/node_composite/node_composite.gml @@ -240,7 +240,7 @@ function Node_Composite(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); - outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.atlas, []) + outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []) .rejectArrayProcess(); temp_surface = [ surface_create(1, 1), surface_create(1, 1), surface_create(1, 1) ]; @@ -803,7 +803,7 @@ function Node_Composite(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) var _d0 = point_rotate(cx - _sw / 2, cy - _sh / 2, cx, cy, _rot); - array_push(atlas_data, new SurfaceAtlas(_s, [ _d0[0], _d0[1] ], _rot, [ _sca[0], _sca[1] ])); + array_push(atlas_data, new SurfaceAtlas(_s, _d0[0], _d0[1], _rot, _sca[0], _sca[1])); surface_set_shader(temp_surface[_bg], sh_sample, true, BLEND.over); blend_temp_surface = temp_surface[2]; diff --git a/scripts/node_data/node_data.gml b/scripts/node_data/node_data.gml index 1f7abf63e..30261a0bd 100644 --- a/scripts/node_data/node_data.gml +++ b/scripts/node_data/node_data.gml @@ -103,7 +103,11 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x inspectInput2 = nodeValue("Toggle execution", self, JUNCTION_CONNECT.input, VALUE_TYPE.action, false).setVisible(true, true); autoUpdatedTrigger = true; - updatedTrigger = nodeValue("Updated", self, JUNCTION_CONNECT.output, VALUE_TYPE.trigger, false).setVisible(true, true); + updatedInTrigger = nodeValue("Update", self, JUNCTION_CONNECT.input, VALUE_TYPE.trigger, false).setVisible(true, true); + updatedOutTrigger = nodeValue("Updated", self, JUNCTION_CONNECT.output, VALUE_TYPE.trigger, false).setVisible(true, true); + + updatedInTrigger.tags = VALUE_TAG.updateInTrigger; + updatedOutTrigger.tags = VALUE_TAG.updateOutTrigger; insp1UpdateTooltip = __txtx("panel_inspector_execute", "Execute node"); insp1UpdateIcon = [ THEME.sequence_control, 1, COLORS._main_value_positive ]; @@ -125,12 +129,14 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x #region --- attributes ---- attributes = { + update_graph: true, show_update_trigger: false }; attributeEditors = [ - "Node", - ["Update trigger", function() { return attributes.show_update_trigger; }, new checkBox(function() { attributes.show_update_trigger = !attributes.show_update_trigger; }) ] + "Node update", + ["Auto update", function() { return attributes.update_graph; }, new checkBox(function() { attributes.update_graph = !attributes.update_graph; }) ], + ["Update trigger", function() { return attributes.show_update_trigger; }, new checkBox(function() { attributes.show_update_trigger = !attributes.show_update_trigger; }) ], ]; #endregion @@ -369,7 +375,14 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x if(hasInspector1Update()) inspectInput1.name = insp1UpdateTooltip; if(hasInspector2Update()) inspectInput2.name = insp2UpdateTooltip; - updatedTrigger.setValue(false); + if(updatedInTrigger.getValue()) { + getInputs(); + update(); + + updatedInTrigger.setValue(false); + } + + updatedOutTrigger.setValue(false); } #endregion static doStepBegin = function() {} @@ -417,12 +430,9 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x static getInputs = function() { #region inputs_data = array_create(ds_list_size(inputs), undefined); - //input_hash_raw = ""; - for(var i = 0; i < ds_list_size(inputs); i++) { + for(var i = 0; i < ds_list_size(inputs); i++) inputs_data[i] = inputs[| i].getValue(,,, true); - //input_hash_raw += string_copy(string(inputs_data[i]), 1, 256); - } } #endregion static forceUpdate = function() { #region @@ -484,7 +494,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x if(trigger) onInspector2Update(); } - if(autoUpdatedTrigger) updatedTrigger.setValue(true); + updatedOutTrigger.setValue(true); if(!is_instanceof(self, Node_Collection)) render_time = get_timer() - render_timer; @@ -522,7 +532,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x LOG_BLOCK_END(); } #endregion - static resetRenderForward = function() { + static resetRenderForward = function() { #region setRenderStatus(false); for( var i = 0, n = ds_list_size(outputs); i < n; i++ ) { var _outp = outputs[| i]; @@ -536,7 +546,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x _to.node.resetRenderForward(); } } - } + } #endregion static resetRender = function() { setRenderStatus(false); } static isRenderActive = function() { return renderActive || (PREF_MAP[? "render_all_export"] && PROJECT.animator.rendering); } @@ -650,8 +660,11 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x ind++; } - updatedTrigger.x = xx + w * _s; - updatedTrigger.y = yy + 10; + updatedInTrigger.x = xx; + updatedInTrigger.y = yy + 10; + + updatedOutTrigger.x = xx + w * _s; + updatedOutTrigger.y = yy + 10; var inamo = (input_display_list == -1 || !use_display_list)? ds_list_size(inputs) : array_length(input_display_list); var _in = yy + ui(junction_draw_pad_y) * _s; @@ -774,8 +787,10 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x if(hasInspector2Update() && inspectInput2.drawJunction(_s, _mx, _my)) hover = inspectInput2; - if(attributes.show_update_trigger && updatedTrigger.drawJunction(_s, _mx, _my)) - hover = updatedTrigger; + if(attributes.show_update_trigger) { + if(updatedInTrigger.drawJunction(_s, _mx, _my)) hover = updatedInTrigger; + if(updatedOutTrigger.drawJunction(_s, _mx, _my)) hover = updatedOutTrigger; + } return hover; } #endregion @@ -884,6 +899,11 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x if(hov) hovering = hov; } + if(attributes.show_update_trigger) { + if(updatedInTrigger.drawConnections(params)) hovering = updatedInTrigger; + if(updatedOutTrigger.drawConnections(params)) hovering = updatedOutTrigger; + } + return hovering; } #endregion @@ -1018,7 +1038,7 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x draw_sprite_stretched_ext(THEME.node_glow, 0, xx - 9, yy - 9, w * _s + 18, h * _s + 18, COLORS._main_value_negative, 1); drawNodeBase(xx, yy, _s); - if(previewable && ds_list_size(outputs)) { + if(previewable) { if(preview_channel >= ds_list_size(outputs)) preview_channel = 0; drawPreview(xx, yy, _s); @@ -1442,7 +1462,8 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x var _trigger = []; array_push(_trigger, inspectInput1.serialize(scale, preset)); array_push(_trigger, inspectInput2.serialize(scale, preset)); - array_push(_trigger, updatedTrigger.serialize(scale, preset)); + array_push(_trigger, updatedInTrigger.serialize(scale, preset)); + array_push(_trigger, updatedOutTrigger.serialize(scale, preset)); _map.inspectInputs = _trigger; _map.renamed = renamed; @@ -1588,8 +1609,8 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x inspectInput1.applyDeserialize(insInp[0], load_scale, preset); inspectInput2.applyDeserialize(insInp[1], load_scale, preset); - if(array_length(insInp) > 2) - updatedTrigger.applyDeserialize(insInp[2], load_scale, preset); + if(array_length(insInp) > 2) updatedInTrigger.applyDeserialize(insInp[2], load_scale, preset); + if(array_length(insInp) > 3) updatedOutTrigger.applyDeserialize(insInp[3], load_scale, preset); } doApplyDeserialize(); @@ -1623,10 +1644,9 @@ function Node(_x, _y, _group = PANEL_GRAPH.getCurrentContext()) : __Node_Base(_x for(var i = 0; i < ds_list_size(inputs); i++) connected &= inputs[| i].connect(log); - if(struct_has(load_map, "inspectInputs")) { - inspectInput1.connect(log); - inspectInput2.connect(log); - } + inspectInput1.connect(log); + inspectInput2.connect(log); + updatedInTrigger.connect(log); if(!connected) ds_queue_enqueue(CONNECTION_CONFLICT, self); diff --git a/scripts/node_export/node_export.gml b/scripts/node_export/node_export.gml index 35b86cdfd..d6ce3059b 100644 --- a/scripts/node_export/node_export.gml +++ b/scripts/node_export/node_export.gml @@ -589,7 +589,7 @@ function Node_Export(_x, _y, _group = noone) : Node(_x, _y, _group) constructor PROJECT.animator.rendering = false; export(); - updatedTrigger.setValue(true); + updatedOutTrigger.setValue(true); return; } @@ -702,7 +702,7 @@ function Node_Export(_x, _y, _group = noone) : Node(_x, _y, _group) constructor } } - updatedTrigger.setValue(true); + updatedOutTrigger.setValue(true); } #endregion static doApplyDeserialize = function() { onValueUpdate(3); } diff --git a/scripts/node_group_input/node_group_input.gml b/scripts/node_group_input/node_group_input.gml index 4e998a7da..13ba7b2d2 100644 --- a/scripts/node_group_input/node_group_input.gml +++ b/scripts/node_group_input/node_group_input.gml @@ -3,7 +3,6 @@ function Node_Group_Input(_x, _y, _group = noone) : Node(_x, _y, _group) constru destroy_when_upgroup = true; color = COLORS.node_blend_collection; previewable = false; - auto_height = false; inParent = undefined; @@ -24,13 +23,13 @@ function Node_Group_Input(_x, _y, _group = noone) : Node(_x, _y, _group) constru data_type_list = [ "Integer", "Float", "Boolean", "Color", "Surface", "File Path", "Curve", "Text", "Object", "Node", "3D object", "Any", "Path", "Particle", "Rigidbody Object", - "Fluid Domain", "Struct", "Strands", "Mesh", "Trigger" + "Fluid Domain", "Struct", "Strands", "Mesh", "Trigger", ]; data_type_map = [ VALUE_TYPE.integer, VALUE_TYPE.float, VALUE_TYPE.boolean, VALUE_TYPE.color, VALUE_TYPE.surface, VALUE_TYPE.path, VALUE_TYPE.curve, VALUE_TYPE.text, VALUE_TYPE.object, VALUE_TYPE.node, VALUE_TYPE.d3object, VALUE_TYPE.any, VALUE_TYPE.pathnode, VALUE_TYPE.particle, VALUE_TYPE.rigid, - VALUE_TYPE.fdomain, VALUE_TYPE.struct, VALUE_TYPE.strands, VALUE_TYPE.mesh, VALUE_TYPE.trigger + VALUE_TYPE.fdomain, VALUE_TYPE.struct, VALUE_TYPE.strands, VALUE_TYPE.mesh, VALUE_TYPE.trigger, ]; display_list = [ diff --git a/scripts/node_group_output/node_group_output.gml b/scripts/node_group_output/node_group_output.gml index 9980da28f..5ae44ea03 100644 --- a/scripts/node_group_output/node_group_output.gml +++ b/scripts/node_group_output/node_group_output.gml @@ -3,7 +3,6 @@ function Node_Group_Output(_x, _y, _group = noone) : Node(_x, _y, _group) constr destroy_when_upgroup = true; color = COLORS.node_blend_collection; previewable = false; - auto_height = false; attributes.input_priority = group == noone? 0 : ds_list_size(group.inputs); array_push(attributeEditors, "Group"); diff --git a/scripts/node_group_thumbnail/node_group_input.yy b/scripts/node_group_thumbnail/node_group_input.yy new file mode 100644 index 000000000..b48fa62c4 --- /dev/null +++ b/scripts/node_group_thumbnail/node_group_input.yy @@ -0,0 +1,12 @@ +{ + "isDnD": false, + "isCompatibility": false, + "parent": { + "name": "group", + "path": "folders/nodes/data/group.yy", + }, + "resourceVersion": "1.0", + "name": "node_group_input", + "tags": [], + "resourceType": "GMScript", +} \ No newline at end of file diff --git a/scripts/node_group_thumbnail/node_group_thumbnail.gml b/scripts/node_group_thumbnail/node_group_thumbnail.gml new file mode 100644 index 000000000..dfcffcedf --- /dev/null +++ b/scripts/node_group_thumbnail/node_group_thumbnail.gml @@ -0,0 +1,12 @@ +function Node_Group_Thumbnail(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { + name = "Thumbnail"; + destroy_when_upgroup = true; + color = COLORS.node_blend_collection; + + inputs[| 0] = nodeValue("Input", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone) + .setVisible(true, true); + + static getGraphPreviewSurface = function() { #region + return getInputData(0); + } #endregion +} \ No newline at end of file diff --git a/scripts/__atlas/__atlas.yy b/scripts/node_group_thumbnail/node_group_thumbnail.yy similarity index 56% rename from scripts/__atlas/__atlas.yy rename to scripts/node_group_thumbnail/node_group_thumbnail.yy index 272d5c357..bbed0640d 100644 --- a/scripts/__atlas/__atlas.yy +++ b/scripts/node_group_thumbnail/node_group_thumbnail.yy @@ -1,11 +1,11 @@ { "resourceType": "GMScript", "resourceVersion": "1.0", - "name": "__atlas", + "name": "node_group_thumbnail", "isCompatibility": false, "isDnD": false, "parent": { - "name": "geometry", - "path": "folders/functions/geometry.yy", + "name": "group", + "path": "folders/nodes/data/group.yy", }, } \ No newline at end of file diff --git a/scripts/node_image_splice_sheet/node_image_splice_sheet.gml b/scripts/node_image_splice_sheet/node_image_splice_sheet.gml index 88e387ee0..9d438af4d 100644 --- a/scripts/node_image_splice_sheet/node_image_splice_sheet.gml +++ b/scripts/node_image_splice_sheet/node_image_splice_sheet.gml @@ -77,7 +77,7 @@ function Node_Image_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) constru outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); - outputs[| 1] = nodeValue("Atlas Data", self, JUNCTION_CONNECT.output, VALUE_TYPE.struct, []) + outputs[| 1] = nodeValue("Atlas Data", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []) .setArrayDepth(1); attribute_surface_depth(); @@ -350,12 +350,12 @@ function Node_Image_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) constru } if(!empty) { - array_push(_atl, new spriteAtlasData(_spr_pos[0], _spr_pos[1], ww, hh, _s, array_length(surf_array))); + array_push(_atl, new SurfaceAtlas(_s, _spr_pos[0], _spr_pos[1])); array_push(surf_array, _s); } sprite_valid[i] = !empty; } else { - array_push(_atl, new spriteAtlasData(_spr_pos[0], _spr_pos[1], ww, hh, _s, array_length(surf_array))); + array_push(_atl, new SurfaceAtlas(_s, _spr_pos[0], _spr_pos[1])); array_push(surf_array, _s); sprite_valid[i] = true; } diff --git a/scripts/node_pack_sprites/node_pack_sprites.gml b/scripts/node_pack_sprites/node_pack_sprites.gml index c7c07dc2e..68a321910 100644 --- a/scripts/node_pack_sprites/node_pack_sprites.gml +++ b/scripts/node_pack_sprites/node_pack_sprites.gml @@ -14,7 +14,7 @@ function Node_Pack_Sprites(_x, _y, _group = noone) : Node(_x, _y, _group) constr outputs[| 0] = nodeValue("Packed image", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); - outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.atlas, []); + outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []); input_display_list = [ 0, 4, 1, 2, 3, @@ -29,9 +29,9 @@ function Node_Pack_Sprites(_x, _y, _group = noone) : Node(_x, _y, _group) constr for( var i = 0, n = array_length(rect); i < n; i++ ) { var r = rect[i]; - var _surf = r.surface.get(); - var _sx = r.position[0]; - var _sy = r.position[1]; + var _surf = r.getSurface(); + var _sx = r.x; + var _sy = r.y; if(!is_surface(_surf)) continue; @@ -66,8 +66,9 @@ function Node_Pack_Sprites(_x, _y, _group = noone) : Node(_x, _y, _group) constr var s = _inpt[i]; if(!is_surface(s)) continue; - _rects[i] = new spriteAtlasData(0, 0, surface_get_width_safe(s) + _spac * 2, - surface_get_height_safe(s) + _spac * 2, s, i); + _rects[i] = new SurfaceAtlas(s); + _rects[i].w = surface_get_width_safe(s) + _spac * 2; + _rects[i].h = surface_get_height_safe(s) + _spac * 2; } var pack; @@ -109,7 +110,7 @@ function Node_Pack_Sprites(_x, _y, _group = noone) : Node(_x, _y, _group) constr for( var i = 0, n = array_length(rect); i < n; i++ ) { var r = rect[i]; - array_push(atlas, new SurfaceAtlas(r.surface, [ r.x + _spac, r.y + _spac ])); + array_push(atlas, new SurfaceAtlas(r.surface, r.x + _spac, r.y + _spac)); draw_surface_safe(r.surface, r.x + _spac, r.y + _spac); } diff --git a/scripts/node_processor/node_processor.gml b/scripts/node_processor/node_processor.gml index 469583317..28047cc1c 100644 --- a/scripts/node_processor/node_processor.gml +++ b/scripts/node_processor/node_processor.gml @@ -16,7 +16,10 @@ function Node_Processor(_x, _y, _group = noone) : Node(_x, _y, _group) construct process_amount = 0; process_length = []; - dimension_index = 0; + dimension_index = 0; + + manage_atlas = true; + atlas_index = 0; batch_output = false; //Run processData once with all outputs as array. @@ -73,16 +76,27 @@ function Node_Processor(_x, _y, _group = noone) : Node(_x, _y, _group) construct static processDataArray = function(outIndex) { #region var _output = outputs[| outIndex]; var _out = _output.getValue(); + var _atlas = false; + var _pAtl = noone; + var _data = array_create(ds_list_size(inputs)); if(process_amount == 1) { #region render single data if(_output.type == VALUE_TYPE.d3object) //passing 3D vertex call return _out; - if(_output.type == VALUE_TYPE.surface) { //resize surface - if(dimension_index == -1) - surface_array_free(_out); - else { - var surf = inputs_data[dimension_index]; + for(var i = 0; i < ds_list_size(inputs); i++) + _data[i] = inputs_data[i]; + + if(_output.type == VALUE_TYPE.surface) { // Surface preparation + if(manage_atlas) { + _pAtl = _data[atlas_index]; + _atlas = is_instanceof(_pAtl, SurfaceAtlas); + + if(_atlas) _data[atlas_index] = _pAtl.getSurface(); + } + + if(dimension_index > -1) { + var surf = _data[dimension_index]; var _sw = 1, _sh = 1; if(inputs[| dimension_index].type == VALUE_TYPE.surface) { if(is_surface(surf)) { @@ -95,20 +109,31 @@ function Node_Processor(_x, _y, _group = noone) : Node(_x, _y, _group) construct _sh = array_safe_get(surf, 1, 1); } - _out = surface_verify(_out, _sw, _sh, attrDepth()); + if(manage_atlas && is_instanceof(_out, SurfaceAtlas)) { + surface_free_safe(_out.getSurface()) + _out = surface_verify(_out.getSurface(), _sw, _sh, attrDepth()); + } else + _out = surface_verify(_out, _sw, _sh, attrDepth()); } } - current_data = inputs_data; + current_data = _data; - if(active_index > -1 && !inputs_data[active_index]) { // skip + if(active_index > -1 && !_data[active_index]) { // skip if(inputs[| 0].type == VALUE_TYPE.surface) - return surface_clone(inputs_data[0], _out); + return surface_clone(_data[0], _out); else - return inputs_data[0] + return _data[0]; + } + + var data = processData(_out, _data, outIndex, 0); // Process data + + if(manage_atlas && _atlas && is_surface(data)) { // Convert back to atlas + var _atl = _pAtl.clone(); + _atl.setSurface(data); + return _atl; } - var data = processData(_out, inputs_data, outIndex, 0); /// Process data return data; } #endregion @@ -119,39 +144,57 @@ function Node_Processor(_x, _y, _group = noone) : Node(_x, _y, _group) construct array_resize(_out, process_amount); #endregion - var _data = array_create(ds_list_size(inputs)); - for(var l = 0; l < process_amount; l++) { for(var i = 0; i < ds_list_size(inputs); i++) _data[i] = all_inputs[i][l]; - if(_output.type == VALUE_TYPE.surface && dimension_index > -1) { #region output surface verification - var surf = _data[dimension_index]; - var _sw = 1, _sh = 1; - if(inputs[| dimension_index].type == VALUE_TYPE.surface) { - if(is_surface(surf)) { - _sw = surface_get_width_safe(surf); - _sh = surface_get_height_safe(surf); - } else - return noone; - } else if(is_array(surf)) { - _sw = surf[0]; - _sh = surf[1]; + if(_output.type == VALUE_TYPE.surface) { #region // Output surface verification + if(manage_atlas) { + _pAtl = _data[atlas_index]; + _atlas = is_instanceof(_pAtl, SurfaceAtlas); + + if(_atlas) _data[atlas_index] = _pAtl.getSurface(); } - _out[l] = surface_verify(_out[l], _sw, _sh, attrDepth()); + if(dimension_index > -1) { + var surf = _data[dimension_index]; + var _sw = 1, _sh = 1; + if(inputs[| dimension_index].type == VALUE_TYPE.surface) { + if(is_surface(surf)) { + _sw = surface_get_width_safe(surf); + _sh = surface_get_height_safe(surf); + } else + return noone; + } else if(is_array(surf)) { + _sw = surf[0]; + _sh = surf[1]; + } + + if(manage_atlas && is_instanceof(_out[l], SurfaceAtlas)) { + surface_free_safe(_out[l].surface.surface) + _out[l] = surface_verify(_out[l].getSurface(), _sw, _sh, attrDepth()); + } else + _out[l] = surface_verify(_out[l], _sw, _sh, attrDepth()); + } } #endregion if(l == 0 || l == preview_index) current_data = _data; if(active_index > -1 && !_data[active_index]) { // skip - if(inputs[| 0].type == VALUE_TYPE.surface) + if(!_atlas && inputs[| 0].type == VALUE_TYPE.surface) _out[l] = surface_clone(_data[0], _out[l]); else _out[l] = _data[0]; - } else - _out[l] = processData(_out[l], _data, outIndex, l); /// Process data + } else { + _out[l] = processData(_out[l], _data, outIndex, l); // Process data + + if(manage_atlas && _atlas && is_surface(_out[l])) { // Convert back to atlas + var _atl = _pAtl.clone(); + _atl.setSurface(_out[l]); + _out[l] = _atl; + } + } } return _out; diff --git a/scripts/node_registry/node_registry.gml b/scripts/node_registry/node_registry.gml index 8444752bf..1036f6fa7 100644 --- a/scripts/node_registry/node_registry.gml +++ b/scripts/node_registry/node_registry.gml @@ -108,15 +108,17 @@ function NodeObject(_name, _spr, _node, _create, tags = []) constructor { #regio var group = ds_list_create(); addNodeCatagory("Group", group, ["Node_Group"]); #region ds_list_add(group, "Groups"); - addNodeObject(group, "Input", s_node_group_input, "Node_Group_Input", [1, Node_Group_Input]); - addNodeObject(group, "Output", s_node_group_output,"Node_Group_Output", [1, Node_Group_Output]); + addNodeObject(group, "Input", s_node_group_input, "Node_Group_Input", [1, Node_Group_Input]); + addNodeObject(group, "Output", s_node_group_output, "Node_Group_Output", [1, Node_Group_Output]); + addNodeObject(group, "Thumbnail", s_node_group_thumbnail, "Node_Group_Thumbnail", [1, Node_Group_Thumbnail]); #endregion var iter = ds_list_create(); #region addNodeCatagory("Loop", iter, ["Node_Iterate"]); ds_list_add(iter, "Groups"); - addNodeObject(iter, "Input", s_node_loop_input, "Node_Iterator_Input", [1, Node_Iterator_Input]); - addNodeObject(iter, "Output", s_node_loop_output, "Node_Iterator_Output", [1, Node_Iterator_Output]); + addNodeObject(iter, "Input", s_node_loop_input, "Node_Iterator_Input", [1, Node_Iterator_Input]); + addNodeObject(iter, "Output", s_node_loop_output, "Node_Iterator_Output", [1, Node_Iterator_Output]); + addNodeObject(iter, "Thumbnail", s_node_group_thumbnail, "Node_Group_Thumbnail", [1, Node_Group_Thumbnail]); ds_list_add(iter, "Loops"); addNodeObject(iter, "Index", s_node_iterator_index, "Node_Iterator_Index", [1, Node_Iterator_Index]); @@ -126,8 +128,9 @@ function NodeObject(_name, _spr, _node, _create, tags = []) constructor { #regio var itere = ds_list_create(); #region addNodeCatagory("Loop", itere, ["Node_Iterate_Each"]); ds_list_add(itere, "Groups"); - addNodeObject(itere, "Input", s_node_group_input, "Node_Group_Input", [1, Node_Group_Input]); - addNodeObject(itere, "Output", s_node_group_output, "Node_Group_Output", [1, Node_Group_Output]); + addNodeObject(itere, "Input", s_node_group_input, "Node_Group_Input", [1, Node_Group_Input]); + addNodeObject(itere, "Output", s_node_group_output, "Node_Group_Output", [1, Node_Group_Output]); + addNodeObject(itere, "Thumbnail", s_node_group_thumbnail, "Node_Group_Thumbnail", [1, Node_Group_Thumbnail]); ds_list_add(itere, "Loops"); addNodeObject(itere, "Index", s_node_iterator_index, "Node_Iterator_Index", [1, Node_Iterator_Index]); @@ -137,8 +140,9 @@ function NodeObject(_name, _spr, _node, _create, tags = []) constructor { #regio var filter = ds_list_create(); #region addNodeCatagory("Filter", filter, ["Node_Iterate_Filter"]); ds_list_add(filter, "Groups"); - addNodeObject(filter, "Input", s_node_group_input, "Node_Group_Input", [1, Node_Group_Input]); - addNodeObject(filter, "Output", s_node_group_output, "Node_Group_Output", [1, Node_Group_Output]); + addNodeObject(filter, "Input", s_node_group_input, "Node_Group_Input", [1, Node_Group_Input]); + addNodeObject(filter, "Output", s_node_group_output, "Node_Group_Output", [1, Node_Group_Output]); + addNodeObject(filter, "Thumbnail", s_node_group_thumbnail, "Node_Group_Thumbnail", [1, Node_Group_Thumbnail]); ds_list_add(filter, "Loops"); addNodeObject(filter, "Index", s_node_iterator_index, "Node_Iterator_Index", [1, Node_Iterator_Index]); @@ -148,8 +152,9 @@ function NodeObject(_name, _spr, _node, _create, tags = []) constructor { #regio var feed = ds_list_create(); #region addNodeCatagory("Feedback", feed, ["Node_Feedback"]); ds_list_add(feed, "Groups"); - addNodeObject(feed, "Input", s_node_feedback_input, "Node_Feedback_Input", [1, Node_Feedback_Input]); - addNodeObject(feed, "Output", s_node_feedback_output, "Node_Feedback_Output", [1, Node_Feedback_Output]); + addNodeObject(feed, "Input", s_node_feedback_input, "Node_Feedback_Input", [1, Node_Feedback_Input]); + addNodeObject(feed, "Output", s_node_feedback_output, "Node_Feedback_Output", [1, Node_Feedback_Output]); + addNodeObject(feed, "Thumbnail", s_node_group_thumbnail, "Node_Group_Thumbnail", [1, Node_Group_Thumbnail]); #endregion var vfx = ds_list_create(); #region diff --git a/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml b/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml index ddd386563..80edf0eb1 100644 --- a/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml +++ b/scripts/node_render_sprite_sheet/node_render_sprite_sheet.gml @@ -43,7 +43,7 @@ function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); - outputs[| 1] = nodeValue("Atlas Data", self, JUNCTION_CONNECT.output, VALUE_TYPE.atlas, []) + outputs[| 1] = nodeValue("Atlas Data", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []) .setArrayDepth(1); refreshSurface = false; @@ -204,7 +204,7 @@ function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) case 2 : _sy = py + (hh - _h); break; } - _atl[i] = array_push_create(_atl[i], new SurfaceAtlas(inpt[i], [_sx, _sy])); + _atl[i] = array_push_create(_atl[i], new SurfaceAtlas(inpt[i], _sx, _sy)); draw_surface_safe(inpt[i], _sx, _sy); break; @@ -218,7 +218,7 @@ function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) case 2 : _sx = px + (ww - _w); break; } - _atl[i] = array_push_create(_atl[i], new SurfaceAtlas(inpt[i], [_sx, _sy])); + _atl[i] = array_push_create(_atl[i], new SurfaceAtlas(inpt[i], _sx, _sy)); draw_surface_safe(inpt[i], _sx, _sy); break; @@ -230,7 +230,7 @@ function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) px = padd[2] + _col * _w + max(0, _col) * spac; py = padd[1] + _row * _h + max(0, _row) * spac; - _atl[i] = array_push_create(_atl[i], new SurfaceAtlas(inpt[i], [px, py])); + _atl[i] = array_push_create(_atl[i], new SurfaceAtlas(inpt[i], px, py)); draw_surface_safe(inpt[i], px, py); break; } @@ -364,7 +364,7 @@ function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) case 2 : _sy = py + (hh - _h); break; } - array_push(_atl, new SurfaceAtlas(inpt[i], [_sx, _sy])); + array_push(_atl, new SurfaceAtlas(inpt[i], _sx, _sy)); draw_surface_safe(inpt[i], _sx, _sy); px += _w + spac; @@ -384,7 +384,7 @@ function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) case 2 : _sx = px + (ww - _w); break; } - array_push(_atl, new SurfaceAtlas(inpt[i], [_sx, _sy])); + array_push(_atl, new SurfaceAtlas(inpt[i], _sx, _sy)); draw_surface_safe(inpt[i], _sx, _sy); py += _h + spac; @@ -412,7 +412,7 @@ function Node_Render_Sprite_Sheet(_x, _y, _group = noone) : Node(_x, _y, _group) var _w = surface_get_width_safe(inpt[index]); var _h = surface_get_height_safe(inpt[index]); - array_push(_atl, new SurfaceAtlas(inpt[index], [px, py])); + array_push(_atl, new SurfaceAtlas(inpt[index], px, py)); draw_surface_safe(inpt[index], px, py); px += _w + spac; diff --git a/scripts/node_rigid_object/node_rigid_object.gml b/scripts/node_rigid_object/node_rigid_object.gml index 0c4f3b2a2..baf813ca2 100644 --- a/scripts/node_rigid_object/node_rigid_object.gml +++ b/scripts/node_rigid_object/node_rigid_object.gml @@ -30,33 +30,31 @@ function Node_Rigid_Object(_x, _y, _group = noone) : Node(_x, _y, _group) constr inputs[| 6] = nodeValue("Texture", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone); - inputs[| 7] = nodeValue("Start shape", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 16, 16, 4, 4, AREA_SHAPE.rectangle ]) - .setDisplay(VALUE_DISPLAY.area); - inputs[| 7].editWidget.adjust_shape = false; + inputs[| 7] = nodeValue("Start position", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 16, 16 ]) + .setDisplay(VALUE_DISPLAY.vector); inputs[| 8] = nodeValue("Spawn", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true, "Make object spawn when start.") .rejectArray(); inputs[| 9] = nodeValue("Generate mesh", self, JUNCTION_CONNECT.input, VALUE_TYPE.trigger, 0) - .setDisplay(VALUE_DISPLAY.button, { name: "Generate", onClick: function() { - var _tex = getInputData(6); - if(is_array(_tex)) { - for( var i = 0, n = array_length(_tex); i < n; i++ ) - generateMesh(i); - } else - generateMesh(); - doUpdate(); - } }); + .setDisplay(VALUE_DISPLAY.button, { name: "Generate", onClick: function() { generateAllMesh(); } }); inputs[| 10] = nodeValue("Mesh expansion", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0) + .setDisplay(VALUE_DISPLAY.slider, { range: [ -2, 2, 0.1 ] }) .rejectArray(); + inputs[| 11] = nodeValue("Texture type", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0) + .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Surface", "Atlas" ]) + .rejectArray(); + + inputs[| 12] = nodeValue("Atlas", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, []); + outputs[| 0] = nodeValue("Object", self, JUNCTION_CONNECT.output, VALUE_TYPE.rigid, self); input_display_list = [ 8, - ["Texture", false], 6, + ["Texture", false], 11, 6, 12, ["Physical", false], 0, 1, 2, 3, 4, - ["Shape", false], 5, 9, 10, 7, + ["Shape", false], 7, 5, 9, 10, ]; static newMesh = function(index) { @@ -74,7 +72,22 @@ function Node_Rigid_Object(_x, _y, _group = noone) : Node(_x, _y, _group) constr new NodeTool( "Anchor remove", THEME.mesh_tool_delete ), ]; - static getPreviewValues = function() { return getInputData(6); } + static getPreviewValues = function() { + var _typ = getInputData(11); + return _typ? getInputData(12) : getInputData(6); + } + + static generateAllMesh = function() { + var _typ = getInputData(11); + var _tex = _typ? getInputData(12) : getInputData(6); + + if(is_array(_tex)) { + for( var i = 0, n = array_length(_tex); i < n; i++ ) + generateMesh(i); + } else + generateMesh(); + doUpdate(); + } is_convex = true; hover = -1; @@ -84,71 +97,95 @@ function Node_Rigid_Object(_x, _y, _group = noone) : Node(_x, _y, _group) constr anchor_drag_mx = -1; anchor_drag_my = -1; - static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) { - var _shp = getInputData(5); - var _box = getInputData(7); - + static drawOverlayPreview = function(_i, _x, _y, _s, _pr_x, _pr_y, _atl_s, _tex_s) { #region var meshes = attributes.mesh; - if(preview_index >= array_length(meshes)) return; + var _shp = getInputData(5); + var _typ = getInputData(11); + + var ww = max(1, surface_get_width_safe(_tex_s)); + var hh = max(1, surface_get_height_safe(_tex_s)); + + if(_typ == 0) { + _pr_x -= ww * _s / 2; + _pr_y -= hh * _s / 2; + } else if(_typ == 1) { + _pr_x += _atl_s.x * _s; + _pr_y += _atl_s.y * _s; + } + + if(_shp == 2 && array_length(meshes) > _i) { + draw_set_color(is_convex? COLORS._main_accent : COLORS._main_value_negative); + + var _m = meshes[_i]; + var _l = array_length(_m); + + for( var i = 0; i < _l; i++ ) { + var _px0 = _m[i][0]; + var _py0 = _m[i][1]; + var _px1 = _m[safe_mod(i + 1, _l)][0]; + var _py1 = _m[safe_mod(i + 1, _l)][1]; + + _px0 = _pr_x + _px0 * _s; + _py0 = _pr_y + _py0 * _s; + _px1 = _pr_x + _px1 * _s; + _py1 = _pr_y + _py1 * _s; + + draw_line_width(_px0, _py0, _px1, _py1, 1); + } + } + + draw_surface_ext_safe(_tex_s, _pr_x, _pr_y, _s, _s, 0, c_white, 0.5); + } #endregion + + static drawOverlay = function(active, _x, _y, _s, _mx, _my, _snx, _sny) { #region + var _shp = getInputData(5); + var _pos = getInputData(7); + var _typ = getInputData(11); + + var _typ = getInputData(11); + var _atl = getInputData(12); + var _tex = getInputData(6); + + var _atl_s = _atl; + var _tex_s = _tex; + + var _isArr = false; + + if(_typ == 0) { + if(is_array(_tex)) { + _tex_s = array_safe_get(_tex, preview_index); + _isArr = true; + } + } else if(_typ == 1) { + if(is_array(_atl)) { + _atl_s = array_safe_get(_atl, preview_index); + _isArr = true; + } + if(_atl_s == 0) return; + _tex_s = _atl_s.getSurface(); + } if(previewing == 0) { - if(_shp == 2) { - var _tex = getInputData(6); - if(is_array(_tex)) _tex = _tex[safe_mod(preview_index, array_length(_tex))]; - var tw = surface_get_width_safe(_tex); - var th = surface_get_height_safe(_tex); - - draw_set_color(is_convex? COLORS._main_accent : COLORS._main_value_negative); - - for( var j = 0; j < array_length(meshes); j++ ) { - var _m = meshes[j]; - var _l = array_length(_m); - - for( var i = 0; i < _l; i++ ) { - var _px0 = _m[i][0]; - var _py0 = _m[i][1]; - var _px1 = _m[safe_mod(i + 1, _l)][0]; - var _py1 = _m[safe_mod(i + 1, _l)][1]; - - _px0 = (_px0 / tw) * 2 - 1; - _py0 = (_py0 / th) * 2 - 1; - _px1 = (_px1 / tw) * 2 - 1; - _py1 = (_py1 / th) * 2 - 1; - - _px0 = _box[0] + (_box[2]) * _px0; - _py0 = _box[1] + (_box[3]) * _py0; - _px1 = _box[0] + (_box[2]) * _px1; - _py1 = _box[1] + (_box[3]) * _py1; - - var _dx0 = _x + _px0 * _s; - var _dy0 = _y + _py0 * _s; - var _dx1 = _x + _px1 * _s; - var _dy1 = _y + _py1 * _s; + var _pr_x = _x + _pos[0] * _s; + var _pr_y = _y + _pos[1] * _s; - draw_line_width(_dx0, _dy0, _dx1, _dy1, 1); - } + if(_isArr) { + if(_typ == 0) { + for( var i = 0, n = array_length(_tex); i < n; i++ ) + drawOverlayPreview(i, _x, _y, _s, _pr_x, _pr_y, noone, _tex[i]); + } else { + for( var i = 0, n = array_length(_atl); i < n; i++ ) + drawOverlayPreview(i, _x, _y, _s, _pr_x, _pr_y, _atl[i], _atl[i].getSurface()); } - - draw_set_color(COLORS._main_accent); - var x0 = _box[0] - _box[2]; - var x1 = _box[0] + _box[2]; - var y0 = _box[1] - _box[3]; - var y1 = _box[1] + _box[3]; - - x0 = _x + x0 * _s; - x1 = _x + x1 * _s; - y0 = _y + y0 * _s; - y1 = _y + y1 * _s; - - draw_rectangle(x0, y0, x1, y1, true); - } - + } else + drawOverlayPreview(0, _x, _y, _s, _pr_x, _pr_y, _atl, _tex); inputs[| 7].drawOverlay(active, _x, _y, _s, _mx, _my, _snx, _sny); return; } if(_shp != 2) return; + var meshes = attributes.mesh; var _hover = -1, _side = 0; draw_set_color(is_convex? COLORS._main_accent : COLORS._main_value_negative); @@ -245,15 +282,20 @@ function Node_Rigid_Object(_x, _y, _group = noone) : Node(_x, _y, _group) constr anchor_drag_my = _my; } } - } + } #endregion - static generateMesh = function(index = 0) { + static generateMesh = function(index = 0) { #region var _tex = getInputData(6); var _exp = getInputData(10); + var _typ = getInputData(11); + var _atl = getInputData(12); - if(is_array(_tex)) { - index = safe_mod(index, array_length(_tex)); - _tex = _tex[index]; + if(_typ == 0) { + if(is_array(_tex)) _tex = array_safe_get(_tex, index); + } else if(_typ == 1) { + if(is_array(_atl)) _atl = array_safe_get(_atl, index); + if(_atl == 0) return; + _tex = _atl.getSurface(); } if(!is_surface(_tex)) return; @@ -367,9 +409,9 @@ function Node_Rigid_Object(_x, _y, _group = noone) : Node(_x, _y, _group) constr meshes[index] = mesh; attributes.mesh = meshes; - } + } #endregion - static removeColinear = function(mesh) { + static removeColinear = function(mesh) { #region var len = array_length(mesh), _side = 0; var remSt = []; var tolerance = 5; @@ -396,9 +438,9 @@ function Node_Rigid_Object(_x, _y, _group = noone) : Node(_x, _y, _group) constr } return mesh; - } + } #endregion - static removeConcave = function(mesh) { + static removeConcave = function(mesh) { #region var len = array_length(mesh); if(len <= 3) return; @@ -463,26 +505,15 @@ function Node_Rigid_Object(_x, _y, _group = noone) : Node(_x, _y, _group) constr } return mesh; - } + } #endregion - static onValueUpdate = function(index = 0) { - if(index == 5) { - var _spos = getInputData(7); - var _shape = getInputData(5); - _spos[4] = _shape; - inputs[| 7].setValue(_spos); - } - } - - static fixtureCreate = function(fixture, object) { + static fixtureCreate = function(fixture, object, dx = 0, dy = 0) { #region var _mov = getInputData(0); var _den = getInputData(1); var _cnt_frc = getInputData(2); var _air_frc = getInputData(3); var _rot_frc = getInputData(4); - var _spos = getInputData(7); - if(!_mov) { physics_fixture_set_kinematic(fixture); _den = 0; @@ -496,32 +527,41 @@ function Node_Rigid_Object(_x, _y, _group = noone) : Node(_x, _y, _group) constr if(group != noone) physics_fixture_set_collision_group(fixture, group.collIndex); - array_push(object.fixture, physics_fixture_bind_ext(fixture, object, _spos[2], _spos[3])); + array_push(object.fixture, physics_fixture_bind_ext(fixture, object, dx, dy)); physics_fixture_delete(fixture); - } + } #endregion - static spawn = function(rpos = noone, index = 0, object = noone) { - var _shp = getInputData(5); - var _tex = getInputData(6); + static spawn = function(index = 0, object = noone) { #region + var _shp = getInputData(5); + var _tex = getInputData(6); + var _typ = getInputData(11); + var _atl = getInputData(12); - if(is_array(_tex)) { - index = safe_mod(index, array_length(_tex)); - _tex = _tex[index]; - } else - index = 0; + if(_typ == 0 && is_array(_tex)) { index = safe_mod(index, array_length(_tex)); _tex = array_safe_get(_tex, index); } + if(_typ == 1 && is_array(_atl)) { index = safe_mod(index, array_length(_atl)); _atl = array_safe_get(_atl, index); } + if(_typ == 1) { + if(_atl == 0) return; + _tex = _atl.getSurface(); + } var _spos = getInputData(7); var ww = max(1, surface_get_width_safe(_tex)); var hh = max(1, surface_get_height_safe(_tex)); + var sw = ww, sh = hh; - var ox = rpos == noone? _spos[0] : rpos[0]; - var oy = rpos == noone? _spos[1] : rpos[1]; + var ox = _spos[0]; + var oy = _spos[1]; + + if(_typ == 1) { + ox += _atl.x; + oy += _atl.y; + sw = 0; + sh = 0; + } if(object == noone) { - object = instance_create_depth(ox - _spos[2], oy - _spos[3], 0, oRigidbody); - object.xscale = _spos[2] / ww * 2; - object.yscale = _spos[3] / hh * 2; + object = instance_create_depth(ox - sw / 2, oy - sh / 2, 0, oRigidbody); object.surface = _tex; } else if(instance_exists(object)) { for( var i = 0, n = array_length(object.fixture); i < n; i++ ) @@ -532,12 +572,17 @@ function Node_Rigid_Object(_x, _y, _group = noone) : Node(_x, _y, _group) constr if(_shp == 0) { var fixture = physics_fixture_create(); - physics_fixture_set_box_shape(fixture, _spos[2], _spos[3]); - fixtureCreate(fixture, object); + + physics_fixture_set_box_shape(fixture, ww / 2, hh / 2); + + fixtureCreate(fixture, object, ww / 2, hh / 2); } else if(_shp == 1) { var fixture = physics_fixture_create(); - physics_fixture_set_circle_shape(fixture, min(_spos[2], _spos[3])); - fixtureCreate(fixture, object); + var rr = min(ww, hh) / 2; + + physics_fixture_set_circle_shape(fixture, rr); + + fixtureCreate(fixture, object, rr, rr); } else if(_shp == 2) { var meshes = attributes.mesh; if(array_safe_get(meshes, index, noone) == noone) @@ -569,17 +614,8 @@ function Node_Rigid_Object(_x, _y, _group = noone) : Node(_x, _y, _group) constr cx /= len; cy /= len; - cmx = cx; - cmy = cy; - - cx = (cx / ww) * 2 - 1; - cy = (cy / hh) * 2 - 1; - - cx = _spos[2] * cx; - cy = _spos[3] * cy; - if(!is_convex) return object; - if(len < 3) return object; + if(len < 3) return object; if(len <= 8) { var fixture = physics_fixture_create(); @@ -589,16 +625,10 @@ function Node_Rigid_Object(_x, _y, _group = noone) : Node(_x, _y, _group) constr var _px0 = mesh[i][0]; var _py0 = mesh[i][1]; - _px0 = (_px0 / ww) * 2 - 1; - _py0 = (_py0 / hh) * 2 - 1; - - _px0 = _spos[2] * _px0; - _py0 = _spos[3] * _py0; - - physics_fixture_add_point(fixture, round(_px0), round(_py0)); + physics_fixture_add_point(fixture, _px0, _py0); } - fixtureCreate(fixture, object); + fixtureCreate(fixture, object, -1, -1); } else { for( var i = 0; i < len; i++ ) { var fixture = physics_fixture_create(); @@ -608,43 +638,30 @@ function Node_Rigid_Object(_x, _y, _group = noone) : Node(_x, _y, _group) constr var _py0 = mesh[safe_mod(i + 0, len)][1]; var _px1 = mesh[safe_mod(i + 1, len)][0]; var _py1 = mesh[safe_mod(i + 1, len)][1]; - - _px0 = (_px0 / ww) * 2 - 1; - _py0 = (_py0 / hh) * 2 - 1; - _px1 = (_px1 / ww) * 2 - 1; - _py1 = (_py1 / hh) * 2 - 1; - _px0 = _spos[2] * _px0; - _py0 = _spos[3] * _py0; - _px1 = _spos[2] * _px1; - _py1 = _spos[3] * _py1; - - var d0 = point_direction(cx, cy, _px0, _py0); - var d1 = point_direction(cx, cy, _px1, _py1); - physics_fixture_add_point(fixture, cx, cy); physics_fixture_add_point(fixture, _px0, _py0); physics_fixture_add_point(fixture, _px1, _py1); - fixtureCreate(fixture, object); + fixtureCreate(fixture, object, -1, -1); } } - - //with(object) physics_mass_properties(phy_mass, cmx, cmy, phy_inertia); } return object; - } + } #endregion - static update = function(frame = PROJECT.animator.current_frame) { - if(!isAnimated()) return; - - //for( var i = 0, n = array_length(object); i < n; i++ ) - // spawn(noone, i, object[i]); - } + static update = function(frame = PROJECT.animator.current_frame) { #region + // + } #endregion - static step = function() { + static step = function() { #region var _shp = getInputData(5); + var _tex = getInputData(11); + + inputs[| 6].setVisible(_tex == 0, _tex == 0); + inputs[| 12].setVisible(_tex == 1, _tex == 1); + inputs[| 9].setVisible(_shp == 2); var _tex = getInputData(6); @@ -655,10 +672,12 @@ function Node_Rigid_Object(_x, _y, _group = noone) : Node(_x, _y, _group) constr for( var i = array_length(meshes); i < array_length(_tex); i++ ) newMesh(i); } - } + } #endregion - static reset = function() { - var _tex = getInputData(6); + static reset = function() { #region + var _typ = getInputData(11); + var _tex = _typ? getInputData(12) : getInputData(6); + for( var i = 0, n = array_length(object); i < n; i++ ) { if(instance_exists(object[i])) instance_destroy(object[i]); @@ -670,31 +689,35 @@ function Node_Rigid_Object(_x, _y, _group = noone) : Node(_x, _y, _group) constr if(is_array(_tex)) { for( var i = 0, n = array_length(_tex); i < n; i++ ) - object[i] = spawn(noone, i); + object[i] = spawn(i); } else object = [ spawn() ]; - } + } #endregion - static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { + static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { #region var bbox = drawGetBbox(xx, yy, _s); - var _tex = getInputData(6); - if(is_array(_tex) && array_length(_tex)) _tex = _tex[0]; - var _spos = getInputData(7); + var _typ = getInputData(11); + var _tex = _typ? getInputData(12) : getInputData(6); - draw_surface_stretch_fit(_tex, bbox.xc, bbox.yc, bbox.w, bbox.h, _spos[2], _spos[3]); - } + if(is_array(_tex)) { + if(array_empty(_tex)) return; + _tex = _tex[0]; + } + + draw_surface_bbox(_typ? _tex.getSurface() : _tex, bbox); + } #endregion - static attributeSerialize = function() { + static attributeSerialize = function() { #region var att = {}; var mesh = struct_try_get(attributes, "mesh", []); att.mesh = json_stringify(mesh); return att; - } + } #endregion - static attributeDeserialize = function(attr) { + static attributeDeserialize = function(attr) { #region if(struct_has(attr, "mesh")) attributes.mesh = json_parse(attr.mesh); - } + } #endregion } \ No newline at end of file diff --git a/scripts/node_rigid_render/node_rigid_render.gml b/scripts/node_rigid_render/node_rigid_render.gml index a99254a70..92f4ce3e0 100644 --- a/scripts/node_rigid_render/node_rigid_render.gml +++ b/scripts/node_rigid_render/node_rigid_render.gml @@ -1,8 +1,10 @@ function Node_Rigid_Render(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { - name = "Render"; + name = "Render"; color = COLORS.node_blend_simulation; icon = THEME.rigidSim; + use_cache = CACHE_USE.auto; + update_on_frame = true; inputs[| 0] = nodeValue("Render dimension", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, DEF_SURF) .setDisplay(VALUE_DISPLAY.vector) diff --git a/scripts/node_scatter/node_scatter.gml b/scripts/node_scatter/node_scatter.gml index 59ec8e024..6bbac6237 100644 --- a/scripts/node_scatter/node_scatter.gml +++ b/scripts/node_scatter/node_scatter.gml @@ -66,7 +66,7 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); - outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.atlas, []) + outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []) .rejectArrayProcess(); input_display_list = [ @@ -261,7 +261,7 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c var clr = color.eval(grSamp); var alp = random_range_seed(alpha[0], alpha[1], posS); posS++; - array_push(scatter_data, new SurfaceAtlas(surf, [ _x, _y ], _r, [ _scx, _scy ], clr, alp)); + array_push(scatter_data, new SurfaceAtlas(surf, _x, _y, _r, _scx, _scy, clr, alp)); draw_surface_ext_safe(surf, _x, _y, _scx, _scy, _r, clr, alp); if(_dist == 5) { diff --git a/scripts/node_seperate_shapes/node_seperate_shapes.gml b/scripts/node_seperate_shapes/node_seperate_shapes.gml index 98081076a..7f914fdca 100644 --- a/scripts/node_seperate_shapes/node_seperate_shapes.gml +++ b/scripts/node_seperate_shapes/node_seperate_shapes.gml @@ -20,7 +20,7 @@ function Node_Seperate_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) cons outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); - outputs[| 1] = nodeValue("Atlas", self, JUNCTION_CONNECT.output, VALUE_TYPE.atlas, []); + outputs[| 1] = nodeValue("Atlas", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []); input_display_list = [ ["Shape", false], 0, 1, 4, @@ -28,7 +28,6 @@ function Node_Seperate_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) cons ] attribute_surface_depth(); - attribute_auto_execute(true); temp_surface = [ surface_create(1, 1), surface_create(1, 1) ]; surface_buffer = buffer_create(1 * 1 * 4, buffer_fixed, 2); @@ -53,8 +52,7 @@ function Node_Seperate_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) cons static onInspector1Update = function() { separateShape(); } static update = function() { - if(attributes.auto_exe) - separateShape(); + separateShape(); } static separateShape = function() { @@ -127,52 +125,52 @@ function Node_Seperate_Shape(_x, _y, _group = noone) : Node(_x, _y, _group) cons outputs[| 0].setValue(_val); var _atlas = array_create(px); + var _pad = 0; buffer_delete(surface_buffer); surface_buffer = buffer_create(ww * hh * 4, buffer_fixed, 2); buffer_get_surface(surface_buffer, temp_surface[res_index], 0); for(var i = 0; i < px; i++) { - _outSurf = surface_create_valid(ww, hh); + var ccx = surface_get_pixel_ext(_pixel_surface, 1 + i, 0); + var alpha = (ccx >> 24) & 255; + var blue = (ccx >> 16) & 255; + var green = (ccx >> 8) & 255; + var red = ccx & 255; + + var min_x = floor(red / 255 * ww); + var min_y = floor(green / 255 * hh); + var max_x = ceil(blue / 255 * ww); + var max_y = ceil(alpha / 255 * hh); + var t = max_y; + var b = min_y; + var l = max_x; + var r = min_x; + + for( var j = min_x; j < max_x; j++ ) + for( var k = min_y; k < max_y; k++ ) { + var _sc = get_color_buffer(j, k); + if(_sc != ccx) continue; + + t = min(t, k); + b = max(b, k); + l = min(l, j); + r = max(r, j); + } + + _outSurf = surface_create_valid(r - l + 1 + _pad * 2, b - t + 1 + _pad * 2); _val[i] = _outSurf; surface_set_shader(_outSurf, sh_seperate_shape_sep); - var ccx = surface_get_pixel_ext(_pixel_surface, 1 + i, 0); - var alpha = (ccx >> 24) & 255; - var blue = (ccx >> 16) & 255; - var green = (ccx >> 8) & 255; - var red = ccx & 255; - - var min_x = floor(red / 255 * ww); - var min_y = floor(green / 255 * hh); - var max_x = ceil(blue / 255 * ww); - var max_y = ceil(alpha / 255 * hh); - var t = max_y; - var b = min_y; - var l = max_x; - var r = min_x; - - for( var j = min_x; j < max_x; j++ ) - for( var k = min_y; k < max_y; k++ ) { - var _sc = get_color_buffer(j, k); - if(_sc != ccx) continue; - - t = min(t, k); - b = max(b, k); - l = min(l, j); - r = max(r, j); - } - - _atlas[i] = [l, t, r, b]; - //_atlas[i] = new SurfaceAtlas(_outSurf, [ r.x + _spac, r.y + _spac ]); - shader_set_surface("original", _inSurf); shader_set_f("color", red, green, blue, alpha); shader_set_i("override", _ovr); shader_set_f("overColor", colToVec4(_ovrclr)); - draw_surface_safe(temp_surface[res_index], 0, 0); + draw_surface_safe(temp_surface[res_index], -l + _pad, -t + _pad); surface_reset_shader(); + + _atlas[i] = new SurfaceAtlas(_outSurf, l, t).setOrginalSurface(_inSurf); } outputs[| 1].setValue(_atlas); diff --git a/scripts/node_seperate_shapes/node_seperate_shapes.yy b/scripts/node_seperate_shapes/node_seperate_shapes.yy index 4b7e2f574..ab50a4011 100644 --- a/scripts/node_seperate_shapes/node_seperate_shapes.yy +++ b/scripts/node_seperate_shapes/node_seperate_shapes.yy @@ -5,7 +5,7 @@ "isCompatibility": false, "isDnD": false, "parent": { - "name": "generator", - "path": "folders/nodes/data/generator.yy", + "name": "regions", + "path": "folders/nodes/data/generator/regions.yy", }, } \ No newline at end of file diff --git a/scripts/node_stack/node_stack.gml b/scripts/node_stack/node_stack.gml index e95e77017..417aec17d 100644 --- a/scripts/node_stack/node_stack.gml +++ b/scripts/node_stack/node_stack.gml @@ -23,7 +23,7 @@ function Node_Stack(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone); - outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.atlas, []); + outputs[| 1] = nodeValue("Atlas data", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, []); attribute_surface_depth(); @@ -126,7 +126,7 @@ function Node_Stack(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { sy = hh / 2 - sh / 2; } - array_push(atlas, new SurfaceAtlas(_surf[j], [ sx, sy ])); + array_push(atlas, new SurfaceAtlas(_surf[j], sx, sy)); draw_surface_safe(_surf[j], sx, sy); if(_axis == 0) diff --git a/scripts/node_value/node_value.gml b/scripts/node_value/node_value.gml index 4bf9c853f..6831b64e2 100644 --- a/scripts/node_value/node_value.gml +++ b/scripts/node_value/node_value.gml @@ -132,8 +132,9 @@ enum VALUE_UNIT { } enum VALUE_TAG { - updateTrigger = 1 << 0, - none = 0 + updateInTrigger = -2, + updateOutTrigger = -3, + none = 0 } function value_color(i) { #region @@ -186,7 +187,7 @@ function value_bit(i) { #region case VALUE_TYPE.color : return 1 << 4; case VALUE_TYPE.gradient : return 1 << 25; case VALUE_TYPE.dynaSurface : - case VALUE_TYPE.surface : return 1 << 5; + case VALUE_TYPE.surface : return 1 << 5 | 1 << 23; case VALUE_TYPE.path : return 1 << 10; case VALUE_TYPE.text : return 1 << 10; case VALUE_TYPE.object : return 1 << 13; @@ -200,7 +201,6 @@ function value_bit(i) { #region case VALUE_TYPE.struct : return 1 << 19; case VALUE_TYPE.strands : return 1 << 20; case VALUE_TYPE.mesh : return 1 << 21; - case VALUE_TYPE.atlas : return 1 << 23; case VALUE_TYPE.armature : return 1 << 26 | 1 << 19; case VALUE_TYPE.node : return 1 << 32; @@ -275,7 +275,6 @@ function value_type_from_string(str) { #region case "strands" : return VALUE_TYPE.strands; case "mesh" : return VALUE_TYPE.mesh; case "trigger" : return VALUE_TYPE.trigger; - case "atlas" : return VALUE_TYPE.atlas; case "d3vertex" : return VALUE_TYPE.d3vertex; case "gradient" : return VALUE_TYPE.gradient; @@ -451,7 +450,7 @@ function nodeValueUnit(_nodeValue) constructor { #region function nodeValue(_name, _node, _connect, _type, _value, _tooltip = "") { return new NodeValue(_name, _node, _connect, _type, _value, _tooltip); } function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constructor { - static DISPLAY_DATA_KEYS = [ "linked", "angle_display", "bone_id", "area_type", "unit" ]; + static DISPLAY_DATA_KEYS = [ "linked", "angle_display", "bone_id", "area_type", "unit", "atlas_crop" ]; #region ---- main ---- node = _node; @@ -544,6 +543,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru draw_line_blend = 1; drawLineIndex = 1; draw_line_vb = noone; + draw_junction_index = type; junction_drawing = [ THEME.node_junctions_single, type ]; @@ -566,9 +566,9 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru display_type = VALUE_DISPLAY._default; if(_type == VALUE_TYPE.curve) display_type = VALUE_DISPLAY.curve; else if(_type == VALUE_TYPE.d3vertex) display_type = VALUE_DISPLAY.d3vertex; - - display_data = {}; - display_attribute = noone; + + display_data = { update: method(node, node.triggerRender) }; + display_attribute = noone; popup_dialog = noone; #endregion @@ -719,7 +719,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru editWidget = noone; switch(display_type) { case VALUE_DISPLAY.button : #region - editWidget = button(display_data.onClick); + editWidget = button(method(node, display_data.onClick)); editWidget.text = display_data.name; if(!struct_has(display_data, "output")) display_data.output = false; @@ -1105,6 +1105,8 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru editWidget = new surfaceBox(function(ind) { return setValueDirect(ind); } ); + + if(!struct_has(display_data, "atlas")) display_data.atlas = true; show_in_inspector = true; extract_node = "Node_Canvas"; break; #endregion @@ -1311,6 +1313,15 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru var val = _getValue(_time, applyUnit, arrIndex, log); + draw_junction_index = type; + if(type == VALUE_TYPE.surface) { + var _sval = val; + if(is_array(_sval) && !array_empty(_sval)) + _sval = _sval[0]; + if(is_instanceof(_sval, SurfaceAtlas)) + draw_junction_index = VALUE_TYPE.atlas; + } + if(useCache) { is_changed = !isEqual(cache_value[2], val); cache_value[0] = true; @@ -1498,7 +1509,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru if(array_length(v) >= 100) return $"[{array_length(v)}]"; } - if(editWidget != noone && instanceof(editWidget) != "textArea" && string_length(string(val)) > 1024) + if(editWidget != noone && instanceof(editWidget) == "textBox" && string_length(string(val)) > 1024) val = $"[Long string ({string_length(string(val))} char)]"; return val; @@ -1568,8 +1579,6 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru } #endregion static setValue = function(val = 0, record = true, time = PROJECT.animator.current_frame, _update = true) { #region - //if(type == VALUE_TYPE.d3vertex && !is_array(val)) - // print(val); val = unit.invApply(val); return setValueDirect(val, noone, record, time, _update); } #endregion @@ -1605,26 +1614,36 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru if(type == VALUE_TYPE.gradient) updated = true; if(display_type == VALUE_DISPLAY.palette) updated = true; - if(updated) { - if(connect_type == JUNCTION_CONNECT.input) { - node.inputs_data[self.index] = animator.getValue(time); - - node.triggerRender(); - if(_update) node.valueUpdate(self.index); - node.clearCacheForward(); - - if(fullUpdate) RENDER_ALL - else RENDER_PARTIAL - - if(!LOADING) PROJECT.modified = true; - } - - cache_value[0] = false; + if(!updated) return false; + + draw_junction_index = type; + if(type == VALUE_TYPE.surface) { + var _sval = val; + if(is_array(_sval) && !array_empty(_sval)) + _sval = _sval[0]; + if(is_instanceof(_sval, SurfaceAtlas)) + draw_junction_index = VALUE_TYPE.atlas; } + if(connect_type == JUNCTION_CONNECT.output) return; + + node.inputs_data[self.index] = animator.getValue(time); + + if(tags != VALUE_TAG.none) return true; + + node.triggerRender(); + if(_update) node.valueUpdate(self.index); + node.clearCacheForward(); + + if(fullUpdate) RENDER_ALL + else RENDER_PARTIAL + + if(!LOADING) PROJECT.modified = true; + + cache_value[0] = false; onValidate(); - return updated; + return true; } #endregion static isConnectable = function(_valueFrom, checkRecur = true, log = false) { #region @@ -1857,12 +1876,12 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru if(type == VALUE_TYPE.action) junction_drawing = [THEME.node_junction_inspector, 1]; else - junction_drawing = [isArray()? THEME.node_junctions_array_hover : THEME.node_junctions_single_hover, type]; + junction_drawing = [isArray()? THEME.node_junctions_array_hover : THEME.node_junctions_single_hover, draw_junction_index]; } else { if(type == VALUE_TYPE.action) junction_drawing = [THEME.node_junction_inspector, 0]; else - junction_drawing = [isArray()? THEME.node_junctions_array : THEME.node_junctions_single, type]; + junction_drawing = [isArray()? THEME.node_junctions_array : THEME.node_junctions_single, draw_junction_index]; } draw_sprite_ext(junction_drawing[0], junction_drawing[1], x, y, ss, ss, 0, c_white, 1); @@ -2130,20 +2149,17 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru } #endregion static isVisible = function() { #region - if(!node.active) - return false; - - if(value_from) - return true; + if(!node.active) return false; - if(connect_type == JUNCTION_CONNECT.input) { - if(!visible) - return false; - - if(is_array(node.input_display_list)) - return array_exists(node.input_display_list, index); - } - return visible; + if(connect_type == JUNCTION_CONNECT.output) + return visible || !ds_list_empty(value_to); + + if(value_from) return true; + if(!visible) return false; + + if(is_array(node.input_display_list)) + return array_exists(node.input_display_list, index); + return true; } #endregion static extractNode = function(_type = extract_node) { #region @@ -2201,7 +2217,7 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru } #endregion static getJunctionTo = function() { #region - var to = []; + var to = []; for(var j = 0; j < ds_list_size(value_to); j++) { var _to = value_to[| j]; @@ -2250,10 +2266,8 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru if(!preset && value_from) { _map.from_node = value_from.node.node_id; - if(value_from.tags & VALUE_TAG.updateTrigger > 0) - _map.from_index = -2; - else - _map.from_index = value_from.index; + if(value_from.tags != 0) _map.from_index = value_from.tags; + else _map.from_index = value_from.index; } else { _map.from_node = -1; _map.from_index = -1; @@ -2349,9 +2363,9 @@ function NodeValue(_name, _node, _connect, _type, _value, _tooltip = "") constru if(log) log_warning("LOAD", $"[Connect] Reconnecting {node.name} to {_nd.name}", node); - if(con_index == -2) { - setFrom(_nd.updatedTrigger); - } else if(con_index < _ol) { + if(con_index == VALUE_TAG.updateInTrigger) setFrom(_nd.updatedInTrigger); + else if(con_index == VALUE_TAG.updateOutTrigger) setFrom(_nd.updatedOutTrigger); + else if(con_index < _ol) { var _set = setFrom(_nd.outputs[| con_index], false, true); if(_set) return true; diff --git a/scripts/pack_best_fit/pack_best_fit.gml b/scripts/pack_best_fit/pack_best_fit.gml index 282e6441a..0cfc0f236 100644 --- a/scripts/pack_best_fit/pack_best_fit.gml +++ b/scripts/pack_best_fit/pack_best_fit.gml @@ -3,7 +3,7 @@ function sprite_pack_best_fit(rectangles) { return rect2.w * rect2.h - rect1.w * rect1.h; }); - var area = new spriteAtlasData(0, 0, 0, 0); + var area = new Rectangle(0, 0, 0, 0); var grW = 1; var grH = 1; diff --git a/scripts/pack_skyline/pack_skyline.gml b/scripts/pack_skyline/pack_skyline.gml index 6c399d541..e34b1d17f 100644 --- a/scripts/pack_skyline/pack_skyline.gml +++ b/scripts/pack_skyline/pack_skyline.gml @@ -1,10 +1,3 @@ -function Strip(x, y, w, h) constructor { - self.x = x; - self.y = y; - self.w = w; - self.h = h; -} - function sprite_pack_skyline(rectangles, width, height) { var maxw = 0; var maxh = 0; @@ -13,7 +6,7 @@ function sprite_pack_skyline(rectangles, width, height) { return b.w - a.w; }); - var skyline = [ new Strip(0, 0, width, height) ]; + var skyline = [ new Rectangle(0, 0, width, height) ]; var packed = []; for (var i = 0; i < array_length(rectangles); i++) { @@ -39,10 +32,10 @@ function sprite_pack_skyline(rectangles, width, height) { array_push(packed, rect); if (bestStrip.w > rect.w) - array_push(skyline, new Strip(bestStrip.x + rect.w, bestStrip.y, bestStrip.w - rect.w, bestStrip.h)); + array_push(skyline, new Rectangle(bestStrip.x + rect.w, bestStrip.y, bestStrip.w - rect.w, bestStrip.h)); if (bestStrip.h > rect.h) - array_push(skyline, new Strip(bestStrip.x, bestStrip.y + rect.h, rect.w, bestStrip.h - rect.h)); + array_push(skyline, new Rectangle(bestStrip.x, bestStrip.y + rect.h, rect.w, bestStrip.h - rect.h)); array_remove(skyline, bestStrip); diff --git a/scripts/panel_inspector/panel_inspector.gml b/scripts/panel_inspector/panel_inspector.gml index 28843b604..c584b5f2f 100644 --- a/scripts/panel_inspector/panel_inspector.gml +++ b/scripts/panel_inspector/panel_inspector.gml @@ -212,17 +212,7 @@ function Panel_Inspector() : PanelContent() constructor { var wh = 0; var _data = PROJECT.attributes[$ param]; - wh = editW.drawParam(new widgetParam( - ui(16), - yy, - w - ui(16 + 48), - TEXTBOX_HEIGHT, - _data, - {}, - _m, - rx, - ry, - )); + wh = editW.drawParam(new widgetParam(ui(16), yy, w - ui(16 + 48), TEXTBOX_HEIGHT, _data, {}, _m, rx, ry)); yy += wh + ui(8); hh += wh + ui(8); diff --git a/scripts/render_data/render_data.gml b/scripts/render_data/render_data.gml index e5b472784..3742bc966 100644 --- a/scripts/render_data/render_data.gml +++ b/scripts/render_data/render_data.gml @@ -7,7 +7,6 @@ enum RENDER_TYPE { #region globalvar globalvar UPDATE, RENDER_QUEUE, RENDER_ORDER, UPDATE_RENDER_ORDER; UPDATE_RENDER_ORDER = false; - global.FLAG.render = 0; global.group_inputs = [ "Node_Group_Input", "Node_Feedback_Input", "Node_Iterator_Input", "Node_Iterator_Each_Input" ]; @@ -117,6 +116,8 @@ function Render(partial = false, runAction = false) { #region if(!_node.active) { LOG_IF(global.FLAG.render == 1, $"Skip inactive {_node.internalName}"); continue; } if(!_node.isRenderActive()) { LOG_IF(global.FLAG.render == 1, $"Skip non-renderActive {_node.internalName}"); continue; } + if(!_node.attributes.update_graph) { LOG_IF(global.FLAG.render == 1, $"Skip non-auto update {_node.internalName}"); continue; } + if(_node.rendered && !_node.isAnimated()) { _node.anim_last_step = false; LOG_IF(global.FLAG.render == 1, $"Skip rendered {_node.internalName}"); diff --git a/scripts/save_function/save_function.gml b/scripts/save_function/save_function.gml index c148d3298..13c908bf3 100644 --- a/scripts/save_function/save_function.gml +++ b/scripts/save_function/save_function.gml @@ -38,6 +38,7 @@ function save_serialize(project = PROJECT, _outMap = false) { _map.previewGrid = project.previewGrid; _map.graphGrid = project.graphGrid; + _map.attributes = project.attributes; var prev = PANEL_PREVIEW.getNodePreviewSurface(); if(!is_surface(prev)) _map.preview = ""; diff --git a/scripts/struct_functions/struct_functions.gml b/scripts/struct_functions/struct_functions.gml index ff8f9d18b..6e48c735f 100644 --- a/scripts/struct_functions/struct_functions.gml +++ b/scripts/struct_functions/struct_functions.gml @@ -7,7 +7,6 @@ function struct_override(original, override) { var _key = args[i]; if(!struct_has(original, _key)) continue; - original[$ _key] = override[$ _key]; } diff --git a/scripts/surfaceBox/surfaceBox.gml b/scripts/surfaceBox/surfaceBox.gml index 1c3a76c5b..5e3b640b7 100644 --- a/scripts/surfaceBox/surfaceBox.gml +++ b/scripts/surfaceBox/surfaceBox.gml @@ -7,6 +7,12 @@ function surfaceBox(_onModify, def_path = "") : widget() constructor { open_ry = 0; align = fa_center; + display_data = {}; + + cb_atlas_crop = new checkBox(function() { + display_data.atlas_crop = !display_data.atlas_crop; + display_data.update(); + }); static trigger = function() { open = true; @@ -16,11 +22,16 @@ function surfaceBox(_onModify, def_path = "") : widget() constructor { } } - static drawParam = function(params) { - return draw(params.x, params.y, params.w, params.h, params.data, params.m, params.rx, params.ry); + static setInteract = function(interactable) { + self.interactable = interactable; + cb_atlas_crop.interactable = true; } - static draw = function(_x, _y, _w, _h, _surface, _m, _rx, _ry) { + static drawParam = function(params) { + return draw(params.x, params.y, params.w, params.h, params.data, params.display_data, params.m, params.rx, params.ry); + } + + static draw = function(_x, _y, _w, _h, _surface, _display_data, _m, _rx, _ry) { _h = ui(96); x = _x; @@ -29,13 +40,25 @@ function surfaceBox(_onModify, def_path = "") : widget() constructor { h = _h; open_rx = _rx; open_ry = _ry; + display_data = _display_data; var hoverRect = point_in_rectangle(_m[0], _m[1], _x, _y, _x + _w, _y + _h); + var _type = VALUE_TYPE.surface; + + var _surf_single = _surface; + if(is_array(_surf_single) && !array_empty(_surf_single)) + _surf_single = _surf_single[0]; + + if(is_instanceof(_surf_single, dynaSurf)) { + _type = VALUE_TYPE.dynaSurface; + } else if(is_instanceof(_surf_single, SurfaceAtlas)) { + _type = VALUE_TYPE.atlas; + } if(!open) { draw_sprite_stretched(THEME.textbox, 3, _x, _y, _w, _h); - if(hover && hoverRect) { + if(_type == VALUE_TYPE.surface && hover && hoverRect) { draw_sprite_stretched(THEME.textbox, 1, _x, _y, _w, _h); if(mouse_press(mb_left, active)) trigger(); @@ -72,9 +95,23 @@ function surfaceBox(_onModify, def_path = "") : widget() constructor { draw_surface_ext_safe(_surface, _sx, _sy, ss, ss, 0, c_white, 1); } - draw_sprite_ui_uniform(THEME.scroll_box_arrow, 0, _x + _w - ui(20), _y + _h / 2, 1, COLORS._main_icon); + if(_type == VALUE_TYPE.surface) + draw_sprite_ui_uniform(THEME.scroll_box_arrow, 0, _x + _w - ui(20), _y + _h / 2, 1, COLORS._main_icon); } + //if(_type == VALUE_TYPE.atlas) { + // draw_sprite_stretched_ext(THEME.ui_panel_inner_bg, 1, _x, _y + _h + ui(8), _w, ui(40), COLORS.node_composite_bg_blend, 1); + + // var set_y = _y + _h + ui(16); + // var set_w = ui(64); + // var set_h = ui(24); + + // draw_set_text(f_p0, fa_left, fa_center, COLORS._main_text); + // draw_text_add(_x + ui(16), set_y + set_h / 2, __txt("Crop atlas")); + + // cb_atlas_crop.drawParam(new widgetParam(_x + _w - set_w, set_y, set_w, set_h, display_data.atlas_crop,, _m, _rx, _ry)); + //} + if(WIDGET_CURRENT == self) draw_sprite_stretched_ext(THEME.widget_selecting, 0, _x - ui(3), _y - ui(3), _w + ui(6), _h + ui(6), COLORS._main_accent, 1); diff --git a/scripts/surface_functions/surface_functions.gml b/scripts/surface_functions/surface_functions.gml index d9348024e..07de96e64 100644 --- a/scripts/surface_functions/surface_functions.gml +++ b/scripts/surface_functions/surface_functions.gml @@ -2,9 +2,12 @@ function draw_surface_safe(surface, _x = 0, _y = 0) { gml_pragma("forceinline"); - if(is_struct(surface) && is_instanceof(surface, dynaSurf)) { - surface.draw(_x, _y); - return; + if(is_struct(surface)) { + if(is_instanceof(surface, dynaSurf)) { + surface.draw(_x, _y); + return; + } else if(is_instanceof(surface, SurfaceAtlas)) + surface = surface.getSurface(); } if(!is_surface(surface)) return; @@ -16,9 +19,12 @@ function draw_surface_safe(surface, _x = 0, _y = 0) { function draw_surface_stretched_safe(surface, _x, _y, _w, _h) { gml_pragma("forceinline"); - if(is_struct(surface) && is_instanceof(surface, dynaSurf)) { - surface.drawStretch(_x, _y, _w, _h); - return; + if(is_struct(surface)) { + if(is_instanceof(surface, dynaSurf)) { + surface.drawStretch(_x, _y, _w, _h); + return; + } else if(is_instanceof(surface, SurfaceAtlas)) + surface = surface.getSurface(); } if(!is_surface(surface)) return; @@ -30,9 +36,12 @@ function draw_surface_stretched_safe(surface, _x, _y, _w, _h) { function draw_surface_ext_safe(surface, _x, _y, _xs = 1, _ys = 1, _rot = 0, _col = c_white, _alpha = 1) { gml_pragma("forceinline"); - if(is_struct(surface) && is_instanceof(surface, dynaSurf)) { - surface.draw(_x, _y, _xs, _ys, _rot, _col, _alpha); - return; + if(is_struct(surface)) { + if(is_instanceof(surface, dynaSurf)) { + surface.draw(_x, _y, _xs, _ys, _rot, _col, _alpha); + return; + } else if(is_instanceof(surface, SurfaceAtlas)) + surface = surface.getSurface(); } if(!is_surface(surface)) return; @@ -44,9 +53,12 @@ function draw_surface_ext_safe(surface, _x, _y, _xs = 1, _ys = 1, _rot = 0, _col function draw_surface_tiled_safe(surface, _x, _y) { gml_pragma("forceinline"); - if(is_struct(surface) && is_instanceof(surface, dynaSurf)) { - surface.drawTile(_x, _y); - return; + if(is_struct(surface)) { + if(is_instanceof(surface, dynaSurf)) { + surface.drawTile(_x, _y); + return; + } else if(is_instanceof(surface, SurfaceAtlas)) + surface = surface.getSurface(); } if(!is_surface(surface)) return; @@ -58,9 +70,12 @@ function draw_surface_tiled_safe(surface, _x, _y) { function draw_surface_tiled_ext_safe(surface, _x, _y, _xs = 1, _ys = 1, _col = c_white, _alpha = 1) { gml_pragma("forceinline"); - if(is_struct(surface) && is_instanceof(surface, dynaSurf)) { - surface.drawTile(_x, _y, _xs, _ys, _col, _alpha); - return; + if(is_struct(surface)) { + if(is_instanceof(surface, dynaSurf)) { + surface.drawTile(_x, _y, _xs, _ys, _col, _alpha); + return; + } else if(is_instanceof(surface, SurfaceAtlas)) + surface = surface.getSurface(); } if(!is_surface(surface)) return; @@ -72,9 +87,12 @@ function draw_surface_tiled_ext_safe(surface, _x, _y, _xs = 1, _ys = 1, _col = c function draw_surface_part_ext_safe(surface, _l, _t, _w, _h, _x, _y, _xs = 1, _ys = 1, _rot = 0, _col = c_white, _alpha = 1) { gml_pragma("forceinline"); - if(is_struct(surface) && is_instanceof(surface, dynaSurf)) { - surface.drawPart(_l, _t, _w, _h, _x, _y, _xs, _ys, _rot, _col, _alpha); - return; + if(is_struct(surface)) { + if(is_instanceof(surface, dynaSurf)) { + surface.drawPart(_l, _t, _w, _h, _x, _y, _xs, _ys, _rot, _col, _alpha); + return; + } else if(is_instanceof(surface, SurfaceAtlas)) + surface = surface.getSurface(); } if(!is_surface(surface)) return; @@ -131,23 +149,33 @@ function surface_save_safe(surface, path) { return; } -function surface_get_width_safe(s) { +function surface_get_width_safe(s, crop = true) { gml_pragma("forceinline"); - return (is_struct(s) && is_instanceof(s, dynaSurf))? s.getWidth() : surface_get_width(s); + if(is_struct(s)) { + if(is_instanceof(s, dynaSurf)) return s.getWidth(); + else if(is_instanceof(s, SurfaceAtlas)) return crop? surface_get_width(s.getSurface()) : s.oriSurf_w; + } + + return surface_get_width(s); } -function surface_get_height_safe(s) { +function surface_get_height_safe(s, crop = true) { gml_pragma("forceinline"); - return (is_struct(s) && is_instanceof(s, dynaSurf))? s.getHeight() : surface_get_height(s); + if(is_struct(s)) { + if(is_instanceof(s, dynaSurf)) return s.getHeight(); + else if(is_instanceof(s, SurfaceAtlas)) return crop? surface_get_height(s.getSurface()) : s.oriSurf_h; + } + + return surface_get_height(s); } //check function is_surface(s) { gml_pragma("forceinline"); - if(is_struct(s) && is_instanceof(s, dynaSurf)) return true; + if(is_instanceof(s, dynaSurf) || is_instanceof(s, SurfaceAtlas)) return true; if(is_real(s) && s > 0 && surface_exists(s)) return true; return false; } diff --git a/shaders/sh_d3d_default/sh_d3d_default.fsh b/shaders/sh_d3d_default/sh_d3d_default.fsh index 508ece38d..f5e328659 100644 --- a/shaders/sh_d3d_default/sh_d3d_default.fsh +++ b/shaders/sh_d3d_default/sh_d3d_default.fsh @@ -233,7 +233,7 @@ void main() { vec3 light_phong = phongLight(normal, lightVector, viewDirection, light_dir_color[i].rgb); - light_effect += light_phong; + light_effect += light_phong * light_dir_intensity[i]; } #endregion @@ -278,7 +278,7 @@ void main() { vec3 light_phong = phongLight(normal, lightVector, viewDirection, light_pnt_color[i].rgb * light_attenuation); - light_effect += light_phong; + light_effect += light_phong * light_pnt_intensity[i]; } #endregion @@ -293,6 +293,8 @@ void main() { final_color.rgb *= light_effect; #endregion + if(final_color.a < 0.1) discard; + gl_FragData[0] = final_color; gl_FragData[1] = vec4(0.5 + normal * 0.5, final_color.a); gl_FragData[2] = vec4(vec3(v_cameraDistance), final_color.a); diff --git a/shaders/sh_d3d_geometry/sh_d3d_geometry.fsh b/shaders/sh_d3d_geometry/sh_d3d_geometry.fsh index 00e65a8a6..51c785a71 100644 --- a/shaders/sh_d3d_geometry/sh_d3d_geometry.fsh +++ b/shaders/sh_d3d_geometry/sh_d3d_geometry.fsh @@ -12,6 +12,7 @@ void main() { vec2 uv_coord = v_vTexcoord; if(mat_flip == 1) uv_coord.y = -uv_coord.y; vec4 mat_baseColor = texture2D( gm_BaseTexture, uv_coord ); + if(mat_baseColor.a < 0.1) discard; gl_FragData[0] = vec4(v_worldPosition.xyz, mat_baseColor.a); gl_FragData[1] = vec4(v_viewPosition, mat_baseColor.a); diff --git a/sprites/s_node_group_thumbnail/73969580-2c2a-4003-9463-a742cfdd83de.png b/sprites/s_node_group_thumbnail/73969580-2c2a-4003-9463-a742cfdd83de.png new file mode 100644 index 0000000000000000000000000000000000000000..e306712629a739a775004def95c1eeef0c64982f GIT binary patch literal 1120 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=3dtTpz6=aiY77hwEes65fI|H*Yfq^;L)5S5Q;?~>Q=d*7m z$h6BJbqGBY6n68`!JaBX?Y9%ywi#M$uCdLz@R$8={k6}0i;r&$h&lbjL1VSYN2N1z zT8o!^Wy-n~unRwT$vwk=S*7|w_rA9G-%rl2`J|P<;PzXiBYnT3jz`Nd?|!w~Kf$4a zZzHeq7B7x@Es0Y^_!75>2C>GDp|?&g*(~;(YVteJ@&{F=k!WTKczn<9v4Y z+KbwM)?8mM{y?>E`|W>X2Aub~IV@uv;*>5L%*>H8oarD?m8$L4{_Lvh)^4ls<+;ws zOIsU$)buz7zB6B^$e|cCsbhvuL6FwvT|4Lgy3zknsKe#3@@#prK#fx_ixS^+o=CYY zJX?Osgp9h4N8eZ+E-6jKh&i;)FhZh&botrqx?f;-yp?f2J5o+pcKf3$$%ZRDSY&)Sdc ztBK8dcYhB5UFwQV?QYmJM|pDWrmYJi zk1xq%)Q{hPLAE$;W~$FCu@7estk+FbJ)@*1|F_6OUw?L#@2)t88`6{42{1ehn>k6*#*^{#hxmretQKeM8U4f`nCuf@V6DHe#_odkmCzq`Y(1hAPFj8rpDOF~ zD)o(Oz@1wxclH)0>B&5+w7UB~RirU*`)|?rZ-uU&E}XD%?Gn4>@Y|MEegD7lg*Ak} zRomg4Z@n@;W2No);02EP`ngA6o=S6YeY@3ABO&0BdR6qcptHiB=l}{!Vs6hj6LrG?CYH>+oZUJsRLDIHeKs^keu6{1-oD!M|H*Yfq^;L)5S5Q;?~>Q=d*7m z$h6BJbqGBY6n68`!JaBX?Y9%ywi#M$uCdLz@R$8={k6}0i;r&$h&lbjL1VSYN2N1z zT8o!^Wy-n~unRwT$vwk=S*7|w_rA9G-%rl2`J|P<;PzXiBYnT3jz`Nd?|!w~Kf$4a zZzHeq7B7x@Es0Y^_!75>2C>GDp|?&g*(~;(YVteJ@&{F=k!WTKczn<9v4Y z+KbwM)?8mM{y?>E`|W>X2Aub~IV@uv;*>5L%*>H8oarD?m8$L4{_Lvh)^4ls<+;ws zOIsU$)buz7zB6B^$e|cCsbhvuL6FwvT|4Lgy3zknsKe#3@@#prK#fx_ixS^+o=CYY zJX?Osgp9h4N8eZ+E-6jKh&i;)FhZh&botrqx?f;-yp?f2J5o+pcKf3$$%ZRDSY&)Sdc ztBK8dcYhB5UFwQV?QYmJM|pDWrmYJi zk1xq%)Q{hPLAE$;W~$FCu@7estk+FbJ)@*1|F_6OUw?L#@2)t88`6{42{1ehn>k6*#*^{#hxmretQKeM8U4f`nCuf@V6DHe#_odkmCzq`Y(1hAPFj8rpDOF~ zD)o(Oz@1wxclH)0>B&5+w7UB~RirU*`)|?rZ-uU&E}XD%?Gn4>@Y|MEegD7lg*Ak} zRomg4Z@n@;W2No);02EP`ngA6o=S6YeY@3ABO&0BdR6qcptHiB=l}{!Vs6hj6LrG?CYH>+oZUJsRLDIHeKs^keu6{1-oD!M","resourceVersion":"1.0","Keyframes":[],}, + "eventStubScript": null, + "eventToFunction": {}, + "length": 1.0, + "lockOrigin": false, + "moments": {"resourceType":"KeyframeStore","resourceVersion":"1.0","Keyframes":[],}, + "playback": 1, + "playbackSpeed": 30.0, + "playbackSpeedType": 0, + "showBackdrop": true, + "showBackdropImage": false, + "timeUnits": 1, + "tracks": [ + {"resourceType":"GMSpriteFramesTrack","resourceVersion":"1.0","name":"frames","builtinName":0,"events":[],"inheritsTrackColour":true,"interpolation":1,"isCreationTrack":false,"keyframes":{"resourceType":"KeyframeStore","resourceVersion":"1.0","Keyframes":[ + {"resourceType":"Keyframe","resourceVersion":"1.0","Channels":{"0":{"resourceType":"SpriteFrameKeyframe","resourceVersion":"1.0","Id":{"name":"73969580-2c2a-4003-9463-a742cfdd83de","path":"sprites/s_node_group_thumbnail/s_node_group_thumbnail.yy",},},},"Disabled":false,"id":"1e629b24-d265-4813-8896-966f6d27dcd4","IsCreationKey":false,"Key":0.0,"Length":1.0,"Stretch":false,}, + ],},"modifiers":[],"spriteId":null,"trackColour":0,"tracks":[],"traits":0,}, + ], + "visibleRange": null, + "volume": 1.0, + "xorigin": 32, + "yorigin": 32, + }, + "swatchColours": null, + "swfPrecision": 2.525, + "textureGroupId": { + "name": "Default", + "path": "texturegroups/Default", + }, + "type": 0, + "VTile": false, + "width": 64, +} \ No newline at end of file