GE Lua Documentation

Press F to search!

processVehicleCameraConfigChanged

Definition


-- @/lua/ge/extensions/core/camera.lua:528

-- TODO trigger this also for global cameras?
local function processVehicleCameraConfigChanged(vid, vdata, focusedCamNamePrevious)
  local camerasOld = vdata.cameras or {}
  vdata.cameras = {}
  local vmvd = extensions.core_vehicle_manager.getVehicleData(vid)
  if vmvd then
    vmvd = vmvd.vdata
  else
    return
  end

  local refNodes = vmvd.refNodes[0]
  local vmcd = vmvd.cameraData or {}
  local camConfigs = {}
  for camMode,constructor in pairs(getConstructors()) do
    if tableFindKey(multicams, camMode) then
      local jbeamConfigs = vmcd[camMode] or {}
      for i,jbeamConfig in pairs(jbeamConfigs) do
        table.insert(camConfigs, {name=camMode.."."..jbeamConfig.name, constructor=constructor, jbeamConfig=jbeamConfig})
      end
    else
      local jbeamConfig = vmcd[camMode] or {}
      table.insert(camConfigs, {name=camMode, constructor=constructor, jbeamConfig=jbeamConfig})
    end
  end
  for k,v in ipairs(camConfigs) do
    if v.name ~= "onboard.driver" and string.lower(v.name) == "onboard.driver" then
      log("W", "", "Possibly incorrect camera name '"..v.name.."' (rename to 'onboard.driver'?)")
    end
    local cam = initCam(camerasOld[v.name], v.jbeamConfig, v.constructor)
    if cam then
      if cam.setRefNodes then
        local refNodes = (vmvd.cameraRefNodes and vmvd.cameraRefNodes[v.name]) or refNodes
        cam:setRefNodes(refNodes.ref, refNodes.left, refNodes.back)
      end
      vdata.cameras[v.name] = cam
    end
  end

  if not arrayFindValueIndex(tableKeys(vdata.cameras), "onboard.driver") then
    vdata.cameras.driver = nil -- there's no driver data to feed the driver cam, so remove it
  end

  -- initial camera config
  local initialConfiguration = {
     {name="orbit"}
    ,{name="driver"}
    ,{name="onboard.hood"}
    ,{name="external"}
    ,{name="relative"}
    ,{name="chase"}
  }
  local savedConfiguration = settings.getValue('cameraConfig')
  if savedConfiguration and savedConfiguration ~= "" then
    -- fix INI values that passed through javascript (e.g. when opening Options menu)
    savedConfiguration = savedConfiguration:gsub("'",'"')
    -- and then deserialize, so we can follow the user settings
    savedConfiguration = jsonDecode(savedConfiguration)
    -- if user settings version is good, go ahead and use it
    if savedConfiguration and (savedConfiguration.version or 0) >= currentVersion then
      initialConfiguration = savedConfiguration.data
    end
  end

  -- fill pre-configured cameras (even if it's a disabled/unknown camera)
  configuration = {}
  for k,v in ipairs(initialConfiguration) do
    local enabled = v.enabled
    if enabled == nil then
      enabled = true
      local cam = vdata.cameras[v.name]
      if cam then
        enabled = cam.disabledByDefault ~= true
      end
    end
    table.insert(configuration, {name=v.name, enabled=enabled})
  end

  -- append non-configured cameras
  local renaminingCamNames = {}
  for name, cam in pairs(vdata.cameras) do
    local configured = false
    for _,v in ipairs(configuration) do
      if v.name == name then configured = true end
    end
    if not configured then
      table.insert(renaminingCamNames, name)
    end
  end

  -- now, a bit more complex: order the remaining cameras with their order number (if present) or jbeam order
  while #renaminingCamNames > 0 do
    local orderMin = 99999
    local lowestOrderId = nil
    for k, name in ipairs(renaminingCamNames) do
      -- locate idx with the minimum order value
      local cam = vdata.cameras[name]
      if cam.order then
        if type(cam.order) == 'number' then
          if cam.order < orderMin then
            orderMin = cam.order
            lowestOrderId = k
          end
        else
          log("E", "", "Incorrectly defined camera, 'order' field is not numeric: "..dumps(type(order)))
        end
      end
    end

    if not lowestOrderId then
      -- no ordering? simply take first one then
      lowestOrderId = 1
    end

    local name = renaminingCamNames[lowestOrderId]
    local enabled = vdata.cameras[name].disabledByDefault ~= true
    table.insert(configuration, {name=name, enabled=enabled})
    table.remove(renaminingCamNames, lowestOrderId)
  end

  -- 1st try: we got a saved request, honour it before anything else
  local cameraSet = false
  if requestedCam[vid] then
    cameraSet = _setVehicleCameraByName(vdata, requestedCam[vid].name)
    if cameraSet and vdata.cameras[requestedCam[vid].name].setCustomData then
      vdata.cameras[requestedCam[vid].name]:setCustomData( requestedCam[vid].customData )
    end
    requestedCam[vid] = nil
  end

  -- 2nd try: let's continue using the previous cam (which may have disappeared if we replaced the vehicle)
  if not cameraSet and focusedCamNamePrevious then
    cameraSet = _setVehicleCameraByName(vdata, focusedCamNamePrevious)
  end

  -- 3rd try: let's find the first 'enabled' camera and use it (i.e. the default camera)
  if not cameraSet then
    for k,v in pairs(configuration) do
      if v.enabled and vdata.cameras[v.name] and not vdata.cameras[v.name].hidden then
        cameraSet = _setVehicleCameraByIndex(vdata, k)
        if cameraSet then break end
      end
    end
  end

  -- 4th try: let's find the first 'visible' camera and use it
  if not cameraSet then
    for k,v in pairs(configuration) do
      if vdata.cameras[v.name] then
        cameraSet = _setVehicleCameraByIndex(vdata, k)
        if cameraSet then break end
      end
    end
  end

  -- 5th try: panic and don't keep calm
  if not cameraSet then
    log("E", "", "Unable to find a single usable camera, not even 'orbit' fallback. All bets are off from this point on")
  end
  saveConfiguration(vdata)
end

Callers

@/lua/ge/extensions/core/camera.lua
  local focusedCamNamePrevious = ((vehicleCamerasCache or {})[vid] or {}).focusedCamName
  M.processVehicleCameraConfigChanged(vid, vdata, focusedCamNamePrevious)
  target[vid] = vdata
  for vid, vdata in pairs(getVehicleData()) do
    processVehicleCameraConfigChanged(vid, vdata, vdata.focusedCamName)
  end