rotate, scale, 1.15.0.5 patch

This commit is contained in:
Tanasart 2023-08-15 19:35:31 +02:00
parent 6633cc5d0c
commit da48f8b24a
21 changed files with 418 additions and 161 deletions

View file

@ -23,6 +23,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. /// @var {Real} The fourth component of the quaternion.
W = _w; 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) /// @func Add(_q)
/// ///
/// @desc Adds quaternions and returns the result as a new quaternion. /// @desc Adds quaternions and returns the result as a new quaternion.
@ -255,6 +264,16 @@ function BBMOD_Quaternion(_x=0.0, _y=0.0, _z=0.0, _w=1.0) constructor
return self; 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() /// @func GetAngle()
/// ///
/// @desc Retrieves the rotation angle of the quaternion. /// @desc Retrieves the rotation angle of the quaternion.
@ -556,6 +575,32 @@ function BBMOD_Quaternion(_x=0.0, _y=0.0, _z=0.0, _w=1.0) constructor
return self; 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]]) /// @func ToMatrix([_dest[, _index]])
/// ///
/// @desc Converts quaternion into a matrix. /// @desc Converts quaternion into a matrix.
@ -571,11 +616,13 @@ function BBMOD_Quaternion(_x=0.0, _y=0.0, _z=0.0, _w=1.0) constructor
_dest ??= matrix_build_identity(); _dest ??= matrix_build_identity();
var _norm = Normalize();
var _temp0, _temp1, _temp2; var _temp0, _temp1, _temp2;
var _q0 = X; var _q0 = _norm.X;
var _q1 = Y; var _q1 = _norm.Y;
var _q2 = Z; var _q2 = _norm.Z;
var _q3 = W; var _q3 = _norm.W;
_temp0 = _q0 * _q0; _temp0 = _q0 * _q0;
_temp1 = _q1 * _q1; _temp1 = _q1 * _q1;

View file

@ -410,11 +410,8 @@ enum CAMERA_PROJ {
case 2 : _n = new BBMOD_Vec3(0.0, 0.0, 1.0); break; 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) { if(drag_prev != undefined) {
var _currQ = new BBMOD_Quaternion().FromEuler(_rot[0], _rot[1], _rot[2]); 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 _currR = new BBMOD_Quaternion().FromAxisAngle(_n, (mAng - drag_prev) * (_currQ.Rotate(_n).Z > 0? -1 : 1));
var _mulp = _currQ.Mul(_currR); var _mulp = _currQ.Mul(_currR);
var _Nrot = new BBMOD_Matrix(_mulp.ToMatrix()).ToEuler(); var _Nrot = new BBMOD_Matrix(_mulp.ToMatrix()).ToEuler();

View file

@ -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 ]) inputs[| 0] = nodeValue("Position", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 0, 0, 0 ])
.setDisplay(VALUE_DISPLAY.vector); .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); .setDisplay(VALUE_DISPLAY.vector);
inputs[| 2] = nodeValue("Scale", self, JUNCTION_CONNECT.input, VALUE_TYPE.float, [ 1, 1, 1 ]) 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_my = 0;
drag_px = 0; drag_px = 0;
drag_py = 0; drag_py = 0;
drag_c0x = 0; drag_cx = 0;
drag_c0y = 0; drag_cy = 0;
drag_c1x = 0;
drag_c1y = 0;
drag_c2x = 0;
drag_c2y = 0;
drag_original = 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 _camAx = _camera.focus_angle_x;
var _camAy = _camera.focus_angle_y; 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 _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 _vpos = new __vec3( _pos[0], _pos[1], _pos[2] );
var _posView = _camera.worldPointToViewPoint(_vpos); var _posView = _camera.worldPointToViewPoint(_vpos);
@ -78,6 +67,11 @@ function Node_3DObject(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constru
var th; 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[0] = new BBMOD_Vec3(-size, 0, 0);
ga[1] = new BBMOD_Vec3(0, 0, size); ga[1] = new BBMOD_Vec3(0, 0, size);
ga[2] = new BBMOD_Vec3(0, -size, 0); 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), ]; new BBMOD_Vec3(-hs + sq, -hs + sq, 0), ];
for( var i = 0; i < 3; i++ ) { 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); th = 2 + (axis_hover == i || drag_axis == i);
if(drag_axis != noone && 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) 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); draw_line_round(cx, cy, cx + ga[i].X, cy + ga[i].Y, th);
else 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); var _d = distance_to_line(_mx, _my, cx, cy, cx + ga[i].X, cy + ga[i].Y);
if(_d < _hoverDist) { 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 i = 3; i < 6; i++ ) {
for( var j = 0; j < 4; j++ ) 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; th = 1;
@ -155,32 +149,36 @@ function Node_3DObject(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constru
} }
axis_hover = _hover; axis_hover = _hover;
print(_camera.viewPointToWorldRay(_mx, _my))
if(drag_axis != noone) { if(drag_axis != noone) {
if(!MOUSE_WRAPPING) { if(!MOUSE_WRAPPING) {
drag_mx += _mx - drag_px; drag_mx += _mx - drag_px;
drag_my += _my - drag_py; drag_my += _my - drag_py;
var _mmx = drag_mx - drag_c0x; var _mmx = drag_mx - drag_cx;
var _mmy = drag_my - drag_c0y; var _mmy = drag_my - drag_cy;
var mAdj; var mAdj, nor;
var ray = _camera.viewPointToWorldRay(_mx, _my);
if(drag_axis < 3) { if(drag_axis < 3) {
var _max = drag_c1x; switch(drag_axis) {
var _may = drag_c1y; case 0 : nor = new __vec3(0, 0, 1); break;
mAdj = dot_product(_mmx, _mmy, _max, _may); 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) { 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)) if(inputs[| 0].setValue(_pos))
UNDO_HOLDING = true; UNDO_HOLDING = true;
} }
} else { } else {
var ray = _camera.viewPointToWorldRay(_mx, _my);
var nor;
switch(drag_axis) { switch(drag_axis) {
case 3 : nor = new __vec3(0, 0, 1); break; case 3 : nor = new __vec3(0, 0, 1); break;
case 4 : nor = new __vec3(1, 0, 0); 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_my = _my;
drag_px = _mx; drag_px = _mx;
drag_py = _my; drag_py = _my;
drag_cx = cx;
drag_c0x = cx; drag_cy = cy;
drag_c0y = cy;
drag_original = new __vec3(_pos); drag_original = new __vec3(_pos);
if(drag_axis < 3) {
drag_c1x = ga[drag_axis].X;
drag_c1y = ga[drag_axis].Y;
}
} }
#endregion #endregion
} else if(isUsingTool(1)) { #region rotate } 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 #endregion
} else if(isUsingTool(2)) { #region scale } 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 #endregion
} }
@ -248,7 +466,7 @@ function Node_3DObject(_x, _y, _group = noone) : Node_3D(_x, _y, _group) constru
var _sca = inputs[| 2].getValue(); var _sca = inputs[| 2].getValue();
object.position.set(_pos[0], _pos[1], _pos[2]); 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]); object.scale.set(_sca[0], _sca[1], _sca[2]);
outputs[| 0].setValue(object); outputs[| 0].setValue(object);

