--[[ Some helping utilities for dealing with car physics. Examples: • Get value for selected tyres from “tyres.ini”: local carsUtils = require('shared/sim/cars') carsUtils.getTyreConfigValue(0, true, 'ANGULAR_INERTIA', 1.05) • Get thermal value for selected tyres from “tyres.ini”: local carsUtils = require('shared/sim/cars') carsUtils.getTyreThermalConfigValue(0, true, 'SURFACE_TRANSFER', 0.01) ]] ---@diagnostic disable local tyresCache = {} local function getTyreConfigSection(car, prefix) local i = car and car.compoundIndex or 0 return i == 0 and prefix or prefix..'_'..i end local function initCarEntry(carIndex) return {ac.getCar(carIndex), ac.INIConfig.carData(carIndex, 'tyres.ini')} end -- Actual library: local carsUtils = {} ---Get value from “tyres.ini” for a certain car for currently selected set of tyres. ---@generic T ---@param carIndex integer @0-based car index. ---@param frontTyres boolean @Set to `true` for front tyres or `false` for rear tyres. ---@param key string @Parameter key. ---@param defaultValue T @Default parameter value in case config is damaged or unavailable. ---@return T function carsUtils.getTyreConfigValue(carIndex, frontTyres, key, defaultValue) local entry = table.getOrCreate(tyresCache, carIndex, initCarEntry, carIndex) return entry[2]:get(getTyreConfigSection(entry[1], frontTyres and 'FRONT' or 'REAR'), key, defaultValue) end ---Get thermal value from “tyres.ini” for a certain car for currently selected set of tyres. ---@generic T ---@param carIndex integer @0-based car index. ---@param frontTyres boolean @Set to `true` for front tyres or `false` for rear tyres. ---@param key string @Parameter key. ---@param defaultValue T @Default parameter value in case config is damaged or unavailable. ---@return T function carsUtils.getTyreThermalConfigValue(carIndex, frontTyres, key, defaultValue) local entry = table.getOrCreate(tyresCache, carIndex, initCarEntry, carIndex) return entry[2]:get(getTyreConfigSection(entry[1], frontTyres and 'THERMAL_FRONT' or 'THERMAL_REAR'), key, defaultValue) end ---Get car position and direction from a binary blob generated by `ac.saveCarStateAsync()`. ---@param data binary ---@return mat4x4? @If data is damaged, returns `nil`. function carsUtils.getCarStateTransform(data) return __util.native('car_state_transform', 1, data) end ---Alter car position and velocity in a binary blob generated by `ac.saveCarStateAsync()`. Car physics should be available ---for car state to be editable. --- ---For example, to rotate car state around vertical axis you can use this transform: ---``` ---local tr = mat4x4.translation(-ac.getCar(0).position) --- :mulSelf(mat4x4.rotation(math.pi / 10, vec3(0, 1, 0))) --- :mulSelf(mat4x4.translation(ac.getCar(0).position)) ---``` ---@param data binary ---@param transform mat4x4 @Transformation matrix (please avoid using skewing or scaling here, or the car might break). ---@return binary? @If data is damaged, returns `nil`. function carsUtils.alterCarStateTransform(data, transform) return __util.native('car_state_transform', 2, data, transform) end ---Alter car velocity and angular velocity in a binary blob generated by `ac.saveCarStateAsync()`. New velocities will be added ---on top. Car physics should be available ---for car state to be editable. ---@param data binary ---@param velocity vec3 ---@param angularVelocity vec3? @Default value: `vec3()` ---@return binary? @If data is damaged, returns `nil`. function carsUtils.alterCarStateVelocity(data, velocity, angularVelocity) return __util.native('car_state_transform', 3, data, velocity, angularVelocity or vec3()) end return carsUtils