diff --git a/scripts/BBMOD_Quaternion/BBMOD_Quaternion.gml b/scripts/BBMOD_Quaternion/BBMOD_Quaternion.gml index b14705f81..88176b17b 100644 --- a/scripts/BBMOD_Quaternion/BBMOD_Quaternion.gml +++ b/scripts/BBMOD_Quaternion/BBMOD_Quaternion.gml @@ -22,6 +22,15 @@ function BBMOD_Quaternion(_x=0.0, _y=0.0, _z=0.0, _w=1.0) constructor /// @var {Real} The fourth component of the quaternion. W = _w; + + static set = function(x, y, z, w) { + gml_pragma("forceinline"); + X = x; + Y = y; + Z = z; + W = w; + return self; + } /// @func Add(_q) /// @@ -254,6 +263,16 @@ function BBMOD_Quaternion(_x=0.0, _y=0.0, _z=0.0, _w=1.0) constructor W = _w; return self; }; + + static FromMatrix = function(rotMatrix) { + gml_pragma("forceinline"); + + W = sqrt(1 + rotMatrix[0] + rotMatrix[5] + rotMatrix[10]) / 2; + X = (rotMatrix[9] - rotMatrix[6]) / (4 * W); + Y = (rotMatrix[2] - rotMatrix[8]) / (4 * W); + Z = (rotMatrix[4] - rotMatrix[1]) / (4 * W); + return self; + } /// @func GetAngle() /// @@ -555,6 +574,32 @@ function BBMOD_Quaternion(_x=0.0, _y=0.0, _z=0.0, _w=1.0) constructor buffer_write(_buffer, _type, W); return self; }; + + static ToEuler = function() { + var ysqr = Y * Y; + + // roll (x-axis rotation) + var t0 = +2.0 * (W * X + Y * Z); + var t1 = +1.0 - 2.0 * (X * X + ysqr); + var roll = arctan2(t0, t1); + + // pitch (y-axis rotation) + var t2 = +2.0 * (W * Y - Z * X); + t2 = clamp(t2, -1.0, 1.0); // Prevent numerical instability + var pitch = arcsin(t2); + + // yaw (z-axis rotation) + var t3 = +2.0 * (W * Z + X * Y); + var t4 = +1.0 - 2.0 * (ysqr + Z * Z); + var yaw = arctan2(t3, t4); + + // Convert radians to degrees + var _dx = roll * 180.0 / pi; + var _dy = pitch * 180.0 / pi; + var _dz = yaw * 180.0 / pi; + + return new __rot3(_dx, _dy, _dz); + } /// @func ToMatrix([_dest[, _index]]) /// @@ -570,12 +615,14 @@ function BBMOD_Quaternion(_x=0.0, _y=0.0, _z=0.0, _w=1.0) constructor gml_pragma("forceinline"); _dest ??= matrix_build_identity(); - + + var _norm = Normalize(); + var _temp0, _temp1, _temp2; - var _q0 = X; - var _q1 = Y; - var _q2 = Z; - var _q3 = W; + var _q0 = _norm.X; + var _q1 = _norm.Y; + var _q2 = _norm.Z; + var _q3 = _norm.W; _temp0 = _q0 * _q0; _temp1 = _q1 * _q1; diff --git a/scripts/_3D/_3D.gml b/scripts/_3D/_3D.gml index cc70c5f12..344ca3d9b 100644 --- a/scripts/_3D/_3D.gml +++ b/scripts/_3D/_3D.gml @@ -410,11 +410,8 @@ enum CAMERA_PROJ { case 2 : _n = new BBMOD_Vec3(0.0, 0.0, 1.0); break; } - var camVector = new BBMOD_Vec3(0.0, 0.0, 1.0); - if(drag_prev != undefined) { var _currQ = new BBMOD_Quaternion().FromEuler(_rot[0], _rot[1], _rot[2]); - var _currR = new BBMOD_Quaternion().FromAxisAngle(_n, (mAng - drag_prev) * (_currQ.Rotate(_n).Z > 0? -1 : 1)); var _mulp = _currQ.Mul(_currR); var _Nrot = new BBMOD_Matrix(_mulp.ToMatrix()).ToEuler(); diff --git a/scripts/__node_3d_object/__node_3d_object.gml b/scripts/__node_3d_object/__node_3d_object.gml index 9c7673cb4..1c476601c 100644 --- a/scripts/__node_3d_object/__node_3d_object.gml +++ b/scripts/__node_3d_object/__node_3d_object.gml @@ -8,7 +8,7 @@ function Node_3DObject(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constru inputs[| 0] = nodeValue("Position", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0, 0 ]) .setDisplay(VALUE_DISPLAY.vector); - inputs[| 1] = nodeValue("Rotation", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0, 0 ]) + inputs[| 1] = nodeValue("Rotation", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0, 0, 1 ]) .setDisplay(VALUE_DISPLAY.vector); inputs[| 2] = nodeValue("Scale", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 1, 1, 1 ]) @@ -28,12 +28,8 @@ function Node_3DObject(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constru drag_my = 0; drag_px = 0; drag_py = 0; - drag_c0x = 0; - drag_c0y = 0; - drag_c1x = 0; - drag_c1y = 0; - drag_c2x = 0; - drag_c2y = 0; + drag_cx = 0; + drag_cy = 0; drag_original = 0; @@ -58,15 +54,8 @@ function Node_3DObject(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constru var _camAx = _camera.focus_angle_x; var _camAy = _camera.focus_angle_y; - var _qrot = new BBMOD_Quaternion().FromEuler(_rot[0], -_rot[1], -_rot[2]); var _qview = new BBMOD_Quaternion().FromEuler(_camAy, -_camAx, 0); - var ga = []; - var dir = 0; - var size = 64; - var hs = size / 2; - var sq = 8; - var _vpos = new __vec3( _pos[0], _pos[1], _pos[2] ); var _posView = _camera.worldPointToViewPoint(_vpos); @@ -77,7 +66,12 @@ function Node_3DObject(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constru var _hoverDist = 10; var th; - if(isUsingTool(0)) { #region move + if(isUsingTool(0)) { #region move + var ga = []; + var size = 64; + var hs = size / 2; + var sq = 8; + ga[0] = new BBMOD_Vec3(-size, 0, 0); ga[1] = new BBMOD_Vec3(0, 0, size); ga[2] = new BBMOD_Vec3(0, -size, 0); @@ -96,7 +90,7 @@ function Node_3DObject(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constru new BBMOD_Vec3(-hs + sq, -hs + sq, 0), ]; for( var i = 0; i < 3; i++ ) { - ga[i] = _qview.Rotate(_qrot.Rotate(ga[i])); + ga[i] = _qview.Rotate(ga[i]); th = 2 + (axis_hover == i || drag_axis == i); if(drag_axis != noone && drag_axis != i) @@ -106,7 +100,7 @@ function Node_3DObject(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constru if(point_distance(cx, cy, cx + ga[i].X, cy + ga[i].Y) < 5) draw_line_round(cx, cy, cx + ga[i].X, cy + ga[i].Y, th); else - draw_line_round_arrow(cx, cy, cx + ga[i].X, cy + ga[i].Y, th, 2); + draw_line_round_arrow(cx, cy, cx + ga[i].X, cy + ga[i].Y, th, 3); var _d = distance_to_line(_mx, _my, cx, cy, cx + ga[i].X, cy + ga[i].Y); if(_d < _hoverDist) { @@ -117,7 +111,7 @@ function Node_3DObject(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constru for( var i = 3; i < 6; i++ ) { for( var j = 0; j < 4; j++ ) - ga[i][j] = _qview.Rotate(_qrot.Rotate(ga[i][j])); + ga[i][j] = _qview.Rotate(ga[i][j]); th = 1; @@ -155,32 +149,36 @@ function Node_3DObject(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constru } axis_hover = _hover; - print(_camera.viewPointToWorldRay(_mx, _my)) if(drag_axis != noone) { if(!MOUSE_WRAPPING) { drag_mx += _mx - drag_px; drag_my += _my - drag_py; - var _mmx = drag_mx - drag_c0x; - var _mmy = drag_my - drag_c0y; - var mAdj; + var _mmx = drag_mx - drag_cx; + var _mmy = drag_my - drag_cy; + var mAdj, nor; + + var ray = _camera.viewPointToWorldRay(_mx, _my); if(drag_axis < 3) { - var _max = drag_c1x; - var _may = drag_c1y; - mAdj = dot_product(_mmx, _mmy, _max, _may); + switch(drag_axis) { + case 0 : nor = new __vec3(0, 0, 1); break; + case 1 : nor = new __vec3(1, 0, 0); break; + case 2 : nor = new __vec3(0, 1, 0); break; + } + + var pln = new __plane(drag_original, nor); + mAdj = d3d_intersect_ray_plane(ray, pln); if(drag_prev != undefined) { - _pos[drag_axis] += (mAdj - drag_prev) * _camDis / 20000; + var _diff = mAdj.subtract(drag_prev); + _pos[drag_axis] += _diff.getIndex(drag_axis); if(inputs[| 0].setValue(_pos)) UNDO_HOLDING = true; } } else { - var ray = _camera.viewPointToWorldRay(_mx, _my); - var nor; - switch(drag_axis) { case 3 : nor = new __vec3(0, 0, 1); break; case 4 : nor = new __vec3(1, 0, 0); break; @@ -216,23 +214,243 @@ function Node_3DObject(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constru drag_my = _my; drag_px = _mx; drag_py = _my; - - drag_c0x = cx; - drag_c0y = cy; + drag_cx = cx; + drag_cy = cy; drag_original = new __vec3(_pos); - - if(drag_axis < 3) { - drag_c1x = ga[drag_axis].X; - drag_c1y = ga[drag_axis].Y; - } } #endregion } else if(isUsingTool(1)) { #region rotate + var size = 64; + var _qrot = object.rotation; + var _qinv = new BBMOD_Quaternion().FromAxisAngle(new BBMOD_Vec3(1, 0, 0), 90); + for( var i = 0; i < 3; i++ ) { + var op, np; + + th = 2 + (axis_hover == i || drag_axis == i); + if(drag_axis != noone && drag_axis != i) + continue; + + draw_set_color(COLORS.axis[i]); + for( var j = 0; j <= 32; j++ ) { + var ang = j / 32 * 360; + + switch(i) { + case 0 : np = new BBMOD_Vec3(0, lengthdir_x(size, ang), lengthdir_y(size, ang)); break; + case 1 : np = new BBMOD_Vec3(lengthdir_x(size, ang), lengthdir_y(size, ang), 0); break; + case 2 : np = new BBMOD_Vec3(lengthdir_x(size, ang), 0, lengthdir_y(size, ang)); break; + } + + np = _qview.Rotate(_qinv.Rotate(_qrot.Rotate(np))); + + if(j && (op.Z > 0 && np.Z > 0 || drag_axis == i)) { + draw_line_round(cx + op.X, cy + op.Y, cx + np.X, cy + np.Y, th); + var _d = distance_to_line(_mx, _my, cx + op.X, cy + op.Y, cx + np.X, cy + np.Y); + if(_d < _hoverDist) { + _hover = i; + _hoverDist = _d; + } + } + + op = np; + } + } + + axis_hover = _hover; + + if(drag_axis != noone) { + var mAng = point_direction(cx, cy, _mx, _my); + var _n = BBMOD_VEC3_FORWARD; + + switch(drag_axis) { + case 0 : _n = new BBMOD_Vec3(-1, 0, 0); break; + case 1 : _n = new BBMOD_Vec3( 0, 0, -1); break; + case 2 : _n = new BBMOD_Vec3( 0, -1, 0); break; + } + + _n = _qrot.Rotate(_n).Normalize(); + + var _nv = _qview.Rotate(_qinv.Rotate(_n)); + draw_line_round(cx, cy, cx + _nv.X * 100, cy + _nv.Y * 100, 2); + + if(drag_prev != undefined) { + var _rd = (mAng - drag_prev) * (_nv.Z > 0? 1 : -1); + + var _currR = new BBMOD_Quaternion().FromAxisAngle(_n, _rd); + var _mulp = _currR.Mul(_qrot); + var _Nrot = _mulp.ToArray(); + + if(inputs[| 1].setValue(_Nrot)) + UNDO_HOLDING = true; + } + + draw_set_color(COLORS._main_accent); + draw_line_dashed(cx, cy, _mx, _my, 1, 4); + + drag_prev = mAng; + } + + if(_hover != noone && mouse_press(mb_left, active)) { + drag_axis = _hover; + drag_prev = undefined; + } #endregion } else if(isUsingTool(2)) { #region scale + var ga = []; + var size = 64; + var hs = size / 2; + var sq = 8; + var _qrot = object.rotation; + var _qinv = new BBMOD_Quaternion().FromAxisAngle(new BBMOD_Vec3(1, 0, 0), 90); + ga[0] = new BBMOD_Vec3(-size, 0, 0); + ga[1] = new BBMOD_Vec3(0, -size, 0); + ga[2] = new BBMOD_Vec3(0, 0, -size); + + ga[3] = [ new BBMOD_Vec3(-hs + sq, -hs - sq, 0), + new BBMOD_Vec3(-hs - sq, -hs - sq, 0), + new BBMOD_Vec3(-hs - sq, -hs + sq, 0), + new BBMOD_Vec3(-hs + sq, -hs + sq, 0), ]; + ga[4] = [ new BBMOD_Vec3( 0, -hs + sq, -hs - sq), + new BBMOD_Vec3( 0, -hs - sq, -hs - sq), + new BBMOD_Vec3( 0, -hs - sq, -hs + sq), + new BBMOD_Vec3( 0, -hs + sq, -hs + sq), ]; + ga[5] = [ new BBMOD_Vec3(-hs + sq, 0, -hs - sq), + new BBMOD_Vec3(-hs - sq, 0, -hs - sq), + new BBMOD_Vec3(-hs - sq, 0, -hs + sq), + new BBMOD_Vec3(-hs + sq, 0, -hs + sq), ]; + + for( var i = 0; i < 3; i++ ) { + ga[i] = _qview.Rotate(_qinv.Rotate(_qrot.Rotate(ga[i]))); + + th = 2 + (axis_hover == i || drag_axis == i); + if(drag_axis != noone && drag_axis != i) + continue; + + draw_set_color(COLORS.axis[i]); + if(point_distance(cx, cy, cx + ga[i].X, cy + ga[i].Y) < 5) + draw_line_round(cx, cy, cx + ga[i].X, cy + ga[i].Y, th); + else + draw_line_round_arrow_block(cx, cy, cx + ga[i].X, cy + ga[i].Y, th, 3); + + var _d = distance_to_line(_mx, _my, cx, cy, cx + ga[i].X, cy + ga[i].Y); + if(_d < _hoverDist) { + _hover = i; + _hoverDist = _d; + } + } + + for( var i = 3; i < 6; i++ ) { + for( var j = 0; j < 4; j++ ) + ga[i][j] = _qview.Rotate(_qinv.Rotate(_qrot.Rotate(ga[i][j]))); + + th = 1; + + var p0x = cx + ga[i][0].X, p0y = cy + ga[i][0].Y; + var p1x = cx + ga[i][1].X, p1y = cy + ga[i][1].Y; + var p2x = cx + ga[i][2].X, p2y = cy + ga[i][2].Y; + var p3x = cx + ga[i][3].X, p3y = cy + ga[i][3].Y; + + var _pax = (p0x + p1x + p2x + p3x) / 4; + var _pay = (p0y + p1y + p2y + p3y) / 4; + + if((abs(p0x - _pax) + abs(p1x - _pax) + abs(p2x - _pax) + abs(p3x - _pax)) / 4 < 1) + continue; + if((abs(p0y - _pay) + abs(p1y - _pay) + abs(p2y - _pay) + abs(p3y - _pay)) / 4 < 1) + continue; + + draw_set_color(COLORS.axis[(i - 3 - 1 + 3) % 3]); + if(axis_hover == i || drag_axis == i) { + draw_primitive_begin(pr_trianglestrip); + draw_vertex(p0x, p0y); + draw_vertex(p1x, p1y); + draw_vertex(p3x, p3y); + draw_vertex(p2x, p2y); + draw_primitive_end(); + } else if (drag_axis == noone) { + draw_line(p0x, p0y, p1x, p1y); + draw_line(p1x, p1y, p2x, p2y); + draw_line(p2x, p2y, p3x, p3y); + draw_line(p3x, p3y, p0x, p0y); + } else + continue; + + if(point_in_rectangle_points(_mx, _my, p0x, p0y, p1x, p1y, p3x, p3y, p2x, p2y)) + _hover = i; + } + + axis_hover = _hover; + + if(drag_axis != noone) { + if(!MOUSE_WRAPPING) { + drag_mx += _mx - drag_px; + drag_my += _my - drag_py; + + var _mmx = drag_mx - drag_cx; + var _mmy = drag_my - drag_cy; + var mAdj, nor; + + var ray = _camera.viewPointToWorldRay(_mx, _my); + + if(drag_axis < 3) { + switch(drag_axis) { + case 0 : nor = new __vec3(0, 0, 1); break; + case 1 : nor = new __vec3(1, 0, 0); break; + case 2 : nor = new __vec3(0, 1, 0); break; + } + + var pln = new __plane(drag_original, nor); + mAdj = d3d_intersect_ray_plane(ray, pln); + + if(drag_prev != undefined) { + var _diff = mAdj.subtract(drag_prev); + _sca[drag_axis] += _diff.getIndex(drag_axis); + + if(inputs[| 2].setValue(_sca)) + UNDO_HOLDING = true; + } + } else { + switch(drag_axis) { + case 3 : nor = new __vec3(0, 0, 1); break; + case 4 : nor = new __vec3(1, 0, 0); break; + case 5 : nor = new __vec3(0, 1, 0); break; + } + + var pln = new __plane(drag_original, nor); + mAdj = d3d_intersect_ray_plane(ray, pln); + + if(drag_prev != undefined) { + var _diff = mAdj.subtract(drag_prev); + _sca[0] += _diff.x; + _sca[1] += _diff.y; + _sca[2] += _diff.z; + + if(inputs[| 2].setValue(_sca)) + UNDO_HOLDING = true; + } + } + + drag_prev = mAdj; + } + + setMouseWrap(); + drag_px = _mx; + drag_py = _my; + } + + if(_hover != noone && mouse_press(mb_left, active)) { + drag_axis = _hover; + drag_prev = undefined; + drag_mx = _mx; + drag_my = _my; + drag_px = _mx; + drag_py = _my; + drag_cx = cx; + drag_cy = cy; + + drag_original = new __vec3(_sca); + } #endregion } @@ -248,7 +466,7 @@ function Node_3DObject(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constru var _sca = inputs[| 2].getValue(); object.position.set(_pos[0], _pos[1], _pos[2]); - object.rotation.set(_rot[0], _rot[1], _rot[2]); + object.rotation.set(_rot[0], _rot[1], _rot[2], _rot[3]); object.scale.set(_sca[0], _sca[1], _sca[2]); outputs[| 0].setValue(object); diff --git a/scripts/d3d_light/d3d_light.gml b/scripts/d3d_light/d3d_light.gml index f3cfab089..fe6f5f276 100644 --- a/scripts/d3d_light/d3d_light.gml +++ b/scripts/d3d_light/d3d_light.gml @@ -8,7 +8,7 @@ function __3dLight() : __3dObject() constructor { intensity = 1; static presubmit = function(params = {}) { - var _rot = new __rot3(0, 0, 0).lookAt(position, params.cameraPosition); + var _rot = new __rot3(0, 0, 0).lookAt(position, params.camera.position); var rot = matrix_build(0, 0, 0, _rot.x, _rot.y, _rot.z, diff --git a/scripts/d3d_matrix4/d3d_matrix4.gml b/scripts/d3d_matrix4/d3d_matrix4.gml index cb40c7cc1..8a524780d 100644 --- a/scripts/d3d_matrix4/d3d_matrix4.gml +++ b/scripts/d3d_matrix4/d3d_matrix4.gml @@ -98,6 +98,20 @@ function __mat4() constructor { return result; }; + + static multiplyBBMODVector = function(vector) { + var result = new BBMOD_Vec4(); + + // Perform matrix-vector multiplication + for (var i = 0; i < 4; i++) { + result.SetIndex(i, raw[i * 4 + 0] * vector.X + + raw[i * 4 + 1] * vector.Y + + raw[i * 4 + 2] * vector.Z + + raw[i * 4 + 3] * vector.W); + } + + return result; + }; static clone = function() { var result = new __mat4(); diff --git a/scripts/d3d_object/d3d_object.gml b/scripts/d3d_object/d3d_object.gml index e6fdc1cd1..5453d7bd7 100644 --- a/scripts/d3d_object/d3d_object.gml +++ b/scripts/d3d_object/d3d_object.gml @@ -23,7 +23,7 @@ function __3dObject() constructor { custom_shader = noone; position = new __vec3(0, 0, 0); - rotation = new __rot3(0, 0, 0); + rotation = new BBMOD_Quaternion(); scale = new __vec3(1, 1, 1); static build = function(_buffer = VB, _vertex = vertex, _normal = normals) { @@ -81,15 +81,13 @@ function __3dObject() constructor { presubmit(params); if(VB != noone) { - var rot = matrix_build(0, 0, 0, - rotation.x, rotation.y, rotation.z, - 1, 1, 1); - var sca = matrix_build(0, 0, 0, - 0, 0, 0, - scale.x, scale.y, scale.z); var pos = matrix_build(position.x, position.y, position.z, 0, 0, 0, 1, 1, 1); + var rot = rotation.ToMatrix(); + var sca = matrix_build(0, 0, 0, + 0, 0, 0, + scale.x, scale.y, scale.z); matrix_stack_clear(); matrix_stack_push(pos); diff --git a/scripts/d3d_rot3/d3d_rot3.gml b/scripts/d3d_rot3/d3d_rot3.gml index 40318676e..2e0f70d8d 100644 --- a/scripts/d3d_rot3/d3d_rot3.gml +++ b/scripts/d3d_rot3/d3d_rot3.gml @@ -72,4 +72,6 @@ function __rot3(_x = 0, _y = 0, _z = 0) constructor { } static toString = function() { return $"[{x}, {y}, {z}]"; } + + static toArray = function() { return [ x, y, z ]; } } \ No newline at end of file diff --git a/scripts/d3d_vec3/d3d_vec3.gml b/scripts/d3d_vec3/d3d_vec3.gml index e2a500c81..2ee77a760 100644 --- a/scripts/d3d_vec3/d3d_vec3.gml +++ b/scripts/d3d_vec3/d3d_vec3.gml @@ -11,6 +11,13 @@ function __vec3(_x = 0, _y = 0, _z = 0) constructor { return; } + if(is_struct(_x) && is_instanceof(_x, BBMOD_Vec3)) { + x = _x.X; + y = _x.Y; + z = _x.Z; + return; + } + if(is_array(_x)) { x = _x[0]; y = _x[1]; @@ -33,6 +40,15 @@ function __vec3(_x = 0, _y = 0, _z = 0) constructor { } return self; } + + static getIndex = function(index) { + switch(index) { + case 0 : return x; + case 1 : return y; + case 2 : return z; + } + return 0; + } static add = function(_vec3) { gml_pragma("forceinline"); @@ -154,4 +170,6 @@ function __vec3(_x = 0, _y = 0, _z = 0) constructor { static toString = function() { return $"[{x}, {y}, {z}]"; } static toBBMOD = function() { return new BBMOD_Vec3(x, y, z); } + + static toArray = function() { return [ x, y, z ]; } } diff --git a/scripts/d3d_vec4/d3d_vec4.gml b/scripts/d3d_vec4/d3d_vec4.gml index 9220a19b0..c59fe8504 100644 --- a/scripts/d3d_vec4/d3d_vec4.gml +++ b/scripts/d3d_vec4/d3d_vec4.gml @@ -42,6 +42,16 @@ function __vec4(_x = 0, _y = 0, _z = 0, _w = 0) constructor { return self; } + static getIndex = function(index) { + switch(index) { + case 0 : return x; + case 1 : return y; + case 2 : return z; + case 3 : return w; + } + return 0; + } + static add = function(_vec4) { gml_pragma("forceinline"); return new __vec4(x + _vec4.x, y + _vec4.y, z + _vec4.z, w + _vec4.w); @@ -153,7 +163,7 @@ function __vec4(_x = 0, _y = 0, _z = 0, _w = 0) constructor { return new __vec4(x, y, z, w); } - static toString = function() { - return $"[{x}, {y}, {z}, {w}]"; - } + static toString = function() { return $"[{x}, {y}, {z}, {w}]"; } + + static toArray = function() { return [ x, y, z, w ]; } } diff --git a/scripts/draw_line_elbow_diag/draw_line_elbow_diag.gml b/scripts/draw_line_elbow_diag/draw_line_elbow_diag.gml index d928e1c19..9dcc14083 100644 --- a/scripts/draw_line_elbow_diag/draw_line_elbow_diag.gml +++ b/scripts/draw_line_elbow_diag/draw_line_elbow_diag.gml @@ -1,4 +1,12 @@ function draw_line_elbow_diag_color(x0, y0, x1, y1, cx = noone, cy = noone, _s = 1, thick = 1, c1 = c_white, c2 = c_white, corner = 0, indexIn = 1, indexOut = 1, type = LINE_STYLE.solid) { + if(y0 == y1) { + if(type == LINE_STYLE.solid) + draw_line_width_color(x0, y0, x1, y1, thick, c1, c2); + else + draw_line_dashed_color(x0, y0, x1, y1, thick, c1, c2); + return; + } + var sample = corner / 4; sample = clamp(sample, 1, 8); diff --git a/scripts/draw_line_round/draw_line_round.gml b/scripts/draw_line_round/draw_line_round.gml index 54b86766c..357996958 100644 --- a/scripts/draw_line_round/draw_line_round.gml +++ b/scripts/draw_line_round/draw_line_round.gml @@ -56,4 +56,16 @@ function draw_line_round_arrow_scale(x1, y1, x2, y2, w, as = 4) { x2 + lengthdir_x(as * w, a + 90 * 2), y2 + lengthdir_y(as * w, a + 90 * 2), x2 + lengthdir_x(as * w, a + 90 * 3), y2 + lengthdir_y(as * w, a + 90 * 3), false); +} + +function draw_line_round_arrow_block(x1, y1, x2, y2, w, as = 4) { + draw_line_round(x1, y1, x2, y2, w); + + var a = point_direction(x1, y1, x2, y2); + draw_primitive_begin(pr_trianglestrip); + draw_vertex(x2 + lengthdir_x(as * w, a + 90 * 0), y2 + lengthdir_y(as * w, a + 90 * 0)); + draw_vertex(x2 + lengthdir_x(as * w, a + 90 * 1), y2 + lengthdir_y(as * w, a + 90 * 1)); + draw_vertex(x2 + lengthdir_x(as * w, a + 90 * 3), y2 + lengthdir_y(as * w, a + 90 * 3)); + draw_vertex(x2 + lengthdir_x(as * w, a + 90 * 2), y2 + lengthdir_y(as * w, a + 90 * 2)); + draw_primitive_end(); } \ No newline at end of file diff --git a/scripts/globals/globals.gml b/scripts/globals/globals.gml index a7c47e8ec..6569ad5b3 100644 --- a/scripts/globals/globals.gml +++ b/scripts/globals/globals.gml @@ -101,10 +101,10 @@ globalvar VERSION, SAVE_VERSION, VERSION_STRING, BUILD_NUMBER; - VERSION = 11501; + VERSION = 11505; SAVE_VERSION = 11500; - VERSION_STRING = "1.15.0.1"; - BUILD_NUMBER = 11501; + VERSION_STRING = "1.15.0.5"; + BUILD_NUMBER = 11505; globalvar APPEND_MAP; APPEND_MAP = ds_map_create(); diff --git a/scripts/node_3d_light_directional/node_3d_light_directional.gml b/scripts/node_3d_light_directional/node_3d_light_directional.gml index 7b33faf28..778238b6f 100644 --- a/scripts/node_3d_light_directional/node_3d_light_directional.gml +++ b/scripts/node_3d_light_directional/node_3d_light_directional.gml @@ -11,6 +11,7 @@ function Node_3D_Light_Directional(_x, _y, _group = noone) : Node_3D_Light(_x, _ setTransform(); setLight(); - object.rotation.lookAt(object.position, new __vec3()); + var _rot = new __rot3().lookAt(object.position, new __vec3()); + object.rotation.FromEuler(_rot.x, _rot.y, _rot.z); } } \ No newline at end of file diff --git a/scripts/node_canvas/node_canvas.gml b/scripts/node_canvas/node_canvas.gml index b8cc8907f..4f671f597 100644 --- a/scripts/node_canvas/node_canvas.gml +++ b/scripts/node_canvas/node_canvas.gml @@ -247,7 +247,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor function get_color_buffer(_x, _y) { #region var pos = (surface_w * _y + _x) * 4; - if(pos > buffer_get_size(canvas_buffer)) { + if(pos >= buffer_get_size(canvas_buffer)) { print("Error buffer overflow " + string(pos) + "/" + string(buffer_get_size(canvas_buffer))); return 0; } diff --git a/scripts/node_crop_content/node_crop_content.gml b/scripts/node_crop_content/node_crop_content.gml index 088575fc1..154360caa 100644 --- a/scripts/node_crop_content/node_crop_content.gml +++ b/scripts/node_crop_content/node_crop_content.gml @@ -5,7 +5,7 @@ function Node_Crop_Content(_x, _y, _group = noone) : Node(_x, _y, _group) constr inputs[| 1] = nodeValue("Active", self, JUNCTION_CONNECT.input, VALUE_TYPE.boolean, true); - inputs[| 2] = nodeValue("Array", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 0, "Cropping mode for dealing with image array.") + inputs[| 2] = nodeValue("Array", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, 1, "Cropping mode for dealing with image array.") .setDisplay(VALUE_DISPLAY.enum_scroll, [ "Largest, same size", "Independent" ]); inputs[| 3] = nodeValue("Padding", self, JUNCTION_CONNECT.input, VALUE_TYPE.integer, [ 0, 0, 0, 0 ], "Add padding back after crop.") @@ -27,68 +27,6 @@ function Node_Crop_Content(_x, _y, _group = noone) : Node(_x, _y, _group) constr temp_surface = [ surface_create(1, 1, surface_r32float) ]; - //static findBoundary = function(surface) { - // if(!is_surface(surface)) return [ 0, 0, 0, 0 ]; - - // var _w = surface_get_width(surface); - // var _h = surface_get_height(surface); - - // var s = surface_create(_w, _h, surface_r8unorm); - // surface_set_target(s); - // DRAW_CLEAR - // draw_surface_safe(surface, 0, 0); - // surface_reset_target(); - - // var buff = buffer_create(_w * _h, buffer_fast, 1); - // buffer_get_surface(buff, s, 0); - - // var top = 0; - // for( var i = top; i < _h; i++ ) - // for( var j = 0; j < _w; j++ ) { - // var col = buffer_read_at(buff, i * _w + j, buffer_u8); - // if(col > 0) { - // top = i; - // i = _h; - // break; - // } - // } - - // var bottom = _h; - // for( var i = bottom; i >= top; i-- ) - // for( var j = 0; j < _w; j++ ) { - // var col = buffer_read_at(buff, i * _w + j, buffer_u8); - // if(col > 0) { - // bottom = i; - // i = 0; - // break; - // } - // } - - // var left = 0; - // for( var j = 0; j < _w; j++ ) - // for( var i = top; i < bottom; i++ ) { - // var col = buffer_read_at(buff, i * _w + j, buffer_u8); - // if(col > 0) { - // left = j; - // j = _w; - // break; - // } - // } - - // var right = 0; - // for( var j = _w; j >= left; j-- ) - // for( var i = top; i < bottom; i++ ) { - // var col = buffer_read_at(buff, i * _w + j, buffer_u8); - // if(col > 0) { - // right = j; - // j = 0; - // break; - // } - // } - - // return [ left, top, right + 1, bottom + 1 ]; - //} - static update = function() { var _inSurf = inputs[| 0].getValue(); var _active = inputs[| 1].getValue(); @@ -143,10 +81,10 @@ function Node_Crop_Content(_x, _y, _group = noone) : Node(_x, _y, _group) constr surface_reset_target(); switch(i) { - case 0 : _minx = round(surface_get_pixel_ext(temp_surface[0], 0, 0) / 255); break; - case 1 : _miny = round(surface_get_pixel_ext(temp_surface[0], 0, 0) / 255); break; - case 2 : _maxx = round(surface_get_pixel_ext(temp_surface[0], 0, 0) / 255) + 1; break; - case 3 : _maxy = round(surface_get_pixel_ext(temp_surface[0], 0, 0) / 255) + 1; break; + case 0 : _minx = surface_getpixel(temp_surface[0], 0, 0)[0]; break; + case 1 : _miny = surface_getpixel(temp_surface[0], 0, 0)[0]; break; + case 2 : _maxx = surface_getpixel(temp_surface[0], 0, 0)[0]; break; + case 3 : _maxy = surface_getpixel(temp_surface[0], 0, 0)[0]; break; } } @@ -174,7 +112,7 @@ function Node_Crop_Content(_x, _y, _group = noone) : Node(_x, _y, _group) constr var _surf = _inSurf[i]; if(_array == 0) { - var resDim = [maxx - minx, maxy - miny]; + var resDim = [maxx - minx + 1, maxy - miny + 1]; resDim[DIMENSION.width] += _padd[PADDING.left] + _padd[PADDING.right]; resDim[DIMENSION.height] += _padd[PADDING.top] + _padd[PADDING.bottom]; @@ -187,7 +125,7 @@ function Node_Crop_Content(_x, _y, _group = noone) : Node(_x, _y, _group) constr BLEND_NORMAL surface_reset_target(); } else if(_array == 1) { - var resDim = [maxx[i] - minx[i], maxy[i] - miny[i]]; + var resDim = [maxx[i] - minx[i] + 1, maxy[i] - miny[i] + 1]; resDim[DIMENSION.width] += _padd[PADDING.left] + _padd[PADDING.right]; resDim[DIMENSION.height] += _padd[PADDING.top] + _padd[PADDING.bottom]; diff --git a/scripts/node_palette_extract/node_palette_extract.gml b/scripts/node_palette_extract/node_palette_extract.gml index 4af65df5b..4a5f9b1c9 100644 --- a/scripts/node_palette_extract/node_palette_extract.gml +++ b/scripts/node_palette_extract/node_palette_extract.gml @@ -28,7 +28,6 @@ function Node_Palette_Extract(_x, _y, _group = noone) : Node(_x, _y, _group) con current_color = 0; attribute_surface_depth(); - attribute_auto_execute(true); function sortPalette(pal) { array_sort(pal, function(c0, c1) { @@ -300,17 +299,14 @@ function Node_Palette_Extract(_x, _y, _group = noone) : Node(_x, _y, _group) con } outputs[| 0].setValue(res); - - triggerRender(); } - static onInspector1Update = function() { extractPalettes(); } + static onInspector1Update = function() { extractPalettes(); triggerRender(); } static onValueUpdate = function() { extractPalettes(); } static onValueFromUpdate = function() { extractPalettes(); } function update() { - if(attributes.auto_exe) - extractPalettes(); + extractPalettes(); } static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { diff --git a/scripts/node_registry/node_registry.gml b/scripts/node_registry/node_registry.gml index 9d38d0e1f..f4c01725d 100644 --- a/scripts/node_registry/node_registry.gml +++ b/scripts/node_registry/node_registry.gml @@ -358,22 +358,21 @@ function NodeObject(_name, _spr, _node, _create, tags = []) constructor { ds_list_add(threeD, "Light"); addNodeObject(threeD, "Directional Light", s_node_3d_cube, "Node_3D_Light_Directional", [1, Node_3D_Light_Directional]); - //ds_list_add(threeD, "3D generates"); - //addNodeObject(threeD, "3D Object", s_node_3d_obj, "Node_3D_Obj", [0, Node_create_3D_Obj],, "Load .obj file from your computer as a 3D object."); - //addNodeObject(threeD, "3D Plane", s_node_3d_plane, "Node_3D_Plane", [1, Node_3D_Plane],, "Put 2D image on a plane in 3D space."); - //addNodeObject(threeD, "3D Cube", s_node_3d_cube, "Node_3D_Cube", [1, Node_3D_Cube]); - //addNodeObject(threeD, "3D Cylinder", s_node_3d_cylinder, "Node_3D_Cylinder", [1, Node_3D_Cylinder]); - //addNodeObject(threeD, "3D Sphere", s_node_3d_sphere, "Node_3D_Sphere", [1, Node_3D_Sphere]).setVersion(1090); - //addNodeObject(threeD, "3D Cone", s_node_3d_cone, "Node_3D_Cone", [1, Node_3D_Cone]).setVersion(1090); - //addNodeObject(threeD, "3D Extrude", s_node_3d_extrude, "Node_3D_Extrude", [1, Node_3D_Extrude],, "Extrude 2D image into 3D object."); + ds_list_add(threeD, "Legacy"); + addNodeObject(threeD, "3D Object", s_node_3d_obj, "Node_3D_Obj", [0, Node_create_3D_Obj],, "Load .obj file from your computer as a 3D object."); + addNodeObject(threeD, "3D Plane", s_node_3d_plane, "Node_3D_Plane", [1, Node_3D_Plane],, "Put 2D image on a plane in 3D space."); + addNodeObject(threeD, "3D Cube", s_node_3d_cube, "Node_3D_Cube", [1, Node_3D_Cube]); + addNodeObject(threeD, "3D Cylinder", s_node_3d_cylinder, "Node_3D_Cylinder", [1, Node_3D_Cylinder]); + addNodeObject(threeD, "3D Sphere", s_node_3d_sphere, "Node_3D_Sphere", [1, Node_3D_Sphere]).setVersion(1090); + addNodeObject(threeD, "3D Cone", s_node_3d_cone, "Node_3D_Cone", [1, Node_3D_Cone]).setVersion(1090); + addNodeObject(threeD, "3D Extrude", s_node_3d_extrude, "Node_3D_Extrude", [1, Node_3D_Extrude],, "Extrude 2D image into 3D object."); - //ds_list_add(threeD, "3D operations"); - //addNodeObject(threeD, "3D Transform", s_node_3d_transform, "Node_3D_Transform", [1, Node_3D_Transform]).setVersion(1080); - //addNodeObject(threeD, "3D Combine", s_node_3d_obj_combine, "Node_3D_Combine", [1, Node_3D_Combine],, "Combine multiple 3D object to a single scene,").setVersion(1080); - //addNodeObject(threeD, "3D Repeat", s_node_3d_array, "Node_3D_Repeat", [1, Node_3D_Repeat], ["3d array"], "Repeat 3D object multiple times.").setVersion(1080); - //addNodeObject(threeD, "3D Displace", s_node_3d_displace, "Node_3D_Displace", [1, Node_3D_Displace]).setVersion(1143); + addNodeObject(threeD, "3D Transform", s_node_3d_transform, "Node_3D_Transform", [1, Node_3D_Transform]).setVersion(1080); + addNodeObject(threeD, "3D Combine", s_node_3d_obj_combine, "Node_3D_Combine", [1, Node_3D_Combine],, "Combine multiple 3D object to a single scene,").setVersion(1080); + addNodeObject(threeD, "3D Repeat", s_node_3d_array, "Node_3D_Repeat", [1, Node_3D_Repeat], ["3d array"], "Repeat 3D object multiple times.").setVersion(1080); + addNodeObject(threeD, "3D Displace", s_node_3d_displace, "Node_3D_Displace", [1, Node_3D_Displace]).setVersion(1143); - //addNodeObject(threeD, "3D Export", s_node_3d_export, "Node_3D_Export", [1, Node_3D_Export]).setVersion(1143); + addNodeObject(threeD, "3D Export", s_node_3d_export, "Node_3D_Export", [1, Node_3D_Export]).setVersion(1143); var generator = ds_list_create(); addNodeCatagory("Generate", generator); diff --git a/scripts/panel_preview/panel_preview.gml b/scripts/panel_preview/panel_preview.gml index 97580c16a..5363ad767 100644 --- a/scripts/panel_preview/panel_preview.gml +++ b/scripts/panel_preview/panel_preview.gml @@ -673,9 +673,9 @@ function Panel_Preview() : PanelContent() constructor { shader_set(sh_d3d_default); shader_set_f("light_ambient", colToVec4(d3_light_ambient)); - //shader_set_f("light_dir_direction", 0, 0, 0); - //shader_set_f("light_dir_color", 0); - //shader_set_f("light_dir_intensity", 0); + shader_set_f("light_dir_direction", 1, 2, 3); + shader_set_f("light_dir_color", colToVec4(c_white)); + shader_set_f("light_dir_intensity", 0.5); shader_reset(); _prev_node.submitUI(d3_preview_params); diff --git a/scripts/surface_functions/surface_functions.gml b/scripts/surface_functions/surface_functions.gml index 036522ee7..89acc31cf 100644 --- a/scripts/surface_functions/surface_functions.gml +++ b/scripts/surface_functions/surface_functions.gml @@ -151,7 +151,6 @@ function surface_get_pixel_ext(surface, _x, _y) { gml_pragma("forceinline"); if(!is_surface(surface)) return; - var f = surface_get_format(surface); var px = surface_getpixel_ext(surface, _x, _y); if(is_real(px)) return px; diff --git a/shaders/sh_d3d_default/sh_d3d_default.fsh b/shaders/sh_d3d_default/sh_d3d_default.fsh index bc24db871..7505e7084 100644 --- a/shaders/sh_d3d_default/sh_d3d_default.fsh +++ b/shaders/sh_d3d_default/sh_d3d_default.fsh @@ -7,9 +7,9 @@ varying vec3 v_vNormal; varying vec3 v_worldPosition; -uniform vec4 light_ambient; -uniform vec3 light_dir_direction; -uniform vec4 light_dir_color; +uniform vec4 light_ambient; +uniform vec3 light_dir_direction; +uniform vec4 light_dir_color; uniform float light_dir_intensity; void main() { diff --git a/shaders/sh_find_boundary/sh_find_boundary.fsh b/shaders/sh_find_boundary/sh_find_boundary.fsh index f375a4fe8..765896f17 100644 --- a/shaders/sh_find_boundary/sh_find_boundary.fsh +++ b/shaders/sh_find_boundary/sh_find_boundary.fsh @@ -35,7 +35,7 @@ void main() { } } } else if(mode == 2) { //maxx - for( i = _w; i > bbox.x; i-- ) + for( i = _w; i >= bbox.x; i-- ) for( j = bbox.y; j < _h; j++ ) { col = texture2D( texture, vec2(i, j) / dimension); if(col.r > 0.) { @@ -44,8 +44,8 @@ void main() { } } } else if(mode == 3) { //maxy - for( i = _h; i > bbox.y; i-- ) - for( j = bbox.x; j < bbox.z; j++ ) { + for( i = _h; i >= bbox.y; i-- ) + for( j = bbox.x; j <= bbox.z; j++ ) { col = texture2D( texture, vec2(j, i) / dimension); if(col.r > 0.) { gl_FragColor = vec4(i);