View file

@ -8,7 +8,7 @@ function __3dLight() : __3dObject() constructor {
intensity = 1; intensity = 1;
static presubmit = function(params = {}) { 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, var rot = matrix_build(0, 0, 0,
_rot.x, _rot.y, _rot.z, _rot.x, _rot.y, _rot.z,

View file

@ -99,6 +99,20 @@ function __mat4() constructor {
return result; 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() { static clone = function() {
var result = new __mat4(); var result = new __mat4();

View file

@ -23,7 +23,7 @@ function __3dObject() constructor {
custom_shader = noone; custom_shader = noone;
position = new __vec3(0, 0, 0); position = new __vec3(0, 0, 0);
rotation = new __rot3(0, 0, 0); rotation = new BBMOD_Quaternion();
scale = new __vec3(1, 1, 1); scale = new __vec3(1, 1, 1);
static build = function(_buffer = VB, _vertex = vertex, _normal = normals) { static build = function(_buffer = VB, _vertex = vertex, _normal = normals) {
@ -81,15 +81,13 @@ function __3dObject() constructor {
presubmit(params); presubmit(params);
if(VB != noone) { 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, var pos = matrix_build(position.x, position.y, position.z,
0, 0, 0, 0, 0, 0,
1, 1, 1); 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_clear();
matrix_stack_push(pos); matrix_stack_push(pos);

View file

@ -72,4 +72,6 @@ function __rot3(_x = 0, _y = 0, _z = 0) constructor {
} }
static toString = function() { return $"[{x}, {y}, {z}]"; } static toString = function() { return $"[{x}, {y}, {z}]"; }
static toArray = function() { return [ x, y, z ]; }
} }

View file

@ -11,6 +11,13 @@ function __vec3(_x = 0, _y = 0, _z = 0) constructor {
return; return;
} }
if(is_struct(_x) && is_instanceof(_x, BBMOD_Vec3)) {
x = _x.X;
y = _x.Y;
z = _x.Z;
return;
}
if(is_array(_x)) { if(is_array(_x)) {
x = _x[0]; x = _x[0];
y = _x[1]; y = _x[1];
@ -34,6 +41,15 @@ function __vec3(_x = 0, _y = 0, _z = 0) constructor {
return self; 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) { static add = function(_vec3) {
gml_pragma("forceinline"); gml_pragma("forceinline");
return new __vec3(x + _vec3.x, y + _vec3.y, z + _vec3.z); return new __vec3(x + _vec3.x, y + _vec3.y, z + _vec3.z);
@ -154,4 +170,6 @@ function __vec3(_x = 0, _y = 0, _z = 0) constructor {
static toString = function() { return $"[{x}, {y}, {z}]"; } static toString = function() { return $"[{x}, {y}, {z}]"; }
static toBBMOD = function() { return new BBMOD_Vec3(x, y, z); } static toBBMOD = function() { return new BBMOD_Vec3(x, y, z); }
static toArray = function() { return [ x, y, z ]; }
} }

View file

@ -42,6 +42,16 @@ function __vec4(_x = 0, _y = 0, _z = 0, _w = 0) constructor {
return self; 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) { static add = function(_vec4) {
gml_pragma("forceinline"); gml_pragma("forceinline");
return new __vec4(x + _vec4.x, y + _vec4.y, z + _vec4.z, w + _vec4.w); 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); return new __vec4(x, y, z, w);
} }
static toString = function() { static toString = function() { return $"[{x}, {y}, {z}, {w}]"; }
return $"[{x}, {y}, {z}, {w}]";
} static toArray = function() { return [ x, y, z, w ]; }
} }

View file

@ -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) { 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; var sample = corner / 4;
sample = clamp(sample, 1, 8); sample = clamp(sample, 1, 8);

View file

@ -57,3 +57,15 @@ function draw_line_round_arrow_scale(x1, y1, x2, y2, w, as = 4) {
x2 + lengthdir_x(as * w, a + 90 * 3), y2 + lengthdir_y(as * w, a + 90 * 3), x2 + lengthdir_x(as * w, a + 90 * 3), y2 + lengthdir_y(as * w, a + 90 * 3),
false); 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();
}

View file

@ -101,10 +101,10 @@
globalvar VERSION, SAVE_VERSION, VERSION_STRING, BUILD_NUMBER; globalvar VERSION, SAVE_VERSION, VERSION_STRING, BUILD_NUMBER;
VERSION = 11501; VERSION = 11505;
SAVE_VERSION = 11500; SAVE_VERSION = 11500;
VERSION_STRING = "1.15.0.1"; VERSION_STRING = "1.15.0.5";
BUILD_NUMBER = 11501; BUILD_NUMBER = 11505;
globalvar APPEND_MAP; globalvar APPEND_MAP;
APPEND_MAP = ds_map_create(); APPEND_MAP = ds_map_create();

View file

@ -11,6 +11,7 @@ function Node_3D_Light_Directional(_x, _y, _group = noone) : Node_3D_Light(_x, _
setTransform(); setTransform();
setLight(); 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);
} }
} }

View file

@ -247,7 +247,7 @@ function Node_Canvas(_x, _y, _group = noone) : Node(_x, _y, _group) constructor
function get_color_buffer(_x, _y) { #region function get_color_buffer(_x, _y) { #region
var pos = (surface_w * _y + _x) * 4; 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))); print("Error buffer overflow " + string(pos) + "/" + string(buffer_get_size(canvas_buffer)));
return 0; return 0;
} }

