2023-01-09 03:14:20 +01:00
|
|
|
enum CAMERA_PROJ {
|
|
|
|
ortho,
|
|
|
|
perspective
|
|
|
|
}
|
|
|
|
|
2022-01-13 05:24:03 +01:00
|
|
|
#region setup
|
2023-07-25 20:12:40 +02:00
|
|
|
globalvar PRIMITIVES, FORMAT_P, FORMAT_PT, FORMAT_PNT, FORMAT_2PC;
|
2022-01-13 05:24:03 +01:00
|
|
|
PRIMITIVES = ds_map_create();
|
|
|
|
|
2023-02-14 11:40:24 +01:00
|
|
|
vertex_format_begin();
|
|
|
|
vertex_format_add_position_3d();
|
|
|
|
FORMAT_P = vertex_format_end();
|
|
|
|
|
2022-01-13 05:24:03 +01:00
|
|
|
vertex_format_begin();
|
|
|
|
vertex_format_add_position_3d();
|
|
|
|
vertex_format_add_texcoord();
|
|
|
|
FORMAT_PT = vertex_format_end();
|
2022-12-12 09:08:03 +01:00
|
|
|
|
|
|
|
vertex_format_begin();
|
|
|
|
vertex_format_add_position_3d();
|
|
|
|
vertex_format_add_normal();
|
|
|
|
vertex_format_add_texcoord();
|
|
|
|
FORMAT_PNT = vertex_format_end();
|
2023-07-25 20:12:40 +02:00
|
|
|
|
|
|
|
vertex_format_begin();
|
|
|
|
vertex_format_add_position();
|
|
|
|
vertex_format_add_color();
|
|
|
|
FORMAT_2PC = vertex_format_end();
|
2022-01-13 05:24:03 +01:00
|
|
|
#endregion
|
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
#region 3d obj
|
|
|
|
function VertexObject() constructor {
|
|
|
|
positions = [];
|
|
|
|
textures = [];
|
|
|
|
normals = [];
|
|
|
|
|
|
|
|
faces = [];
|
|
|
|
buffer = noone;
|
|
|
|
renderSurface = noone;
|
|
|
|
renderTexture = noone;
|
|
|
|
|
|
|
|
static addPosition = function(_pos, _merge = false) {
|
|
|
|
if(!_merge) {
|
|
|
|
array_push(positions, _pos);
|
|
|
|
return array_length(positions) - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
var ind = array_find(positions, _pos);
|
|
|
|
|
|
|
|
if(ind == -1) {
|
|
|
|
array_push(positions, _pos);
|
|
|
|
return array_length(positions) - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ind;
|
|
|
|
}
|
|
|
|
|
|
|
|
static addNormal = function(_nor, _merge = false) {
|
|
|
|
if(!_merge) {
|
|
|
|
array_push(normals, _nor);
|
|
|
|
return array_length(normals) - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
var ind = array_find(normals, _nor);
|
|
|
|
|
|
|
|
if(ind == -1) {
|
|
|
|
array_push(normals, _nor);
|
|
|
|
return array_length(normals) - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ind;
|
|
|
|
}
|
|
|
|
|
|
|
|
static addTexture = function(_tex, _merge = false) {
|
|
|
|
if(!_merge) {
|
|
|
|
array_push(textures, _tex);
|
|
|
|
return array_length(textures) - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
var ind = array_find(textures, _tex);
|
|
|
|
|
|
|
|
if(ind == -1) {
|
|
|
|
array_push(textures, _tex);
|
|
|
|
return array_length(textures) - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ind;
|
|
|
|
}
|
|
|
|
|
2023-05-08 10:50:42 +02:00
|
|
|
static addFace = function(v1 = [0, 0, 0], n1 = [0, 0, 0], t1 = [0, 0],
|
|
|
|
v2 = [0, 0, 0], n2 = [0, 0, 0], t2 = [0, 0],
|
|
|
|
v3 = [0, 0, 0], n3 = [0, 0, 0], t3 = [0, 0], _merge = false) {
|
2023-05-03 21:42:17 +02:00
|
|
|
var pi0 = addPosition(v1, _merge);
|
|
|
|
var pi1 = addPosition(v2, _merge);
|
|
|
|
var pi2 = addPosition(v3, _merge);
|
|
|
|
|
|
|
|
var ni0 = addNormal(n1, _merge);
|
|
|
|
var ni1 = addNormal(n2, _merge);
|
|
|
|
var ni2 = addNormal(n3, _merge);
|
|
|
|
|
|
|
|
var ti0 = addTexture(t1, _merge);
|
|
|
|
var ti1 = addTexture(t2, _merge);
|
|
|
|
var ti2 = addTexture(t3, _merge);
|
|
|
|
|
|
|
|
array_append(faces, [
|
|
|
|
[pi0, ni0, ti0],
|
|
|
|
[pi1, ni1, ti1],
|
|
|
|
[pi2, ni2, ti2],
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
static createBuffer = function() {
|
|
|
|
if(buffer != noone) vertex_delete_buffer(buffer);
|
|
|
|
|
|
|
|
var VB = vertex_create_buffer();
|
|
|
|
vertex_begin(VB, FORMAT_PNT);
|
|
|
|
|
2023-07-25 20:12:40 +02:00
|
|
|
for( var i = 0, n = array_length(faces); i < n; i++ ) {
|
2023-05-03 21:42:17 +02:00
|
|
|
var face = faces[i];
|
|
|
|
var _pos = positions[face[0]];
|
|
|
|
var _nor = normals [face[1]];
|
|
|
|
var _tex = textures [face[2]];
|
|
|
|
|
|
|
|
vertex_add_pnt(VB, _pos, _nor, _tex);
|
|
|
|
}
|
|
|
|
|
|
|
|
vertex_end(VB);
|
|
|
|
vertex_freeze(VB);
|
|
|
|
|
|
|
|
buffer = VB;
|
|
|
|
return VB;
|
|
|
|
}
|
|
|
|
|
|
|
|
static submit = function(surface = noone) {
|
|
|
|
if(!is_surface(surface)) {
|
|
|
|
__submit();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
renderSurface = surface;
|
|
|
|
submitTexture(surface_get_texture(surface));
|
|
|
|
}
|
|
|
|
|
|
|
|
static submitTexture = function(texture) {
|
|
|
|
renderTexture = texture;
|
|
|
|
__submit();
|
|
|
|
}
|
|
|
|
|
|
|
|
static __submit = function() {
|
2023-05-16 21:28:16 +02:00
|
|
|
if(renderTexture == noone) return;
|
|
|
|
if(buffer == noone) return;
|
2023-05-03 21:42:17 +02:00
|
|
|
|
|
|
|
vertex_submit(buffer, pr_trianglelist, renderTexture);
|
|
|
|
}
|
|
|
|
|
|
|
|
static clone = function(_submit = true) {
|
|
|
|
var v = new VertexObject();
|
|
|
|
v.positions = array_clone(positions);
|
|
|
|
v.textures = array_clone(textures);
|
|
|
|
v.normals = array_clone(normals);
|
|
|
|
|
|
|
|
v.faces = array_clone(faces);
|
|
|
|
v.renderTexture = renderTexture;
|
|
|
|
|
|
|
|
if(_submit) v.createBuffer();
|
|
|
|
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
static destroy = function() {
|
|
|
|
vertex_delete_buffer(buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region primitives
|
2022-01-13 05:24:03 +01:00
|
|
|
var _0 = -.5;
|
|
|
|
var _1 = .5;
|
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
var v = new VertexObject();
|
|
|
|
v.addFace( [_1, _0, 0], [0, 0, 1], [1, 0],
|
|
|
|
[_0, _0, 0], [0, 0, 1], [0, 0],
|
|
|
|
[_1, _1, 0], [0, 0, 1], [1, 1], );
|
2023-01-01 02:06:02 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
v.addFace( [_1, _1, 0], [0, 0, 1], [1, 1],
|
|
|
|
[_0, _0, 0], [0, 0, 1], [0, 0],
|
|
|
|
[_0, _1, 0], [0, 0, 1], [0, 1], );
|
2022-12-12 09:08:03 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
PRIMITIVES[? "plane"] = v;
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
var v = [];
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
v[0] = new VertexObject();
|
|
|
|
v[0].addFace( [_1, _0, _0], [0, 0, -1], [1, 0],
|
|
|
|
[_0, _0, _0], [0, 0, -1], [0, 0],
|
|
|
|
[_1, _1, _0], [0, 0, -1], [1, 1], );
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
v[0].addFace( [_1, _1, _0], [0, 0, -1], [1, 1],
|
|
|
|
[_0, _0, _0], [0, 0, -1], [0, 0],
|
|
|
|
[_0, _1, _0], [0, 0, -1], [0, 1], );
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
v[1] = new VertexObject();
|
|
|
|
v[1].addFace( [_1, _0, _1], [0, 0, 1], [0, 0],
|
|
|
|
[_0, _0, _1], [0, 0, 1], [1, 0],
|
|
|
|
[_1, _1, _1], [0, 0, 1], [0, 1], );
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
v[1].addFace( [_1, _1, _1], [0, 0, 1], [0, 1],
|
|
|
|
[_0, _0, _1], [0, 0, 1], [1, 0],
|
|
|
|
[_0, _1, _1], [0, 0, 1], [1, 1], );
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
v[2] = new VertexObject();
|
|
|
|
v[2].addFace( [_1, _0, _0], [0, -1, 0], [1, 0],
|
|
|
|
[_0, _0, _0], [0, -1, 0], [0, 0],
|
|
|
|
[_1, _0, _1], [0, -1, 0], [1, 1], );
|
2022-01-13 05:24:03 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
v[2].addFace( [_1, _0, _1], [0, -1, 0], [1, 1],
|
|
|
|
[_0, _0, _0], [0, -1, 0], [0, 0],
|
|
|
|
[_0, _0, _1], [0, -1, 0], [0, 1], );
|
|
|
|
|
|
|
|
v[3] = new VertexObject();
|
|
|
|
v[3].addFace( [_1, _1, _0], [0, 1, 0], [1, 0],
|
|
|
|
[_0, _1, _0], [0, 1, 0], [0, 0],
|
|
|
|
[_1, _1, _1], [0, 1, 0], [1, 1], );
|
2023-02-14 11:40:24 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
v[3].addFace( [_1, _1, _1], [0, 1, 0], [1, 1],
|
|
|
|
[_0, _1, _0], [0, 1, 0], [0, 0],
|
|
|
|
[_0, _1, _1], [0, 1, 0], [0, 1], );
|
2023-02-14 11:40:24 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
v[4] = new VertexObject();
|
|
|
|
v[4].addFace( [_0, _1, _0], [-1, 0, 0], [1, 1],
|
|
|
|
[_0, _0, _0], [-1, 0, 0], [1, 0],
|
|
|
|
[_0, _1, _1], [-1, 0, 0], [0, 1], );
|
|
|
|
|
|
|
|
v[4].addFace( [_0, _1, _1], [-1, 0, 0], [0, 1],
|
|
|
|
[_0, _0, _0], [-1, 0, 0], [1, 0],
|
|
|
|
[_0, _0, _1], [-1, 0, 0], [0, 0], );
|
|
|
|
|
|
|
|
v[5] = new VertexObject();
|
|
|
|
v[5].addFace( [_1, _1, _0], [1, 0, 0], [0, 1],
|
|
|
|
[_1, _0, _0], [1, 0, 0], [0, 0],
|
|
|
|
[_1, _1, _1], [1, 0, 0], [1, 1], );
|
|
|
|
|
|
|
|
v[5].addFace( [_1, _1, _1], [1, 0, 0], [1, 1],
|
|
|
|
[_1, _0, _0], [1, 0, 0], [0, 0],
|
|
|
|
[_1, _0, _1], [1, 0, 0], [1, 0], );
|
|
|
|
|
|
|
|
PRIMITIVES[? "cube"] = v;
|
2023-02-14 11:40:24 +01:00
|
|
|
#endregion
|
|
|
|
|
2023-01-01 02:06:02 +01:00
|
|
|
#region helper
|
2023-05-03 21:42:17 +02:00
|
|
|
enum GIZMO_3D_TYPE {
|
|
|
|
move,
|
|
|
|
rotate,
|
|
|
|
scale
|
|
|
|
}
|
|
|
|
|
|
|
|
function _3d_node_init(iDim, gPos, gSca, iPos, iRot, iSca) {
|
2023-01-01 02:06:02 +01:00
|
|
|
VB = [];
|
|
|
|
use_normal = true;
|
|
|
|
|
2023-08-14 19:22:04 +02:00
|
|
|
TM = matrix_build(0, 0, 0, 0, 0, 0, 1, 1, 1);
|
2023-01-01 02:06:02 +01:00
|
|
|
cam = camera_create();
|
2023-01-09 03:14:20 +01:00
|
|
|
|
2023-01-01 02:06:02 +01:00
|
|
|
cam_view = matrix_build_lookat(0, 0, 1, 0, 0, 0, 0, 1, 0);
|
|
|
|
cam_proj = matrix_build_projection_ortho(1, 1, 1, 100);
|
|
|
|
|
2023-01-09 03:14:20 +01:00
|
|
|
camera_set_view_mat(cam, cam_view);
|
|
|
|
camera_set_proj_mat(cam, cam_proj);
|
2023-01-01 02:06:02 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
drag_index = noone;
|
|
|
|
drag_sv = 0;
|
|
|
|
drag_delta = 0;
|
|
|
|
drag_prev = 0;
|
2023-01-01 02:06:02 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
drag_mx = 0;
|
|
|
|
drag_my = 0;
|
2023-01-01 02:06:02 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
input_dim = iDim;
|
|
|
|
global_pos = gPos;
|
|
|
|
global_sca = gSca;
|
|
|
|
input_pos = iPos;
|
|
|
|
input_rot = iRot;
|
|
|
|
input_sca = iSca;
|
2023-01-01 02:06:02 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
gizmo_hover = noone;
|
2023-01-01 02:06:02 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
tools = [
|
|
|
|
new NodeTool( "Transform", THEME.tools_3d_transform ),
|
|
|
|
new NodeTool( "Rotate", THEME.tools_3d_rotate ),
|
|
|
|
new NodeTool( "Scale", THEME.tools_3d_scale ),
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2023-06-13 14:42:06 +02:00
|
|
|
function _3d_gizmo(active, _x, _y, _s, _mx, _my, _snx, _sny) { #region
|
2023-10-02 08:57:44 +02:00
|
|
|
var _gpos = getInputData(global_pos);
|
|
|
|
var _gsca = getInputData(global_sca);
|
2023-01-01 02:06:02 +01:00
|
|
|
|
2023-10-02 08:57:44 +02:00
|
|
|
var _pos = getInputData(input_pos);
|
|
|
|
var _rot = getInputData(input_rot);
|
|
|
|
var _sca = getInputData(input_sca);
|
2023-05-03 21:42:17 +02:00
|
|
|
|
|
|
|
var cx = _x + _gpos[0] * _s;
|
|
|
|
var cy = _y + _gpos[1] * _s;
|
2023-08-14 19:22:04 +02:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
var _qrot = new BBMOD_Quaternion().FromEuler(_rot[0], -_rot[1], -_rot[2]);
|
|
|
|
var _hover = noone;
|
|
|
|
var _hoverDist = 10;
|
2023-01-01 02:06:02 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
if(isUsingTool(0)) {
|
|
|
|
var ga = [];
|
|
|
|
var dir = 0;
|
2023-01-01 02:06:02 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
ga[0] = new BBMOD_Vec3(64, 0, 0);
|
|
|
|
ga[1] = new BBMOD_Vec3( 0, -64, 0);
|
|
|
|
ga[2] = new BBMOD_Vec3( 0, 0, 64);
|
2023-01-01 02:06:02 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
for( var i = 0; i < 3; i++ ) {
|
|
|
|
ga[i] = _qrot.Rotate(ga[i]);
|
|
|
|
|
|
|
|
var th = 2 + (gizmo_hover == i);
|
|
|
|
if(drag_index == i) {
|
|
|
|
th = 3;
|
|
|
|
dir = point_direction(0, 0, ga[i].X, ga[i].Y);
|
|
|
|
} else if(drag_index != noone)
|
|
|
|
th = 1;
|
|
|
|
|
|
|
|
draw_set_color(COLORS.axis[i]);
|
|
|
|
draw_line_round_arrow(cx, cy, cx + ga[i].X, cy + ga[i].Y, th);
|
|
|
|
|
|
|
|
var _d = distance_to_line(_mx, _my, cx, cy, cx + ga[i].X, cy + ga[i].Y);
|
|
|
|
if(_d < _hoverDist) {
|
|
|
|
_hover = i;
|
|
|
|
_hoverDist = _d;
|
|
|
|
}
|
2023-01-01 02:06:02 +01:00
|
|
|
}
|
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
gizmo_hover = _hover;
|
2023-01-01 02:06:02 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
if(drag_index != noone) {
|
|
|
|
var mAng = point_direction(cx, cy, _mx, _my);
|
|
|
|
var _n = BBMOD_VEC3_FORWARD;
|
|
|
|
|
|
|
|
var _mmx = _mx - cx;
|
|
|
|
var _mmy = _my - cy;
|
|
|
|
var _max = ga[drag_index].X;
|
|
|
|
var _may = ga[drag_index].Y;
|
|
|
|
|
|
|
|
var mAdj = dot_product(_mmx, _mmy, _max, _may);
|
|
|
|
|
|
|
|
if(drag_prev != undefined) {
|
|
|
|
_pos[drag_index] += (mAdj - drag_prev) / 8000;
|
|
|
|
|
2024-08-08 06:57:51 +02:00
|
|
|
if(inputs[input_pos].setValue(_pos))
|
2023-05-03 21:42:17 +02:00
|
|
|
UNDO_HOLDING = true;
|
|
|
|
}
|
|
|
|
drag_prev = mAdj;
|
2023-01-01 02:06:02 +01:00
|
|
|
}
|
2023-05-03 21:42:17 +02:00
|
|
|
} else if(isUsingTool(1)) {
|
|
|
|
var _pa = [], pa = [];
|
|
|
|
var drx, dry, drz;
|
|
|
|
|
|
|
|
var _sub = 64;
|
|
|
|
for( var i = 0; i <= _sub; i++ ) {
|
|
|
|
var ang = i * 360 / _sub;
|
|
|
|
|
|
|
|
pa[0] = new BBMOD_Vec3(0, lengthdir_x(64, ang), lengthdir_y(64, ang));
|
|
|
|
pa[0] = _qrot.Rotate(pa[0]);
|
2023-01-01 02:06:02 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
pa[1] = new BBMOD_Vec3(lengthdir_x(64, ang), 0, lengthdir_y(64, ang));
|
|
|
|
pa[1] = _qrot.Rotate(pa[1]);
|
2023-01-01 02:06:02 +01:00
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
pa[2] = new BBMOD_Vec3(lengthdir_x(64, ang), lengthdir_y(64, ang), 0);
|
|
|
|
pa[2] = _qrot.Rotate(pa[2]);
|
|
|
|
|
|
|
|
if(i) {
|
|
|
|
for( var j = 0; j < 3; j++ ) {
|
|
|
|
draw_set_color(COLORS.axis[j]);
|
|
|
|
var th = (_pa[j].Z >= 0) + 1 + (gizmo_hover == j);
|
|
|
|
if(drag_index == j)
|
|
|
|
th = 3;
|
|
|
|
else if(drag_index != noone)
|
|
|
|
th = 1;
|
|
|
|
|
|
|
|
if(_pa[j].Z >= 0 || i % 2 || drag_index == j) {
|
|
|
|
draw_line_round(cx + _pa[j].X, cy + _pa[j].Y, cx + pa[j].X, cy + pa[j].Y, th);
|
|
|
|
drx = point_direction(cx + _pa[j].X, cy + _pa[j].Y, cx + pa[j].X, cy + pa[j].Y);
|
|
|
|
}
|
|
|
|
|
|
|
|
var _d = distance_to_line(_mx, _my, cx + _pa[j].X, cy + _pa[j].Y, cx + pa[j].X, cy + pa[j].Y);
|
|
|
|
if(_d < _hoverDist) {
|
|
|
|
_hover = j;
|
|
|
|
_hoverDist = _d;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for( var j = 0; j < 3; j++ )
|
|
|
|
_pa[j] = pa[j];
|
2023-01-01 02:06:02 +01:00
|
|
|
}
|
2023-05-03 21:42:17 +02:00
|
|
|
|
|
|
|
gizmo_hover = _hover;
|
|
|
|
|
|
|
|
if(drag_index != noone) {
|
|
|
|
var mAng = point_direction(cx, cy, _mx, _my);
|
|
|
|
var _n = BBMOD_VEC3_FORWARD;
|
|
|
|
|
|
|
|
switch(drag_index) {
|
|
|
|
case 0 : _n = new BBMOD_Vec3(1.0, 0.0, 0.0); break;
|
|
|
|
case 1 : _n = new BBMOD_Vec3(0.0, 1.0, 0.0); break;
|
|
|
|
case 2 : _n = new BBMOD_Vec3(0.0, 0.0, 1.0); break;
|
2023-01-01 02:06:02 +01:00
|
|
|
}
|
2023-05-03 21:42:17 +02:00
|
|
|
|
|
|
|
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();
|
|
|
|
|
2024-08-08 06:57:51 +02:00
|
|
|
if(inputs[input_rot].setValue(_Nrot))
|
2023-05-03 21:42:17 +02:00
|
|
|
UNDO_HOLDING = true;
|
2023-01-01 02:06:02 +01:00
|
|
|
}
|
2023-05-03 21:42:17 +02:00
|
|
|
|
|
|
|
draw_set_color(COLORS._main_accent);
|
|
|
|
draw_line_dashed(cx, cy, _mx, _my, 2, 8);
|
|
|
|
|
|
|
|
drag_prev = mAng;
|
|
|
|
}
|
|
|
|
} else if(isUsingTool(2)) {
|
|
|
|
var ga = [];
|
|
|
|
|
|
|
|
ga[0] = new BBMOD_Vec3(64, 0, 0);
|
|
|
|
ga[1] = new BBMOD_Vec3( 0, -64, 0);
|
|
|
|
ga[2] = new BBMOD_Vec3( 0, 0, 64);
|
|
|
|
|
|
|
|
for( var i = 0; i < 3; i++ ) {
|
|
|
|
ga[i] = _qrot.Rotate(ga[i]);
|
|
|
|
|
|
|
|
var th = 2 + (gizmo_hover == i);
|
|
|
|
if(drag_index == i)
|
|
|
|
th = 3;
|
|
|
|
else if(drag_index != noone)
|
|
|
|
th = 1;
|
|
|
|
|
|
|
|
draw_set_color(COLORS.axis[i]);
|
|
|
|
draw_line_round_arrow_scale(cx, cy, cx + ga[i].X, cy + ga[i].Y, th);
|
|
|
|
|
|
|
|
var _d = distance_to_line(_mx, _my, cx, cy, cx + ga[i].X, cy + ga[i].Y);
|
|
|
|
if(_d < _hoverDist) {
|
|
|
|
_hover = i;
|
|
|
|
_hoverDist = _d;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gizmo_hover = _hover;
|
|
|
|
|
|
|
|
if(drag_index != noone) {
|
|
|
|
var mAng = point_direction(cx, cy, _mx, _my);
|
|
|
|
var _n = BBMOD_VEC3_FORWARD;
|
|
|
|
|
|
|
|
var _mmx = _mx - cx;
|
|
|
|
var _mmy = _my - cy;
|
|
|
|
var _max = ga[drag_index].X;
|
|
|
|
var _may = ga[drag_index].Y;
|
|
|
|
|
|
|
|
var mAdj = dot_product(_mmx, _mmy, _max, _may);
|
|
|
|
|
|
|
|
if(drag_prev != undefined) {
|
|
|
|
_sca[drag_index] += (mAdj - drag_prev) / 8000;
|
|
|
|
|
2024-08-08 06:57:51 +02:00
|
|
|
if(inputs[input_sca].setValue(_sca))
|
2023-05-03 21:42:17 +02:00
|
|
|
UNDO_HOLDING = true;
|
2023-01-01 02:06:02 +01:00
|
|
|
}
|
2023-05-03 21:42:17 +02:00
|
|
|
drag_prev = mAdj;
|
2023-01-01 02:06:02 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-03 21:42:17 +02:00
|
|
|
if(drag_index != noone && mouse_release(mb_left)) {
|
|
|
|
drag_index = noone;
|
|
|
|
UNDO_HOLDING = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(_hover != noone && mouse_press(mb_left, active)) {
|
|
|
|
drag_index = _hover;
|
|
|
|
drag_prev = undefined;
|
|
|
|
drag_mx = _mx;
|
|
|
|
drag_my = _my;
|
|
|
|
}
|
|
|
|
|
2024-08-08 06:57:51 +02:00
|
|
|
inputs[global_pos].drawOverlay(hover, active, _x, _y, _s, _mx, _my, _snx, _sny);
|
2023-06-13 14:42:06 +02:00
|
|
|
#endregion
|
2023-01-01 02:06:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function _3d_local_transform(_lpos, _lrot, _lsca) {
|
|
|
|
matrix_stack_push(matrix_build(0, 0, 0, _lrot[0], _lrot[1], _lrot[2], 1, 1, 1));
|
2023-05-03 21:42:17 +02:00
|
|
|
matrix_stack_push(matrix_build(-_lpos[0], -_lpos[1], _lpos[2], 0, 0, 0, 1, 1, 1));
|
2023-01-01 02:06:02 +01:00
|
|
|
matrix_stack_push(matrix_build(0, 0, 0, 0, 0, 0, _lsca[0], _lsca[1], _lsca[2]));
|
|
|
|
|
|
|
|
matrix_set(matrix_world, matrix_stack_top());
|
|
|
|
}
|
|
|
|
|
|
|
|
function _3d_clear_local_transform() {
|
|
|
|
matrix_stack_pop();
|
|
|
|
matrix_stack_pop();
|
|
|
|
matrix_stack_pop();
|
|
|
|
}
|
|
|
|
|
2023-06-13 14:42:06 +02:00
|
|
|
function __3d_transform(pos = 0, rot = 0, sca = 0, lpos = 0, lrot = 0, lsca = 0, apply_local = true, sdim = true) constructor {
|
|
|
|
self.pos = pos;
|
|
|
|
self.rot = rot;
|
|
|
|
self.sca = sca;
|
|
|
|
|
|
|
|
self.local_pos = lpos;
|
|
|
|
self.local_rot = lrot;
|
|
|
|
self.local_sca = lsca;
|
|
|
|
|
|
|
|
self.apply_local = apply_local;
|
|
|
|
self.scaleDimension = sdim;
|
|
|
|
}
|
|
|
|
|
|
|
|
function __3d_light(dir = 0, height = 0, intensity = 0, color = c_white, ambient = c_white) constructor {
|
|
|
|
self.dir = dir;
|
|
|
|
self.height = height;
|
|
|
|
self.intensity = intensity;
|
|
|
|
self.color = color;
|
|
|
|
self.ambient = ambient;
|
|
|
|
}
|
|
|
|
|
|
|
|
function __3d_camera(proj, fov) constructor {
|
|
|
|
self.projection = proj;
|
|
|
|
self.fov = fov;
|
|
|
|
}
|
|
|
|
|
|
|
|
function _3d_pre_setup(_outSurf, _dim, _transform, _light, _cam, _pass = "diff") {
|
2023-01-01 02:06:02 +01:00
|
|
|
_outSurf = surface_verify(_outSurf, _dim[0], _dim[1]);
|
|
|
|
|
2023-06-13 14:42:06 +02:00
|
|
|
var _pos = _transform.pos;
|
|
|
|
var _sca = _transform.sca;
|
|
|
|
var _lpos = _transform.local_pos;
|
|
|
|
var _lrot = _transform.local_rot;
|
|
|
|
var _lsca = _transform.local_sca;
|
|
|
|
|
|
|
|
var _ldir = _light.dir;
|
|
|
|
var _lhgt = _light.height;
|
|
|
|
var _lint = _light.intensity;
|
|
|
|
var _lclr = _light.color;
|
|
|
|
var _aclr = _light.ambient;
|
|
|
|
|
2023-02-23 07:02:19 +01:00
|
|
|
var _proj = _cam.projection;
|
|
|
|
var _fov = _cam.fov;
|
2023-06-13 14:42:06 +02:00
|
|
|
|
|
|
|
var _applyLocal = _transform.apply_local;
|
|
|
|
var scaleDimension = _transform.scaleDimension;
|
2023-02-23 07:02:19 +01:00
|
|
|
|
2023-01-01 02:06:02 +01:00
|
|
|
var lightFor = [ -cos(degtorad(_ldir)), -_lhgt, -sin(degtorad(_ldir)) ];
|
|
|
|
|
|
|
|
gpu_set_ztestenable(true);
|
2024-01-25 08:24:02 +01:00
|
|
|
|
2023-01-01 02:06:02 +01:00
|
|
|
surface_set_target(_outSurf);
|
2023-03-19 09:17:39 +01:00
|
|
|
DRAW_CLEAR
|
2023-01-01 02:06:02 +01:00
|
|
|
|
2023-01-09 03:14:20 +01:00
|
|
|
var shader = sh_vertex_pnt_light;
|
|
|
|
if(_pass == "diff") shader = sh_vertex_pnt_light;
|
|
|
|
else if(_pass == "norm") shader = sh_vertex_normal_pass;
|
|
|
|
else if(_pass == "dept") shader = sh_vertex_depth_pass;
|
|
|
|
|
|
|
|
uniVertex_lightFor = shader_get_uniform(shader, "u_LightForward");
|
|
|
|
uniLightAmb = shader_get_uniform(shader, "u_AmbientLight");
|
|
|
|
uniLightClr = shader_get_uniform(shader, "u_LightColor");
|
|
|
|
uniLightInt = shader_get_uniform(shader, "u_LightIntensity");
|
|
|
|
uniLightNrm = shader_get_uniform(shader, "useNormal");
|
|
|
|
|
|
|
|
shader_set(shader);
|
2023-02-14 11:40:24 +01:00
|
|
|
shader_set_uniform_f_array_safe(uniVertex_lightFor, lightFor);
|
2024-06-14 12:46:25 +02:00
|
|
|
shader_set_uniform_f_array_safe(uniLightAmb, colorToArray(_aclr));
|
|
|
|
shader_set_uniform_f_array_safe(uniLightClr, colorToArray(_lclr));
|
2023-01-01 02:06:02 +01:00
|
|
|
shader_set_uniform_f(uniLightInt, _lint);
|
|
|
|
shader_set_uniform_i(uniLightNrm, use_normal);
|
2023-01-04 02:30:04 +01:00
|
|
|
|
2023-01-09 03:14:20 +01:00
|
|
|
var cam_view, cam_proj;
|
2024-03-31 05:36:11 +02:00
|
|
|
var dw = array_safe_get_fast(_dim, 0);
|
|
|
|
var dh = array_safe_get_fast(_dim, 1);
|
2023-01-09 03:14:20 +01:00
|
|
|
|
|
|
|
if(_proj == CAMERA_PROJ.ortho) {
|
|
|
|
cam_view = matrix_build_lookat(0, 0, 128, 0, 0, 0, 0, 1, 0);
|
2023-02-14 11:40:24 +01:00
|
|
|
cam_proj = matrix_build_projection_ortho(dw, dh, 0.1, 256);
|
2023-01-09 03:14:20 +01:00
|
|
|
} else {
|
|
|
|
var _adjFov = power(_fov / 90, 1 / 4) * 90;
|
|
|
|
var dist = _dim[0] / 2 * dtan(90 - _adjFov);
|
|
|
|
cam_view = matrix_build_lookat(0, 0, 1 + dist, 0, 0, 0, 0, 1, 0);
|
2023-02-14 11:40:24 +01:00
|
|
|
cam_proj = matrix_build_projection_perspective(dw, dh, dist, dist + 256);
|
2023-01-09 03:14:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
var cam = camera_get_active();
|
2023-02-14 11:40:24 +01:00
|
|
|
camera_set_view_size(cam, dw, dh);
|
2023-01-09 03:14:20 +01:00
|
|
|
camera_set_view_mat(cam, cam_view);
|
|
|
|
camera_set_proj_mat(cam, cam_proj);
|
2023-01-01 02:06:02 +01:00
|
|
|
camera_apply(cam);
|
|
|
|
|
2023-01-09 03:14:20 +01:00
|
|
|
if(_proj == CAMERA_PROJ.ortho)
|
2023-02-23 07:02:19 +01:00
|
|
|
matrix_stack_push(matrix_build(dw / 2 - _pos[0], _pos[1] - dh / 2, 0, 0, 0, 0, (scaleDimension? dw : 1) * _sca[0], (scaleDimension? dh : 1) * _sca[1], 1));
|
2023-01-09 03:14:20 +01:00
|
|
|
else
|
2023-02-23 07:02:19 +01:00
|
|
|
matrix_stack_push(matrix_build(dw / 2 - _pos[0], _pos[1] - dh / 2, 0, 0, 0, 0, (scaleDimension? dw : 1) * _sca[0], (scaleDimension? dh : 1) * _sca[1], 1));
|
2023-01-09 03:14:20 +01:00
|
|
|
//matrix_stack_push(matrix_build(0, 0, 0, 0, 0, 0, 1, 1, 1));
|
|
|
|
|
2023-01-01 02:06:02 +01:00
|
|
|
if(_applyLocal) _3d_local_transform(_lpos, _lrot, _lsca);
|
|
|
|
|
|
|
|
matrix_set(matrix_world, matrix_stack_top());
|
2023-05-03 21:42:17 +02:00
|
|
|
|
|
|
|
return _outSurf;
|
2023-01-01 02:06:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function _3d_post_setup() {
|
|
|
|
shader_reset();
|
|
|
|
|
|
|
|
matrix_stack_clear();
|
|
|
|
matrix_set(matrix_world, MATRIX_IDENTITY);
|
|
|
|
|
|
|
|
gpu_set_ztestenable(false);
|
2024-01-25 08:24:02 +01:00
|
|
|
|
2023-01-09 03:14:20 +01:00
|
|
|
var cam = camera_get_active();
|
|
|
|
camera_set_view_mat(cam, matrix_build_lookat(0, 0, 1, 0, 0, 0, 0, 1, 0));
|
|
|
|
camera_set_proj_mat(cam, matrix_build_projection_ortho(1, 1, 0.1, 256));
|
|
|
|
camera_apply(cam);
|
2023-01-01 02:06:02 +01:00
|
|
|
|
|
|
|
surface_reset_target();
|
|
|
|
}
|
2022-01-13 05:24:03 +01:00
|
|
|
#endregion
|