mirror of
https://github.com/Ttanasart-pt/Pixel-Composer.git
synced 2024-12-25 14:36:13 +01:00
- [L System] Improve generation performance.
This commit is contained in:
parent
9e14536790
commit
734601b5d8
12 changed files with 157 additions and 81 deletions
|
@ -189,6 +189,7 @@
|
|||
{"name":"blinker","order":30,"path":"folders/shader/generator/blinker.yy",},
|
||||
{"name":"cell","order":31,"path":"folders/shader/generator/cell.yy",},
|
||||
{"name":"grid","order":32,"path":"folders/shader/generator/grid.yy",},
|
||||
{"name":"interpret","order":35,"path":"folders/shader/generator/interpret.yy",},
|
||||
{"name":"noise","order":33,"path":"folders/shader/generator/noise.yy",},
|
||||
{"name":"random shape","order":29,"path":"folders/shader/generator/random shape.yy",},
|
||||
{"name":"region","order":34,"path":"folders/shader/generator/region.yy",},
|
||||
|
@ -209,7 +210,6 @@
|
|||
{"name":"biterator","order":2,"path":"folders/VCT/biterator.yy",},
|
||||
{"name":"widget","order":3,"path":"folders/VCT/widget.yy",},
|
||||
{"name":"widgets","order":5,"path":"folders/widgets.yy",},
|
||||
{"name":"interpret","order":35,"path":"folders/shader/generator/interpret.yy",},
|
||||
],
|
||||
"ResourceOrderSettings": [
|
||||
{"name":"s_node_corner","order":16,"path":"sprites/s_node_corner/s_node_corner.yy",},
|
||||
|
@ -669,7 +669,7 @@
|
|||
{"name":"node_VFX_effect_destroy","order":12,"path":"scripts/node_VFX_effect_destroy/node_VFX_effect_destroy.yy",},
|
||||
{"name":"node_cache","order":9,"path":"scripts/node_cache/node_cache.yy",},
|
||||
{"name":"sh_bw","order":3,"path":"shaders/sh_bw/sh_bw.yy",},
|
||||
{"name":"real_comparison","order":18,"path":"scripts/real_comparison/real_comparison.yy",},
|
||||
{"name":"var_comparison","order":1,"path":"scripts/var_comparison/var_comparison.yy",},
|
||||
{"name":"node_array_zip","order":25,"path":"scripts/node_array_zip/node_array_zip.yy",},
|
||||
{"name":"fd_rectangle_get_collision_mask_sprite_image","order":5,"path":"scripts/fd_rectangle_get_collision_mask_sprite_image/fd_rectangle_get_collision_mask_sprite_image.yy",},
|
||||
{"name":"s_node_stripe","order":16,"path":"sprites/s_node_stripe/s_node_stripe.yy",},
|
||||
|
|
|
@ -225,6 +225,7 @@
|
|||
{"resourceType":"GMFolder","resourceVersion":"1.0","name":"blinker","folderPath":"folders/shader/generator/blinker.yy",},
|
||||
{"resourceType":"GMFolder","resourceVersion":"1.0","name":"cell","folderPath":"folders/shader/generator/cell.yy",},
|
||||
{"resourceType":"GMFolder","resourceVersion":"1.0","name":"grid","folderPath":"folders/shader/generator/grid.yy",},
|
||||
{"resourceType":"GMFolder","resourceVersion":"1.0","name":"interpret","folderPath":"folders/shader/generator/interpret.yy",},
|
||||
{"resourceType":"GMFolder","resourceVersion":"1.0","name":"noise","folderPath":"folders/shader/generator/noise.yy",},
|
||||
{"resourceType":"GMFolder","resourceVersion":"1.0","name":"random shape","folderPath":"folders/shader/generator/random shape.yy",},
|
||||
{"resourceType":"GMFolder","resourceVersion":"1.0","name":"region","folderPath":"folders/shader/generator/region.yy",},
|
||||
|
@ -248,7 +249,6 @@
|
|||
{"resourceType":"GMFolder","resourceVersion":"1.0","name":"biterator","folderPath":"folders/VCT/biterator.yy",},
|
||||
{"resourceType":"GMFolder","resourceVersion":"1.0","name":"widget","folderPath":"folders/VCT/widget.yy",},
|
||||
{"resourceType":"GMFolder","resourceVersion":"1.0","name":"widgets","folderPath":"folders/widgets.yy",},
|
||||
{"resourceType":"GMFolder","resourceVersion":"1.0","name":"interpret","folderPath":"folders/shader/generator/interpret.yy",},
|
||||
],
|
||||
"IncludedFiles": [
|
||||
{"resourceType":"GMIncludedFile","resourceVersion":"1.0","name":"ApolloHelp.html","ConfigValues":{"Itch":{"CopyToMask":"0",},},"CopyToMask":-1,"filePath":"datafiles",},
|
||||
|
@ -1272,7 +1272,7 @@
|
|||
{"id":{"name":"node_VFX_effect_destroy","path":"scripts/node_VFX_effect_destroy/node_VFX_effect_destroy.yy",},},
|
||||
{"id":{"name":"node_cache","path":"scripts/node_cache/node_cache.yy",},},
|
||||
{"id":{"name":"sh_bw","path":"shaders/sh_bw/sh_bw.yy",},},
|
||||
{"id":{"name":"real_comparison","path":"scripts/real_comparison/real_comparison.yy",},},
|
||||
{"id":{"name":"var_comparison","path":"scripts/var_comparison/var_comparison.yy",},},
|
||||
{"id":{"name":"sh_sdf_tex","path":"shaders/sh_sdf_tex/sh_sdf_tex.yy",},},
|
||||
{"id":{"name":"node_array_zip","path":"scripts/node_array_zip/node_array_zip.yy",},},
|
||||
{"id":{"name":"fd_rectangle_get_collision_mask_sprite_image","path":"scripts/fd_rectangle_get_collision_mask_sprite_image/fd_rectangle_get_collision_mask_sprite_image.yy",},},
|
||||
|
|
|
@ -16,8 +16,9 @@ if(PROJECT.active) {
|
|||
PROJECT.nodes[| i].triggerCheck();
|
||||
PROJECT.nodes[| i].step();
|
||||
}
|
||||
} catch(e)
|
||||
} catch(e) {
|
||||
noti_warning("Step error: " + exception_print(e));
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ function controlPointBox(_onModify) : widget() constructor {
|
|||
tbW.draw(_x + lw, yy, _w - lw, TEXTBOX_HEIGHT, _wid, _m);
|
||||
yy += TEXTBOX_HEIGHT + ui(8);
|
||||
|
||||
rot.draw(_x + _w / 2, yy, _fy, _m);
|
||||
rot.draw(_x + _w / 2, yy, _w, _fy, _m);
|
||||
yy += ui(94 + 8);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ function __3dCamera_object() : __3dObject() constructor {
|
|||
VB = build();
|
||||
|
||||
transform.position.set(-5, -5, 5);
|
||||
transform.rotation.set(0, 30, 135);
|
||||
transform.rotation.FromEuler(0, 30, 135);
|
||||
transform.scale.set(1, room_width / room_height, 1);
|
||||
|
||||
static submitSel = function(params = {}) {
|
||||
|
|
|
@ -70,7 +70,7 @@ function __3dObject() constructor {
|
|||
}
|
||||
} #endregion
|
||||
|
||||
static buildVertex = function(_vertex, _normal, _uv) { #region
|
||||
static buildVertex = function(_vertex) { #region
|
||||
var _buffer = vertex_create_buffer();
|
||||
vertex_begin(_buffer, VF);
|
||||
for( var i = 0, n = array_length(_vertex); i < n; i++ ) {
|
||||
|
|
|
@ -162,7 +162,7 @@ function variable_editor(nodeVal) constructor {
|
|||
draw_set_text(f_p0, fa_left, fa_center, COLORS._main_text_sub);
|
||||
draw_text(_x + ui(8), _y + wd_h / 2, "Range");
|
||||
|
||||
vb_range.draw(_x + lb_w, _y, _w - lb_w, wd_h, slider_range, _m);
|
||||
vb_range.draw(_x + lb_w, _y, _w - lb_w, wd_h, slider_range, noone, _m);
|
||||
_h += wd_h + ui(4);
|
||||
_y += wd_h + ui(4);
|
||||
|
||||
|
|
|
@ -77,6 +77,14 @@ function Node_Path_L_System(_x, _y, _group = noone) : Node(_x, _y, _group) const
|
|||
}
|
||||
|
||||
return hh;
|
||||
}, function(parent = noone) {
|
||||
for( var i = input_fix_len; i < ds_list_size(inputs); i += data_length ) {
|
||||
var _name = inputs[| i + 0];
|
||||
var _rule = inputs[| i + 1];
|
||||
|
||||
_name.editWidget.register(parent);
|
||||
_rule.editWidget.register(parent);
|
||||
}
|
||||
}); #endregion
|
||||
|
||||
input_display_list = [
|
||||
|
@ -89,6 +97,15 @@ function Node_Path_L_System(_x, _y, _group = noone) : Node(_x, _y, _group) const
|
|||
current_length = 0;
|
||||
boundary = new BoundingBox();
|
||||
|
||||
cache_data = {
|
||||
start: "",
|
||||
rules: {},
|
||||
end_rule: "",
|
||||
iteration: 0,
|
||||
seed: 0,
|
||||
result: ""
|
||||
}
|
||||
|
||||
static refreshDynamicInput = function() { #region
|
||||
var _l = ds_list_create();
|
||||
|
||||
|
@ -175,97 +192,119 @@ function Node_Path_L_System(_x, _y, _group = noone) : Node(_x, _y, _group) const
|
|||
return new __vec2( _x, _y );
|
||||
} #endregion
|
||||
|
||||
static getPointDistance = function(_dist, _ind = 0) {
|
||||
static getPointDistance = function(_dist, _ind = 0) { #region
|
||||
return getPointRatio(_dist / current_length, _ind);
|
||||
}
|
||||
} #endregion
|
||||
|
||||
static getBoundary = function() { return boundary; }
|
||||
|
||||
static l_system = function(_start, _rules, _end_rule, _iteration, _seed) { #region
|
||||
if(isEqual(cache_data.rules, _rules, true)
|
||||
&& cache_data.start == _start
|
||||
&& cache_data.end_rule == _end_rule
|
||||
&& cache_data.iteration == _iteration
|
||||
&& cache_data.seed == _seed) {
|
||||
|
||||
return cache_data.result;
|
||||
}
|
||||
|
||||
cache_data.start = _start;
|
||||
cache_data.rules = _rules;
|
||||
cache_data.end_rule = _end_rule;
|
||||
cache_data.iteration = _iteration;
|
||||
cache_data.seed = _seed;
|
||||
cache_data.result = _start;
|
||||
|
||||
_temp_s = "";
|
||||
|
||||
for( var j = 1; j <= _iteration; j++ ) {
|
||||
_temp_s = "";
|
||||
|
||||
string_foreach(cache_data.result, function(_ch, _) {
|
||||
if(!struct_has(cache_data.rules, _ch)) {
|
||||
_temp_s += _ch;
|
||||
return;
|
||||
}
|
||||
|
||||
var _chr = cache_data.rules[$ _ch];
|
||||
_chr = array_safe_get(_chr, irandom(array_length(_chr) - 1));
|
||||
|
||||
_temp_s += _chr;
|
||||
})
|
||||
|
||||
cache_data.result = _temp_s;
|
||||
if(string_length(cache_data.result) > 10000) break;
|
||||
}
|
||||
|
||||
var _es = string_splice(_end_rule, ",");
|
||||
for( var i = 0, n = array_length(_es); i < n; i++ ) {
|
||||
var _sp = string_splice(_es[i], "=");
|
||||
if(array_length(_sp) == 2)
|
||||
cache_data.result = string_replace_all(cache_data.result, _sp[0], _sp[1]);
|
||||
}
|
||||
|
||||
return cache_data.result;
|
||||
} #endregion
|
||||
|
||||
static update = function() { #region
|
||||
var _len = inputs[| 0].getValue();
|
||||
var _ang = inputs[| 1].getValue();
|
||||
var _pos = inputs[| 2].getValue();
|
||||
var _itr = inputs[| 3].getValue();
|
||||
var _sta = inputs[| 4].getValue();
|
||||
var _end = inputs[| 5].getValue();
|
||||
var _san = inputs[| 6].getValue();
|
||||
var _sad = inputs[| 7].getValue();
|
||||
lines = [];
|
||||
lineq = ds_queue_create();
|
||||
|
||||
random_set_seed(_sad);
|
||||
current_length = _len;
|
||||
|
||||
if(ds_list_size(inputs) < input_fix_len + 2) return;
|
||||
|
||||
var l = inputs[| 4].getValue();
|
||||
|
||||
var rules = ds_map_create();
|
||||
var rules = {};
|
||||
for( var i = input_fix_len; i < ds_list_size(inputs) - data_length; i += data_length ) {
|
||||
var _name = inputs[| i + 0].getValue();
|
||||
var _rule = inputs[| i + 1].getValue();
|
||||
if(!ds_map_exists(rules, _name))
|
||||
rules[? _name] = [ _rule ];
|
||||
if(!struct_has(rules, _name))
|
||||
rules[$ _name] = [ _rule ];
|
||||
else
|
||||
array_push(rules[? _name], _rule);
|
||||
array_push(rules[$ _name], _rule);
|
||||
}
|
||||
|
||||
for( var j = 1; j <= _itr; j++ ) {
|
||||
var s = "";
|
||||
for( var i = 1; i <= string_length(l); i++ ) {
|
||||
var ch = string_char_at(l, i);
|
||||
if(!ds_map_exists(rules, ch)) {
|
||||
s += ch;
|
||||
continue;
|
||||
}
|
||||
l_system(_sta, rules, _end, _itr, _sad);
|
||||
itr = _itr;
|
||||
ang = _ang;
|
||||
len = _len;
|
||||
st = ds_stack_create();
|
||||
t = new L_Turtle(_pos[0], _pos[1], _san);
|
||||
|
||||
var _chr = rules[? ch];
|
||||
_chr = array_safe_get(_chr, irandom(array_length(_chr) - 1));
|
||||
|
||||
s += _chr;
|
||||
}
|
||||
|
||||
l = s;
|
||||
if(string_length(l) > 10000) break;
|
||||
}
|
||||
|
||||
ds_map_destroy(rules);
|
||||
|
||||
var _end = inputs[| 5].getValue();
|
||||
var _es = string_splice(_end, ",");
|
||||
for( var i = 0, n = array_length(_es); i < n; i++ ) {
|
||||
var _sp = string_splice(_es[i], "=");
|
||||
if(array_length(_sp) == 2)
|
||||
l = string_replace_all(l, _sp[0], _sp[1]);
|
||||
}
|
||||
|
||||
var st = ds_stack_create();
|
||||
var t = new L_Turtle(_pos[0], _pos[1], _san);
|
||||
|
||||
for( var i = 1; i <= string_length(l); i++ ) {
|
||||
var ch = string_char_at(l, i);
|
||||
switch(ch) {
|
||||
string_foreach(cache_data.result, function(_ch, _) {
|
||||
switch(_ch) {
|
||||
case "F":
|
||||
var nx = t.x + lengthdir_x(_len, t.ang);
|
||||
var ny = t.y + lengthdir_y(_len, t.ang);
|
||||
var nx = t.x + lengthdir_x(len, t.ang);
|
||||
var ny = t.y + lengthdir_y(len, t.ang);
|
||||
|
||||
array_push(lines, [ [t.x, t.y, t.w], [nx, ny, t.w] ]);
|
||||
ds_queue_enqueue(lineq, [ [t.x, t.y, t.w], [nx, ny, t.w] ]);
|
||||
|
||||
t.x = nx;
|
||||
t.y = ny;
|
||||
break;
|
||||
case "G":
|
||||
t.x = t.x + lengthdir_x(_len, t.ang);
|
||||
t.y = t.y + lengthdir_y(_len, t.ang);
|
||||
t.x = t.x + lengthdir_x(len, t.ang);
|
||||
t.y = t.y + lengthdir_y(len, t.ang);
|
||||
break;
|
||||
case "f":
|
||||
var nx = t.x + lengthdir_x(_len * frac(_itr), t.ang);
|
||||
var ny = t.y + lengthdir_y(_len * frac(_itr), t.ang);
|
||||
var nx = t.x + lengthdir_x(len * frac(itr), t.ang);
|
||||
var ny = t.y + lengthdir_y(len * frac(itr), t.ang);
|
||||
|
||||
array_push(lines, [ [t.x, t.y, t.w], [nx, ny, t.w] ]);
|
||||
ds_queue_enqueue(lineq, [ [t.x, t.y, t.w], [nx, ny, t.w] ]);
|
||||
|
||||
t.x = nx;
|
||||
t.y = ny;
|
||||
break;
|
||||
case "+": t.ang += _ang; break;
|
||||
case "-": t.ang -= _ang; break;
|
||||
case "+": t.ang += ang; break;
|
||||
case "-": t.ang -= ang; break;
|
||||
case "|": t.ang += 180; break;
|
||||
case "[": ds_stack_push(st, t.clone()); break;
|
||||
case "]": t = ds_stack_pop(st); break;
|
||||
|
@ -273,13 +312,22 @@ function Node_Path_L_System(_x, _y, _group = noone) : Node(_x, _y, _group) const
|
|||
case ">": t.w += 0.1; break;
|
||||
case "<": t.w -= 0.1; break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ds_stack_destroy(st);
|
||||
|
||||
boundary = new BoundingBox();
|
||||
for( var i = 0, n = array_length(lines); i < n; i++ )
|
||||
boundary.addPoint(lines[i][0][0], lines[i][0][1], lines[i][1][0], lines[i][1][1]);
|
||||
|
||||
lines = array_create(ds_queue_size(lineq));
|
||||
var i = 0;
|
||||
|
||||
while(!ds_queue_empty(lineq)) {
|
||||
var _l = ds_queue_dequeue(lineq);
|
||||
lines[i++] = _l;
|
||||
boundary.addPoint(_l[0][0], _l[0][1], _l[1][0], _l[1][1]);
|
||||
}
|
||||
|
||||
ds_queue_destroy(lineq);
|
||||
|
||||
outputs[| 0].setValue(self);
|
||||
} #endregion
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
function Inspector_Custom_Renderer(drawFn) : widget() constructor {
|
||||
function Inspector_Custom_Renderer(drawFn, registerFn = noone) : widget() constructor {
|
||||
h = 64;
|
||||
self.draw = drawFn;
|
||||
register = registerFn;
|
||||
}
|
||||
|
||||
function Panel_Inspector() : PanelContent() constructor {
|
||||
|
@ -463,6 +464,8 @@ function Panel_Inspector() : PanelContent() constructor {
|
|||
if(pFOCUS) jun_disp.register(contentPane);
|
||||
jun_disp.rx = ui(16) + x;
|
||||
jun_disp.ry = top_bar_h + y;
|
||||
if(is_callable(jun_disp.register))
|
||||
jun_disp.register(contentPane);
|
||||
|
||||
hh += jun_disp.draw(ui(6), yy, con_w - ui(12), _m, _hover, pFOCUS) + ui(8);
|
||||
continue;
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
function isEqual(val1, val2) {
|
||||
if(!is_array(val1) && !is_array(val2)) return val1 == val2;
|
||||
if(is_array(val1) ^ is_array(val2)) return false;
|
||||
if(array_length(val1) != array_length(val2)) return false;
|
||||
|
||||
for( var i = 0, n = array_length(val1); i < n; i++ ) {
|
||||
if(val1[i] != val2[i]) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
35
scripts/var_comparison/var_comparison.gml
Normal file
35
scripts/var_comparison/var_comparison.gml
Normal file
|
@ -0,0 +1,35 @@
|
|||
function isEqual(val1, val2, struct_expand = false) {
|
||||
gml_pragma("forceinline");
|
||||
|
||||
if(is_array(val1) && is_array(val2)) return array_member_equal(val1, val2);
|
||||
if(struct_expand && is_struct(val1) && is_struct(val2)) return struct_equal(val1, val2);
|
||||
|
||||
return val1 == val2;
|
||||
}
|
||||
|
||||
function array_member_equal(arr1, arr2) {
|
||||
gml_pragma("forceinline");
|
||||
|
||||
if(array_length(arr1) != array_length(arr2)) return false;
|
||||
|
||||
for( var i = 0, n = array_length(arr1); i < n; i++ )
|
||||
if(!isEqual(arr1[i], arr2[i])) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function struct_equal(str1, str2) {
|
||||
gml_pragma("forceinline");
|
||||
|
||||
//return json_stringify(str1) == json_stringify(str2);
|
||||
|
||||
var key1 = variable_struct_get_names(str1);
|
||||
var key2 = variable_struct_get_names(str2);
|
||||
|
||||
if(!array_equals(key1, key2)) return false;
|
||||
|
||||
for( var i = 0, n = array_length(key1); i < n; i++ )
|
||||
if(!isEqual(str1[$ key1[i]], str2[$ key1[i]])) return false;
|
||||
|
||||
return true;
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"resourceType": "GMScript",
|
||||
"resourceVersion": "1.0",
|
||||
"name": "real_comparison",
|
||||
"name": "var_comparison",
|
||||
"isCompatibility": false,
|
||||
"isDnD": false,
|
||||
"parent": {
|
||||
"name": "value",
|
||||
"path": "folders/functions/value.yy",
|
||||
"name": "variables",
|
||||
"path": "folders/functions/variables.yy",
|
||||
},
|
||||
}
|
Loading…
Reference in a new issue