View file

@ -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[| 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" ]); .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.") 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) ]; 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() { static update = function() {
var _inSurf = inputs[| 0].getValue(); var _inSurf = inputs[| 0].getValue();
var _active = inputs[| 1].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(); surface_reset_target();
switch(i) { switch(i) {
case 0 : _minx = round(surface_get_pixel_ext(temp_surface[0], 0, 0) / 255); break; case 0 : _minx = surface_getpixel(temp_surface[0], 0, 0)[0]; break;
case 1 : _miny = round(surface_get_pixel_ext(temp_surface[0], 0, 0) / 255); break; case 1 : _miny = surface_getpixel(temp_surface[0], 0, 0)[0]; break;
case 2 : _maxx = round(surface_get_pixel_ext(temp_surface[0], 0, 0) / 255) + 1; break; case 2 : _maxx = surface_getpixel(temp_surface[0], 0, 0)[0]; break;
case 3 : _maxy = round(surface_get_pixel_ext(temp_surface[0], 0, 0) / 255) + 1; 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]; var _surf = _inSurf[i];
if(_array == 0) { 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.width] += _padd[PADDING.left] + _padd[PADDING.right];
resDim[DIMENSION.height] += _padd[PADDING.top] + _padd[PADDING.bottom]; 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 BLEND_NORMAL
surface_reset_target(); surface_reset_target();
} else if(_array == 1) { } 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.width] += _padd[PADDING.left] + _padd[PADDING.right];
resDim[DIMENSION.height] += _padd[PADDING.top] + _padd[PADDING.bottom]; resDim[DIMENSION.height] += _padd[PADDING.top] + _padd[PADDING.bottom];

View file

@ -28,7 +28,6 @@ function Node_Palette_Extract(_x, _y, _group = noone) : Node(_x, _y, _group) con
current_color = 0; current_color = 0;
attribute_surface_depth(); attribute_surface_depth();
attribute_auto_execute(true);
function sortPalette(pal) { function sortPalette(pal) {
array_sort(pal, function(c0, c1) { array_sort(pal, function(c0, c1) {
@ -300,16 +299,13 @@ function Node_Palette_Extract(_x, _y, _group = noone) : Node(_x, _y, _group) con
} }
outputs[| 0].setValue(res); outputs[| 0].setValue(res);
triggerRender();
} }
static onInspector1Update = function() { extractPalettes(); } static onInspector1Update = function() { extractPalettes(); triggerRender(); }
static onValueUpdate = function() { extractPalettes(); } static onValueUpdate = function() { extractPalettes(); }
static onValueFromUpdate = function() { extractPalettes(); } static onValueFromUpdate = function() { extractPalettes(); }
function update() { function update() {
if(attributes.auto_exe)
extractPalettes(); extractPalettes();
} }

View file

@ -358,22 +358,21 @@ function NodeObject(_name, _spr, _node, _create, tags = []) constructor {
ds_list_add(threeD, "Light"); ds_list_add(threeD, "Light");
addNodeObject(threeD, "Directional Light", s_node_3d_cube, "Node_3D_Light_Directional", [1, Node_3D_Light_Directional]); addNodeObject(threeD, "Directional Light", s_node_3d_cube, "Node_3D_Light_Directional", [1, Node_3D_Light_Directional]);
//ds_list_add(threeD, "3D generates"); 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 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 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 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 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 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 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."); 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 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 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 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 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(); var generator = ds_list_create();
addNodeCatagory("Generate", generator); addNodeCatagory("Generate", generator);

View file

@ -673,9 +673,9 @@ function Panel_Preview() : PanelContent() constructor {
shader_set(sh_d3d_default); shader_set(sh_d3d_default);
shader_set_f("light_ambient", colToVec4(d3_light_ambient)); shader_set_f("light_ambient", colToVec4(d3_light_ambient));
//shader_set_f("light_dir_direction", 0, 0, 0); shader_set_f("light_dir_direction", 1, 2, 3);
//shader_set_f("light_dir_color", 0); shader_set_f("light_dir_color", colToVec4(c_white));
//shader_set_f("light_dir_intensity", 0); shader_set_f("light_dir_intensity", 0.5);
shader_reset(); shader_reset();
_prev_node.submitUI(d3_preview_params); _prev_node.submitUI(d3_preview_params);

View file

@ -151,7 +151,6 @@ function surface_get_pixel_ext(surface, _x, _y) {
gml_pragma("forceinline"); gml_pragma("forceinline");
if(!is_surface(surface)) return; if(!is_surface(surface)) return;
var f = surface_get_format(surface);
var px = surface_getpixel_ext(surface, _x, _y); var px = surface_getpixel_ext(surface, _x, _y);
if(is_real(px)) return px; if(is_real(px)) return px;

View file

@ -35,7 +35,7 @@ void main() {
} }
} }
} else if(mode == 2) { //maxx } 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++ ) { for( j = bbox.y; j < _h; j++ ) {
col = texture2D( texture, vec2(i, j) / dimension); col = texture2D( texture, vec2(i, j) / dimension);
if(col.r > 0.) { if(col.r > 0.) {
@ -44,8 +44,8 @@ void main() {
} }
} }
} else if(mode == 3) { //maxy } else if(mode == 3) { //maxy
for( i = _h; i > bbox.y; i-- ) for( i = _h; i >= bbox.y; i-- )
for( j = bbox.x; j < bbox.z; j++ ) { for( j = bbox.x; j <= bbox.z; j++ ) {
col = texture2D( texture, vec2(j, i) / dimension); col = texture2D( texture, vec2(j, i) / dimension);
if(col.r > 0.) { if(col.r > 0.) {
gl_FragColor = vec4(i); gl_FragColor = vec4(i);