Greatly improve looking target precision

Change "/camera look_target" to "/camera look" command
Add "here" paramater to "/camera look" command for looking at player position
Add "/camera mode <0|2>" command for normal velocity (0) or locked velocity to player's first look direction (2)
This commit is contained in:
sys4-fr 2017-05-05 09:04:35 +02:00
parent 71924a4d07
commit 87a7e729c5
1 changed files with 57 additions and 40 deletions

View File

@ -3,6 +3,7 @@
Copyright 2016-2017 - Auke Kok <sofar@foo-projects.org>
Copyright 2017 - Elijah Duffy <theoctacian@gmail.com>
Copyright 2017 - sys4 <sys4@free.fr>
License:
- Code: MIT
@ -18,6 +19,17 @@ Usage: /camera
Use /camera save <name> to save the last recording
- saved recordings exist through game restarts
Use /camera list to show all saved recording
Use /camera mode <0|2> to change the velocity behaviour
- 0: Velocity follow mouse (default),
- 2: Velocity locked to player's first look direction with released mouse
Use /camera look <nil|here|x,y,z>
- nil: remove looking target,
- here: set looking target to player position,
- x,y,z: Coords to look at
Use /camera speed <speed>
- 10 is default speed,
- > 10 decrease speed factor,
- < 10 increase speed factor
--]]
local recordings = {}
@ -89,9 +101,10 @@ local camera = {
end,
}
local player_look_dir = nil
local target_look_position = nil
local player_look_dir = nil -- player look direction when starting record
local target_look_position = nil -- looking target
local speed_factor = 0.1 -- default speed factor
local rec_mode = 0 -- record mode
-- [event] On step
function camera:on_step(dtime)
@ -106,11 +119,11 @@ function camera:on_step(dtime)
local dir = self.driver:get_look_dir()
-- if record mode
if self.mode == 0 then
if self.mode == 0 or self.mode == 2 then
-- Calculate pitch and yaw if target_look_position defined
if target_look_position then
local vec_pos = vector.subtract(target_look_position, pos)
--print("vec_pos "..dump(vec_pos))
print("vec_pos "..dump(vec_pos))
-- Pitch
local opp = vec_pos.y
@ -120,64 +133,52 @@ function camera:on_step(dtime)
adj = vec_pos.z
end
if adj > 0 then opp = opp * -1 end
self.driver:set_look_pitch(opp/adj)
self.driver:set_look_vertical(math.atan((opp*-1)/math.abs(adj)))
-- Yaw
opp = vec_pos.x
adj = vec_pos.z
local yaw = opp/adj
local yaw = math.atan(opp/adj)
if math.abs(vec_pos.x) > math.abs(vec_pos.z) then
--print("INVINVINVINVINVINVINVINVINVINV")
yaw = adj/opp
yaw = math.atan(adj/opp)
if adj < 0 and opp < 0 then
--print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!!!!!!")
yaw = yaw + math.pi/2
end
if adj > 0 and opp > 0 then
--print("++++++++++++++++++++++++++++++!!!!!!")
yaw = yaw + math.pi + math.pi/2
end
if yaw < 0 then
--print("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB!!!!!!")
if opp > 0 then
--print("OPP>0 OPP>0 OPP>0 OPP>0 OPP>0 OPP>0 OPP>0 OPP>0 OPP>0")
yaw = math.pi + math.pi/2 + yaw
else
--print("OPP<0 OPP<0 OPP<0 OPP<0 OPP<0 OPP<0 OPP<0 OPP<0 OPP<0 ")
yaw = math.pi/2 + yaw
end
end
else
--print("NORMNORMNORMNORMNORMNORMNORMNORMNORM!!!!!!")
if adj < 0 and opp < 0 then
--print("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA!!!!!!")
yaw = yaw - math.pi
end
if adj > 0 and opp > 0 then
--print("++++++++++++++++++++++++++++++!!!!!!")
yaw = math.pi*2 - yaw
end
if yaw < 0 then
--print("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB!!!!!!")
if opp > 0 then
--print("OPP>0 OPP>0 OPP>0 OPP>0 OPP>0 OPP>0 OPP>0 OPP>0 OPP>0")
yaw = math.pi - yaw
else
--print("OPP<0 OPP<0 OPP<0 OPP<0 OPP<0 OPP<0 OPP<0 OPP<0 OPP<0 ")
yaw = math.pi*2 - yaw
end
end
end
self.driver:set_look_yaw(yaw)
self.driver:set_look_horizontal(yaw)
end
-- Update path
@ -191,12 +192,6 @@ function camera:on_step(dtime)
-- Modify yaw and pitch to match driver (player)
self.object:set_look_pitch(self.driver:get_look_pitch())
self.object:set_look_yaw(self.driver:get_look_yaw())
--print("look pitch "..dump(self.driver:get_look_pitch()))
--print("look vertical "..dump(self.driver:get_look_vertical()))
--print("look yaw "..dump(self.driver:get_look_yaw()))
--print("look horizontal "..dump(self.driver:get_look_horizontal()))
--print("velocity "..dump(self.object:getvelocity()))
--print("look dir "..dump(dir))
-- Get controls
local ctrl = self.driver:get_player_control()
@ -229,8 +224,11 @@ function camera:on_step(dtime)
end
-- Set updated velocity
--self.object:setvelocity(vector.multiply(self.driver:get_look_dir(), speed))
self.object:setvelocity(vector.multiply(player_look_dir, speed))
if self.mode == 0 then
self.object:setvelocity(vector.multiply(self.driver:get_look_dir(), speed))
elseif self.mode == 2 then
self.object:setvelocity(vector.multiply(player_look_dir, speed))
end
elseif self.mode == 1 then -- elseif playback mode
-- Get controls
local ctrl = self.driver:get_player_control()
@ -308,21 +306,27 @@ minetest.register_chatcommand("camera", {
end
elseif param1 == "list" then -- elseif list, list recordings
return true, "Recordings: "..get_recordings(name)
elseif param1 == "look_target" then
elseif param1 == "look" then
if param2 and param2 ~= "" then
if param2 == "nil" then
target_look_position = nil
return true, "Target look deleted"
end
local coord = string.split(param2, ",")
if #coord == 3 then
target_look_position = {x=tonumber(coord[1]), y=tonumber(coord[2]), z=tonumber(coord[3])}
return true, "Target look fixed"
return true, "Looking target removed"
elseif param2 == "here" then
rec_mode = 2
target_look_position = player:getpos()
return true, "Looking target fixed"
else
return false, "Wrong formated coords (/camera look_target <x,y,z>)"
local coord = string.split(param2, ",")
if #coord == 3 then
target_look_position = {x=tonumber(coord[1]), y=tonumber(coord[2]), z=tonumber(coord[3])}
rec_mode = 2
return true, "Looking target fixed"
else
return false, "Wrong formated look coords (/camera look <x,y,z>)"
end
end
else
return false, "Missing coords (/camera look_target <x,y,z>)"
return false, "Missing look parameter (/camera look <nil|here|x,y,z>)"
end
elseif param1 == "speed" then
if param2 and param2 ~= "" then
@ -336,10 +340,23 @@ minetest.register_chatcommand("camera", {
else
return false, "Missing speed parameter (/camera speed <number>)"
end
elseif param1 == "mode" then
if param2 and param2 ~= "" then
local mode = tonumber(param2)
if mode == 0 or mode == 2 then
rec_mode = mode
return true, "Record mode is set"
else
return false, "Invalid mode (0: Velocity follow mouse (default), 2: Velocity locked to player first look direction)"
end
else
return false, "Missing mode parameter (/camera mode <0|2>)"
end
else -- else, begin recording
player_look_dir = player:get_look_dir()
local object = minetest.add_entity(player:getpos(), "camera:camera")
object:get_luaentity():init(player, 0)
object:get_luaentity():init(player, rec_mode)
object:setyaw(player:get_look_yaw())
player:set_attach(object, "", {x=0,y=10,z=0}, {x=0,y=0,z=0})
return true, "Recording started"