local C = {} C.__index = C local function rotateEuler(x, y, z, q) q = q or quat() q = quatFromEuler(0, z, 0) * q q = quatFromEuler(0, 0, x) * q q = quatFromEuler(y, 0, 0) * q return q end function C:reloaded() -- global fov tuning self.fov = self.fov + settings.getValue('cameraFOVTune') or 0 self.fov = math.min(150, math.max(1, self.fov)) self.sensitivity = settings.getValue("cameraTransitionTime")/10000 self.globalOffset = vec3( settings.getValue('cameraPosTuneX') or 0, settings.getValue('cameraPosTuneY') or 0, settings.getValue('cameraPosTuneZ') or 0 ) if self.otherCameras.onboard and tableSize(self.otherCameras.onboard) > 0 then for k,v in pairs(self.otherCameras.onboard) do if v.name == "driver" then self.camNodeID = v.camNodeID self.rightHandCamera = v.rightHandCamera self.register = true end end end -- if right hand drive, invert X axis if self.rightHandCamera then self.globalOffset.x = - self.globalOffset.x end end function C:init() self.baseMode = true self.register = false self.steering = 0 self.reverse = 0 self.state = 0 self.camOffset = 0 self.sensitivity = settings.getValue("cameraTransitionTime")/10000 self.camRot = vec3(0, 0, 0) self.fov = self.fov or 55 self:reloaded() return true end function C:reset() self.camRot = vec3(0, 0, 0) BeamEngine.camX = 0 BeamEngine.camY = 0 self.state = 0 self.camOffset = 0 end function C:hotkey(value) --unused function self.steering = value.steering or 0 self.reverse = value.reverse or 0 end function C:lookback() if self.camRot.x > 0 then self.camRot.x = 0 else self.camRot.x = 180 end end function C:update(data) be:getPlayerVehicle(0):queueLuaCommand(string.format('obj:queueGameEngineLua(string.format(%q, serialize(electrics.values)))', 'extensions.core_camera.hotkey(0, unserialize(%q))')) self.camRot.y = self.camRot.y - BeamEngine.camY * 10 + (MoveManager.pitchUpSpeed - MoveManager.pitchDownSpeed) * (-1000 * data.dt) self.camRot.x = (self.sensitivity * -self.steering) --self.camRot.x + BeamEngine.camX * 10 + (MoveManager.yawLeftSpeed - MoveManager.yawRightSpeed) * (1000 * data.dt) if MoveManager.yawRightSpeed > 0 and self.state == 0 then self.camOffset = -0.7 self.state = 1 end if MoveManager.yawLeftSpeed > 0 and self.state == 1 then self.camOffset = 0 self.state = 0 end local rdz = (BeamEngine.zoomInSpeed - BeamEngine.zoomOutSpeed) * data.dt * 4000 self.fov = math.min(math.max(self.fov + rdz, 10), 150) if self.camRot.y > 85 then self.camRot.y = 85 end if self.camRot.y < -85 then self.camRot.y = -85 end if self.reverse == 1 then self.camRot.x = 180 end self.globalOffset.x = -0.3 * self.reverse self.globalOffset.x = self.globalOffset.x + BeamEngine.camX + self.camOffset self.globalOffset.y = -0.2 * self.reverse if self.rightHandCamera == true then self.globalOffset.x = - self.globalOffset.x end --BeamEngine.camX = 0 BeamEngine.camY = 0 local ref = vec3(data.veh:getNodePosition(self.refNodes.ref)) local left = vec3(data.veh:getNodePosition(self.refNodes.left)) local back = vec3(data.veh:getNodePosition(self.refNodes.back)) local internalCamPos = vec3(data.veh:getNodePosition(self.camNodeID)) local dir = (ref - back):normalized() local camPos = data.pos + internalCamPos local camLeft = (ref - left):normalized() if dir:squaredLength() == 0 or camLeft:squaredLength() == 0 then data.res.pos = camPos data.res.rot = quatFromDir(vec3(0,1,0), vec3(0, 0, 1)) return false end local camUp = -(dir:cross(camLeft):normalized()) local qdir = quatFromDir(dir) local rotatedUp = vec3(0, 0, 1) rotatedUp = qdir * rotatedUp qdir = rotateEuler(-math.rad(-self.camRot.x), -math.rad(self.camRot.y), math.atan2(rotatedUp:dot(camLeft), rotatedUp:dot(camUp)), qdir) local camOffset = (qdir * self.globalOffset) data.res.pos = camPos + camOffset data.res.rot = qdir data.res.fov = self.fov return true end function C:onSerialize() local data = {} for k,v in pairs(self) do if type(v) ~= 'function' then data[k] = v end end --log('I', 'internal', 'onSerialize called...') --dump(data) return data end function C:onDeserialized(data) if not data then return end for k,v in pairs(data) do self[k] = v end end -- DO NOT CHANGE CLASS IMPLEMENTATION BELOW return function(...) local o = ... or {} setmetatable(o, C) o:init() return o end