@jgengine/core 0.18.1 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/CHANGELOG.md +158 -7
  2. package/dist/ai/decisionGraph.d.ts +48 -4
  3. package/dist/ai/decisionGraph.js +153 -23
  4. package/dist/ai/groupAssist.d.ts +10 -0
  5. package/dist/ai/groupAssist.js +11 -0
  6. package/dist/ai/pursuit.d.ts +1 -1
  7. package/dist/ai/pursuit.js +1 -1
  8. package/dist/ai/threat.d.ts +8 -0
  9. package/dist/ai/threat.js +10 -0
  10. package/dist/anim/animGraph.d.ts +11 -0
  11. package/dist/anim/animGraph.js +128 -0
  12. package/dist/anim/boneTexture.d.ts +55 -0
  13. package/dist/anim/boneTexture.js +43 -0
  14. package/dist/anim/footPlacement.d.ts +57 -0
  15. package/dist/anim/footPlacement.js +67 -0
  16. package/dist/anim/locomotionGraph.d.ts +9 -0
  17. package/dist/anim/locomotionGraph.js +29 -0
  18. package/dist/audio/audioFalloff.d.ts +2 -0
  19. package/dist/audio/doppler.d.ts +21 -0
  20. package/dist/audio/doppler.js +32 -0
  21. package/dist/audio/engineLayers.d.ts +83 -0
  22. package/dist/audio/engineLayers.js +115 -0
  23. package/dist/combat/abilityKit.d.ts +1 -0
  24. package/dist/combat/abilityKit.js +1 -0
  25. package/dist/combat/death.d.ts +7 -0
  26. package/dist/combat/shotOrigin.d.ts +6 -0
  27. package/dist/combat/shotOrigin.js +6 -0
  28. package/dist/combat/weaponFeedback.d.ts +36 -0
  29. package/dist/combat/weaponFeedback.js +42 -0
  30. package/dist/combat/weaponHandling.d.ts +161 -0
  31. package/dist/combat/weaponHandling.js +202 -0
  32. package/dist/combat/weaponPresentation.d.ts +115 -0
  33. package/dist/combat/weaponPresentation.js +96 -0
  34. package/dist/devtools/warnOnce.d.ts +8 -0
  35. package/dist/devtools/warnOnce.js +18 -0
  36. package/dist/editor/document.js +3 -1
  37. package/dist/editor/environment.js +8 -0
  38. package/dist/editor/types.d.ts +4 -0
  39. package/dist/faction/reputation.d.ts +6 -0
  40. package/dist/faction/reputation.js +11 -0
  41. package/dist/game/cameraConfig.d.ts +51 -1
  42. package/dist/game/events.d.ts +6 -0
  43. package/dist/game/lootTable.d.ts +4 -0
  44. package/dist/game/lootTable.js +16 -0
  45. package/dist/game/playableGame.d.ts +84 -17
  46. package/dist/game/toasts.d.ts +8 -0
  47. package/dist/game/toasts.js +7 -0
  48. package/dist/game/vfxInstance.d.ts +9 -0
  49. package/dist/game/vfxInstance.js +12 -1
  50. package/dist/game/viewports.d.ts +43 -0
  51. package/dist/game/viewports.js +46 -0
  52. package/dist/game/worldItem.d.ts +5 -1
  53. package/dist/game/worldItem.js +0 -1
  54. package/dist/input/actionBindings.d.ts +15 -1
  55. package/dist/input/actionBindings.js +14 -3
  56. package/dist/input/actionContexts.d.ts +25 -1
  57. package/dist/input/actionContexts.js +82 -25
  58. package/dist/input/axisInput.d.ts +4 -0
  59. package/dist/input/axisInput.js +4 -0
  60. package/dist/input/axisShaper.d.ts +73 -0
  61. package/dist/input/axisShaper.js +105 -0
  62. package/dist/input/gamepadModel.d.ts +36 -2
  63. package/dist/input/gamepadModel.js +69 -30
  64. package/dist/input/haptics.d.ts +50 -0
  65. package/dist/input/haptics.js +74 -0
  66. package/dist/input/inputBuffer.d.ts +40 -0
  67. package/dist/input/inputBuffer.js +59 -0
  68. package/dist/input/lookChannel.d.ts +10 -0
  69. package/dist/input/lookChannel.js +6 -0
  70. package/dist/input/pointer.d.ts +2 -0
  71. package/dist/input/pointer.js +4 -0
  72. package/dist/item/affix.d.ts +6 -0
  73. package/dist/item/affix.js +6 -0
  74. package/dist/meta/changelog.d.ts +1 -1
  75. package/dist/meta/changelog.js +112 -1
  76. package/dist/movement/glideModel.d.ts +3 -0
  77. package/dist/movement/glideModel.js +6 -0
  78. package/dist/movement/grappleSwing.d.ts +2 -0
  79. package/dist/movement/grappleSwing.js +5 -1
  80. package/dist/movement/movementModel.d.ts +39 -0
  81. package/dist/movement/movementModel.js +62 -19
  82. package/dist/movement/movementProbe.d.ts +51 -0
  83. package/dist/movement/movementProbe.js +119 -0
  84. package/dist/movement/playerMovement.d.ts +21 -2
  85. package/dist/movement/playerMovement.js +89 -6
  86. package/dist/movement/solidObstacles.d.ts +9 -1
  87. package/dist/movement/solidObstacles.js +44 -2
  88. package/dist/movement/voxelController.js +7 -7
  89. package/dist/nav/navFromEnvironment.d.ts +9 -3
  90. package/dist/nav/navFromEnvironment.js +18 -12
  91. package/dist/nav/navMesh.d.ts +43 -2
  92. package/dist/nav/navMesh.js +534 -128
  93. package/dist/physics/aircraftDynamics.d.ts +390 -0
  94. package/dist/physics/aircraftDynamics.js +704 -0
  95. package/dist/physics/boatDynamics.d.ts +116 -0
  96. package/dist/physics/boatDynamics.js +160 -0
  97. package/dist/physics/drivableVehicle.d.ts +22 -8
  98. package/dist/physics/drivableVehicle.js +4 -2
  99. package/dist/physics/flightDynamics.d.ts +21 -4
  100. package/dist/physics/flightDynamics.js +28 -5
  101. package/dist/physics/handlingProbe.d.ts +249 -0
  102. package/dist/physics/handlingProbe.js +606 -0
  103. package/dist/physics/kinematicVehicle.d.ts +32 -2
  104. package/dist/physics/kinematicVehicle.js +15 -0
  105. package/dist/physics/physicsBackend.d.ts +12 -0
  106. package/dist/physics/physicsBackendConformance.js +34 -0
  107. package/dist/physics/physicsWorldBackend.d.ts +1 -0
  108. package/dist/physics/physicsWorldBackend.js +33 -0
  109. package/dist/physics/vehicleBackendLink.d.ts +49 -0
  110. package/dist/physics/vehicleBackendLink.js +102 -0
  111. package/dist/physics/vehicleDynamics.d.ts +374 -0
  112. package/dist/physics/vehicleDynamics.js +737 -0
  113. package/dist/physics/worldColliders.d.ts +1 -1
  114. package/dist/physics/worldColliders.js +35 -3
  115. package/dist/puzzle/cellGrid.d.ts +15 -9
  116. package/dist/puzzle/cellGrid.js +13 -9
  117. package/dist/render/lookPreset.d.ts +9 -2
  118. package/dist/render/lookPreset.js +29 -2
  119. package/dist/render/postProcessing.d.ts +30 -0
  120. package/dist/render/postProcessing.js +1 -1
  121. package/dist/runtime/cameraDirector.d.ts +17 -3
  122. package/dist/runtime/cameraDirector.js +25 -0
  123. package/dist/runtime/commandInput.d.ts +37 -0
  124. package/dist/runtime/commandInput.js +58 -0
  125. package/dist/runtime/commandRunner.d.ts +27 -0
  126. package/dist/runtime/commandRunner.js +31 -3
  127. package/dist/runtime/context/combat.d.ts +1 -0
  128. package/dist/runtime/context/combat.js +2 -1
  129. package/dist/runtime/context/deathLoot.d.ts +2 -0
  130. package/dist/runtime/context/deathLoot.js +1 -0
  131. package/dist/runtime/gameContext.js +7 -0
  132. package/dist/runtime/gameContextTypes.d.ts +19 -3
  133. package/dist/runtime/gameRuntime.d.ts +3 -1
  134. package/dist/runtime/gameRuntime.js +4 -0
  135. package/dist/runtime/inputSnapshot.d.ts +6 -0
  136. package/dist/runtime/inputSnapshot.js +10 -0
  137. package/dist/runtime/localPlayers.d.ts +73 -0
  138. package/dist/runtime/localPlayers.js +119 -0
  139. package/dist/runtime/transport.d.ts +9 -0
  140. package/dist/runtime/transport.js +7 -1
  141. package/dist/scene/behaviorRuntime.d.ts +12 -2
  142. package/dist/scene/behaviorRuntime.js +30 -14
  143. package/dist/scene/behaviors.d.ts +5 -1
  144. package/dist/scene/sceneKinds.d.ts +9 -0
  145. package/dist/scene/vehicleSeat.d.ts +5 -1
  146. package/dist/scene/vehicleSeat.js +5 -1
  147. package/dist/sensor/concealment.d.ts +6 -0
  148. package/dist/sensor/concealment.js +8 -0
  149. package/dist/sensor/freezeMonitor.d.ts +6 -0
  150. package/dist/sensor/freezeMonitor.js +8 -0
  151. package/dist/sensor/perception.d.ts +11 -1
  152. package/dist/sensor/perception.js +57 -10
  153. package/dist/sensor/recordingBuffer.d.ts +3 -0
  154. package/dist/sensor/recordingBuffer.js +8 -0
  155. package/dist/session/roundState.d.ts +4 -0
  156. package/dist/session/roundState.js +11 -0
  157. package/dist/settings/frameRateLimit.d.ts +16 -0
  158. package/dist/settings/frameRateLimit.js +37 -0
  159. package/dist/settings/graphicsProfile.d.ts +2 -0
  160. package/dist/settings/graphicsProfile.js +12 -0
  161. package/dist/settings/graphicsSettings.d.ts +40 -0
  162. package/dist/settings/graphicsSettings.js +81 -0
  163. package/dist/settings/settingsModel.d.ts +9 -1
  164. package/dist/settings/settingsModel.js +10 -0
  165. package/dist/stats/eventMeter.d.ts +1 -1
  166. package/dist/stats/eventMeter.js +1 -1
  167. package/dist/vfx/feedbackMixer.d.ts +61 -0
  168. package/dist/vfx/feedbackMixer.js +106 -0
  169. package/dist/visibility/simulationCulling.d.ts +8 -1
  170. package/dist/visibility/simulationCulling.js +7 -0
  171. package/dist/visibility/spatialIndex.d.ts +21 -0
  172. package/dist/visibility/spatialIndex.js +16 -0
  173. package/dist/world/authoredSolids.d.ts +46 -0
  174. package/dist/world/authoredSolids.js +75 -0
  175. package/dist/world/buildingGenerator.js +2 -2
  176. package/dist/world/buildingKit.d.ts +3 -1
  177. package/dist/world/buildings.d.ts +34 -2
  178. package/dist/world/buildings.js +11 -1
  179. package/dist/world/cityKind.d.ts +7 -0
  180. package/dist/world/cityKind.js +52 -1
  181. package/dist/world/features.d.ts +29 -2
  182. package/dist/world/features.js +6 -0
  183. package/dist/world/footprintGrid.d.ts +7 -0
  184. package/dist/world/footprintGrid.js +16 -0
  185. package/dist/world/interiors.d.ts +1 -0
  186. package/dist/world/interiors.js +5 -3
  187. package/dist/world/lod.d.ts +6 -0
  188. package/dist/world/lod.js +8 -0
  189. package/dist/world/terraform.d.ts +8 -0
  190. package/dist/world/terraform.js +7 -0
  191. package/dist/world/walls.d.ts +7 -0
  192. package/dist/world/walls.js +7 -0
  193. package/dist/world/worldSolids.d.ts +84 -0
  194. package/dist/world/worldSolids.js +240 -0
  195. package/dist/world.d.ts +2 -2
  196. package/dist/world.js +1 -1
  197. package/package.json +1 -1
  198. package/skills/ce-handoff/SKILL.md +1 -1
  199. package/skills/game-design/SKILL.md +2 -2
  200. package/skills/jgengine/SKILL.md +7 -5
  201. package/skills/jgengine/api.md +118 -89
  202. package/skills/jgengine/capabilities.md +28 -0
  203. package/skills/jgengine/recipes/minimal-game.md +3 -0
  204. package/skills/jgengine-combat/SKILL.md +5 -0
  205. package/skills/jgengine-combat/api.md +138 -103
  206. package/skills/jgengine-combat/capabilities.md +29 -1
  207. package/skills/jgengine-combat/recipes/weapon-feel.md +50 -0
  208. package/skills/jgengine-gameplay/api.md +462 -436
  209. package/skills/jgengine-gameplay/capabilities.md +24 -0
  210. package/skills/jgengine-gameplay/reference-systems.md +4 -0
  211. package/skills/jgengine-world/SKILL.md +15 -3
  212. package/skills/jgengine-world/api.md +873 -626
  213. package/skills/jgengine-world/capabilities.md +130 -6
  214. package/skills/jgengine-world/recipes/character-animation.md +39 -0
  215. package/skills/jgengine-world/recipes/controls.md +44 -0
  216. package/skills/jgengine-world/recipes/flight-feel.md +76 -0
  217. package/skills/jgengine-world/recipes/npc-senses.md +43 -0
  218. package/skills/jgengine-world/recipes/vehicle-feel.md +85 -0
  219. package/skills/jgengine-world/reference.md +31 -2
  220. package/skills/jgengine-world/visibility.md +112 -0
