#pragma once #include "CoreMinimal.h" /** * Constants of the carrier CANTICLE (DESIGN_UE.md section 3; v2 06_carrier.js). All distances are CARRIER-LOCAL METRES * (+X bow, +Y starboard, +Z up) unless the name says otherwise. One header per namespace (Core/Tuning/README.md). */ namespace Descent::Tune::Carrier { // ---- hull (section 3.3) ------------------------------------------------------------------------------------- constexpr double HullRadiusM = 12.0; // v2 C_R: radius of the cylindrical middle, |x| <= 40 constexpr double HullCylinderHalfLengthM = 40.0; constexpr double HullHalfLengthM = 60.0; // nose at x = +60, stern cap at x = -60 constexpr double HullSternRadiusM = 7.0; // radius at x = -60 (12 - 5) constexpr double DryHullMarginM = 0.3; // IsDry: hypot(y, z) < HullRadius(x) - 0.3 // ---- decks and rooms (section 3.3) -------------------------------------------------------------------------- constexpr double DeckFloorZ1 = -7.5; // D1: only the sub bay constexpr double DeckFloorZ2 = -3.0; // D2 constexpr double DeckFloorZ3 = 1.5; // D3 constexpr double RoomHeightM = 4.2; constexpr double TallRoomHeightM = 8.7; // stairwell and sub bay constexpr double DoorHeightM = 2.4; constexpr double WallThicknessM = 0.16; // each room builds its own four walls, inset by half of this (v2) constexpr double FloorSlabM = 0.2; constexpr double CeilingSlabM = 0.1; constexpr double EyeHeightM = 1.65; // ---- moon pool (section 3.3) -------------------------------------------------------------------------------- constexpr double PoolX0 = -35.0; constexpr double PoolX1 = -23.0; constexpr double PoolY0 = 3.5; constexpr double PoolY1 = 8.5; constexpr double PoolWaterZ = -8.3; constexpr double PoolShaftBottomZ = -11.6; // ---- start pose (section 1.5) ------------------------------------------------------------------------------- constexpr double StartZM = -30.0; // world Z of the carrier origin at the start constexpr double StreamFocusRadiusM = 120.0; // the carrier keeps the world loaded around it (section 1.5 step 4) // ---- render channels (sections 3.2 and 7.4) ----------------------------------------------------------------- constexpr int32 InteriorStencilValue = 1; // "dry": PP_Water leaves these pixels alone // Lighting channels: sea = 0, carrier interior = 1. constexpr uint8 ChannelSea = 0; constexpr uint8 ChannelInterior = 1; /** The trace channel "Placement" (section 3.2) is ECC_GameTraceChannel1; the project config does not name it yet (see Docs/status/carrier.md). */ constexpr int32 PlacementTraceChannelIndex = 1; // ---- lights (sections 3.3 and 7.5) -------------------------------------------------------------------------- constexpr double LampRadiusM = 11.0; // room lamps; tall rooms use TallLampRadiusM constexpr double TallLampRadiusM = 16.0; constexpr float LampFalloffExponent = 3.0f; // attenuation (1 - (d/R)^2)^3, no inverse-square (section 7.5) constexpr float LampSourceRadiusCm = 12.f; /** * Design intensities are unitless ("1.3" for the bridge); brightness = intensity * this. With bUseInverseSquaredFalloff = false the * engine uses the value as it is (no unit conversion). Integration pass (Docs/status/integ.md): the carrier track had calibrated 2700 * against a scenario-only exposure (bias 1.0 WITH the physical camera exposure, about 1/1146 per unit); the game's one authority, * ADescentEnvironment, uses a manual exposure without the physical camera, at descent.Look.ExposureEV (about 1.0 per unit), so the * three numbers (this, EMISSIVE_NITS and AMBIENT_NITS in assets_35_carrier_materials.py) were multiplied by the same factor * InteriorExposureFactor and then trimmed by the m2_walk room shots. Console variable descent.Carrier.LampScale scales it live. */ constexpr float LampBrightnessUnit = 4.6f; /** The factor all three interior brightness numbers were scaled by when the exposure authority moved to ADescentEnvironment. */ constexpr float InteriorExposureFactor = 0.0017f; // Exterior lights (V4a): exactly six, nothing else. constexpr int32 ExteriorLightCount = 6; constexpr double NavRedX = 24.0, NavRedY = -12.1, NavRedZ = 0.5; constexpr double NavGreenX = 24.0, NavGreenY = 12.1, NavGreenZ = 0.5; constexpr double MastX = 8.0, MastY = 0.0, MastZ = 22.9; constexpr double MastFlashOnSec = 0.12, MastFlashPeriodSec = 2.2; constexpr double SternX = -60.5, SternY = 0.0, SternZ = 2.0; constexpr double FloodX = 46.0, FloodY = 0.0, FloodZ = -9.2; constexpr double FloodAimX = 130.0, FloodAimY = 0.0, FloodAimZ = -30.0; constexpr double PoolGlowX = -29.0, PoolGlowY = 6.0, PoolGlowZ = -12.0; constexpr double NavRadiusM = 9.0; constexpr double FloodRadiusM = 160.0; constexpr double FloodInnerConeDeg = 13.0, FloodOuterConeDeg = 24.0; constexpr double PoolGlowRadiusM = 20.0; constexpr float NavIntensity = 0.4f, FloodIntensity = 5.0f, PoolGlowIntensity = 1.4f; // ---- the walking-on-a-moving-vessel proof (R2, section 11): the carrier's design maxima ----------------------- constexpr double MaxSpeedMps = 2.0; // U9 constexpr double MaxYawRateRadPerSec = 0.10; // section 3.6: omega_target clamp constexpr double MaxPitchDeg = 10.0; // hard limit of the helm constexpr double PitchResponseSec = 2.5; // section 3.6: first-order response of the pitch constexpr double RollPerYawRateRad = -0.25; // section 3.6: roll = -0.25 * omega (cosmetic) // ---- cosmetics ---------------------------------------------------------------------------------------------- constexpr double EngineLampPulseHz = 2.4 / (2.0 * UE_DOUBLE_PI); // 1 + sin(2.4 t) pulse of the engine room lamps }