Pixel-Composer/scripts/node_camera/node_camera.gml

232 lines
7.2 KiB
Text
Raw Normal View History

2023-02-28 09:43:01 +01:00
function Node_Camera(_x, _y, _group = noone) : Node_Processor(_x, _y, _group) constructor {
2022-12-16 09:18:09 +01:00
name = "Camera";
preview_alpha = 0.5;
2023-11-24 10:41:53 +01:00
onSurfaceSize = function() { return surface_get_dimension(getInputData(0)); };
2024-04-03 09:40:37 +02:00
inputs[| 0] = nodeValue("Focus area", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, DEF_AREA)
2024-03-31 05:36:11 +02:00
.setDisplay(VALUE_DISPLAY.area, { onSurfaceSize, useShape : false });
2023-01-17 08:11:55 +01:00
2024-04-03 09:40:37 +02:00
inputs[| 1] = nodeValue("Zoom", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1)
.setDisplay(VALUE_DISPLAY.slider, { range: [ 0.01, 4, 0.01 ] });
2023-01-17 08:11:55 +01:00
2024-04-03 09:40:37 +02:00
inputs[| 2] = nodeValue("Depth of Field", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, false);
2023-02-28 09:43:01 +01:00
2024-04-03 09:40:37 +02:00
inputs[| 3] = nodeValue("Focal distance", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0);
2023-07-11 20:36:44 +02:00
2024-04-03 09:40:37 +02:00
inputs[| 4] = nodeValue("Defocus", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 1);
2023-07-11 20:36:44 +02:00
2024-04-03 09:40:37 +02:00
inputs[| 5] = nodeValue("Focal range", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0);
2023-07-11 20:36:44 +02:00
2023-02-14 05:32:32 +01:00
outputs[| 0] = nodeValue("Surface out", self, JUNCTION_CONNECT.output, VALUE_TYPE.surface, noone);
2022-12-16 09:18:09 +01:00
2023-01-17 08:11:55 +01:00
input_display_list = [
2024-04-03 09:40:37 +02:00
["Camera", false], 0, 1,
["Depth Of Field", true, 2], 3, 5, 4,
2023-07-11 14:18:23 +02:00
["Elements", true],
2023-01-17 08:11:55 +01:00
];
2023-03-19 09:17:39 +01:00
attribute_surface_depth();
2023-08-05 14:00:33 +02:00
2024-04-03 09:40:37 +02:00
setIsDynamicInput(6);
2023-07-11 14:18:23 +02:00
temp_surface = [ noone, noone ];
2023-01-17 08:11:55 +01:00
static createNewInput = function() { #region
2023-01-17 08:11:55 +01:00
var index = ds_list_size(inputs);
var _s = floor((index - input_fix_len) / data_length);
2024-04-03 09:40:37 +02:00
if(_s) array_push(input_display_list, new Inspector_Spacer(20, true));
2024-03-14 14:35:19 +01:00
inputs[| index + 0] = nodeValue($"Element {_s}", self, JUNCTION_CONNECT.input, VALUE_TYPE.surface, noone);
2023-01-17 08:11:55 +01:00
2024-04-03 09:40:37 +02:00
inputs[| index + 1] = nodeValue($"Positioning {_s}", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, false)
.setDisplay(VALUE_DISPLAY.enum_button, [ "Space", "Camera" ]);
inputs[| index + 2] = nodeValue($"Position {_s}", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0 ] )
2023-01-17 08:11:55 +01:00
.setDisplay(VALUE_DISPLAY.vector)
.setUnitRef(function(index) { return getDimension(index); });
2024-04-03 09:40:37 +02:00
inputs[| index + 3] = nodeValue($"Oversample {_s}", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0)
2024-01-28 09:53:41 +01:00
.setDisplay(VALUE_DISPLAY.enum_scroll, [ new scrollItem("Empty ", s_node_camera_repeat, 0),
new scrollItem("Repeat ", s_node_camera_repeat, 1),
new scrollItem("Repeat X", s_node_camera_repeat, 2),
new scrollItem("Repeat Y", s_node_camera_repeat, 3), ]);
2023-07-11 14:18:23 +02:00
2024-04-03 09:40:37 +02:00
inputs[| index + 4] = nodeValue($"Parallax {_s}", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0 ])
.setDisplay(VALUE_DISPLAY.vector);
inputs[| index + 5] = nodeValue($"Depth {_s}", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, 0);
for( var i = 0; i < data_length; i++ ) array_push(input_display_list, index + i);
} if(!LOADING && !APPENDING) createNewInput(); #endregion
2023-01-17 08:11:55 +01:00
static refreshDynamicInput = function() { #region
2023-01-17 08:11:55 +01:00
var _in = ds_list_create();
for( var i = 0; i < input_fix_len; i++ )
ds_list_add(_in, inputs[| i]);
array_resize(input_display_list, input_display_len);
2024-04-03 09:40:37 +02:00
var sep = false;
2023-01-17 08:11:55 +01:00
for( var i = input_fix_len; i < ds_list_size(inputs); i += data_length ) {
if(inputs[| i].value_from) {
2024-04-03 09:40:37 +02:00
if(sep) array_push(input_display_list, new Inspector_Spacer(20, true));
sep = true;
for( var j = 0; j < data_length; j++ ) {
ds_list_add(_in, inputs[| i + j]);
array_push(input_display_list, i + j);
}
2023-01-17 08:11:55 +01:00
} else {
2024-04-03 09:40:37 +02:00
for( var j = 0; j < data_length; j++ )
delete inputs[| i + j];
2023-01-17 08:11:55 +01:00
}
}
for( var i = 0; i < ds_list_size(_in); i++ )
_in[| i].index = i;
ds_list_destroy(inputs);
inputs = _in;
createNewInput();
} #endregion
2023-01-17 08:11:55 +01:00
static onValueFromUpdate = function(index) { #region
2023-01-17 08:11:55 +01:00
if(index < input_fix_len) return;
if(LOADING || APPENDING) return;
refreshDynamicInput();
} #endregion
2023-01-17 08:11:55 +01:00
2024-04-03 09:40:37 +02:00
static getPreviewValues = function() { return getInputData(input_fix_len); }
2022-12-16 09:18:09 +01:00
2024-04-03 09:40:37 +02:00
static drawOverlay = function(hover, active, _x, _y, _s, _mx, _my, _snx, _sny, _params) { #region
2022-12-27 04:00:50 +01:00
if(array_length(current_data) == 0) return;
2024-04-03 09:40:37 +02:00
var _out = outputs[| 0].getValue();
if(is_array(_out)) _out = _out[preview_index];
var _area = current_data[0];
var _zoom = current_data[1];
2022-12-16 09:18:09 +01:00
2023-07-11 14:18:23 +02:00
var _cam_x = _x + (_area[0] - _area[2] * _zoom) * _s;
var _cam_y = _y + (_area[1] - _area[3] * _zoom) * _s;
2023-01-17 08:11:55 +01:00
2024-04-03 09:40:37 +02:00
if(PANEL_PREVIEW.getNodePreview() == self)
draw_surface_ext_safe(_out, _cam_x, _cam_y, _s * _zoom, _s * _zoom);
inputs[| 0].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
2023-01-17 08:11:55 +01:00
draw_set_color(COLORS._main_accent);
2023-07-11 14:18:23 +02:00
var x0 = _cam_x;
var y0 = _cam_y;
2023-01-17 08:11:55 +01:00
var x1 = x0 + _area[2] * 2 * _zoom * _s;
var y1 = y0 + _area[3] * 2 * _zoom * _s;
draw_rectangle_dashed(x0, y0, x1, y1);
} #endregion
2022-12-16 09:18:09 +01:00
static processData = function(_outSurf, _data, _output_index, _array_index) { #region
2024-04-03 09:40:37 +02:00
if(!is_surface(_data[input_fix_len])) return;
var _area = _data[0];
var _zoom = _data[1];
2023-07-11 20:36:44 +02:00
2024-04-03 09:40:37 +02:00
var _dof = _data[2];
var _dof_dist = _data[3];
var _dof_stop = _data[4];
var _dof_rang = _data[5];
2023-07-11 20:36:44 +02:00
2024-04-03 09:40:37 +02:00
var cDep = attrDepth();
2022-12-16 09:18:09 +01:00
2023-07-11 14:18:23 +02:00
var _cam_x = round(_area[0]);
var _cam_y = round(_area[1]);
var _cam_w = round(_area[2]);
var _cam_h = round(_area[3]);
var _surf_w = round(surface_valid_size(_cam_w * 2));
var _surf_h = round(surface_valid_size(_cam_h * 2));
_outSurf = surface_verify(_outSurf, _surf_w, _surf_h, cDep);
2024-04-03 09:40:37 +02:00
for( var i = 0, n = array_length(temp_surface); i < n; i++ ) {
temp_surface[i] = surface_verify(temp_surface[i], _surf_w, _surf_h, cDep);
surface_clear(temp_surface[i]);
}
2023-01-25 06:49:00 +01:00
2023-02-28 09:43:01 +01:00
var amo = (ds_list_size(inputs) - input_fix_len) / data_length - 1;
2023-07-11 20:36:44 +02:00
shader_set(sh_camera);
shader_set_f("camDimension", _surf_w, _surf_h);
shader_set_f("zoom", _zoom);
2023-01-25 06:49:00 +01:00
2024-04-03 09:40:37 +02:00
var ppInd = 0;
for( var i = 0; i < amo; i++ ) {
var ind = input_fix_len + i * data_length;
var _surf = _data[ind + 0];
var _sposT = _data[ind + 1];
var _spos = _data[ind + 2];
var _samp = _data[ind + 3];
var _paral = _data[ind + 4];
var _sdof = _data[ind + 5];
if(!is_surface(_surf)) continue;
2023-01-25 06:49:00 +01:00
ppInd = !ppInd;
2023-01-17 08:11:55 +01:00
2024-04-03 09:40:37 +02:00
var sx = _spos[0] + _paral[0] * _cam_x;
var sy = _spos[1] + _paral[1] * _cam_y;
2023-07-11 20:36:44 +02:00
2024-04-03 09:40:37 +02:00
var px, py;
if(_sposT == 0) {
px = _cam_x - sx;
py = _cam_y - sy;
} else {
px = -sx;
py = -sy;
2023-07-11 20:36:44 +02:00
}
2024-04-03 09:40:37 +02:00
var _scnW = surface_get_width_safe(_surf);
var _scnH = surface_get_height_safe(_surf);
2023-01-17 08:11:55 +01:00
2023-07-11 20:36:44 +02:00
px /= _scnW;
py /= _scnH;
2023-07-11 14:18:23 +02:00
2023-07-11 20:36:44 +02:00
shader_set_i("sampleMode", _samp);
shader_set_f("scnDimension", _scnW, _scnH);
shader_set_f("position", px, py);
2024-04-03 09:40:37 +02:00
shader_set_f("bokehStrength", 0);
2023-07-11 20:36:44 +02:00
if(_dof) {
2024-04-03 09:40:37 +02:00
var _x = max(abs(_sdof - _dof_dist) - _dof_rang, 0);
2023-07-11 20:36:44 +02:00
_x = _x * tanh(_x / 10);
shader_set_f("bokehStrength", _x * _dof_stop);
2024-04-03 09:40:37 +02:00
}
2023-01-25 06:49:00 +01:00
2024-04-03 09:40:37 +02:00
shader_set_surface("backg", temp_surface[!ppInd]); //prev surface
shader_set_surface("scene", _surf); //surface to draw
2023-07-11 14:18:23 +02:00
2024-04-03 09:40:37 +02:00
surface_set_target(temp_surface[ppInd]);
draw_sprite_stretched(s_fx_pixel, 0, 0, 0, _surf_w, _surf_h);
2023-01-25 06:49:00 +01:00
surface_reset_target();
}
2023-01-17 08:11:55 +01:00
shader_reset();
2023-01-25 06:49:00 +01:00
2024-04-03 09:40:37 +02:00
surface_set_shader(_outSurf, noone);
draw_surface_safe(temp_surface[ppInd]);
surface_reset_shader();
2022-12-16 09:18:09 +01:00
return _outSurf;
} #endregion
2024-04-03 09:40:37 +02:00
static processDeserialize = function() { #region
if(LOADING_VERSION < 11690)
ds_list_clear(load_map.inputs);
} #endregion
2022-12-16 09:18:09 +01:00
}