|
|
|
local nodecore, vector, math_round
|
|
|
|
= nodecore, vector, math.round
|
|
|
|
|
|
|
|
local TAU = math.pi * 2 -- The real circle constant.
|
|
|
|
local QUARTER_CIRCLE = TAU / 4
|
|
|
|
|
|
|
|
local LABEL_ROTATION_HINT = "rotation hint"
|
|
|
|
local LABEL_AXIS_HINT = "axis hint"
|
|
|
|
|
|
|
|
local TEX_ROTATE_FACE = "nc_extended_rotating_hud_rotate_face.png"
|
|
|
|
local TEX_ROTATE_EDGE = "nc_extended_rotating_hud_rotate_edge.png"
|
|
|
|
local TEX_ROTATION_AXIS = "nc_extended_rotating_hud_rotation_axis.png"
|
|
|
|
|
|
|
|
|
|
|
|
local hud = {}
|
|
|
|
|
|
|
|
function hud.update_player_hud(player, state)
|
|
|
|
local rotation_texture = nil
|
|
|
|
local axis_texture = nil
|
|
|
|
|
|
|
|
local mode = state and state.mode
|
|
|
|
if mode == "face" then
|
|
|
|
local tex = TEX_ROTATE_FACE
|
|
|
|
if state.invert then tex = tex .. "^[transformFX" end
|
|
|
|
rotation_texture = tex
|
|
|
|
|
|
|
|
elseif mode == "edge" then
|
|
|
|
local tex = TEX_ROTATE_EDGE
|
|
|
|
if state.invert then tex = tex .. "^[transformFX" end
|
|
|
|
|
|
|
|
local face = state.face -- Face looked at.
|
|
|
|
local edge = state.edge -- Face, edge or corner looked at.
|
|
|
|
local axis = state.axis -- Actual axis of rotation.
|
|
|
|
local look = player:get_look_dir() -- Player look vector.
|
|
|
|
|
|
|
|
-- Transform a vertical face to an equivalent horizontal one,
|
|
|
|
-- to make the following comparisons work in either case.
|
|
|
|
if state.face.y ~= 0 then
|
|
|
|
local player_yaw = math_round(player:get_look_horizontal() / QUARTER_CIRCLE) * QUARTER_CIRCLE
|
|
|
|
local playing_facing = vector.new(0, 0, 1):rotate_around_axis(vector.new(0, 1, 0), player_yaw)
|
|
|
|
local rotation_axis = face:cross(playing_facing)
|
|
|
|
|
|
|
|
face = face:rotate_around_axis(rotation_axis, QUARTER_CIRCLE)
|
|
|
|
edge = edge:rotate_around_axis(rotation_axis, QUARTER_CIRCLE)
|
|
|
|
axis = axis:rotate_around_axis(rotation_axis, QUARTER_CIRCLE)
|
|
|
|
look = look:rotate_around_axis(rotation_axis, QUARTER_CIRCLE)
|
|
|
|
end
|
|
|
|
|
|
|
|
if edge.y == 0 then -- Looking at left or right edge.
|
|
|
|
if axis.y > 0
|
|
|
|
then tex = tex .. "^[transformFX" -- left
|
|
|
|
else -- right
|
|
|
|
end
|
|
|
|
-- Flip side the arrow is on depending on look vector.
|
|
|
|
if look.y < 0 then tex = tex .. "^[transformFY" end
|
|
|
|
-- Vertical axis rotation texture.
|
|
|
|
axis_texture = TEX_ROTATION_AXIS
|
|
|
|
|
|
|
|
else -- Looking at top or bottom edge.
|
|
|
|
if edge.y > 0
|
|
|
|
then tex = tex .. "^[transformR90" -- top
|
|
|
|
else tex = tex .. "^[transformFXR90" -- bottom
|
|
|
|
end
|
|
|
|
-- Flip side the arrow is on depending on look vector.
|
|
|
|
if face:cross(look).y < 0 then tex = tex .. "^[transformFX" end
|
|
|
|
-- Horizontal axis rotation texture.
|
|
|
|
axis_texture = TEX_ROTATION_AXIS .. "^[transformR270"
|
|
|
|
end
|
|
|
|
|
|
|
|
rotation_texture = tex
|
|
|
|
|
|
|
|
elseif mode == "corner" then
|
|
|
|
-- TODO: Handle corners.
|
|
|
|
end
|
|
|
|
|
|
|
|
local function crosshair_hud_element(label, texture)
|
|
|
|
if texture then return {
|
|
|
|
label = label,
|
|
|
|
hud_elem_type = "image",
|
|
|
|
text = texture .. "^[opacity:" .. 192,
|
|
|
|
position = { x = 0.5, y = 0.5 },
|
|
|
|
offset = { x = 0, y = 0 },
|
|
|
|
alignment = { x = 0, y = 0 },
|
|
|
|
scale = { x = 1, y = 1 },
|
|
|
|
quick = true,
|
|
|
|
} else return {
|
|
|
|
label = label,
|
|
|
|
ttl = 0,
|
|
|
|
} end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Actually update the HUD elements.
|
|
|
|
nodecore.hud_set(player, crosshair_hud_element(LABEL_ROTATION_HINT, rotation_texture))
|
|
|
|
nodecore.hud_set(player, crosshair_hud_element(LABEL_AXIS_HINT, axis_texture))
|
|
|
|
end
|
|
|
|
|
|
|
|
return hud
|