diff --git a/init.lua b/init.lua index a96df66..272cc4e 100644 --- a/init.lua +++ b/init.lua @@ -3,6 +3,7 @@ Copyright 2016-2017 - Auke Kok Copyright 2017 - Elijah Duffy +Copyright 2017 - sys4 License: - Code: MIT @@ -18,6 +19,17 @@ Usage: /camera Use /camera save 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: remove looking target, + - here: set looking target to player position, + - x,y,z: Coords to look at + Use /camera 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 )" + 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 )" + end end else - return false, "Missing coords (/camera look_target )" + return false, "Missing look parameter (/camera look )" 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 )" 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"