mirror of
https://github.com/Ttanasart-pt/Pixel-Composer.git
synced 2024-09-21 21:01:20 +02:00
158 lines
4.0 KiB
Plaintext
158 lines
4.0 KiB
Plaintext
|
function Node_Palette_Extract(_x, _y, _group = -1) : Node_Processor(_x, _y, _group) constructor {
|
||
|
name = "Palette extract";
|
||
|
|
||
|
|
||
|
w = 96;
|
||
|
|
||
|
inputs[| 0] = nodeValue(0, "Surface in", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, 0);
|
||
|
|
||
|
inputs[| 1] = nodeValue(1, "Colors", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 5);
|
||
|
|
||
|
inputs[| 2] = nodeValue(2, "Seed", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, irandom(99999));
|
||
|
|
||
|
outputs[| 0] = nodeValue(0, "Palette", self, JUNCTION_CONNECT.output, VALUE_TYPE.color, [ ])
|
||
|
.setDisplay(VALUE_DISPLAY.palette);
|
||
|
|
||
|
static getPreviewValue = function() { return inputs[| 0]; }
|
||
|
|
||
|
input_display_list = [
|
||
|
["Surface", false], 0,
|
||
|
["Palette", false], 1, 2,
|
||
|
]
|
||
|
|
||
|
current_palette = [];
|
||
|
current_color = 0;
|
||
|
|
||
|
function extractPalette(_surfFull, _size, _seed) {
|
||
|
var _surf = surface_create(min(32, surface_get_width(_surfFull)), min(32, surface_get_height(_surfFull)));
|
||
|
_size = max(1, _size);
|
||
|
|
||
|
var ww = surface_get_width(_surf);
|
||
|
var hh = surface_get_height(_surf);
|
||
|
|
||
|
surface_set_target(_surf);
|
||
|
draw_clear_alpha(0, 0);
|
||
|
BLEND_OVERRIDE
|
||
|
gpu_set_texfilter(true);
|
||
|
draw_surface_stretched(_surfFull, 0, 0, ww, hh);
|
||
|
gpu_set_texfilter(false);
|
||
|
BLEND_NORMAL
|
||
|
surface_reset_target();
|
||
|
|
||
|
var c_buffer = buffer_create(ww * hh * 4, buffer_fixed, 2);
|
||
|
var colors = array_create(ww * hh);
|
||
|
|
||
|
buffer_get_surface(c_buffer, _surf, 0);
|
||
|
buffer_seek(c_buffer, buffer_seek_start, 0);
|
||
|
|
||
|
var _min = [ 1, 1, 1 ];
|
||
|
var _max = [ 0, 0, 0 ];
|
||
|
|
||
|
for( var i = 0; i < ww * hh; i++ ) {
|
||
|
var c = buffer_read(c_buffer, buffer_u32) & ~(0b11111111 << 24);
|
||
|
colors[i] = [ color_get_hue(c) / 255, color_get_saturation(c) / 255, color_get_value(c) / 255, 0 ];
|
||
|
for( var j = 0; j < 3; j++ ) {
|
||
|
_min[j] = min(_min[j], colors[i][j]);
|
||
|
_max[j] = max(_max[j], colors[i][j]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
buffer_delete(c_buffer);
|
||
|
|
||
|
var cnt = [];
|
||
|
random_set_seed(_seed);
|
||
|
for( var i = 0; i < _size; i++ )
|
||
|
cnt[i] = [ random(1), random(1), random(1), 0 ];
|
||
|
|
||
|
repeat(8) {
|
||
|
var _cnt = [];
|
||
|
for( var i = 0; i < _size; i++ ) {
|
||
|
_cnt[i][0] = cnt[i][0];
|
||
|
_cnt[i][1] = cnt[i][1];
|
||
|
_cnt[i][2] = cnt[i][2];
|
||
|
}
|
||
|
|
||
|
for( var i = 0; i < ww * hh; i++ ) {
|
||
|
var ind = 0;
|
||
|
var dist = 999;
|
||
|
var _cl = colors[i];
|
||
|
|
||
|
for( var j = 0; j < _size; j++ ) {
|
||
|
var _cn = cnt[j];
|
||
|
var d = point_distance_3d(_cl[0], _cl[1], _cl[2], _cn[0], _cn[1], _cn[2]);
|
||
|
if(d < dist) {
|
||
|
dist = d;
|
||
|
ind = j;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
colors[i][3] = ind;
|
||
|
}
|
||
|
|
||
|
for( var i = 0; i < _size; i++ )
|
||
|
cnt[i] = [ 0, 0, 0, 0 ];
|
||
|
|
||
|
for( var i = 0; i < ww * hh; i++ ) {
|
||
|
var _cl = colors[i];
|
||
|
cnt[_cl[3]][0] += _cl[0];
|
||
|
cnt[_cl[3]][1] += _cl[1];
|
||
|
cnt[_cl[3]][2] += _cl[2];
|
||
|
cnt[_cl[3]][3]++;
|
||
|
}
|
||
|
|
||
|
for( var i = 0; i < _size; i++ ) {
|
||
|
cnt[i][0] = cnt[i][3]? cnt[i][0] / cnt[i][3] : 0;
|
||
|
cnt[i][1] = cnt[i][3]? cnt[i][1] / cnt[i][3] : 0;
|
||
|
cnt[i][2] = cnt[i][3]? cnt[i][2] / cnt[i][3] : 0;
|
||
|
}
|
||
|
|
||
|
var del = 0;
|
||
|
for( var i = 0; i < _size; i++ ) {
|
||
|
del = max(del, point_distance_3d(cnt[i][0], cnt[i][1], cnt[i][2], _cnt[i][0], _cnt[i][1], _cnt[i][2]));
|
||
|
}
|
||
|
|
||
|
if(del < 0.001) break;
|
||
|
}
|
||
|
|
||
|
var palette = array_create(_size);
|
||
|
|
||
|
for( var i = 0; i < _size; i++ ) {
|
||
|
var closet = 0;
|
||
|
var dist = 999;
|
||
|
var _cl = cnt[i];
|
||
|
|
||
|
for( var j = 0; j < ww * hh; j++ ) {
|
||
|
var _cn = colors[j];
|
||
|
var d = point_distance_3d(_cl[0], _cl[1], _cl[2], _cn[0], _cn[1], _cn[2]);
|
||
|
|
||
|
if(d < dist) {
|
||
|
dist = d;
|
||
|
closet = j;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
palette[i] = make_color_hsv(colors[closet][0] * 255, colors[closet][1] * 255, colors[closet][2] * 255);
|
||
|
}
|
||
|
|
||
|
surface_free(_surf);
|
||
|
|
||
|
return palette;
|
||
|
}
|
||
|
|
||
|
function process_data(_output, _data, index = 0) {
|
||
|
var _surf = _data[0];
|
||
|
var _size = _data[1];
|
||
|
var _seed = _data[2];
|
||
|
|
||
|
if(!is_surface(_surf)) return [];
|
||
|
|
||
|
return extractPalette(_surf, _size, _seed);
|
||
|
}
|
||
|
|
||
|
static onDrawNode = function(xx, yy, _mx, _my, _s) {
|
||
|
var bbox = drawGetBbox(xx, yy, _s);
|
||
|
if(bbox.h < 1) return;
|
||
|
|
||
|
drawPalette(outputs[| 0].getValue(), bbox.x0, bbox.y0, bbox.w, bbox.h);
|
||
|
}
|
||
|
}
|