mirror of
https://github.com/teverse/teverse
synced 2025-08-27 08:34:45 +02:00
Compare commits
No commits in common. "38920adfa2c1d753d0c8a5326b602ce7efacd002" and "d7b768e5fa82280ff506c760de9e3c58eff7e3a4" have entirely different histories.
38920adfa2
...
d7b768e5fa
@ -7,27 +7,6 @@ local function round(n, mult)
|
|||||||
return math.floor((n + mult/2)/mult) * mult
|
return math.floor((n + mult/2)/mult) * mult
|
||||||
end
|
end
|
||||||
|
|
||||||
local function calculateVertices (block)
|
|
||||||
local vertices = {}
|
|
||||||
for x = -1,1,2 do
|
|
||||||
for y = -1,1,2 do
|
|
||||||
for z = -1,1,2 do
|
|
||||||
table.insert(vertices, block.position + block.rotation* (vector3(x,y,z) *block.size/2))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return vertices
|
|
||||||
end
|
|
||||||
|
|
||||||
local faces = {
|
|
||||||
{5, 6, 8, 7}, -- x forward,
|
|
||||||
{1, 2, 4, 3}, -- x backward,
|
|
||||||
{7, 8, 4, 3}, -- y upward,
|
|
||||||
{5, 6, 2, 1}, -- y downward,
|
|
||||||
{6, 2, 4, 8}, -- z forward
|
|
||||||
{5, 1, 3, 7} -- z backward
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
-- Storing workshop is important because sandbox access is restricted.
|
-- Storing workshop is important because sandbox access is restricted.
|
||||||
workshop = nil,
|
workshop = nil,
|
||||||
@ -38,32 +17,6 @@ return {
|
|||||||
roundVector3 = function(v, mult)
|
roundVector3 = function(v, mult)
|
||||||
return vector3(round(v.x, mult), round(v.y, mult), round(v.z, mult))
|
return vector3(round(v.x, mult), round(v.y, mult), round(v.z, mult))
|
||||||
end,
|
end,
|
||||||
roundDp = function (num, numDecimalPlaces)
|
|
||||||
local mult = 10^(numDecimalPlaces or 0)
|
|
||||||
return math.floor(num * mult + 0.5) / mult
|
|
||||||
end,
|
|
||||||
|
|
||||||
calculateVertices = calculateVertices,
|
|
||||||
|
|
||||||
getCentreOfFace = function (block, face)
|
|
||||||
local vertices = calculateVertices(block)
|
|
||||||
local avg = vector3(0,0,0)
|
|
||||||
for _,i in pairs(faces[face]) do
|
|
||||||
avg = avg + vertices[i]
|
|
||||||
end
|
|
||||||
|
|
||||||
return avg/4
|
|
||||||
end,
|
|
||||||
|
|
||||||
--[[guiLine = function(a, b, parent)
|
|
||||||
local avg = (a + b) / 2
|
|
||||||
local size = a - b
|
|
||||||
local length = size:length()
|
|
||||||
return engine.construct("guiFrame", parent, {
|
|
||||||
position = guiCoord(0, avg.x, 0, avg.y),
|
|
||||||
size = guiCoord(0, 2, 0, length)
|
|
||||||
})
|
|
||||||
end,]]
|
|
||||||
|
|
||||||
-- this is set when workshop is set
|
-- this is set when workshop is set
|
||||||
-- using the haslocaltevgit api
|
-- using the haslocaltevgit api
|
||||||
|
@ -6,5 +6,5 @@ return {
|
|||||||
handTool = require("tevgit:workshop/controllers/sidetools/hand.lua"),
|
handTool = require("tevgit:workshop/controllers/sidetools/hand.lua"),
|
||||||
moveTool = require("tevgit:workshop/controllers/sidetools/move.lua"),
|
moveTool = require("tevgit:workshop/controllers/sidetools/move.lua"),
|
||||||
scaleTool = require("tevgit:workshop/controllers/sidetools/scale.lua"),
|
scaleTool = require("tevgit:workshop/controllers/sidetools/scale.lua"),
|
||||||
rotateTool = require("tevgit:workshop/controllers/sidetools/rotate.lua"),
|
--rotateTool = require("tevgit:workshop/controllers/sidetools/rotate.lua"),
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,6 @@ local function updateHandles()
|
|||||||
for _,v in pairs(handles) do
|
for _,v in pairs(handles) do
|
||||||
v[1].size = vector3(0,0,0)
|
v[1].size = vector3(0,0,0)
|
||||||
v[1].opacity = 0
|
v[1].opacity = 0
|
||||||
v[1].line.positionA = vector3(0, 0, 0)
|
|
||||||
v[1].line.positionB = vector3(0, 0, 0)
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
for _,v in pairs(handles) do
|
for _,v in pairs(handles) do
|
||||||
@ -32,8 +30,6 @@ local function updateHandles()
|
|||||||
v[1].rotation = v[1].rotation * quaternion():setEuler(math.rad(90), 0, 0)
|
v[1].rotation = v[1].rotation * quaternion():setEuler(math.rad(90), 0, 0)
|
||||||
v[1].size = vector3(0.2, 0.4, 0.2)
|
v[1].size = vector3(0.2, 0.4, 0.2)
|
||||||
v[1].opacity = 1
|
v[1].opacity = 1
|
||||||
v[1].line.positionA = v[1].position
|
|
||||||
v[1].line.positionB = selection.box.position
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -122,8 +118,6 @@ return {
|
|||||||
mesh = "primitive:cone"
|
mesh = "primitive:cone"
|
||||||
})
|
})
|
||||||
|
|
||||||
engine.construct("line", handle, {name = "line", colour = handle.colour})
|
|
||||||
|
|
||||||
handle:mouseLeftPressed(function()
|
handle:mouseLeftPressed(function()
|
||||||
gridGuideline.size = vector3(300, 0.1, 300)
|
gridGuideline.size = vector3(300, 0.1, 300)
|
||||||
|
|
||||||
@ -136,8 +130,6 @@ return {
|
|||||||
|
|
||||||
local last = nil
|
local last = nil
|
||||||
|
|
||||||
history.beginAction(selection.selection, "Move tool drag")
|
|
||||||
|
|
||||||
while engine.input:isMouseButtonDown(enums.mouseButton.left) do
|
while engine.input:isMouseButtonDown(enums.mouseButton.left) do
|
||||||
-- Position and rotate the invisible guideline to face the camera.
|
-- Position and rotate the invisible guideline to face the camera.
|
||||||
-- We use this guideline to raycast with
|
-- We use this guideline to raycast with
|
||||||
@ -198,8 +190,6 @@ return {
|
|||||||
wait()
|
wait()
|
||||||
end
|
end
|
||||||
|
|
||||||
history.endAction()
|
|
||||||
|
|
||||||
gridVisual:destroy()
|
gridVisual:destroy()
|
||||||
gridGuideline.size = vector3(0, 0, 0)
|
gridGuideline.size = vector3(0, 0, 0)
|
||||||
end)
|
end)
|
||||||
|
@ -5,207 +5,16 @@ local toolName = "Rotate"
|
|||||||
local toolDesc = ""
|
local toolDesc = ""
|
||||||
local toolIcon = "fa:s-redo"
|
local toolIcon = "fa:s-redo"
|
||||||
|
|
||||||
local selection = require("tevgit:workshop/controllers/core/selection.lua")
|
|
||||||
local history = require("tevgit:workshop/controllers/core/history.lua")
|
|
||||||
local ui = require("tevgit:workshop/controllers/ui/core/ui.lua")
|
|
||||||
local shared = require("tevgit:workshop/controllers/shared.lua")
|
|
||||||
|
|
||||||
local sensitivity = 50
|
|
||||||
|
|
||||||
local arrows = {
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{}
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Each axis gets four arrows...
|
|
||||||
-- This table maps each arrow index to an vertice index
|
|
||||||
local arrowsVerticesMap = {
|
|
||||||
{6, 4, 2, 1}, --x
|
|
||||||
{2, 1, 7, 6}, --y
|
|
||||||
{5, 7, 3, 1} --z
|
|
||||||
}
|
|
||||||
|
|
||||||
local function positionArrows()
|
|
||||||
if selection.box.size == vector3(0,0,0) then
|
|
||||||
for _,v in pairs(arrows) do
|
|
||||||
for i,arrow in pairs(v) do
|
|
||||||
arrow.physics = false
|
|
||||||
arrow.opacity = 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
local vertices = shared.calculateVertices(selection.box)
|
|
||||||
|
|
||||||
for a,v in pairs(arrows) do
|
|
||||||
for i,arrow in pairs(v) do
|
|
||||||
if i == 2 then i = 3 end
|
|
||||||
arrow.physics = true
|
|
||||||
arrow.opacity = 1
|
|
||||||
arrow.position = vertices[arrowsVerticesMap[a][i]]
|
|
||||||
if a == 1 then
|
|
||||||
arrow.rotation = quaternion:setEuler(math.rad((i)*90), 0, math.rad(-90))
|
|
||||||
elseif a == 2 then
|
|
||||||
arrow.rotation = quaternion:setEuler(0, math.rad((i-1)*-90), 0)
|
|
||||||
else
|
|
||||||
arrow.rotation = quaternion:setEuler(math.rad((i-1)*-90), math.rad(90), math.rad(90))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local boundingEvent
|
|
||||||
|
|
||||||
-- calculates angle ABC
|
|
||||||
-- returns in radians
|
|
||||||
local function calculateAngleBetween3Points(a, b, c)
|
|
||||||
local v1 = a - b
|
|
||||||
local v2 = c - b
|
|
||||||
return math.acos(v1:normal():dot(v2:normal()))
|
|
||||||
end
|
|
||||||
|
|
||||||
local function calculateCircleAngle(hitbox, pos)
|
|
||||||
local hitboxPosition = hitbox.position
|
|
||||||
local hitboxRotation = hitbox.rotation
|
|
||||||
|
|
||||||
local hitboxUp = hitboxPosition + (hitboxRotation * vector3(0,0,-10))
|
|
||||||
local hitboxRight = hitboxPosition + (hitboxRotation * vector3(10,0,0))
|
|
||||||
|
|
||||||
local angle = calculateAngleBetween3Points(hitboxUp, hitboxPosition, pos)
|
|
||||||
if hitboxRight:dot(pos) < 0 then
|
|
||||||
angle = (math.pi-angle)+math.pi
|
|
||||||
end
|
|
||||||
|
|
||||||
return angle
|
|
||||||
end
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name = toolName,
|
name = toolName,
|
||||||
icon = toolIcon,
|
icon = toolIcon,
|
||||||
desc = toolDesc,
|
desc = toolDesc,
|
||||||
|
|
||||||
activate = function()
|
activate = function()
|
||||||
for axis = 1, 3 do
|
print("tool activated")
|
||||||
local newArrow = engine.construct("block", engine.workspace, {
|
|
||||||
name = "_CreateMode_",
|
|
||||||
castsShadows = false,
|
|
||||||
opacity = 0,
|
|
||||||
renderQueue=1,
|
|
||||||
doNotSerialise=true,
|
|
||||||
size = vector3(.4, 0.1, .4),
|
|
||||||
colour = colour(axis == 1 and 1 or 0, axis == 2 and 1 or 0, axis == 3 and 1 or 0),
|
|
||||||
emissiveColour = colour(axis == 1 and 0.5 or 0, axis == 2 and 0.5 or 0, axis == 3 and 0.5 or 0),
|
|
||||||
workshopLocked = true,
|
|
||||||
mesh = "tevurl:3d/arrowCurved.glb"
|
|
||||||
})
|
|
||||||
|
|
||||||
newArrow:mouseLeftPressed(function ()
|
|
||||||
local hitbox = engine.construct("block", workspace, {
|
|
||||||
name = "_CreateMode_",
|
|
||||||
castsShadows = false,
|
|
||||||
opacity = 0,
|
|
||||||
renderQueue = 1,
|
|
||||||
doNotSerialise=true,
|
|
||||||
size = vector3(60, 0.1, 60),
|
|
||||||
workshopLocked = true,
|
|
||||||
position = shared.getCentreOfFace(selection.box, (axis*2)-1),
|
|
||||||
rotation = newArrow.rotation
|
|
||||||
})
|
|
||||||
hitbox.rotation = hitbox.rotation:setLookRotation( hitbox.position - workspace.camera.position ) * quaternion():setEuler(math.rad(90),0,0)
|
|
||||||
--hitbox:lookAt(workspace.camera.position)
|
|
||||||
|
|
||||||
local mouseHits = engine.physics:rayTestScreenAllHits( engine.input.mousePosition )
|
|
||||||
local mouseHit = nil
|
|
||||||
for _,hit in pairs(mouseHits) do
|
|
||||||
if hit.object == hitbox then
|
|
||||||
mouseHit = hit
|
|
||||||
goto skip_loop
|
|
||||||
end
|
|
||||||
end
|
|
||||||
::skip_loop::
|
|
||||||
|
|
||||||
if not mouseHit then
|
|
||||||
print("Did not collide")
|
|
||||||
hitbox:destroy()
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local start = mouseHit.hitPosition
|
|
||||||
history.beginAction(selection.selection, "Rotate tool drag")
|
|
||||||
|
|
||||||
while engine.input:isMouseButtonDown(enums.mouseButton.left) and wait() do
|
|
||||||
hitbox.rotation = hitbox.rotation:setLookRotation( hitbox.position - workspace.camera.position ) * quaternion():setEuler(math.rad(90),0,0)
|
|
||||||
|
|
||||||
local mouseHits = engine.physics:rayTestScreenAllHits( engine.input.mousePosition )
|
|
||||||
local mouseHit = nil
|
|
||||||
for _,hit in pairs(mouseHits) do
|
|
||||||
if hit.object == hitbox then
|
|
||||||
mouseHit = hit
|
|
||||||
goto skip_loop
|
|
||||||
end
|
|
||||||
end
|
|
||||||
::skip_loop::
|
|
||||||
|
|
||||||
if mouseHit then
|
|
||||||
local current = mouseHit.hitPosition
|
|
||||||
local diff = (start-current)
|
|
||||||
local travelled = diff:length()
|
|
||||||
|
|
||||||
-- length of vectors is never less than 0. let's fix that
|
|
||||||
if (newArrow.rotation * vector3(0,0,1)):dot(diff) < 0 then
|
|
||||||
--user moved their mouse in an opposite direction to the arrow
|
|
||||||
travelled = -travelled
|
|
||||||
end
|
|
||||||
|
|
||||||
local n = shared.round(math.rad(travelled*sensitivity), math.rad(10))
|
|
||||||
|
|
||||||
for _,v in pairs(selection.selection) do
|
|
||||||
local euler = vector3(
|
|
||||||
axis == 1 and n or 0,
|
|
||||||
axis == 2 and n or 0,
|
|
||||||
axis == 3 and n or 0
|
|
||||||
)
|
|
||||||
|
|
||||||
v.rotation = v.rotation * quaternion:setEuler(v.rotation:inverse() * euler)
|
|
||||||
end
|
|
||||||
|
|
||||||
if n ~= 0 then
|
|
||||||
start = current
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
hitbox:destroy()
|
|
||||||
|
|
||||||
history.endAction()
|
|
||||||
end)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
table.insert(arrows[axis], newArrow)
|
|
||||||
end
|
|
||||||
|
|
||||||
boundingEvent = selection.box:changed(positionArrows)
|
|
||||||
|
|
||||||
positionArrows()
|
|
||||||
end,
|
end,
|
||||||
|
|
||||||
deactivate = function ()
|
deactivate = function ()
|
||||||
boundingEvent:disconnect()
|
print("tool deactivated")
|
||||||
boundingEvent = nil
|
|
||||||
|
|
||||||
for _,v in pairs(arrows) do
|
|
||||||
for _,arrow in pairs(v) do
|
|
||||||
print(arrow)
|
|
||||||
arrow:destroy()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
arrows = {
|
|
||||||
{},
|
|
||||||
{},
|
|
||||||
{}
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,6 @@ local function updateHandles()
|
|||||||
for _,v in pairs(handles) do
|
for _,v in pairs(handles) do
|
||||||
v[1].size = vector3(0,0,0)
|
v[1].size = vector3(0,0,0)
|
||||||
v[1].opacity = 0
|
v[1].opacity = 0
|
||||||
v[1].line.positionA = vector3(0, 0, 0)
|
|
||||||
v[1].line.positionB = vector3(0, 0, 0)
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
for _,v in pairs(handles) do
|
for _,v in pairs(handles) do
|
||||||
@ -32,8 +30,6 @@ local function updateHandles()
|
|||||||
v[1].rotation = v[1].rotation * quaternion():setEuler(math.rad(90), 0, 0)
|
v[1].rotation = v[1].rotation * quaternion():setEuler(math.rad(90), 0, 0)
|
||||||
v[1].size = vector3(0.4, 0.4, 0.4)
|
v[1].size = vector3(0.4, 0.4, 0.4)
|
||||||
v[1].opacity = 1
|
v[1].opacity = 1
|
||||||
v[1].line.positionA = v[1].position
|
|
||||||
v[1].line.positionB = selection.box.position
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -129,8 +125,6 @@ return {
|
|||||||
workshopLocked = true
|
workshopLocked = true
|
||||||
})
|
})
|
||||||
|
|
||||||
engine.construct("line", handle, {name = "line", colour = handle.colour})
|
|
||||||
|
|
||||||
handle:mouseLeftPressed(function()
|
handle:mouseLeftPressed(function()
|
||||||
gridGuideline.size = vector3(300, 0.1, 300)
|
gridGuideline.size = vector3(300, 0.1, 300)
|
||||||
|
|
||||||
@ -143,8 +137,6 @@ return {
|
|||||||
|
|
||||||
local last = nil
|
local last = nil
|
||||||
|
|
||||||
history.beginAction(selection.selection, "Scale tool drag")
|
|
||||||
|
|
||||||
while engine.input:isMouseButtonDown(enums.mouseButton.left) do
|
while engine.input:isMouseButtonDown(enums.mouseButton.left) do
|
||||||
-- Position and rotate the invisible guideline to face the camera.
|
-- Position and rotate the invisible guideline to face the camera.
|
||||||
-- We use this guideline to raycast with
|
-- We use this guideline to raycast with
|
||||||
@ -229,7 +221,7 @@ return {
|
|||||||
|
|
||||||
wait()
|
wait()
|
||||||
end
|
end
|
||||||
history.endAction()
|
|
||||||
gridVisual:destroy()
|
gridVisual:destroy()
|
||||||
gridGuideline.size = vector3(0, 0, 0)
|
gridGuideline.size = vector3(0, 0, 0)
|
||||||
end)
|
end)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user