Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 32 additions & 21 deletions [editor]/editor_main/client/rotation.lua
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
local rotationFixes = {}
local elementQuat = {}
local fromQuatThreshold = 0.499999999

function loadRotationFixXML()
local xmlRoot = xmlLoadFile("client/rotation_fix.xml")
if not xmlRoot then
outputDebugString("Cannot load rotation_fix.xml")
return false
end

rotationFixes = {}

local models = xmlNodeGetChildren(xmlRoot)
for k,model in ipairs(models) do
local id = tonumber(xmlNodeGetAttribute(model, "id"))
Expand All @@ -24,9 +25,9 @@ function loadRotationFixXML()
outputDebugString("Incorrect entry in rotation_fix.xml")
end
end

xmlUnloadFile(xmlRoot)

return true
end

Expand All @@ -43,7 +44,7 @@ function applyIncrementalRotation(element, axis, angle, world_space)
local offset_quat -- Normalized
local arad = math.rad(angle)
local sina = math.sin(arad / 2)

if axis == "yaw" then
offset_quat = {
sina, 0, 0
Expand All @@ -60,7 +61,10 @@ function applyIncrementalRotation(element, axis, angle, world_space)
return false
end
offset_quat[4] = math.cos(arad / 2)


-- Get rotation patch userdata
local enableRotPatch = exports["editor_gui"]:sx_getOptionData("enableRotPatch")

-- Get current rotation
local cur_quat
if elementQuat[element] then
Expand All @@ -71,7 +75,7 @@ function applyIncrementalRotation(element, axis, angle, world_space)
if euler_rot[1] == 0 and euler_rot[2] == 0 and euler_rot[3] == 0 then
-- Is there a fix and are rotation patches enabled
local id = getElementModel(element)
if rotationFixes[id] and exports["editor_gui"]:sx_getOptionData("enableRotPatch") then
if rotationFixes[id] and enableRotPatch then
-- Rotate from the fix
cur_quat = {unpack(rotationFixes[id])}
else
Expand All @@ -83,20 +87,27 @@ function applyIncrementalRotation(element, axis, angle, world_space)
cur_quat = getQuatFromEuler(euler_rot)
end
end

-- Rotate by the offset quaternion
-- Right or left multiplication for world or local space
if world_space then
cur_quat = quatMul(cur_quat, offset_quat)

-- Check if rotation patch is enabled
if enableRotPatch then
-- Rotate by the offset quaternion
-- Right or left multiplication for world or local space
cur_quat = world_space == true and quatMul(cur_quat, offset_quat) or quatMul(offset_quat, cur_quat)
else
cur_quat = quatMul(offset_quat, cur_quat)
-- Do the old rotation behaviour
if world_space then
cur_quat = axis == "yaw" and quatMul(cur_quat, offset_quat) or quatMul(offset_quat, cur_quat)
else
cur_quat = quatMul(offset_quat, cur_quat)
end
end

elementQuat[element] = cur_quat

-- Convert to euler and apply
local cur_euler = getEulerFromQuat(cur_quat)
setElementRotation(element, cur_euler[1], cur_euler[2], cur_euler[3], "ZYX")

return unpack(cur_euler)
end

Expand Down Expand Up @@ -128,16 +139,16 @@ end

function getEulerFromQuat(quat)
local q0, q1, q2, q3 = quat[1], quat[2], quat[3], quat[4]
local treshold = q0 * q2 - q3 * q1
if treshold > 0.499 then
local threshold = q0 * q2 - q3 * q1

if threshold > fromQuatThreshold then
return {math.deg(2 * math.atan2(q1, q0)), 90, 0}
elseif treshold < -0.499 then
return {math.deg(-2 * math.atan2(q1, q0)), -90, 0}
elseif threshold < -fromQuatThreshold then
return {math.deg(2 * math.atan2(q1, q0)), -90, 0}
else
return {
math.deg(math.atan2(2 * (q0 * q1 + q2 * q3), 1 - 2 * (q1^2 + q2^2))),
math.deg(math.asin(2 * treshold)),
math.deg(math.asin(2 * threshold)),
math.deg(math.atan2(2 * (q0 * q3 + q1 * q2), 1 - 2 * (q2^2 + q3^2)))
}
end
Expand Down