sampler surface

This commit is contained in:
Tanasart 2025-02-21 15:08:49 +07:00
parent ed5663b718
commit 9daa77056a
14 changed files with 180 additions and 55 deletions

View file

@ -1746,6 +1746,7 @@
{"name":"sh_noise_cristal","order":43,"path":"shaders/sh_noise_cristal/sh_noise_cristal.yy",},
{"name":"sh_noise_fbm","order":7,"path":"shaders/sh_noise_fbm/sh_noise_fbm.yy",},
{"name":"sh_noise_flow","order":41,"path":"shaders/sh_noise_flow/sh_noise_flow.yy",},
{"name":"surface_sampler","order":10,"path":"scripts/surface_sampler/surface_sampler.yy",},
{"name":"sh_noise_fold","order":33,"path":"shaders/sh_noise_fold/sh_noise_fold.yy",},
{"name":"sh_noise_gabor","order":27,"path":"shaders/sh_noise_gabor/sh_noise_gabor.yy",},
{"name":"sh_noise_grid_hex","order":11,"path":"shaders/sh_noise_grid_hex/sh_noise_grid_hex.yy",},

View file

@ -1326,11 +1326,7 @@
{"$GMIncludedFile":"","%Name":"Canvas.png","CopyToMask":-1,"filePath":"datafiles/data/Welcome files/Templates","name":"Canvas.png","resourceType":"GMIncludedFile","resourceVersion":"2.0",},
{"$GMIncludedFile":"","%Name":"Canvas.pxc","CopyToMask":-1,"filePath":"datafiles/data/Welcome files/Templates","name":"Canvas.pxc","resourceType":"GMIncludedFile","resourceVersion":"2.0",},
{"$GMIncludedFile":"","%Name":"Welcome files.zip","CopyToMask":-1,"filePath":"datafiles/data/Welcome files","name":"Welcome files.zip","resourceType":"GMIncludedFile","resourceVersion":"2.0",},
{"$GMIncludedFile":"","%Name":"dllcredits.txt","ConfigValues":{
"Itch":{
"CopyToMask":"0",
},
},"CopyToMask":0,"filePath":"datafiles","name":"dllcredits.txt","resourceType":"GMIncludedFile","resourceVersion":"2.0",},
{"$GMIncludedFile":"","%Name":"dllcredits.txt","ConfigValues":{"Itch":{"CopyToMask":"0",},},"CopyToMask":0,"filePath":"datafiles","name":"dllcredits.txt","resourceType":"GMIncludedFile","resourceVersion":"2.0",},
{"$GMIncludedFile":"","%Name":"dlltest1.dll","CopyToMask":-1,"filePath":"datafiles","name":"dlltest1.dll","resourceType":"GMIncludedFile","resourceVersion":"2.0",},
{"$GMIncludedFile":"","%Name":"ffmpeg.exe","CopyToMask":-1,"filePath":"datafiles/ffmpeg/bin","name":"ffmpeg.exe","resourceType":"GMIncludedFile","resourceVersion":"2.0",},
{"$GMIncludedFile":"","%Name":"LICENSE","CopyToMask":-1,"filePath":"datafiles/ffmpeg","name":"LICENSE","resourceType":"GMIncludedFile","resourceVersion":"2.0",},
@ -1349,11 +1345,7 @@
{"$GMIncludedFile":"","%Name":"mf.dll","CopyToMask":-1,"filePath":"datafiles","name":"mf.dll","resourceType":"GMIncludedFile","resourceVersion":"2.0",},
{"$GMIncludedFile":"","%Name":"mfcore.dll","CopyToMask":-1,"filePath":"datafiles","name":"mfcore.dll","resourceType":"GMIncludedFile","resourceVersion":"2.0",},
{"$GMIncludedFile":"","%Name":"mfplat.dll","CopyToMask":-1,"filePath":"datafiles","name":"mfplat.dll","resourceType":"GMIncludedFile","resourceVersion":"2.0",},
{"$GMIncludedFile":"","%Name":"PixelComposer_profile-2.provisionprofile","ConfigValues":{
"Itch":{
"CopyToMask":"2",
},
},"CopyToMask":-1,"filePath":"datafiles","name":"PixelComposer_profile-2.provisionprofile","resourceType":"GMIncludedFile","resourceVersion":"2.0",},
{"$GMIncludedFile":"","%Name":"PixelComposer_profile-2.provisionprofile","ConfigValues":{"Itch":{"CopyToMask":"2",},},"CopyToMask":-1,"filePath":"datafiles","name":"PixelComposer_profile-2.provisionprofile","resourceType":"GMIncludedFile","resourceVersion":"2.0",},
{"$GMIncludedFile":"","%Name":"data.win","CopyToMask":-1,"filePath":"datafiles/report","name":"data.win","resourceType":"GMIncludedFile","resourceVersion":"2.0",},
{"$GMIncludedFile":"","%Name":"execute_shell_simple_ext_x64.dll","CopyToMask":-1,"filePath":"datafiles/report","name":"execute_shell_simple_ext_x64.dll","resourceType":"GMIncludedFile","resourceVersion":"2.0",},
{"$GMIncludedFile":"","%Name":"options.ini","CopyToMask":-1,"filePath":"datafiles/report","name":"options.ini","resourceType":"GMIncludedFile","resourceVersion":"2.0",},
@ -1501,6 +1493,7 @@
{"id":{"name":"Obj_FirebaseREST_Listener_On_firestore_collection","path":"objects/Obj_FirebaseREST_Listener_On_firestore_collection/Obj_FirebaseREST_Listener_On_firestore_collection.yy",},},
{"id":{"name":"Obj_FirebaseREST_Listener_On_firestore_document","path":"objects/Obj_FirebaseREST_Listener_On_firestore_document/Obj_FirebaseREST_Listener_On_firestore_document.yy",},},
{"id":{"name":"Obj_FirebaseREST_Listener_On_Firestore","path":"objects/Obj_FirebaseREST_Listener_On_Firestore/Obj_FirebaseREST_Listener_On_Firestore.yy",},},
{"id":{"name":"surface_sampler","path":"scripts/surface_sampler/surface_sampler.yy",},},
{"id":{"name":"Obj_FirebaseREST_Listener_Once_Firestore","path":"objects/Obj_FirebaseREST_Listener_Once_Firestore/Obj_FirebaseREST_Listener_Once_Firestore.yy",},},
{"id":{"name":"oRigidbody","path":"objects/oRigidbody/oRigidbody.yy",},},
{"id":{"name":"project_loader","path":"objects/project_loader/project_loader.yy",},},

