From d4ec643fd6ba373c61a38ec56fe88d12db5e8500 Mon Sep 17 00:00:00 2001 From: Sorata <39014375+q8X@users.noreply.github.com> Date: Tue, 21 Apr 2026 23:37:07 +0300 Subject: [PATCH] Feature: local move space --- [editor]/editor_main/client/controls.lua | 1 + [editor]/editor_main/client/main.lua | 6 ++ [editor]/move_keyboard/meta.xml | 3 + [editor]/move_keyboard/move_keyboard.lua | 104 +++++++++++++++-------- 4 files changed, 79 insertions(+), 35 deletions(-) diff --git a/[editor]/editor_main/client/controls.lua b/[editor]/editor_main/client/controls.lua index da6fdf9b3..6ac7126e7 100644 --- a/[editor]/editor_main/client/controls.lua +++ b/[editor]/editor_main/client/controls.lua @@ -32,6 +32,7 @@ local defaultControls = { { name="mod_rotate", key ="lctrl", friendlyName="Rotate Modifier World Space" }, { name="mod_rotate_local", key ="rctrl", friendlyName="Rotate Modifier Local Space" }, { name="high_sensitivity_mode", key ="e", friendlyName="High Sensivity Mode" }, +{ name="local_move_space_mode", key ="v", friendlyName="Local Move Space Mode" }, { name="element_move_right", key ="arrow_r", friendlyName="Move Element Right / Yaw" }, { name="element_move_left", key ="arrow_l", friendlyName="Move Element Left / Yaw" }, { name="element_move_forward", key ="arrow_u", friendlyName="Move Element Forward / Pitch" }, diff --git a/[editor]/editor_main/client/main.lua b/[editor]/editor_main/client/main.lua index 3f36f99cd..599c8507a 100644 --- a/[editor]/editor_main/client/main.lua +++ b/[editor]/editor_main/client/main.lua @@ -1171,6 +1171,7 @@ function bindInput(commandsOnly) bindControl("redo", "down", keyboardRedo) bindControl("high_sensitivity_mode", "down", toggleSensitivityMode) bindControl("lock_selected_element", "down", lockSelectedElement) + bindControl("local_move_space_mode", "down", toggleLocalMoveSpaceMode) end function unbindInput(commandsOnly) @@ -1192,6 +1193,7 @@ function unbindInput(commandsOnly) unbindControl("redo", "down", keyboardRedo) unbindControl("high_sensitivity_mode", "down", toggleSensitivityMode) unbindControl("lock_selected_element", "down", lockSelectedElement) + unbindControl("local_move_space_mode", "down", toggleLocalMoveSpaceMode) end -- get the point and element targeted by the camera @@ -1329,6 +1331,10 @@ function toggleSensitivityMode () end end +function toggleLocalMoveSpaceMode() + exports.move_keyboard:toggleLocalMoveSpace() +end + function streamInCollessObjects() if getElementType(source) == "object" then g_colless[source] = true diff --git a/[editor]/move_keyboard/meta.xml b/[editor]/move_keyboard/meta.xml index 177d0ad20..dce871d9d 100644 --- a/[editor]/move_keyboard/meta.xml +++ b/[editor]/move_keyboard/meta.xml @@ -16,4 +16,7 @@ + + + diff --git a/[editor]/move_keyboard/move_keyboard.lua b/[editor]/move_keyboard/move_keyboard.lua index 2a1c14ee1..2ac36a8f2 100644 --- a/[editor]/move_keyboard/move_keyboard.lua +++ b/[editor]/move_keyboard/move_keyboard.lua @@ -24,6 +24,8 @@ local MOVEMENT_MOVE = 1 local MOVEMENT_ROTATE_WORLD = 2 local MOVEMENT_ROTATE_LOCAL = 3 +local localMoveSpace = false + local hasRotation = { object = true, player = true, @@ -33,6 +35,14 @@ local hasRotation = { -- PRIVATE +local function getPositionFromElementOffset(element,offX,offY,offZ) + local m = getElementMatrix ( element ) + local x = offX * m[1][1] + offY * m[2][1] + offZ * m[3][1] + m[4][1] + local y = offX * m[1][2] + offY * m[2][2] + offZ * m[3][2] + m[4][2] + local z = offX * m[1][3] + offY * m[2][3] + offZ * m[3][3] + m[4][3] + return x, y, z +end + local function getCameraRotation () local px, py, pz, lx, ly, lz = getCameraMatrix() local rotz = 6.2831853071796 - math.atan2 ( ( lx - px ), ( ly - py ) ) % 6.2831853071796 @@ -110,38 +120,53 @@ local function onClientRender_keyboard() speed = moveSpeed.medium end - -- convert getCameraRotation output to radians - camRotZ = math.rad(camRotZ) - local distanceX = speed * math.cos(camRotZ) - local distanceY = speed * math.sin(camRotZ) + if not localMoveSpace then + -- convert getCameraRotation output to radians + camRotZ = math.rad(camRotZ) + local distanceX = speed * math.cos(camRotZ) + local distanceY = speed * math.sin(camRotZ) - -- right/left - if (getCommandState("element_move_right")) then - tempX = tempX + distanceX - tempY = tempY - distanceY - end - if (getCommandState("element_move_left")) then - tempX = tempX - distanceX - tempY = tempY + distanceY - end + -- right/left + if (getCommandState("element_move_right")) then + tempX = tempX + distanceX + tempY = tempY - distanceY + end + if (getCommandState("element_move_left")) then + tempX = tempX - distanceX + tempY = tempY + distanceY + end - -- forward/back - if (getCommandState("element_move_forward")) then - tempX = tempX + distanceY - tempY = tempY + distanceX - end + -- forward/back + if (getCommandState("element_move_forward")) then + tempX = tempX + distanceY + tempY = tempY + distanceX + end - if (getCommandState("element_move_backward")) then - tempX = tempX - distanceY - tempY = tempY - distanceX - end + if (getCommandState("element_move_backward")) then + tempX = tempX - distanceY + tempY = tempY - distanceX + end - -- up/down - if (getCommandState("element_move_upwards")) then - tempZ = tempZ + speed - end - if (getCommandState("element_move_downwards")) then - tempZ = tempZ - speed + -- up/down + if (getCommandState("element_move_upwards")) then + tempZ = tempZ + speed + end + if (getCommandState("element_move_downwards")) then + tempZ = tempZ - speed + end + else + -- local space + local x, y, z = 0, 0, 0 + if getCommandState("element_move_right") then x = x + speed end + if getCommandState("element_move_left") then x = x - speed end + if getCommandState("element_move_forward") then y = y + speed end + if getCommandState("element_move_backward") then y = y - speed end + if getCommandState("element_move_upwards") then z = z + speed end + if getCommandState("element_move_downwards") then z = z - speed end + + if x ~= 0 or y ~= 0 or z ~= 0 then + tempX, tempY, tempZ = getPositionFromElementOffset(selectedElement, x, y, z) + end end -- check if position changed @@ -192,9 +217,9 @@ local function onClientRender_keyboard() else local tempRotX, tempRotY, tempRotZ = rotX, rotY, rotZ if (not tempRotX) then return false end - + local yaw, pitch, roll = 0, 0, 0 - + -- yaw if (getCommandTogSTATE("element_move_right")) then yaw = speed @@ -208,14 +233,14 @@ local function onClientRender_keyboard() elseif (getCommandTogSTATE("element_move_downwards")) then pitch = -speed end - + -- roll if (getCommandTogSTATE("element_move_forward")) then roll = speed elseif (getCommandTogSTATE("element_move_backward")) then roll = -speed end - + -- Perform rotation about one axis at a time if yaw ~= 0 then tempRotX, tempRotY, tempRotZ = exports.editor_main:applyIncrementalRotation(selectedElement, "yaw", yaw, world_space) @@ -289,7 +314,7 @@ local function onClientRender_keyboard() if (not tempRotX) then return false end local yaw, pitch, roll = 0, 0, 0 - + -- yaw if (getCommandTogSTATE("element_move_right")) then yaw = speed @@ -303,14 +328,14 @@ local function onClientRender_keyboard() elseif (getCommandTogSTATE("element_move_downwards")) then pitch = -speed end - + -- roll if (getCommandTogSTATE("element_move_forward")) then roll = speed elseif (getCommandTogSTATE("element_move_backward")) then roll = -speed end - + -- Perform rotation about one axis at a time if yaw ~= 0 then tempRotX, tempRotY, tempRotZ = exports.editor_main:applyIncrementalRotation(selectedElement, "yaw", yaw, world_space) @@ -538,6 +563,15 @@ function toggleAxesLock ( bool ) return true end +function toggleLocalMoveSpace() + localMoveSpace = not localMoveSpace + exports.editor_gui:outputMessage("Local Move Space Mode "..(localMoveSpace and "Enabled" or "Disabled"), 50, 255, 50) +end + +function isLocalMoveSpace() + return localMoveSpace +end + function enable() if isEnabled then return false