sokol-luajit/engine/libs/camera/orbitGO.lua
2025-10-17 09:43:15 +10:30

131 lines
3.8 KiB
Lua

-- A camera controller so I can pan and move around the scene.
-- Enable/Disable using keys
--------------------------------------------------------------------------------
-- Soft start and stop - all movements should be softened to make a nice movement
-- experience. Camera motion should also be dampened.
local tf = require("engine.utils.transforms")
local hmm = require("hmm")
local move_dampen = 0.89
local look_dampen = 0.89
local cameraorbit = {}
--------------------------------------------------------------------------------
local function newcamera()
local cameraorbit = {
playerheight = 1.3,
cameraheight = 2.0,
-- Where the look focus is in the distance
lookdistance = 4.0,
looklimityaw = math.pi * 0.5,
looklimitpitch = math.pi * 0.5,
lookvec = hmm.HMM_Vec3(0,0,0),
pos = hmm.HMM_Vec3(0,0,0),
movevec = hmm.HMM_Vec3(0,0,0),
xangle = 0.0,
yangle = 0.0,
}
return cameraorbit
end
--------------------------------------------------------------------------------
-- A simple handler, can be easily replaced
local function defaulthandler( self, delta )
local pitch = -self.xangle
local yaw = self.yangle
if (yaw > math.pi) then yaw = -math.pi; self.yangle = -math.pi end
if (yaw < -math.pi) then yaw = math.pi; self.yangle = math.pi end
if (pitch > math.pi * 0.5) then pitch = math.pi * 0.5; self.xangle = math.pi * 0.5 end
if (pitch < -math.pi * 0.5) then pitch = -math.pi * 0.5; self.xangle = -math.pi * 0.5 end
local camrot = vmath.quat_rotation_y( yaw )
camrot = camrot * vmath.quat_rotation_x( pitch )
local camrotinv = vmath.quat_rotation_y( yaw)
camrotinv = camrotinv * vmath.quat_rotation_x( pitch)
local campos = vmath.matrix4_from_quat(camrot) * hmm.HMM_Vec4(0, 0, self.distance, 0)
self.prevtpos = hmm.HMM_Vec3(self.tpos)
local ospos = go.get_position(self.target)
self.tpos = hmm.HMM_Vec3(ospos.x, ospos.y, ospos.z)
local tgtrot = go.get_rotation(self.target)
local osfwd = tf.QuatToDir( tgtrot )
self.trot = tf.DirToQuat(hmm.HMM_Vec3(osfwd.x, osfwd.y, osfwd.z))
self.tspeed = 0.0
self.teuler = tf.ToEulerAngles(self.trot)
self.tvelocity = hmm.HMM_Vec3(0,0,0)
self.throttle = math.floor(self.tspeed/10.0 * 10)
if(self.use_target == nil and self.tPos) then self.tpos = self.tPos end
self.pos = self.tpos + hmm.HMM_Vec3(campos.x, campos.y, campos.z)
self.rot = camrotinv
go.set_rotation( self.rot, self.cameraobj )
go.set_position( self.pos, self.cameraobj )
local objdata = {
speed = self.tspeed,
climb = self.tvelocity.y,
heading = 180 - math.deg(self.teuler.y),
altitude = self.tpos.y,
throttle = self.throttle,
fuelpercent = 0,
weight = 0,
angles = { x = self.teuler.x, y = self.teuler.y, z = self.teuler.z },
}
msg.post("/gui", "object", objdata)
end
--------------------------------------------------------------------------------
cameraorbit.init = function( cameraobj, target, distance, handler )
local newcam = newcamera()
newcam.cameraobj = cameraobj
newcam.target = target
newcam.handler = handler or defaulthandler
newcam.distance = distance
newcam.smooth = 0.98
newcam.speed = 1.0
newcam.flat = true -- define if the camera rolls
local tvec = hmm.HMM_Vec3(0,0,0) -- go.get_position(target)
newcam.tpos = hmm.HMM_Vec3(tvec.X, tvec.Y, tvec.Z)
-- newcam.pos = go.get_position(cameraobj)
-- newcam.rot = go.get_rotation(cameraobj)
newcam.enabled = true -- enabled by default
newcam.update = function( self, delta )
if(newcam.enabled ~= true) then return end
if(newcam.handler) then newcam.handler( newcam, delta ) end
end
return newcam
end
--------------------------------------------------------------------------------
return cameraorbit
--------------------------------------------------------------------------------