Binary file not shown.

View file

@ -9,6 +9,7 @@ enum PARTICLE_BLEND_MODE {
alpha,
additive,
maximum,
minimum,
}
enum PARTICLE_RENDER_TYPE {

View file

@ -12,6 +12,7 @@
#macro BLEND_ALPHA gpu_set_blendmode_ext_sepalpha(bm_one, bm_inv_src_alpha, bm_one, bm_one);
#macro BLEND_ALPHA_MULP gpu_set_blendmode_ext_sepalpha(bm_src_alpha, bm_inv_src_alpha, bm_one, bm_one);
#macro BLEND_MAX gpu_set_blendmode(bm_normal); gpu_set_blendequation(bm_eq_max);
#macro BLEND_MIN gpu_set_blendmode(bm_normal); gpu_set_blendequation_sepalpha(bm_eq_min, bm_add);
#macro BLEND_MULTIPLY gpu_set_blendmode_ext(bm_dest_colour, bm_zero);
#macro BLEND_SUBTRACT gpu_set_blendmode(bm_subtract);

View file

@ -126,6 +126,8 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co
newInput(55, nodeValue_PathNode("Spawn Path", self, noone ));
newInput(56, nodeValue_Surface("Sample Surface", self, noone));
for (var i = 2, n = array_length(inputs); i < n; i++)
inputs[i].rejectArray();
input_len = array_length(inputs);
@ -171,7 +173,7 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co
["Rotation", true], 15, 8, 9,
["Scale", true], 10, 17, 11,
["Wiggles", true], 20, 41, 42, 43,
["Color", true], 12, 28, 50, 13, 14,
["Color", true], 12, 28, 50, 13, 14, 56,
["Render", true], 21,
];
@ -207,6 +209,8 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co
custom_parameter_map = {};
attributes.parameter_curves = {};
surfSamp = new Surface_sampler();
static spawn = function(_time = CURRENT_FRAME, _pos = -1) {
var _inSurf = getInputData( 0);
@ -278,10 +282,12 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co
_index = irandom(array_length(_inSurf) - 1);
_spr = _inSurf[_index];
break;
case 1 :
_index = safe_mod(spawn_index, array_length(_inSurf));
_spr = _inSurf[_index];
break;
case 2 :
case 3 :
_spr = _inSurf;
@ -353,6 +359,11 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co
var _clr_ind = array_safe_get(_color_idx, safe_mod(spawn_index, _color_idx_len), cola(c_white));
_bld = colorMultiply(_bld, _clr_ind);
if(surfSamp.active) {
var _samC = surfSamp.getPixel(xx, yy);
_bld = colorMultiply(_bld, _samC);
}
part.seed = irandom_range(100000, 999999);
part.create(_spr, xx, yy, _lif);
part.anim_speed = random_range(_anim_speed[0], _anim_speed[1]);
@ -586,6 +597,10 @@ function Node_VFX_Spawner_Base(_x, _y, _group = noone) : Node(_x, _y, _group) co
static onDrawOverlay = -1;
static update = function(frame = CURRENT_FRAME) {
var sampSrf = getInputData(56);
surfSamp.setSurface(sampSrf);
var _surf = getInputData(0);
if(is(_surf, dynaDraw)) {
custom_parameter_names = _surf.parameters;

View file

@ -82,7 +82,7 @@ function Node_Padding(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
DRAW_CLEAR
BLEND_OVERRIDE
} else if(fill == 1)
draw_clear_alpha(fillClr, 1);
draw_clear_alpha(fillClr, color_get_alpha(fillClr));
draw_surface_safe(surf, padding[2], padding[1]);
BLEND_NORMAL
@ -99,7 +99,7 @@ function Node_Padding(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
DRAW_CLEAR
BLEND_OVERRIDE
} else if(fill == 1)
draw_clear(fillClr);
draw_clear_alpha(fillClr, color_get_alpha(fillClr));
var sx = 0;
var sy = 0;

View file

@ -119,13 +119,18 @@ function Node_Particle(_x, _y, _group = noone) : Node_VFX_Spawner_Base(_x, _y, _
if(is_surface(_bg)) _dim = surface_get_dimension(_bg)
surface_set_shader(_outSurf, _type == PARTICLE_RENDER_TYPE.surface? sh_sample : noone);
if(is_surface(_bg)) draw_surface_safe(_bg);
draw_surface_safe(_bg);
switch(_blend) {
case PARTICLE_BLEND_MODE.normal: BLEND_NORMAL break;
case PARTICLE_BLEND_MODE.alpha: BLEND_ALPHA break;
case PARTICLE_BLEND_MODE.additive: BLEND_ADD break;
case PARTICLE_BLEND_MODE.maximum: BLEND_MAX break;
case PARTICLE_BLEND_MODE.minimum:
draw_clear_alpha(c_white, 0.);
draw_surface_safe(_bg);
BLEND_MIN
break;
}
if(_type == PARTICLE_RENDER_TYPE.surface)

View file

@ -1147,10 +1147,18 @@ function Node_Path(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
// Surface generate
var pad = min(8, abs(boundary.maxx - boundary.minx) * 0.1, abs(boundary.maxy - boundary.miny) * 0.1);
var minx = boundary.minx - pad, miny = boundary.miny - pad;
var maxx = boundary.maxx + pad, maxy = boundary.maxy + pad;
var rngx = maxx - minx, rngy = maxy - miny;
var pad = min(8, abs(boundary.maxx - boundary.minx) * 0.1, abs(boundary.maxy - boundary.miny) * 0.1);
var minx = boundary.minx - pad, maxx = boundary.maxx + pad;
var cx = (minx + maxx) / 2;
var miny = boundary.miny - pad, maxy = boundary.maxy + pad;
var cy = (miny + maxy) / 2;
var rng = max(maxx - minx, maxy - miny);
var x0 = cx - rng / 2, x1 = cx + rng / 2;
var y0 = cy - rng / 2, y1 = cy + rng / 2;
var prev_s = 128;
_path_preview_surface = surface_verify(_path_preview_surface, prev_s, prev_s);
@ -1163,8 +1171,8 @@ function Node_Path(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
var segment = segments[i];
for (var j = 0, m = array_length(segment); j < m; j += 2) {
nx = (segment[j + 0] - minx) / rngx * prev_s;
ny = (segment[j + 1] - miny) / rngy * prev_s;
nx = (segment[j + 0] - x0) / rng * prev_s;
ny = (segment[j + 1] - y0) / rng * prev_s;
if(j) draw_line_round(ox, oy, nx, ny, 4);
@ -1176,7 +1184,7 @@ function Node_Path(_x, _y, _group = noone) : Node(_x, _y, _group) constructor {
draw_set_color(COLORS._main_accent);
for (var i = 0, n = array_length(anchors); i < n; i++) {
var _a0 = anchors[i];
draw_circle((_a0[0] - minx) / rngx * prev_s, (_a0[1] - miny) / rngy * prev_s, 8, false);
draw_circle((_a0[0] - x0) / rng * prev_s, (_a0[1] - y0) / rng * prev_s, 8, false);
}
surface_reset_target();

View file

@ -40,8 +40,8 @@ function Node_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
new scrollItem("Grid", s_node_repeat_axis, 1),
new scrollItem("Circular", s_node_repeat_axis, 2), ]));
newInput(4, nodeValue_Vec2("Shift position", self, [ DEF_SURF_W / 2, 0 ]))
.setUnitRef(function() /*=>*/ {return getDimension()});
newInput(4, nodeValue_Vec2("Shift position", self, [ .5, 0 ]))
.setUnitRef(function() /*=>*/ {return getDimension()}, VALUE_UNIT.reference);
newInput(5, nodeValue_Rotation_Range("Repeat rotation", self, [ 0, 0 ]));
@ -52,7 +52,7 @@ function Node_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
newInput(8, nodeValue_Float("Radius", self, 1));
newInput(9, nodeValue_Vec2("Start position", self, [ 0, 0 ]))
.setUnitRef(function(index) { return getInputData(1); });
.setUnitRef(function() /*=>*/ {return getInputData(1)}, VALUE_UNIT.reference);
newInput(10, nodeValue_Curve("Scale over copy", self, CURVE_DEF_11 ));
@ -76,8 +76,8 @@ function Node_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
newInput(18, nodeValue_Int("Column", self, 4));
newInput(19, nodeValue_Vec2("Column shift", self, [0, DEF_SURF_H / 2]))
.setUnitRef(function() /*=>*/ {return getDimension()});
newInput(19, nodeValue_Vec2("Column shift", self, [0, .5]))
.setUnitRef(function() /*=>*/ {return getDimension()}, VALUE_UNIT.reference);
/* deprecated */ newInput(20, nodeValue_Float("Animator midpoint", self, 0.5))
.setDisplay(VALUE_DISPLAY.slider, { range: [-1, 2, 0.01] });
@ -128,6 +128,8 @@ function Node_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
newInput(37, nodeValue_Padding("Padding", self, [ 0, 0, 0, 0 ]));
newInput(38, nodeValue_Curve("Shift per copy", self, CURVE_DEF_11 ));
newOutput(0, nodeValue_Output("Surface Out", self, VALUE_TYPE.surface, noone));
typeList = [ "Linear Transform", "Blending" ];
@ -247,7 +249,7 @@ function Node_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
["Surfaces", true], 0, 35, 36, 37, 1, 16, 17,
["Pattern", false], 3, 9, 32, 2, 18, 7, 8,
["Path", true], 11, 12, 13,
["Position", false], 4, 26, 19,
["Position", false], 4, 26, 19, 38,
["Rotation", false], 33, 5,
["Scale", false], 6, 10,
["Render", false], 34, 14, 30,
@ -313,6 +315,7 @@ function Node_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
inputs[19].setVisible( _pat == 1);
inputs[26].setVisible( _pat == 0);
inputs[32].setVisible( _pat == 2);
inputs[38].setVisible( _pat == 0);
inputs[14].mappableStep();
}
@ -333,6 +336,8 @@ function Node_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
var _srot = _data[32];
var _rpos = _data[ 4];
var _cpos = _data[38];
var _rsta = _data[26];
var _rrot = _data[ 5];
var _rots = _data[33];
@ -383,7 +388,7 @@ function Node_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
inputs[_ind + 14].setVisible(_selc == 2, _selc == 2);
}
var _surf, runx, runy, posx, posy, scax, scay, rot;
var _surf, posx, posy, scax, scay, rot;
var _dim, _sdim = [ 1, 1 ];
var _surf = _iSrf;
@ -404,18 +409,20 @@ function Node_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
var atlases = array_create(_amo, 0);
var atlas_i = 0;
runx = 0;
runy = 0;
var runx = 0;
var runy = 0;
var _rposx = 0;
var _rposy = 0;
for( var i = 0; i < _amo; i++ ) {
posx = runx;
posy = runy;
var _prg = i / (_amo - 1);
if(_pat == 0) {
if(_path == noone || !variable_struct_exists(_path, "getPointRatio")) {
posx += _spos[0] + _rpos[0] * i;
posy += _spos[1] + _rpos[1] * i;
} else {
if(struct_has(_path, "getPointRatio")) {
var rat = _prsh + _prng[0] + (_prng[1] - _prng[0]) * i / _amo;
if(_prng[1] - _prng[0] == 0) break;
rat = abs(frac(rat));
@ -423,7 +430,16 @@ function Node_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
var _p = _path.getPointRatio(rat);
posx = _p.x;
posy = _p.y;
} else {
posx += _spos[0] + _rposx;
posy += _spos[1] + _rposy;
var _rpos_sca = eval_curve_x(_cpos, _prg);
_rposx += _rpos[0] * _rpos_sca;
_rposy += _rpos[1] * _rpos_sca;
}
} else if(_pat == 1) {
var row = floor(i / _col);
var col = safe_mod(i, _col);
@ -437,9 +453,9 @@ function Node_Repeat(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) co
posy = _spos[1] + lengthdir_y(_arad, aa);
}
scax = eval_curve_x(_msca, i / (_amo - 1)) * _rsca;
scax = eval_curve_x(_msca, _prg) * _rsca;
scay = scax;
rot = _rots + lerp(_rrot[0], _rrot[1], i / _amo);
rot = _rots + lerp(_rrot[0], _rrot[1], i / _amo);
var _surf = _iSrf;
if(is_array(_iSrf)) {

View file

@ -118,6 +118,10 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
newInput(40, nodeValue_Vec2("Anchor", self, [ 0.5, 0.5 ]));
inputs[40].setDisplay(VALUE_DISPLAY.vector, { side_button : new buttonAnchor(inputs[40]) });
newInput(41, nodeValue_Surface("Sample Surface", self, noone));
newInput(42, nodeValue_Vec2_Range("Sample Wiggle", self, [ 0, 0, 0, 0 ]));
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
newOutput(0, nodeValue_Output("Surface Out", self, VALUE_TYPE.surface, noone));
@ -127,13 +131,14 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
.rejectArrayProcess();
input_display_list = [ 10,
["Surfaces", true], 0, 1, 15, 24, 25, 26, 27,
["Scatter", false], 6, 5, 13, 14, 17, 9, 31, 2, 30, 35,
["Path", false], 19, 38, 20, 21, 22,
["Position", false], 40, 33, 36, 37, 39,
["Rotation", false], 7, 4, 32,
["Scale", false], 3, 8, 34,
["Render", false], 18, 11, 28, 12, 16, 23,
["Surfaces", true], 0, 1, 15, 24, 25, 26, 27,
["Scatter", false], 6, 5, 13, 14, 17, 9, 31, 2, 30, 35,
["Path", false], 19, 38, 20, 21, 22,
["Position", false], 40, 33, 36, 37, 39,
["Rotation", false], 7, 4, 32,
["Scale", false], 3, 8, 34,
["Color", false], 11, 28, 12, 16, 41, 42,
["Render", false], 18, 23,
];
attribute_surface_depth();
@ -148,6 +153,8 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
scatter_maps = 0;
scatter_mapp = [];
surfSamp = new Surface_sampler();
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny) {
PROCESSOR_OVERLAY_CHECK
@ -285,6 +292,9 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
var shfRad = _data[39];
var anchor = _data[40];
var sampSrf = _data[41]; surfSamp.setSurface(sampSrf);
var sampWig = _data[42];
var _in_w, _in_h;
var vSca = array_exists(useV, "Scale");
@ -561,9 +571,7 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
var _animInd = ind + CURRENT_FRAME * _arrAnim_spd;
switch(arrAnimEnd) {
case 0 :
ind = safe_mod(_animInd, _arrLen);
break;
case 0 : ind = safe_mod(_animInd, _arrLen); break;
case 1 :
var pp = safe_mod(_animInd, _arrLen * 2 - 1);
@ -600,15 +608,18 @@ function Node_Scatter(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) c
if(vCol && _v != noone)
grSamp *= _v;
var clr = _clrUni? _clrSin : evaluate_gradient_map(grSamp, color, clr_map, clr_rng, inputs[11], true);
var clr = _clrUni? _clrSin : evaluate_gradient_map(grSamp, color, clr_map, clr_rng, inputs[11], true);
var alp = _alpUni? alpha[0] : random_range_seed(alpha[0], alpha[1], _sed++);
var _atl = _sct_len >= _datLen? noone : scatter_data[_sct_len];
if(posExt) {
_x = round(_x);
_y = round(_y);
if(surfSamp.active) {
var _samC = surfSamp.getPixel(_x + random_range_seed(sampWig[0], sampWig[1], _sed++), _y + random_range_seed(sampWig[2], sampWig[3], _sed++));
clr = colorMultiply(clr, _samC);
alp *= color_get_alpha(_samC);
}
if(posExt) { _x = round(_x); _y = round(_y); }
if(!is(_atl, SurfaceAtlasFast)) _atl = new SurfaceAtlasFast(surf, _x, _y, _r, _scx, _scy, clr, alp);
else _atl.set(surf, _x, _y, _r, _scx, _scy, clr, alp);

View file

@ -16,6 +16,7 @@
function panel_animation_copy() { CALL("animation_copy"); PANEL_ANIMATION.doCopy(); }
function panel_animation_paste() { CALL("animation_paste"); if(PANEL_ANIMATION.value_focusing != noone) PANEL_ANIMATION.doPaste(PANEL_ANIMATION.value_focusing.prop); }
function panel_animation_show_nodes() { CALL("animation_toggle_nodes"); PANEL_ANIMATION.show_nodes = !PANEL_ANIMATION.show_nodes; }
function panel_animation_quantize() { CALL("animation_quantize"); PANEL_ANIMATION.doQuantize(); }
function panel_animation_edit_keyframe_value() { CALL("animation_edit_keyframe_value"); PANEL_ANIMATION.edit_keyframe_value(); }
function panel_animation_edit_keyframe_lock_y() { CALL("animation_edit_lock_keyframe_y"); PANEL_ANIMATION.edit_keyframe_lock_y(); }
@ -53,6 +54,7 @@
registerFunction("Animation", "Paste", "V", MOD_KEY.ctrl, panel_animation_paste ).setMenu("animation_paste", THEME.paste)
registerFunction("Animation", "Collapse Toggle", "C", MOD_KEY.none, panel_animation_collapseToggle ).setMenu("animation_collapse_toggle", )
registerFunction("Animation", "Toggle Nodes", "H", MOD_KEY.none, panel_animation_show_nodes ).setMenu("animation_toggle_nodes", )
registerFunction("Animation", "Quantize", "Q", MOD_KEY.none, panel_animation_quantize ).setMenu("animation_quantize", )
registerFunction("Animation", "Settings", "S", MOD_KEY.ctrl | MOD_KEY.shift, panel_animation_settings ).setMenu("animation_settings", THEME.animation_setting )
registerFunction("Animation", "Scaler", "", MOD_KEY.none, panel_animation_scale ).setMenu("animation_scaler", THEME.animation_timing )
@ -210,8 +212,13 @@ function Panel_Animation() : PanelContent() constructor {
keyframe_drag_my = 0;
keyframe_drag_sv = 0;
keyframe_drag_st = 0;
keyframe_selecting = [];
keyframe_selecting = [];
keyframe_selecting_f = noone;
keyframe_selecting_l = noone;
_keyframe_selecting_f = noone;
_keyframe_selecting_l = noone;
keyframe_boxable = true;
keyframe_boxing = false;
keyframe_box_sx = -1;
@ -1427,6 +1434,7 @@ function Panel_Animation() : PanelContent() constructor {
}
var hc = COLORS._main_accent;
var sca_back = noone;
if(pHOVER && point_in_circle(msx, msy, t, prop_y, ui(8))) {
cc = COLORS.panel_animation_keyframe_selected;
@ -1434,6 +1442,11 @@ function Panel_Animation() : PanelContent() constructor {
if(!instance_exists(o_dialog_menubox))
TOOLTIP = [ keyframe.value, animator.prop.type ];
if(_scaling) {
hc = CDEF.cyan;
sca_back = keyframe.time == keyframe_selecting_f.time;
}
if(pFOCUS && !key_mod_press(SHIFT)) {
if(DOUBLE_CLICK) {
@ -1453,11 +1466,12 @@ function Panel_Animation() : PanelContent() constructor {
keyframe_drag_mx = mx;
keyframe_drag_my = my;
keyframe_drag_st = keyframe.time;
keyframe_drag_sv = sca_back? keyframe_selecting_l : keyframe_selecting_f;
}
}
}
if(_scaling) hc = CDEF.cyan;
}
if(stagger_mode == 1 && _select)
@ -1467,8 +1481,19 @@ function Panel_Animation() : PanelContent() constructor {
draw_sprite_ui_uniform(THEME.timeline_keyframe, ind, t, prop_y, 1, cc);
if(_select) {
if(keyframe_drag_sv == noone) keyframe_drag_sv = keyframe;
if(_keyframe_selecting_f == noone) _keyframe_selecting_f = keyframe;
else _keyframe_selecting_f = keyframe.time < _keyframe_selecting_f.time? keyframe : _keyframe_selecting_f;
if(_keyframe_selecting_l == noone) _keyframe_selecting_l = keyframe;
else _keyframe_selecting_l = keyframe.time > _keyframe_selecting_l.time? keyframe : _keyframe_selecting_l;
if(_scaling && sca_back != noone) {
if(sca_back) draw_sprite_ui_uniform(THEME.arrow, 2, t - ui(12), prop_y, 1, CDEF.cyan, .5);
else draw_sprite_ui_uniform(THEME.arrow, 0, t + ui(12), prop_y, 1, CDEF.cyan, .5);
}
draw_sprite_ui_uniform(THEME.timeline_keyframe_selecting, ind, t, prop_y, 1, hc);
}
if(keyframe_boxing) {
@ -2096,7 +2121,9 @@ function Panel_Animation() : PanelContent() constructor {
}
#region ======= draw keys =======
keyframe_drag_sv = noone;
_keyframe_selecting_f = noone;
_keyframe_selecting_l = noone;
for( var i = 0, n = array_length(timeline_contents); i < n; i++ ) {
var _cont = timeline_contents[i];
if(_cont.type != "node") continue;
@ -2108,6 +2135,9 @@ function Panel_Animation() : PanelContent() constructor {
}
}
keyframe_selecting_f = _keyframe_selecting_f;
keyframe_selecting_l = _keyframe_selecting_l;
#endregion
if(pHOVER && point_in_rectangle(msx, msy, 0, ui(18), dope_sheet_w, dope_sheet_h)) { // selection & stagger

View file

@ -0,0 +1,30 @@
function Surface_sampler(s = noone) constructor {
active = false;
surface = noone;
buffer = noone;
sw = 1;
sh = 1;
static setSurface = function(s) {
if(buffer != noone) buffer_delete(buffer);
surface = s;
buffer = noone;
active = is_surface(surface);
if(!active) return;
sw = surface_get_width(surface);
sh = surface_get_height(surface);
buffer = buffer_create(sw * sh * 4, buffer_fixed, 1);
buffer_get_surface(buffer, surface, 0);
}
setSurface(s);
static getPixel = function(_x, _y) { return buffer_read_at(buffer, (clamp(round(_y), 0, sh - 1) * sw + clamp(round(_x), 0, sw - 1)) * 4, buffer_u32); }
static free = function() {
buffer_delete_safe(buffer);
}
}

View file

@ -0,0 +1,14 @@
{
"$GMScript":"v1",
"%Name":"surface_sampler",
"isCompatibility":false,
"isDnD":false,
"name":"surface_sampler",
"parent":{
"name":"surface",
"path":"folders/functions/surface.yy",
},
"resourceType":"GMScript",
"resourceVersion":"2.0",
"tags":[],
}