@@ -0,0 +1,390 @@
1
+ import { type GravityField } from "./gravityField.js";
2
+ /** Body-frame or world-frame vector, m or N. The body frame is `[left, up, forward]` about the centre of mass. */
3
+ export type AircraftVector = readonly [number, number, number];
4
+ /** Unit quaternion `[x, y, z, w]` taking body-frame vectors to world space. */
5
+ export type AircraftQuaternion = readonly [number, number, number, number];
6
+ /**
7
+ * One lifting surface: a wing panel, a tailplane, a fin, a canard. Its lift acts at `at`, so the moments that pitch,
8
+ * roll and yaw the body come from where the surfaces sit, not from commanded rates.
9
+ */
10
+ export interface AircraftSurface {
11
+ /** Mount point relative to the centre of mass, body frame `[left, up, forward]`, m. */
12
+ at: AircraftVector;
13
+ /** Direction positive lift pushes, body frame (default `[0, 1, 0]`, a horizontal surface; `[1, 0, 0]` is a fin). Kept perpendicular to the chord, which runs along body forward. */
14
+ normal?: AircraftVector;
15
+ /** Planform area, m². */
16
+ area: number;
17
+ /** Lift curve slope, per rad (default `5`; thin-airfoil theory gives `2π`, lower for short spans). */
18
+ liftSlope?: number;
19
+ /** Angle of attack where the surface stalls, rad (default `0.28`). */
20
+ stallAngle?: number;
21
+ /** Lift kept past the stall as a share of peak lift, `0..1` (default `0.6`). */
22
+ postStallLift?: number;
23
+ /** Fixed mounting angle added to the local angle of attack, rad (default `0`); trims the cruise attitude. */
24
+ incidence?: number;
25
+ /** Zero-lift drag coefficient `CD0` of the drag polar `CD = CD0 + k·CL²` (default `0.02`). */
26
+ cd0?: number;
27
+ /** Induced drag factor `k` of the drag polar (default `0.06`). */
28
+ inducedDrag?: number;
29
+ /**
30
+ * Control authority: angle-of-attack change, rad, per rad of each channel's deflection. The sim signs it from the
31
+ * surface's lever arm, so positive input always gives nose-up pitch, right roll and nose-right yaw. A surface on the
32
+ * centreline has no roll arm, so its `roll` does nothing.
33
+ */
34
+ control?: {
35
+ pitch?: number;
36
+ roll?: number;
37
+ yaw?: number;
38
+ };
39
+ }
40
+ /** One control channel's actuator: how far the surfaces move and how fast. */
41
+ export interface AircraftControlChannel {
42
+ /** Largest deflection, rad (default `0.35`). */
43
+ maxDeflection?: number;
44
+ /** Actuator slew rate, rad/s (default `2`). */
45
+ rate?: number;
46
+ }
47
+ /** A thrust source fixed to the body. */
48
+ export interface AircraftEngineTuning {
49
+ /** Thrust at full throttle, N. */
50
+ maxThrust: number;
51
+ /** Engine spool response, 1/s: thrust follows the throttle with this first-order rate (default `1.5`; ~1.5 s to 90%). */
52
+ spoolRate?: number;
53
+ /** Thrust line offset from the centre of mass, body frame m (default on the centre of mass). */
54
+ at?: AircraftVector;
55
+ /** Thrust direction, body frame (default `[0, 0, 1]`, forward). */
56
+ direction?: AircraftVector;
57
+ }
58
+ /** Wheels or skids: what the body rests on when it touches the ground. */
59
+ export interface AircraftGearTuning {
60
+ /** Height of the centre of mass above the ground when resting on the gear, m. */
61
+ height: number;
62
+ /** Rolling resistance coefficient (default `0.02`). */
63
+ rollingResistance?: number;
64
+ /** Deceleration at full `brake`, m/s² (default `4`). */
65
+ brakeDecel?: number;
66
+ /** Sideways friction coefficient of the tyres or skids (default `0.8`). */
67
+ sideGrip?: number;
68
+ /** Largest nose-up attitude the gear allows before the tail strikes, rad (default `0.25`). */
69
+ maxPitch?: number;
70
+ }
71
+ /**
72
+ * A rocket motor: thrust follows a curve over burn time, propellant leaves at a mass flow so the body gets lighter and
73
+ * easier to turn, and the nozzle gimbals on the pitch and yaw channels. Stage by `retune`-ing to the next stage's
74
+ * mass and motor.
75
+ */
76
+ export interface AircraftMotorTuning {
77
+ /** Thrust over burn time, `[seconds since ignition, N]` points, linear between; zero past the last point. */
78
+ thrustCurve: readonly (readonly [number, number])[];
79
+ /** Propellant at ignition, kg, on top of `massKg`. */
80
+ propellantKg: number;
81
+ /** Propellant mass flow at the curve's peak thrust, kg/s; it scales with thrust (constant exhaust velocity). */
82
+ massFlow: number;
83
+ /** Nozzle position relative to the centre of mass, body frame m (default `[0, 0, -1]`, behind it). */
84
+ at?: AircraftVector;
85
+ /** Largest nozzle gimbal angle, rad (default `0`, fixed). Pitch and yaw inputs swing it through their actuators. */
86
+ gimbal?: number;
87
+ }
88
+ /**
89
+ * A main rotor. Collective sets blade pitch, throttle sets rotor speed, and cyclic (the pitch and roll channels) tilts
90
+ * the disc. Its drag torque yaws the body the other way unless a tail rotor, a second rotor or a pedal input cancels it.
91
+ */
92
+ export interface AircraftRotorTuning {
93
+ /** Thrust at full collective and full rotor speed, out of ground effect and in a hover, N. */
94
+ maxThrust: number;
95
+ /** Blade radius, m. Sets the disc area, so the induced velocity behind translational lift, and the ground-effect height. */
96
+ radius: number;
97
+ /** Hub position relative to the centre of mass, body frame m (default `[0, 1.5, 0]`). A hub above the centre of mass turns disc tilt into pitch and roll moments. */
98
+ at?: AircraftVector;
99
+ /** Rotor speed response to throttle, 1/s (default `0.5`): rotors spin up slowly. */
100
+ spoolRate?: number;
101
+ /**
102
+ * Drag torque on the body at full collective and full rotor speed, N·m, scaling with collective and rotor speed².
103
+ * Positive yaws the nose left (a rotor turning counter-clockwise seen from above); negative yaws it right.
104
+ */
105
+ torque: number;
106
+ /** Disc tilt at full cyclic, rad (default `0.15`); the pitch and roll actuators set how fast it gets there. */
107
+ cyclic?: number;
108
+ /** Extra thrust once the rotor moves into clean air, as a share of thrust (default `0.2`): translational lift. */
109
+ translationalLift?: number;
110
+ /** Pitch and roll damping from the disc, N·m per rad/s (default `0`). */
111
+ damping?: number;
112
+ /**
113
+ * Tail rotor: sideways thrust at full yaw input and full rotor speed, N, acting at `at` (body frame m). Neutral pedal
114
+ * gives no thrust, so holding heading takes a yaw input that matches the main rotor torque. `sideDamping`, N per m/s
115
+ * of sideways air through it (default `maxThrust / 10`), is the yaw damping a spinning tail rotor adds.
116
+ */
117
+ tail?: {
118
+ maxThrust: number;
119
+ at: AircraftVector;
120
+ sideDamping?: number;
121
+ };
122
+ }
123
+ /** What an assist sees each substep, derived from the integrator state so it replays deterministically. */
124
+ export interface AircraftAssistContext {
125
+ /** Substep, s. */
126
+ dt: number;
127
+ airspeed: number;
128
+ angleOfAttack: number;
129
+ heading: number;
130
+ pitch: number;
131
+ bank: number;
132
+ /** Body rates, rad/s: positive nose up, nose right, right roll. */
133
+ pitchRate: number;
134
+ yawRate: number;
135
+ rollRate: number;
136
+ /** World velocity, m/s. */
137
+ velocity: AircraftVector;
138
+ /** Horizontal velocity in the heading frame, m/s: `forward` along the nose, `right` to the right. */
139
+ forward: number;
140
+ right: number;
141
+ /** Load factor estimate from pitch rate and attitude, g. */
142
+ gLoad: number;
143
+ heightAboveGround: number;
144
+ /** The pilot's input this tick. */
145
+ pilot: RigidAircraftInput;
146
+ }
147
+ /** Control commands, `-1..1`, that drive the actuators after the assists. */
148
+ export interface AircraftAssistCommand {
149
+ pitch: number;
150
+ roll: number;
151
+ yaw: number;
152
+ }
153
+ /**
154
+ * Flight assists. Each one moves the same actuators the pilot does, so a stronger assist still flies within the
155
+ * airframe's authority. Strengths are `0..1`; an axis the pilot is deflecting gets less help the further the stick is
156
+ * pushed, so full stick is always the pilot's.
157
+ */
158
+ export interface AircraftAssistTuning {
159
+ /**
160
+ * Stability augmentation per axis, `0..1`: opposes body rate and, while that axis is hands-off, holds the attitude
161
+ * or heading it had when the pilot let go, learning the trim it needs. On a helicopter, `yaw` holds heading against
162
+ * rotor torque. Where `autoLevel` or `hoverHold` flies pitch and roll, SAS only damps their rates.
163
+ */
164
+ sas?: {
165
+ pitch?: number;
166
+ roll?: number;
167
+ yaw?: number;
168
+ };
169
+ /** Body rate at which SAS asks for full control, rad/s (default `0.5`); lower is firmer. */
170
+ sasRate?: number;
171
+ /** Hands-off, flies the wings level and the nose to the horizon, `0..1`. */
172
+ autoLevel?: number;
173
+ /** Largest angle of attack the pitch command may ask for, rad. */
174
+ maxAngleOfAttack?: number;
175
+ /** Largest load factor the pitch command may ask for, g. */
176
+ maxG?: number;
177
+ /** Hands-off cyclic flies the helicopter to a stop over the ground, `0..1`: velocity to attitude to rate. */
178
+ hoverHold?: number;
179
+ /** Runs after the built-in assists and returns the command the actuators get; replace or blend any policy here. */
180
+ policy?: (context: AircraftAssistContext, command: AircraftAssistCommand) => AircraftAssistCommand;
181
+ }
182
+ /**
183
+ * A rigid aircraft in physical units. There is no aircraft type: a jet, a glider and a paper plane differ only in these
184
+ * numbers. Rotation comes from surface forces acting on the inertia tensor, so loops, rolls, stalls and weathervaning
185
+ * are outcomes, not special cases.
186
+ */
187
+ export interface RigidAircraftTuning {
188
+ /** Mass, kg; with a `motor`, the mass without propellant. */
189
+ massKg: number;
190
+ /** Principal moments of inertia about the body axes at `massKg`, kg·m²: `pitch` about left, `yaw` about up, `roll` about forward. Propellant scales them by total mass over `massKg`. */
191
+ inertia: {
192
+ pitch: number;
193
+ yaw: number;
194
+ roll: number;
195
+ };
196
+ surfaces: readonly AircraftSurface[];
197
+ engine?: AircraftEngineTuning;
198
+ rotor?: AircraftRotorTuning;
199
+ motor?: AircraftMotorTuning;
200
+ assists?: AircraftAssistTuning;
201
+ /** Actuators per channel; each channel defaults to `{ maxDeflection: 0.35, rate: 2 }`. */
202
+ controls?: {
203
+ pitch?: AircraftControlChannel;
204
+ roll?: AircraftControlChannel;
205
+ yaw?: AircraftControlChannel;
206
+ };
207
+ /** Fuselage drag coefficient × frontal area, m² (default `0`). */
208
+ dragArea?: number;
209
+ /** Omit for a body that never touches the ground (it falls through). */
210
+ gear?: AircraftGearTuning;
211
+ /** Integration substep, s (default `1/240`). */
212
+ maxSubstep?: number;
213
+ }
214
+ /** Pilot input for one tick. */
215
+ export interface RigidAircraftInput {
216
+ /** `0..1`. */
217
+ throttle: number;
218
+ /** `-1..1`, positive pulls the nose up. */
219
+ pitch: number;
220
+ /** `-1..1`, positive rolls right (right wing down). */
221
+ roll: number;
222
+ /** `-1..1`, positive yaws the nose right. */
223
+ yaw: number;
224
+ /** Wheel brake, `0..1`. */
225
+ brake?: number;
226
+ /** Rotor collective, `0..1` (default `0`). */
227
+ collective?: number;
228
+ }
229
+ /** Per-tick overrides layered over tuning: damage, icing, boost, gusts. Each scale defaults to `1`. */
230
+ export interface RigidAircraftModifiers {
231
+ thrustScale?: number;
232
+ liftScale?: number;
233
+ dragScale?: number;
234
+ /** Extra world-space force this tick, N — a tow, a gust, a tractor beam. */
235
+ force?: AircraftVector;
236
+ /** Extra body-frame torque this tick, N·m `[about left, about up, about forward]`. */
237
+ torque?: AircraftVector;
238
+ }
239
+ /** World hooks for one aircraft instance. */
240
+ export interface RigidAircraftOptions {
241
+ position?: AircraftVector;
242
+ velocity?: AircraftVector;
243
+ /** Spawn heading, rad, with forward `[sin h, 0, cos h]`; ignored when `orientation` is set. */
244
+ heading?: number;
245
+ orientation?: AircraftQuaternion;
246
+ /** Wind velocity at a point, m/s. */
247
+ wind?: (position: AircraftVector) => AircraftVector;
248
+ /** Terrain height under a point; the gear rests on it. Default `0`. */
249
+ groundHeight?: (x: number, z: number) => number;
250
+ /** Default uniform `9.81` m/s² down. */
251
+ gravityField?: GravityField;
252
+ /** Air density at an altitude, kg/m³ (default sea level, `1.225`). */
253
+ airDensity?: (altitude: number) => number;
254
+ }
255
+ /** Serializable integrator state: everything `restore` needs to resume bit-for-bit. */
256
+ export interface RigidAircraftState {
257
+ x: number;
258
+ y: number;
259
+ z: number;
260
+ vx: number;
261
+ vy: number;
262
+ vz: number;
263
+ qx: number;
264
+ qy: number;
265
+ qz: number;
266
+ qw: number;
267
+ /** Angular velocity, body frame rad/s. */
268
+ wx: number;
269
+ wy: number;
270
+ wz: number;
271
+ pitchDeflection: number;
272
+ rollDeflection: number;
273
+ yawDeflection: number;
274
+ /** Engine output as a share of `maxThrust`, `0..1`. */
275
+ spool: number;
276
+ /** Rotor speed as a share of its rated speed, `0..1`. */
277
+ rotorSpeed: number;
278
+ /** Seconds the motor has burned. */
279
+ burnTime: number;
280
+ /** Propellant left, kg. */
281
+ propellantKg: number;
282
+ /** SAS hold per axis: body-angle change since that axis went hands-off, rad. */
283
+ holdPitch: number;
284
+ holdRoll: number;
285
+ holdYaw: number;
286
+ /** SAS trim per axis: the steady command it learned to hold against (rotor torque, an out-of-trim wing), rad/s. */
287
+ trimPitch: number;
288
+ trimRoll: number;
289
+ trimYaw: number;
290
+ /** Hover hold: world drift since the cyclic went hands-off, m. */
291
+ driftX: number;
292
+ driftZ: number;
293
+ time: number;
294
+ }
295
+ /** One aircraft tick: pose plus the telemetry HUDs, camera, sound and probes read. */
296
+ export interface RigidAircraftStep {
297
+ position: AircraftVector;
298
+ velocity: AircraftVector;
299
+ orientation: AircraftQuaternion;
300
+ /** Heading, rad, forward `[sin h, 0, cos h]`; equals three.js `rotation.y` in `YXZ` order. */
301
+ heading: number;
302
+ /** Nose-up attitude, rad; three.js `rotation.x = -pitch` in `YXZ` order. */
303
+ pitch: number;
304
+ /** Bank, rad, positive right wing down; three.js `rotation.z` in `YXZ` order. */
305
+ bank: number;
306
+ /** Body rates, rad/s: positive nose up, nose right, right roll. */
307
+ pitchRate: number;
308
+ yawRate: number;
309
+ rollRate: number;
310
+ /** Speed relative to the air, m/s. */
311
+ airspeed: number;
312
+ /** Angle of attack at the centre of mass, rad. */
313
+ angleOfAttack: number;
314
+ /** Sideslip, rad, positive when the body moves to its right. */
315
+ sideslip: number;
316
+ /** Load factor along the body's up axis, g; `1` in level flight, `0` in free fall. */
317
+ gLoad: number;
318
+ /** The largest surface is past its stall angle. */
319
+ stalled: boolean;
320
+ /** Share of surface area past its stall angle, `0..1`. */
321
+ stallFraction: number;
322
+ /** Engine thrust this tick, N. */
323
+ thrust: number;
324
+ /** Current actuator deflection per channel, rad. */
325
+ deflection: {
326
+ pitch: number;
327
+ roll: number;
328
+ yaw: number;
329
+ };
330
+ grounded: boolean;
331
+ /** Total mass including propellant, kg. */
332
+ massKg: number;
333
+ /** The command the actuators got after assists, `-1..1`; equals the pilot's input without assists. */
334
+ command: AircraftAssistCommand;
335
+ /** The AoA or g limiter cut the pitch command this tick. */
336
+ limited: boolean;
337
+ /** Motor telemetry; absent without a `motor` block. */
338
+ motor?: {
339
+ /** Motor thrust this tick, N. */
340
+ thrust: number;
341
+ burnTime: number;
342
+ propellantKg: number;
343
+ /** Out of propellant or past the end of the thrust curve. */
344
+ burnedOut: boolean;
345
+ };
346
+ /** Rotor telemetry; absent without a `rotor` block. */
347
+ rotor?: {
348
+ /** Rotor speed, share of rated, `0..1`. */
349
+ speed: number;
350
+ /** Main rotor thrust, N. */
351
+ thrust: number;
352
+ /** Drag torque on the body, N·m, positive nose left. */
353
+ torque: number;
354
+ /** Thrust multiplier from ground effect, `≥ 1`. */
355
+ groundEffect: number;
356
+ /** Thrust multiplier from translational lift, `≥ 1`. */
357
+ translationalLift: number;
358
+ };
359
+ }
360
+ /** A force-and-torque aircraft on the same tick/snapshot/retune contract as `VehicleDynamics`. */
361
+ export interface RigidAircraft {
362
+ tick(dt: number, input: RigidAircraftInput, modifiers?: RigidAircraftModifiers): RigidAircraftStep;
363
+ pose(): {
364
+ position: AircraftVector;
365
+ orientation: AircraftQuaternion;
366
+ };
367
+ velocity(): AircraftVector;
368
+ /** Adds a world-space velocity change, m/s — a hit, a catapult, an explosion. */
369
+ applyImpulse(dv: AircraftVector): void;
370
+ retune(next: RigidAircraftTuning): void;
371
+ tuning(): RigidAircraftTuning;
372
+ snapshot(): RigidAircraftState;
373
+ restore(state: RigidAircraftState): void;
374
+ resetTo(position: AircraftVector, orientation?: AircraftQuaternion): void;
375
+ }
376
+ /** Quaternion for a heading about world up, forward `[sin h, 0, cos h]`. */
377
+ export declare function aircraftHeadingQuaternion(heading: number): AircraftQuaternion;
378
+ /**
379
+ * Quaternion from heading, nose-up pitch and right bank, rad — the inverse of a step's `heading`/`pitch`/`bank`.
380
+ * Matches three.js `Euler(-pitch, heading, bank, "YXZ")`.
381
+ */
382
+ export declare function aircraftAttitudeQuaternion(heading: number, pitch: number, bank: number): AircraftQuaternion;
383
+ /**
384
+ * Creates a {@link RigidAircraft}: a quaternion rigid body with a diagonal inertia tensor, pushed by lifting surfaces,
385
+ * fuselage drag, an engine and gravity. Controls deflect surfaces through rate-limited actuators; nothing commands a
386
+ * rotation rate, so a jet loops when its tail can push the nose around and a glider stalls when it runs out of speed.
387
+ * Fixed internal substeps make it deterministic for a given `dt` sequence.
388
+ * @capability rigid-aircraft force-and-torque aircraft — lifting surfaces with stall and drag polar, control surfaces, inertia, loops and rolls
389
+ */
390
+ export declare function createRigidAircraft(initial: RigidAircraftTuning, options?: RigidAircraftOptions): RigidAircraft;