@jgengine/core 0.10.0 → 0.11.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.
- package/CHANGELOG.md +13 -2
- package/LICENSE +203 -661
- package/README.md +1 -1
- package/dist/ai/crowd.d.ts +55 -0
- package/dist/ai/crowd.js +114 -0
- package/dist/ai/flock.d.ts +5 -2
- package/dist/ai/flock.js +5 -2
- package/dist/ai/groupAssist.d.ts +1 -0
- package/dist/ai/groupAssist.js +1 -0
- package/dist/ai/heatSystem.d.ts +76 -0
- package/dist/ai/heatSystem.js +97 -0
- package/dist/ai/interestScheduler.d.ts +107 -0
- package/dist/ai/interestScheduler.js +118 -0
- package/dist/ai/jobBoard.d.ts +1 -0
- package/dist/ai/jobBoard.js +1 -0
- package/dist/ai/laneSelect.d.ts +5 -2
- package/dist/ai/laneSelect.js +5 -2
- package/dist/ai/mobBrain.d.ts +1 -0
- package/dist/ai/mobBrain.js +1 -0
- package/dist/ai/spawnDirector.d.ts +7 -2
- package/dist/ai/spawnDirector.js +18 -15
- package/dist/ai/spawnPoint.d.ts +3 -1
- package/dist/ai/spawnPoint.js +3 -1
- package/dist/ai/targetAcquisition.d.ts +84 -0
- package/dist/ai/targetAcquisition.js +92 -0
- package/dist/anim/easing.d.ts +19 -0
- package/dist/anim/easing.js +19 -0
- package/dist/anim/oscillator.d.ts +12 -0
- package/dist/anim/oscillator.js +25 -0
- package/dist/area/areaEffectField.d.ts +127 -0
- package/dist/area/areaEffectField.js +175 -0
- package/dist/area/stackPolicy.d.ts +47 -0
- package/dist/area/stackPolicy.js +99 -0
- package/dist/authoring.d.ts +1 -0
- package/dist/authoring.js +1 -0
- package/dist/board/laneBoard.d.ts +13 -0
- package/dist/board/laneBoard.js +13 -0
- package/dist/board/timelineBoard.d.ts +10 -0
- package/dist/board/timelineBoard.js +10 -0
- package/dist/combat/abilityKit.d.ts +18 -0
- package/dist/combat/abilityKit.js +24 -9
- package/dist/combat/animationState.d.ts +5 -0
- package/dist/combat/animationState.js +5 -0
- package/dist/combat/breakMeters.d.ts +10 -0
- package/dist/combat/breakMeters.js +10 -0
- package/dist/combat/castRunner.d.ts +5 -0
- package/dist/combat/castRunner.js +5 -0
- package/dist/combat/comboPoints.d.ts +5 -0
- package/dist/combat/comboPoints.js +5 -0
- package/dist/combat/comboString.d.ts +5 -0
- package/dist/combat/comboString.js +5 -0
- package/dist/combat/damageInterceptors.d.ts +192 -0
- package/dist/combat/damageInterceptors.js +251 -0
- package/dist/combat/damageMatchup.d.ts +68 -0
- package/dist/combat/damageMatchup.js +42 -0
- package/dist/combat/damageResolution.d.ts +63 -0
- package/dist/combat/damageResolution.js +50 -0
- package/dist/combat/death.d.ts +7 -1
- package/dist/combat/death.js +5 -0
- package/dist/combat/deathReason.d.ts +14 -0
- package/dist/combat/deathReason.js +1 -0
- package/dist/combat/defensiveWindow.d.ts +5 -0
- package/dist/combat/defensiveWindow.js +5 -0
- package/dist/combat/dotField.d.ts +5 -1
- package/dist/combat/dotField.js +5 -1
- package/dist/combat/downed.d.ts +5 -0
- package/dist/combat/downed.js +5 -0
- package/dist/combat/effects.d.ts +5 -0
- package/dist/combat/effects.js +5 -0
- package/dist/combat/encounterSequence.d.ts +258 -0
- package/dist/combat/encounterSequence.js +426 -0
- package/dist/combat/hitReaction.d.ts +57 -1
- package/dist/combat/hitReaction.js +45 -5
- package/dist/combat/magazine.d.ts +54 -0
- package/dist/combat/magazine.js +96 -0
- package/dist/combat/projectiles.d.ts +5 -0
- package/dist/combat/projectiles.js +32 -14
- package/dist/combat/receivedDamage.d.ts +117 -0
- package/dist/combat/receivedDamage.js +92 -0
- package/dist/combat/regenShield.d.ts +5 -1
- package/dist/combat/regenShield.js +5 -1
- package/dist/combat/renderCues.d.ts +51 -0
- package/dist/combat/renderCues.js +44 -0
- package/dist/combat/resourcePool.d.ts +5 -0
- package/dist/combat/resourcePool.js +5 -0
- package/dist/combat/rewardAllocation.d.ts +121 -0
- package/dist/combat/rewardAllocation.js +251 -0
- package/dist/combat/shotOrigin.d.ts +18 -1
- package/dist/combat/shotOrigin.js +39 -0
- package/dist/combat/statusApplication.d.ts +96 -0
- package/dist/combat/statusApplication.js +81 -0
- package/dist/combat/telegraph.d.ts +11 -2
- package/dist/combat/telegraph.js +11 -2
- package/dist/combat/thresholdCrossings.d.ts +85 -0
- package/dist/combat/thresholdCrossings.js +116 -0
- package/dist/combat.d.ts +34 -0
- package/dist/combat.js +34 -0
- package/dist/commands/commandRegistry.d.ts +11 -0
- package/dist/commands/commandRegistry.js +9 -2
- package/dist/crafting/crop.d.ts +18 -0
- package/dist/crafting/crop.js +18 -0
- package/dist/crafting/production.d.ts +5 -0
- package/dist/crafting/production.js +5 -0
- package/dist/devtools/rewriteTunables.d.ts +17 -0
- package/dist/devtools/rewriteTunables.js +276 -0
- package/dist/devtools/saveEndpoint.d.ts +46 -0
- package/dist/devtools/saveEndpoint.js +48 -0
- package/dist/devtools/transformTunables.d.ts +3 -0
- package/dist/devtools/transformTunables.js +3 -0
- package/dist/devtools/tunableSchema.d.ts +31 -0
- package/dist/devtools/tunableSchema.js +31 -0
- package/dist/economy/currency.d.ts +12 -1
- package/dist/economy/currency.js +12 -1
- package/dist/economy/listingBook.d.ts +91 -0
- package/dist/economy/listingBook.js +144 -0
- package/dist/economy/resourceLedger.d.ts +222 -0
- package/dist/economy/resourceLedger.js +353 -0
- package/dist/economy/sharedWallet.d.ts +14 -0
- package/dist/economy/sharedWallet.js +14 -0
- package/dist/economy/techTree.d.ts +12 -0
- package/dist/economy/techTree.js +12 -0
- package/dist/economy/wallet.d.ts +26 -2
- package/dist/economy/wallet.js +35 -6
- package/dist/editor/commands.d.ts +190 -7
- package/dist/editor/commands.js +727 -55
- package/dist/editor/document.d.ts +159 -13
- package/dist/editor/document.js +750 -19
- package/dist/editor/grid.d.ts +229 -0
- package/dist/editor/grid.js +366 -0
- package/dist/editor/gridAdapters.d.ts +80 -0
- package/dist/editor/gridAdapters.js +134 -0
- package/dist/editor/index.d.ts +73 -6
- package/dist/editor/index.js +6 -2
- package/dist/editor/liveSync.d.ts +127 -0
- package/dist/editor/liveSync.js +249 -0
- package/dist/editor/runtimeInspector.d.ts +88 -0
- package/dist/editor/runtimeInspector.js +239 -0
- package/dist/editor/types.d.ts +107 -1
- package/dist/faction/reputation.d.ts +5 -0
- package/dist/faction/reputation.js +5 -0
- package/dist/format/distance.d.ts +17 -0
- package/dist/format/distance.js +18 -0
- package/dist/format/duration.d.ts +27 -0
- package/dist/format/duration.js +45 -0
- package/dist/format/speed.d.ts +17 -0
- package/dist/format/speed.js +25 -0
- package/dist/game/connectedPlayers.d.ts +6 -4
- package/dist/game/connectedPlayers.js +2 -2
- package/dist/game/cosmetics.d.ts +9 -0
- package/dist/game/cosmetics.js +16 -0
- package/dist/game/defineGame.d.ts +100 -2
- package/dist/game/defineGame.js +39 -2
- package/dist/game/defineSystem.d.ts +88 -0
- package/dist/game/defineSystem.js +45 -0
- package/dist/game/dialogue.d.ts +33 -0
- package/dist/game/dialogue.js +21 -0
- package/dist/game/events.d.ts +35 -13
- package/dist/game/events.js +5 -0
- package/dist/game/feed.d.ts +33 -0
- package/dist/game/feed.js +35 -2
- package/dist/game/gamePhase.d.ts +11 -0
- package/dist/game/gamePhase.js +16 -0
- package/dist/game/leaderboard.d.ts +5 -0
- package/dist/game/leaderboard.js +5 -0
- package/dist/game/loadout.d.ts +5 -0
- package/dist/game/loadout.js +5 -0
- package/dist/game/lootFilter.d.ts +2 -0
- package/dist/game/lootFilter.js +2 -0
- package/dist/game/lootPipeline.d.ts +164 -0
- package/dist/game/lootPipeline.js +216 -0
- package/dist/game/lootTable.d.ts +19 -2
- package/dist/game/lootTable.js +15 -5
- package/dist/game/objectives.d.ts +43 -0
- package/dist/game/objectives.js +36 -0
- package/dist/game/paramLayers.d.ts +148 -0
- package/dist/game/paramLayers.js +185 -0
- package/dist/game/ping.d.ts +5 -0
- package/dist/game/ping.js +5 -0
- package/dist/game/playableGame.d.ts +92 -7
- package/dist/game/quest.d.ts +8 -0
- package/dist/game/quest.js +29 -0
- package/dist/game/race.d.ts +141 -0
- package/dist/game/race.js +169 -0
- package/dist/game/recordBook.d.ts +3 -1
- package/dist/game/recordBook.js +4 -1
- package/dist/game/ruleSelection.d.ts +75 -0
- package/dist/game/ruleSelection.js +127 -0
- package/dist/game/runDraft.d.ts +5 -0
- package/dist/game/runDraft.js +5 -0
- package/dist/game/saveStore.d.ts +111 -0
- package/dist/game/saveStore.js +312 -0
- package/dist/game/snapshotHistory.d.ts +67 -0
- package/dist/game/snapshotHistory.js +95 -0
- package/dist/game/social.d.ts +38 -1
- package/dist/game/social.js +71 -0
- package/dist/game/spawnPoints.d.ts +5 -0
- package/dist/game/spawnPoints.js +5 -0
- package/dist/game/systemRuntime.d.ts +50 -0
- package/dist/game/systemRuntime.js +157 -0
- package/dist/game/systemSchedule.d.ts +72 -0
- package/dist/game/systemSchedule.js +242 -0
- package/dist/game/toasts.d.ts +43 -0
- package/dist/game/toasts.js +44 -0
- package/dist/game/trade.d.ts +10 -0
- package/dist/game/trade.js +10 -0
- package/dist/game/unlocks.d.ts +8 -0
- package/dist/game/unlocks.js +16 -0
- package/dist/game/vfxInstance.d.ts +138 -0
- package/dist/game/vfxInstance.js +96 -0
- package/dist/game/worldItem.d.ts +17 -4
- package/dist/game/worldItem.js +17 -4
- package/dist/gameplay.d.ts +91 -0
- package/dist/gameplay.js +91 -0
- package/dist/index.d.ts +5 -14
- package/dist/index.js +5 -14
- package/dist/input/actionBindings.d.ts +23 -6
- package/dist/input/actionBindings.js +23 -6
- package/dist/input/axisInput.d.ts +7 -2
- package/dist/input/axisInput.js +7 -2
- package/dist/input/controlGroups.d.ts +67 -0
- package/dist/input/controlGroups.js +41 -0
- package/dist/input/touchScheme.d.ts +82 -6
- package/dist/input/touchScheme.js +123 -10
- package/dist/interaction/lockpick.d.ts +61 -0
- package/dist/interaction/lockpick.js +168 -0
- package/dist/interaction/proximityPrompt.d.ts +2 -0
- package/dist/interaction/proximityPrompt.js +2 -0
- package/dist/interaction/qte.d.ts +5 -0
- package/dist/interaction/qte.js +5 -0
- package/dist/interaction/skillCheck.d.ts +5 -0
- package/dist/interaction/skillCheck.js +5 -0
- package/dist/inventory/inventoryModel.d.ts +12 -0
- package/dist/inventory/inventoryModel.js +12 -0
- package/dist/inventory/shapedGrid.d.ts +16 -0
- package/dist/inventory/shapedGrid.js +16 -0
- package/dist/inventory/slotModel.d.ts +10 -0
- package/dist/inventory/slotModel.js +10 -0
- package/dist/item/durability.d.ts +5 -0
- package/dist/item/durability.js +5 -0
- package/dist/item/itemIdentity.d.ts +171 -0
- package/dist/item/itemIdentity.js +138 -0
- package/dist/item/itemInstanceRegistry.d.ts +32 -0
- package/dist/item/itemInstanceRegistry.js +34 -0
- package/dist/item/itemgen.d.ts +163 -0
- package/dist/item/itemgen.js +151 -0
- package/dist/item/modularItem.d.ts +5 -0
- package/dist/item/modularItem.js +5 -0
- package/dist/item/use.d.ts +5 -0
- package/dist/item/use.js +5 -0
- package/dist/item/useBehavior.d.ts +142 -0
- package/dist/item/useBehavior.js +105 -0
- package/dist/item/weapon.d.ts +5 -0
- package/dist/item/weapon.js +5 -0
- package/dist/math/scalar.d.ts +25 -0
- package/dist/math/scalar.js +47 -0
- package/dist/meta/changelog.d.ts +4 -1
- package/dist/meta/changelog.js +16 -2
- package/dist/movement/avoidance.d.ts +45 -0
- package/dist/movement/avoidance.js +123 -0
- package/dist/movement/cameraRig.d.ts +8 -0
- package/dist/movement/cameraRig.js +8 -0
- package/dist/movement/dash.d.ts +11 -0
- package/dist/movement/dash.js +11 -0
- package/dist/movement/formation.d.ts +135 -0
- package/dist/movement/formation.js +194 -0
- package/dist/movement/glideModel.d.ts +5 -0
- package/dist/movement/glideModel.js +5 -0
- package/dist/movement/grappleSwing.d.ts +5 -0
- package/dist/movement/grappleSwing.js +5 -0
- package/dist/movement/leaderTrail.d.ts +5 -0
- package/dist/movement/leaderTrail.js +5 -0
- package/dist/movement/movementModel.d.ts +35 -8
- package/dist/movement/movementModel.js +42 -14
- package/dist/movement/playerMovement.js +65 -10
- package/dist/movement/poseState.d.ts +13 -0
- package/dist/movement/poseState.js +16 -0
- package/dist/movement/steering.d.ts +8 -0
- package/dist/movement/steering.js +18 -0
- package/dist/multiplayer/combatSnapshot.d.ts +3 -0
- package/dist/multiplayer/combatSnapshot.js +3 -0
- package/dist/multiplayer/lagCompensation.d.ts +5 -0
- package/dist/multiplayer/lagCompensation.js +5 -0
- package/dist/multiplayer/presenceModel.d.ts +9 -1
- package/dist/multiplayer/presenceModel.js +9 -1
- package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
- package/dist/multiplayer/simultaneousCommit.js +3 -0
- package/dist/multiplayer.d.ts +11 -0
- package/dist/multiplayer.js +11 -0
- package/dist/nav/pathFollow.d.ts +57 -0
- package/dist/nav/pathFollow.js +109 -0
- package/dist/orders/orderKinds.d.ts +156 -0
- package/dist/orders/orderKinds.js +197 -0
- package/dist/orders/orderQueue.d.ts +208 -0
- package/dist/orders/orderQueue.js +211 -0
- package/dist/physics/drivableVehicle.d.ts +29 -0
- package/dist/physics/drivableVehicle.js +16 -0
- package/dist/physics/kinematicVehicle.d.ts +21 -1
- package/dist/physics/kinematicVehicle.js +23 -8
- package/dist/physics/physicsWorld.d.ts +24 -12
- package/dist/physics/physicsWorld.js +11 -5
- package/dist/physics/radialImpulse.d.ts +25 -0
- package/dist/physics/radialImpulse.js +27 -0
- package/dist/procedural.d.ts +3 -0
- package/dist/procedural.js +3 -0
- package/dist/progression/statGraph.d.ts +116 -0
- package/dist/progression/statGraph.js +318 -0
- package/dist/puzzle/cellGrid.d.ts +9 -0
- package/dist/puzzle/cellGrid.js +9 -0
- package/dist/puzzle/fallingPiece.d.ts +9 -0
- package/dist/puzzle/fallingPiece.js +9 -0
- package/dist/puzzle/nonogram.d.ts +39 -0
- package/dist/puzzle/nonogram.js +136 -0
- package/dist/random/nameGen.d.ts +5 -0
- package/dist/random/nameGen.js +5 -0
- package/dist/random/pick.d.ts +8 -0
- package/dist/random/pick.js +31 -0
- package/dist/random/rng.d.ts +22 -0
- package/dist/random/rng.js +28 -8
- package/dist/random/seedLink.d.ts +4 -0
- package/dist/random/seedLink.js +4 -0
- package/dist/relation/keyedValues.d.ts +54 -0
- package/dist/relation/keyedValues.js +115 -0
- package/dist/relation/thresholds.d.ts +62 -0
- package/dist/relation/thresholds.js +62 -0
- package/dist/render/color.d.ts +12 -0
- package/dist/render/color.js +26 -0
- package/dist/render/lookPreset.d.ts +41 -0
- package/dist/render/lookPreset.js +29 -0
- package/dist/render/postProcessing.d.ts +20 -0
- package/dist/render/postProcessing.js +21 -1
- package/dist/rules/predicate.d.ts +53 -0
- package/dist/rules/predicate.js +64 -0
- package/dist/rules/ruleEffects.d.ts +38 -0
- package/dist/rules/ruleEffects.js +37 -0
- package/dist/rules/triggeredRules.d.ts +160 -0
- package/dist/rules/triggeredRules.js +241 -0
- package/dist/runtime/adapter.d.ts +42 -3
- package/dist/runtime/adapter.js +44 -1
- package/dist/runtime/cameraDirector.d.ts +1 -0
- package/dist/runtime/cameraDirector.js +1 -0
- package/dist/runtime/commandRunner.d.ts +1 -0
- package/dist/runtime/commandRunner.js +1 -0
- package/dist/runtime/context/combatFx.d.ts +23 -0
- package/dist/runtime/context/combatFx.js +161 -0
- package/dist/runtime/context/registries.d.ts +13 -0
- package/dist/runtime/context/registries.js +84 -0
- package/dist/runtime/context/worldItems.d.ts +21 -0
- package/dist/runtime/context/worldItems.js +37 -0
- package/dist/runtime/descriptors/baseline.d.ts +48 -0
- package/dist/runtime/descriptors/baseline.js +134 -0
- package/dist/runtime/descriptors/features.d.ts +74 -0
- package/dist/runtime/descriptors/features.js +281 -0
- package/dist/runtime/gameContext.d.ts +114 -13
- package/dist/runtime/gameContext.js +303 -395
- package/dist/runtime/gameRuntime.d.ts +1 -0
- package/dist/runtime/gameRuntime.js +1 -0
- package/dist/runtime/headlessRunner.d.ts +60 -0
- package/dist/runtime/headlessRunner.js +44 -0
- package/dist/runtime/hostPersistence.d.ts +12 -0
- package/dist/runtime/hostPersistence.js +12 -0
- package/dist/runtime/hostedGameRunner.d.ts +8 -3
- package/dist/runtime/hostedGameRunner.js +26 -3
- package/dist/runtime/hostedWorldSession.d.ts +12 -4
- package/dist/runtime/hostedWorldSession.js +11 -4
- package/dist/runtime/inputSnapshot.d.ts +8 -3
- package/dist/runtime/inputSnapshot.js +6 -2
- package/dist/runtime/motionIntents.d.ts +11 -2
- package/dist/runtime/motionIntents.js +16 -2
- package/dist/runtime/perContext.d.ts +15 -0
- package/dist/runtime/perContext.js +21 -0
- package/dist/runtime/runtimeSave.d.ts +79 -0
- package/dist/runtime/runtimeSave.js +105 -0
- package/dist/runtime/save.d.ts +4 -0
- package/dist/runtime/save.js +4 -0
- package/dist/runtime/snapshot.d.ts +7 -0
- package/dist/runtime/snapshot.js +7 -0
- package/dist/runtime/visibility.d.ts +2 -1
- package/dist/runtime/visibility.js +2 -1
- package/dist/runtime/worldChannel.d.ts +7 -3
- package/dist/runtime/worldChannel.js +51 -6
- package/dist/runtime/worldMirror.d.ts +14 -2
- package/dist/runtime/worldMirror.js +15 -2
- package/dist/runtime/worldProjection.d.ts +47 -0
- package/dist/runtime/worldProjection.js +52 -0
- package/dist/runtime/worldReplication.d.ts +30 -7
- package/dist/runtime/worldReplication.js +41 -9
- package/dist/runtime/worldSnapshot.d.ts +30 -3
- package/dist/runtime/worldSnapshot.js +20 -5
- package/dist/scene/assetCatalog.d.ts +21 -0
- package/dist/scene/assetCatalog.js +4 -0
- package/dist/scene/assetDiagnostics.d.ts +69 -0
- package/dist/scene/assetDiagnostics.js +110 -0
- package/dist/scene/assetGenerator.d.ts +65 -0
- package/dist/scene/assetGenerator.js +64 -0
- package/dist/scene/assetSpace.d.ts +137 -0
- package/dist/scene/assetSpace.js +259 -0
- package/dist/scene/authoredTriggers.d.ts +169 -0
- package/dist/scene/authoredTriggers.js +340 -0
- package/dist/scene/behaviorRuntime.d.ts +75 -0
- package/dist/scene/behaviorRuntime.js +217 -0
- package/dist/scene/behaviors.d.ts +14 -2
- package/dist/scene/behaviors.js +7 -2
- package/dist/scene/bodyBind.d.ts +60 -0
- package/dist/scene/bodyBind.js +51 -0
- package/dist/scene/builtinSceneKinds.d.ts +5 -0
- package/dist/scene/builtinSceneKinds.js +62 -0
- package/dist/scene/colliders.d.ts +13 -1
- package/dist/scene/colliders.js +37 -1
- package/dist/scene/entityStats.d.ts +11 -2
- package/dist/scene/entityStats.js +11 -2
- package/dist/scene/entityStore.d.ts +12 -1
- package/dist/scene/entityStore.js +15 -0
- package/dist/scene/facing.d.ts +18 -0
- package/dist/scene/facing.js +26 -0
- package/dist/scene/modelSockets.d.ts +33 -0
- package/dist/scene/modelSockets.js +29 -0
- package/dist/scene/objectQuery.d.ts +2 -0
- package/dist/scene/objectQuery.js +2 -0
- package/dist/scene/objectStore.d.ts +4 -0
- package/dist/scene/objectStore.js +6 -0
- package/dist/scene/possession.d.ts +8 -0
- package/dist/scene/possession.js +14 -0
- package/dist/scene/roster.d.ts +3 -0
- package/dist/scene/roster.js +12 -0
- package/dist/scene/sceneKinds.d.ts +240 -0
- package/dist/scene/sceneKinds.js +214 -0
- package/dist/scene/sceneOwnership.d.ts +169 -0
- package/dist/scene/sceneOwnership.js +179 -0
- package/dist/scene/selectionBookmarks.d.ts +93 -0
- package/dist/scene/selectionBookmarks.js +122 -0
- package/dist/scene/vehicleSeat.d.ts +68 -0
- package/dist/scene/vehicleSeat.js +59 -0
- package/dist/sensor/concealment.d.ts +3 -0
- package/dist/sensor/concealment.js +3 -0
- package/dist/sensor/freezeMonitor.d.ts +1 -0
- package/dist/sensor/freezeMonitor.js +1 -0
- package/dist/sensor/frustumSensor.d.ts +7 -3
- package/dist/sensor/frustumSensor.js +7 -3
- package/dist/sensor/hiddenStateProbe.d.ts +5 -2
- package/dist/sensor/hiddenStateProbe.js +5 -2
- package/dist/sensor/recordingBuffer.d.ts +2 -1
- package/dist/sensor/recordingBuffer.js +2 -1
- package/dist/sensor/replayLoop.d.ts +6 -2
- package/dist/sensor/replayLoop.js +6 -2
- package/dist/sensor/revealQuery.d.ts +2 -1
- package/dist/sensor/revealQuery.js +2 -1
- package/dist/sensor/visionCone.d.ts +10 -3
- package/dist/sensor/visionCone.js +10 -3
- package/dist/session/contestedChannel.d.ts +1 -0
- package/dist/session/contestedChannel.js +1 -0
- package/dist/session/extraction.d.ts +1 -0
- package/dist/session/extraction.js +1 -0
- package/dist/session/roles.d.ts +6 -0
- package/dist/session/roles.js +6 -0
- package/dist/session/roundState.d.ts +8 -0
- package/dist/session/roundState.js +2 -0
- package/dist/settings/settingsModel.d.ts +1 -0
- package/dist/settings/settingsModel.js +1 -0
- package/dist/stats/accumulatorMeter.d.ts +6 -0
- package/dist/stats/accumulatorMeter.js +6 -0
- package/dist/stats/eventMeter.d.ts +5 -0
- package/dist/stats/eventMeter.js +5 -0
- package/dist/stats/rollCheck.d.ts +5 -0
- package/dist/stats/rollCheck.js +5 -0
- package/dist/stats/statModifiers.d.ts +5 -0
- package/dist/stats/statModifiers.js +5 -0
- package/dist/store/defineKeyedStore.d.ts +38 -0
- package/dist/store/defineKeyedStore.js +42 -0
- package/dist/store/defineStore.d.ts +33 -0
- package/dist/store/defineStore.js +35 -0
- package/dist/store/observableKeyedStore.d.ts +5 -0
- package/dist/store/observableKeyedStore.js +34 -2
- package/dist/survival/decayMeter.d.ts +55 -0
- package/dist/survival/decayMeter.js +130 -55
- package/dist/survival/moodle.d.ts +2 -0
- package/dist/survival/regionHealth.d.ts +6 -0
- package/dist/survival/regionHealth.js +5 -0
- package/dist/tactics/fallingGrid.d.ts +4 -2
- package/dist/tactics/fallingGrid.js +4 -2
- package/dist/tactics/predictiveQuery.d.ts +3 -0
- package/dist/tactics/predictiveQuery.js +3 -0
- package/dist/tactics/snapshot.d.ts +2 -0
- package/dist/tactics/snapshot.js +2 -0
- package/dist/tactics/surface.d.ts +1 -0
- package/dist/tactics/surface.js +1 -0
- package/dist/tactics/tacticalGrid.d.ts +1 -0
- package/dist/tactics/tacticalGrid.js +1 -0
- package/dist/time/beatClock.d.ts +14 -4
- package/dist/time/beatClock.js +14 -4
- package/dist/time/calendarClock.d.ts +3 -0
- package/dist/time/calendarClock.js +3 -0
- package/dist/time/idleProgress.d.ts +4 -0
- package/dist/time/idleProgress.js +4 -0
- package/dist/time/simClock.d.ts +2 -0
- package/dist/time/simClock.js +20 -5
- package/dist/ui/actionModel.d.ts +110 -0
- package/dist/ui/actionModel.js +159 -0
- package/dist/ui/gameLayout.d.ts +30 -11
- package/dist/ui/gameLayout.js +30 -11
- package/dist/ui/hudDocument.d.ts +114 -0
- package/dist/ui/hudDocument.js +220 -0
- package/dist/ui/hudLayout.d.ts +33 -1
- package/dist/ui/hudLayout.js +204 -17
- package/dist/ui/selectionModel.d.ts +92 -0
- package/dist/ui/selectionModel.js +88 -0
- package/dist/ui/tooltipModel.d.ts +63 -0
- package/dist/ui/tooltipModel.js +82 -0
- package/dist/ui.d.ts +15 -0
- package/dist/ui.js +15 -0
- package/dist/visibility/bounds.d.ts +8 -1
- package/dist/visibility/bounds.js +8 -1
- package/dist/visibility/frustum.d.ts +12 -3
- package/dist/visibility/frustum.js +12 -3
- package/dist/work/jobQueue.d.ts +201 -0
- package/dist/work/jobQueue.js +253 -0
- package/dist/work/unitTraining.d.ts +58 -0
- package/dist/work/unitTraining.js +52 -0
- package/dist/world/authoredObjects.d.ts +58 -0
- package/dist/world/authoredObjects.js +69 -0
- package/dist/world/buildingGenerator.d.ts +18 -0
- package/dist/world/buildingGenerator.js +62 -0
- package/dist/world/buildings.d.ts +5 -0
- package/dist/world/buildings.js +5 -0
- package/dist/world/catenary.d.ts +22 -0
- package/dist/world/catenary.js +69 -0
- package/dist/world/features.d.ts +115 -7
- package/dist/world/features.js +56 -5
- package/dist/world/footprintGrid.d.ts +59 -0
- package/dist/world/footprintGrid.js +141 -0
- package/dist/world/geometry.d.ts +64 -0
- package/dist/world/geometry.js +94 -0
- package/dist/world/grassKind.d.ts +51 -0
- package/dist/world/grassKind.js +101 -0
- package/dist/world/pathInstances.d.ts +27 -0
- package/dist/world/pathInstances.js +27 -0
- package/dist/world/pathTerrain.d.ts +80 -0
- package/dist/world/pathTerrain.js +142 -0
- package/dist/world/placeAsset.d.ts +81 -0
- package/dist/world/placeAsset.js +77 -0
- package/dist/world/placement.d.ts +4 -0
- package/dist/world/placement.js +4 -0
- package/dist/world/placementController.d.ts +6 -0
- package/dist/world/placementController.js +6 -0
- package/dist/world/polyline.d.ts +34 -0
- package/dist/world/polyline.js +81 -0
- package/dist/world/roads.d.ts +8 -0
- package/dist/world/roads.js +38 -0
- package/dist/world/scatterRegion.d.ts +164 -0
- package/dist/world/scatterRegion.js +409 -0
- package/dist/world/sceneShapes.d.ts +43 -0
- package/dist/world/sceneShapes.js +1 -0
- package/dist/world/segment.d.ts +27 -0
- package/dist/world/segment.js +43 -0
- package/dist/world/soilKind.d.ts +48 -0
- package/dist/world/soilKind.js +92 -0
- package/dist/world/spatialSample.d.ts +241 -0
- package/dist/world/spatialSample.js +465 -0
- package/dist/world/terraform.d.ts +213 -1
- package/dist/world/terraform.js +655 -20
- package/dist/world/terrain.d.ts +119 -20
- package/dist/world/terrain.js +247 -41
- package/dist/world/terrainGuides.d.ts +182 -0
- package/dist/world/terrainGuides.js +343 -0
- package/dist/world/vec2.d.ts +81 -0
- package/dist/world/vec2.js +128 -0
- package/dist/world/vec3.d.ts +49 -0
- package/dist/world/vec3.js +76 -0
- package/dist/world/vegetation.d.ts +71 -0
- package/dist/world/vegetation.js +151 -0
- package/dist/world/visibilityField.d.ts +154 -0
- package/dist/world/visibilityField.js +271 -0
- package/dist/world/volumetricClouds.d.ts +52 -0
- package/dist/world/volumetricClouds.js +43 -0
- package/dist/world/walls.d.ts +9 -0
- package/dist/world/walls.js +9 -0
- package/dist/world/waterKind.d.ts +55 -0
- package/dist/world/waterKind.js +99 -0
- package/dist/world.d.ts +132 -0
- package/dist/world.js +132 -0
- package/package.json +32 -8
- package/skills/jgengine/SKILL.md +51 -0
- package/skills/jgengine/api.md +434 -0
- package/skills/jgengine/capabilities.md +29 -0
- package/skills/jgengine/reference-cartridge.md +72 -0
- package/skills/jgengine-combat/SKILL.md +34 -0
- package/skills/jgengine-combat/api.md +549 -0
- package/skills/jgengine-combat/capabilities.md +169 -0
- package/skills/jgengine-combat/reference.md +98 -0
- package/skills/jgengine-gameplay/SKILL.md +39 -0
- package/skills/jgengine-gameplay/api.md +1794 -0
- package/skills/jgengine-gameplay/capabilities.md +378 -0
- package/skills/jgengine-gameplay/reference-systems.md +60 -0
- package/skills/jgengine-world/SKILL.md +38 -0
- package/skills/jgengine-world/api.md +2652 -0
- package/skills/jgengine-world/capabilities.md +370 -0
- package/skills/jgengine-world/reference.md +222 -0
- package/dist/cartridge/runtime.d.ts +0 -15
- package/dist/cartridge/runtime.js +0 -556
- package/dist/cartridge/spec.d.ts +0 -188
- package/dist/cartridge/spec.js +0 -19
- package/dist/cartridge/validate.d.ts +0 -2
- package/dist/cartridge/validate.js +0 -78
- package/dist/store/engineStore.d.ts +0 -22
- package/dist/store/engineStore.js +0 -50
- package/dist/store/features.d.ts +0 -10
- package/dist/store/features.js +0 -23
- package/llms.txt +0 -5389
package/dist/world/terrain.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { withPathProfiles } from "./pathTerrain.js";
|
|
1
2
|
import { nearestOnPath } from "./roads.js";
|
|
2
3
|
function clamp01(value) {
|
|
3
4
|
return value < 0 ? 0 : value > 1 ? 1 : value;
|
|
@@ -14,7 +15,9 @@ function hash2(ix, iz, seed) {
|
|
|
14
15
|
h ^= h >>> 12;
|
|
15
16
|
return (h >>> 0) / 4294967295;
|
|
16
17
|
}
|
|
17
|
-
/** Smoothly interpolated 2D value noise in `[-1, 1]` for the given seed.
|
|
18
|
+
/** Smoothly interpolated 2D value noise in `[-1, 1]` for the given seed.
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
18
21
|
export function valueNoise(x, z, seed) {
|
|
19
22
|
const x0 = Math.floor(x);
|
|
20
23
|
const z0 = Math.floor(z);
|
|
@@ -30,7 +33,9 @@ export function valueNoise(x, z, seed) {
|
|
|
30
33
|
const bottom = lerp(v01, v11, sx);
|
|
31
34
|
return lerp(top, bottom, sz) * 2 - 1;
|
|
32
35
|
}
|
|
33
|
-
/** Layers `valueNoise` octaves per `config` into a single normalized noise sample.
|
|
36
|
+
/** Layers `valueNoise` octaves per `config` into a single normalized noise sample.
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
34
39
|
export function fractalNoise(x, z, config) {
|
|
35
40
|
let amplitude = 1;
|
|
36
41
|
let frequency = config.frequency;
|
|
@@ -47,6 +52,7 @@ export function fractalNoise(x, z, config) {
|
|
|
47
52
|
}
|
|
48
53
|
return norm === 0 ? 0 : sum / norm;
|
|
49
54
|
}
|
|
55
|
+
/** @internal */
|
|
50
56
|
export function seedFrom(value, fallback) {
|
|
51
57
|
if (typeof value === "number")
|
|
52
58
|
return value | 0;
|
|
@@ -60,7 +66,9 @@ export function seedFrom(value, fallback) {
|
|
|
60
66
|
}
|
|
61
67
|
return fallback;
|
|
62
68
|
}
|
|
63
|
-
/** Derives a `TerrainField.sampleNormal` from a height sampler via finite-difference gradients.
|
|
69
|
+
/** Derives a `TerrainField.sampleNormal` from a height sampler via finite-difference gradients.
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
64
72
|
export function withNormal(sampleHeight) {
|
|
65
73
|
const epsilon = 0.75;
|
|
66
74
|
return (x, z) => {
|
|
@@ -85,11 +93,15 @@ export const FLAT_FIELD = {
|
|
|
85
93
|
sampleHeight: () => 0,
|
|
86
94
|
sampleNormal: () => [0, 1, 0],
|
|
87
95
|
};
|
|
88
|
-
/** A flat, zero-height `TerrainField` for arenas with no elevation.
|
|
96
|
+
/** A flat, zero-height `TerrainField` for arenas with no elevation.
|
|
97
|
+
* @internal
|
|
98
|
+
*/
|
|
89
99
|
export function flatField() {
|
|
90
100
|
return FLAT_FIELD;
|
|
91
101
|
}
|
|
92
|
-
/** Builds a `TerrainField` whose height is fractal noise shaped by `config`.
|
|
102
|
+
/** Builds a `TerrainField` whose height is fractal noise shaped by `config`.
|
|
103
|
+
* @internal
|
|
104
|
+
*/
|
|
93
105
|
export function noiseField(config = {}) {
|
|
94
106
|
const fractal = {
|
|
95
107
|
seed: seedFrom(config.seed, 1337),
|
|
@@ -106,6 +118,7 @@ export function noiseField(config = {}) {
|
|
|
106
118
|
waterLevel: config.waterLevel,
|
|
107
119
|
});
|
|
108
120
|
}
|
|
121
|
+
/** @internal */
|
|
109
122
|
export function rollingField(config = {}) {
|
|
110
123
|
return noiseField({
|
|
111
124
|
seed: config.seed ?? "rolling",
|
|
@@ -126,7 +139,9 @@ function smoothstep(edge0, edge1, value) {
|
|
|
126
139
|
const t = clamp01((value - edge0) / (edge1 - edge0));
|
|
127
140
|
return t * t * (3 - 2 * t);
|
|
128
141
|
}
|
|
129
|
-
/** Builds a `TerrainField` with a flat spawn plateau, rolling hills, and a basin, for combat arenas.
|
|
142
|
+
/** Builds a `TerrainField` with a flat spawn plateau, rolling hills, and a basin, for combat arenas.
|
|
143
|
+
* @internal
|
|
144
|
+
*/
|
|
130
145
|
export function arenaField(config = {}) {
|
|
131
146
|
const seed = seedFrom(config.seed ?? "arena", 7);
|
|
132
147
|
const rolling = {
|
|
@@ -155,12 +170,15 @@ export function arenaField(config = {}) {
|
|
|
155
170
|
};
|
|
156
171
|
return fieldFromHeight(sampleHeight, { bounds: config.bounds, waterLevel: ARENA_WATER_LEVEL });
|
|
157
172
|
}
|
|
173
|
+
/** @internal */
|
|
158
174
|
export function groundFieldFor(world) {
|
|
159
175
|
if (world !== undefined && world.kind === "environment")
|
|
160
176
|
return resolveEnvironmentField(world);
|
|
161
177
|
return flatField();
|
|
162
178
|
}
|
|
163
|
-
/** Whether a world declares real terrain (base heightfield or islands) rather than a flat plane — gates terrain-floor sampling in the movement controllers.
|
|
179
|
+
/** Whether a world declares real terrain (base heightfield or islands) rather than a flat plane — gates terrain-floor sampling in the movement controllers.
|
|
180
|
+
* @internal
|
|
181
|
+
*/
|
|
164
182
|
export function hasEnvironmentTerrain(world) {
|
|
165
183
|
return world?.kind === "environment" && (world.terrain !== undefined || (world.islands?.length ?? 0) > 0);
|
|
166
184
|
}
|
|
@@ -174,7 +192,8 @@ function islandContains(descriptor, x, z) {
|
|
|
174
192
|
* Composes a base terrain and any number of bounded islands into one world field: inside an island's
|
|
175
193
|
* rect the island's own field (sampled in island-local coordinates) wins, elsewhere the base terrain
|
|
176
194
|
* answers, and with no base the gap is `ISLAND_VOID_HEIGHT` void. Later islands win overlaps.
|
|
177
|
-
|
|
195
|
+
* @internal
|
|
196
|
+
*/
|
|
178
197
|
export function composeIslandFields(base, islands, voidHeight = ISLAND_VOID_HEIGHT) {
|
|
179
198
|
if (islands.length === 0)
|
|
180
199
|
return base ?? flatField();
|
|
@@ -209,14 +228,95 @@ export function composeIslandFields(base, islands, voidHeight = ISLAND_VOID_HEIG
|
|
|
209
228
|
...(base?.waterLevel === undefined ? {} : { waterLevel: base.waterLevel }),
|
|
210
229
|
};
|
|
211
230
|
}
|
|
212
|
-
/**
|
|
231
|
+
/** Bilinear offset sampled from an editor {@link TerraformSnapshot}'s vertex grid at a world point. */
|
|
232
|
+
function sampleSnapshotOffset(snapshot, x, z) {
|
|
233
|
+
const { bounds, cols, rows, offsets } = snapshot;
|
|
234
|
+
const vertsX = cols + 1;
|
|
235
|
+
const spanX = Math.max(bounds.maxX - bounds.minX, snapshot.cellSize);
|
|
236
|
+
const spanZ = Math.max(bounds.maxZ - bounds.minZ, snapshot.cellSize);
|
|
237
|
+
const fx = clamp01((x - bounds.minX) / spanX) * cols;
|
|
238
|
+
const fz = clamp01((z - bounds.minZ) / spanZ) * rows;
|
|
239
|
+
const x0 = Math.min(cols, Math.floor(fx));
|
|
240
|
+
const z0 = Math.min(rows, Math.floor(fz));
|
|
241
|
+
const x1 = Math.min(cols, x0 + 1);
|
|
242
|
+
const z1 = Math.min(rows, z0 + 1);
|
|
243
|
+
const tx = fx - x0;
|
|
244
|
+
const tz = fz - z0;
|
|
245
|
+
const v00 = offsets[z0 * vertsX + x0] ?? 0;
|
|
246
|
+
const v10 = offsets[z0 * vertsX + x1] ?? 0;
|
|
247
|
+
const v01 = offsets[z1 * vertsX + x0] ?? 0;
|
|
248
|
+
const v11 = offsets[z1 * vertsX + x1] ?? 0;
|
|
249
|
+
const top = v00 + (v10 - v00) * tx;
|
|
250
|
+
const bottom = v01 + (v11 - v01) * tx;
|
|
251
|
+
return top + (bottom - top) * tz;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Layers an authored sculpt snapshot's offsets over a base field — the editor-to-runtime ground seam.
|
|
255
|
+
* @internal — reached through `environment({ sculpt })`; not called directly by games.
|
|
256
|
+
*/
|
|
257
|
+
export function sculptedField(base, snapshot) {
|
|
258
|
+
const sampleHeight = (x, z) => base.sampleHeight(x, z) + sampleSnapshotOffset(snapshot, x, z);
|
|
259
|
+
return {
|
|
260
|
+
sampleHeight,
|
|
261
|
+
sampleNormal: withNormal(sampleHeight),
|
|
262
|
+
...(base.bounds === undefined ? {} : { bounds: base.bounds }),
|
|
263
|
+
...(base.waterLevel === undefined ? {} : { waterLevel: base.waterLevel }),
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Levels a base field toward each clearance zone's center height within its radius (feathered) — so
|
|
268
|
+
* spawns, plots, and paths sit on flat ground even when a mound is nearby. The strongest overlapping
|
|
269
|
+
* zone wins. Pairs with scatter's avoid: one clearance zone both flattens ground and repels foliage.
|
|
270
|
+
* @internal — reached through `environment({ clearings })`; not called directly by games.
|
|
271
|
+
*/
|
|
272
|
+
export function flattenFieldAround(base, zones) {
|
|
273
|
+
if (zones.length === 0)
|
|
274
|
+
return base;
|
|
275
|
+
const sampleHeight = (x, z) => {
|
|
276
|
+
let best = 0;
|
|
277
|
+
let target = 0;
|
|
278
|
+
for (const zone of zones) {
|
|
279
|
+
const dist = Math.hypot(x - zone.x, z - zone.z);
|
|
280
|
+
if (dist >= zone.radius)
|
|
281
|
+
continue;
|
|
282
|
+
const feather = Math.max(0, zone.feather ?? 0);
|
|
283
|
+
const inner = zone.radius - feather;
|
|
284
|
+
const t = dist <= inner || feather <= 0 ? 1 : (zone.radius - dist) / feather;
|
|
285
|
+
if (t > best) {
|
|
286
|
+
best = t;
|
|
287
|
+
target = base.sampleHeight(zone.x, zone.z);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
const height = base.sampleHeight(x, z);
|
|
291
|
+
return best > 0 ? height + (target - height) * best : height;
|
|
292
|
+
};
|
|
293
|
+
return {
|
|
294
|
+
sampleHeight,
|
|
295
|
+
sampleNormal: withNormal(sampleHeight),
|
|
296
|
+
...(base.bounds === undefined ? {} : { bounds: base.bounds }),
|
|
297
|
+
...(base.waterLevel === undefined ? {} : { waterLevel: base.waterLevel }),
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* The full ground field for an environment world: base `terrain` composed with any `islands`, then
|
|
302
|
+
* any authored `sculpt` snapshot, then any `clearings` flattened on top — so an editor-sculpted
|
|
303
|
+
* heightfield drives both the rendered mesh and player collision, and gameplay spots stay level,
|
|
304
|
+
* through the one seam every consumer already reads.
|
|
305
|
+
* @internal
|
|
306
|
+
*/
|
|
213
307
|
export function resolveEnvironmentField(feature) {
|
|
214
308
|
const base = feature.terrain === undefined ? null : resolveTerrainField(feature.terrain);
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
309
|
+
const composed = feature.islands === undefined || feature.islands.length === 0
|
|
310
|
+
? base ?? flatField()
|
|
311
|
+
: composeIslandFields(base, feature.islands);
|
|
312
|
+
const sculpted = feature.sculpt === undefined ? composed : sculptedField(composed, feature.sculpt);
|
|
313
|
+
return feature.clearings === undefined || feature.clearings.length === 0
|
|
314
|
+
? sculpted
|
|
315
|
+
: flattenFieldAround(sculpted, feature.clearings);
|
|
316
|
+
}
|
|
317
|
+
/** Local slope from the field's normal — the input for gravity-roll, ski acceleration, and slide checks (#284.6).
|
|
318
|
+
* @internal
|
|
319
|
+
*/
|
|
220
320
|
export function sampleSlope(field, x, z) {
|
|
221
321
|
const [nx, ny, nz] = field.sampleNormal(x, z);
|
|
222
322
|
const horizontal = Math.hypot(nx, nz);
|
|
@@ -230,7 +330,8 @@ export function sampleSlope(field, x, z) {
|
|
|
230
330
|
/**
|
|
231
331
|
* Downhill force/acceleration from the local slope: direction × sin(slope angle) × `scale`.
|
|
232
332
|
* Add it to any integrator's XZ velocity each tick (`scale` ≈ gravity for a free-rolling body).
|
|
233
|
-
|
|
333
|
+
* @internal
|
|
334
|
+
*/
|
|
234
335
|
export function slopeForce(field, x, z, scale = 9.8) {
|
|
235
336
|
const [nx, , nz] = field.sampleNormal(x, z);
|
|
236
337
|
if (Math.hypot(nx, nz) < 1e-9)
|
|
@@ -258,7 +359,11 @@ const DEFAULT_TERRAIN_DETAIL = {
|
|
|
258
359
|
roughness: 0.9,
|
|
259
360
|
strength: 1,
|
|
260
361
|
};
|
|
261
|
-
|
|
362
|
+
const DEFAULT_TERRAIN_MATERIAL_REPEAT = 4;
|
|
363
|
+
const DEFAULT_TERRAIN_MATERIAL_STRENGTH = 1;
|
|
364
|
+
/** Fill a `TerrainDetailConfig` with defaults; `waterLevel` falls back to the terrain's own water level.
|
|
365
|
+
* @internal
|
|
366
|
+
*/
|
|
262
367
|
export function resolveTerrainDetail(config, terrainWaterLevel = 0) {
|
|
263
368
|
return {
|
|
264
369
|
rockColor: config.rockColor ?? DEFAULT_TERRAIN_DETAIL.rockColor,
|
|
@@ -269,10 +374,20 @@ export function resolveTerrainDetail(config, terrainWaterLevel = 0) {
|
|
|
269
374
|
detailScale: config.detailScale ?? DEFAULT_TERRAIN_DETAIL.detailScale,
|
|
270
375
|
macroScale: config.macroScale ?? DEFAULT_TERRAIN_DETAIL.macroScale,
|
|
271
376
|
roughness: config.roughness ?? DEFAULT_TERRAIN_DETAIL.roughness,
|
|
272
|
-
strength: config.strength ?? DEFAULT_TERRAIN_DETAIL.strength,
|
|
377
|
+
strength: clamp01(config.strength ?? DEFAULT_TERRAIN_DETAIL.strength),
|
|
273
378
|
waterLevel: config.waterLevel ?? terrainWaterLevel,
|
|
379
|
+
...(config.material === undefined
|
|
380
|
+
? {}
|
|
381
|
+
: {
|
|
382
|
+
material: {
|
|
383
|
+
maps: config.material.maps,
|
|
384
|
+
repeat: config.material.repeat ?? DEFAULT_TERRAIN_MATERIAL_REPEAT,
|
|
385
|
+
strength: clamp01(config.material.strength ?? DEFAULT_TERRAIN_MATERIAL_STRENGTH),
|
|
386
|
+
},
|
|
387
|
+
}),
|
|
274
388
|
};
|
|
275
389
|
}
|
|
390
|
+
/** @internal */
|
|
276
391
|
export function resolveTerrainPalette(descriptor = {}) {
|
|
277
392
|
const material = descriptor.material ?? DEFAULT_TERRAIN_MATERIAL;
|
|
278
393
|
const preset = TERRAIN_MATERIAL_PALETTES[material];
|
|
@@ -314,25 +429,19 @@ function mixPalette(from, to, t) {
|
|
|
314
429
|
waterline: mixHex(from.waterline, to.waterline, t),
|
|
315
430
|
};
|
|
316
431
|
}
|
|
317
|
-
|
|
318
|
-
* Per-z palette sampler over a descriptor's `biomeBands` — ordered zones that cross-fade their
|
|
319
|
-
* ground palette across a `fade`-wide window centered on the midpoint z between adjacent centers.
|
|
320
|
-
* Below the first / above the last band clamps to that band's palette. Returns `fallback` when no
|
|
321
|
-
* bands are declared. Pure math, unit-testable independent of rendering.
|
|
322
|
-
*/
|
|
323
|
-
export function createBiomeBandSampler(bands, fallback) {
|
|
432
|
+
function createBandValueSampler(bands, fallback, resolve, mix) {
|
|
324
433
|
if (bands.length === 0)
|
|
325
434
|
return () => fallback;
|
|
326
435
|
const resolved = bands
|
|
327
|
-
.map((band) => ({ z: band.z, fade: band.fade ?? 64,
|
|
436
|
+
.map((band) => ({ z: band.z, fade: band.fade ?? 64, value: resolve(band) }))
|
|
328
437
|
.sort((a, b) => a.z - b.z);
|
|
329
438
|
const first = resolved[0];
|
|
330
439
|
const last = resolved[resolved.length - 1];
|
|
331
440
|
return (z) => {
|
|
332
441
|
if (z <= first.z)
|
|
333
|
-
return first.
|
|
442
|
+
return first.value;
|
|
334
443
|
if (z >= last.z)
|
|
335
|
-
return last.
|
|
444
|
+
return last.value;
|
|
336
445
|
for (let i = 0; i < resolved.length - 1; i += 1) {
|
|
337
446
|
const lower = resolved[i];
|
|
338
447
|
const upper = resolved[i + 1];
|
|
@@ -341,19 +450,86 @@ export function createBiomeBandSampler(bands, fallback) {
|
|
|
341
450
|
const boundary = (lower.z + upper.z) / 2;
|
|
342
451
|
const half = Math.min(lower.fade, upper.fade) / 2;
|
|
343
452
|
if (z <= boundary - half)
|
|
344
|
-
return lower.
|
|
453
|
+
return lower.value;
|
|
345
454
|
if (z >= boundary + half)
|
|
346
|
-
return upper.
|
|
347
|
-
return
|
|
455
|
+
return upper.value;
|
|
456
|
+
return mix(lower.value, upper.value, smoothstep(boundary - half, boundary + half, z));
|
|
348
457
|
}
|
|
349
458
|
return fallback;
|
|
350
459
|
};
|
|
351
460
|
}
|
|
461
|
+
/**
|
|
462
|
+
* Per-z palette sampler over a descriptor's `biomeBands` — ordered zones that cross-fade their
|
|
463
|
+
* ground palette across a `fade`-wide window centered on the midpoint z between adjacent centers.
|
|
464
|
+
* Below the first / above the last band clamps to that band's palette. Returns `fallback` when no
|
|
465
|
+
* bands are declared. Pure math, unit-testable independent of rendering.
|
|
466
|
+
* @internal
|
|
467
|
+
*/
|
|
468
|
+
export function createBiomeBandSampler(bands, fallback) {
|
|
469
|
+
return createBandValueSampler(bands, fallback, resolveTerrainPalette, mixPalette);
|
|
470
|
+
}
|
|
471
|
+
function mixBiomeFog(from, to, t) {
|
|
472
|
+
if (t <= 0)
|
|
473
|
+
return from;
|
|
474
|
+
if (t >= 1)
|
|
475
|
+
return to;
|
|
476
|
+
return {
|
|
477
|
+
color: mixHex(from.color, to.color, t),
|
|
478
|
+
near: lerp(from.near, to.near, t),
|
|
479
|
+
far: lerp(from.far, to.far, t),
|
|
480
|
+
density: lerp(from.density, to.density, t),
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Per-z fog sampler over a descriptor's `biomeBands` — cross-fades each band's `fog` (unset fields
|
|
485
|
+
* falling through to `fallback`) across the same `fade` window as the ground sampler, so fog color and
|
|
486
|
+
* range track the camera's z. Bands with no `fog` resolve to `fallback`. Pure math, unit-testable.
|
|
487
|
+
* @internal
|
|
488
|
+
*/
|
|
489
|
+
export function createBiomeFogSampler(bands, fallback) {
|
|
490
|
+
return createBandValueSampler(bands, fallback, (band) => band.fog === undefined
|
|
491
|
+
? fallback
|
|
492
|
+
: {
|
|
493
|
+
color: band.fog.color ?? fallback.color,
|
|
494
|
+
near: band.fog.near ?? fallback.near,
|
|
495
|
+
far: band.fog.far ?? fallback.far,
|
|
496
|
+
density: band.fog.density ?? fallback.density,
|
|
497
|
+
}, mixBiomeFog);
|
|
498
|
+
}
|
|
499
|
+
function mixBiomeSky(from, to, t) {
|
|
500
|
+
if (t <= 0)
|
|
501
|
+
return from;
|
|
502
|
+
if (t >= 1)
|
|
503
|
+
return to;
|
|
504
|
+
return {
|
|
505
|
+
horizonColor: mixHex(from.horizonColor, to.horizonColor, t),
|
|
506
|
+
zenithColor: mixHex(from.zenithColor, to.zenithColor, t),
|
|
507
|
+
sunIntensity: lerp(from.sunIntensity, to.sunIntensity, t),
|
|
508
|
+
ambientIntensity: lerp(from.ambientIntensity, to.ambientIntensity, t),
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Per-z sky sampler over a descriptor's `biomeBands` — cross-fades each band's `sky` (unset fields
|
|
513
|
+
* falling through to `fallback`) across the same `fade` window as the ground sampler, so horizon/zenith
|
|
514
|
+
* colors and sun/ambient intensity track the camera's z. Bands with no `sky` resolve to `fallback`.
|
|
515
|
+
* @internal
|
|
516
|
+
*/
|
|
517
|
+
export function createBiomeSkySampler(bands, fallback) {
|
|
518
|
+
return createBandValueSampler(bands, fallback, (band) => band.sky === undefined
|
|
519
|
+
? fallback
|
|
520
|
+
: {
|
|
521
|
+
horizonColor: band.sky.horizonColor ?? fallback.horizonColor,
|
|
522
|
+
zenithColor: band.sky.zenithColor ?? fallback.zenithColor,
|
|
523
|
+
sunIntensity: band.sky.sunIntensity ?? fallback.sunIntensity,
|
|
524
|
+
ambientIntensity: band.sky.ambientIntensity ?? fallback.ambientIntensity,
|
|
525
|
+
}, mixBiomeSky);
|
|
526
|
+
}
|
|
352
527
|
/**
|
|
353
528
|
* Per-position palette sampler over the descriptor's base `material`/`colors` plus its z-ordered
|
|
354
529
|
* `biomeBands` (painted first) and radial `materialRegions` (painted over) — the multi-biome coloring
|
|
355
530
|
* seam. Regions paint fully inside `radius` and blend back across `falloff`; later regions win overlaps.
|
|
356
|
-
|
|
531
|
+
* @internal
|
|
532
|
+
*/
|
|
357
533
|
export function createTerrainPaletteSampler(descriptor) {
|
|
358
534
|
const base = resolveTerrainPalette(descriptor);
|
|
359
535
|
const bandSampler = descriptor.biomeBands === undefined || descriptor.biomeBands.length === 0
|
|
@@ -440,6 +616,7 @@ function withFlattenMasks(sampleHeight, masks) {
|
|
|
440
616
|
return height;
|
|
441
617
|
};
|
|
442
618
|
}
|
|
619
|
+
/** @internal */
|
|
443
620
|
export function heightMapField(config) {
|
|
444
621
|
const { columns, rows, samples } = config;
|
|
445
622
|
if (columns <= 0 || rows <= 0)
|
|
@@ -476,7 +653,9 @@ export function heightMapField(config) {
|
|
|
476
653
|
...(config.waterLevel === undefined ? {} : { waterLevel: config.waterLevel }),
|
|
477
654
|
});
|
|
478
655
|
}
|
|
479
|
-
/** Resolves a `TerrainEnvironmentDescriptor` into a concrete `TerrainField`, applying flatten masks.
|
|
656
|
+
/** Resolves a `TerrainEnvironmentDescriptor` into a concrete `TerrainField`, applying flatten masks.
|
|
657
|
+
* @internal
|
|
658
|
+
*/
|
|
480
659
|
export function resolveTerrainField(descriptor) {
|
|
481
660
|
if (descriptor === undefined)
|
|
482
661
|
return flatField();
|
|
@@ -498,19 +677,44 @@ export function resolveTerrainField(descriptor) {
|
|
|
498
677
|
waterLevel: descriptor.waterLevel,
|
|
499
678
|
bounds: descriptor.bounds,
|
|
500
679
|
});
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
680
|
+
const flattened = descriptor.flatten === undefined || descriptor.flatten.length === 0
|
|
681
|
+
? base
|
|
682
|
+
: fieldFromHeight(withFlattenMasks(base.sampleHeight, descriptor.flatten), {
|
|
683
|
+
bounds: base.bounds,
|
|
684
|
+
waterLevel: base.waterLevel,
|
|
685
|
+
});
|
|
686
|
+
if (descriptor.pathProfiles === undefined || descriptor.pathProfiles.length === 0)
|
|
687
|
+
return flattened;
|
|
688
|
+
return applyPathProfiles(flattened, descriptor.pathProfiles);
|
|
507
689
|
}
|
|
508
|
-
/**
|
|
690
|
+
/**
|
|
691
|
+
* Composes authored path profiles onto a field — the shared seam that turns a scene road/river/ramp path
|
|
692
|
+
* into flattened, graded, carved, or retained ground. Applies after `flatten` masks in `resolveTerrainField`
|
|
693
|
+
* so a corridor grades over already-leveled pads; call it directly to layer profiles onto any field a game
|
|
694
|
+
* builds by hand. Returns the field unchanged when no profile is given.
|
|
695
|
+
* @capability path-terrain apply flatten/grade/carve/retaining path profiles to a terrain field
|
|
696
|
+
*/
|
|
697
|
+
export function applyPathProfiles(field, profiles) {
|
|
698
|
+
if (profiles.length === 0)
|
|
699
|
+
return field;
|
|
700
|
+
const sampleHeight = withPathProfiles((x, z) => field.sampleHeight(x, z), profiles);
|
|
701
|
+
return {
|
|
702
|
+
sampleHeight,
|
|
703
|
+
sampleNormal: withNormal(sampleHeight),
|
|
704
|
+
...(field.bounds === undefined ? {} : { bounds: field.bounds }),
|
|
705
|
+
...(field.waterLevel === undefined ? {} : { waterLevel: field.waterLevel }),
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
/** Returns `position` with `y` replaced by the field's ground height (plus `offset`) at its `x`/`z`.
|
|
709
|
+
* @internal
|
|
710
|
+
*/
|
|
509
711
|
export function snapToGround(field, position, offset = 0) {
|
|
510
712
|
const [x, , z] = position;
|
|
511
713
|
return [x, field.sampleHeight(x, z) + offset, z];
|
|
512
714
|
}
|
|
513
|
-
/** Ground-snaps an already-spawned entity in place; returns false when `id` is unknown.
|
|
715
|
+
/** Ground-snaps an already-spawned entity in place; returns false when `id` is unknown.
|
|
716
|
+
* @internal
|
|
717
|
+
*/
|
|
514
718
|
export function snapEntityToGround(entities, id, field, offset = 0) {
|
|
515
719
|
const entity = entities.get(id);
|
|
516
720
|
if (entity === null)
|
|
@@ -518,7 +722,9 @@ export function snapEntityToGround(entities, id, field, offset = 0) {
|
|
|
518
722
|
return entities.setPose(id, { position: snapToGround(field, entity.position, offset) });
|
|
519
723
|
}
|
|
520
724
|
export const DEFAULT_MAX_WALK_SLOPE = 0.6;
|
|
521
|
-
/** Zeroes out a movement step's x or z component where it would climb steeper than `maxSlope`.
|
|
725
|
+
/** Zeroes out a movement step's x or z component where it would climb steeper than `maxSlope`.
|
|
726
|
+
* @internal
|
|
727
|
+
*/
|
|
522
728
|
export function resolveGroundStep(field, x, z, stepX, stepZ, maxSlope = DEFAULT_MAX_WALK_SLOPE) {
|
|
523
729
|
const baseHeight = field.sampleHeight(x, z);
|
|
524
730
|
const tooSteep = (dx, dz) => {
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import type { TerrainField } from "./terrain.js";
|
|
2
|
+
/** A world-space point on the ground plane as an `[x, z]` pair. */
|
|
3
|
+
export type GroundPoint = readonly [number, number];
|
|
4
|
+
/** A height sampler over the ground: world elevation at any `x`/`z`. */
|
|
5
|
+
export type HeightSampler = (x: number, z: number) => number;
|
|
6
|
+
/** An axis-aligned XZ rectangle to generate terrain-readability guides within. */
|
|
7
|
+
export interface GuideRegion {
|
|
8
|
+
minX: number;
|
|
9
|
+
minZ: number;
|
|
10
|
+
maxX: number;
|
|
11
|
+
maxZ: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A sampled height grid over a region — the shared substrate contour extraction and elevation
|
|
15
|
+
* summaries both read, so a caller can sample once and derive several guides from it.
|
|
16
|
+
* @internal — an intermediate; games call {@link extractContours} / {@link summarizeElevation} directly.
|
|
17
|
+
*/
|
|
18
|
+
export interface HeightGrid {
|
|
19
|
+
region: GuideRegion;
|
|
20
|
+
/** Sample columns and rows (each is `resolution + 1` points across its axis). */
|
|
21
|
+
cols: number;
|
|
22
|
+
rows: number;
|
|
23
|
+
/** Row-major heights, length `cols * rows` (row `r`, column `c` at index `r * cols + c`). */
|
|
24
|
+
heights: Float64Array;
|
|
25
|
+
min: number;
|
|
26
|
+
max: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Samples `sampleHeight` on a `(resolution + 1)²` grid across `region`, capturing the min/max seen —
|
|
30
|
+
* the bounded, budget-capped scan every guide derives from. `resolution` is clamped to `[1, maxSamples]`.
|
|
31
|
+
* @internal — building block behind the public guide generators.
|
|
32
|
+
*/
|
|
33
|
+
export declare function sampleHeightGrid(sampleHeight: HeightSampler, region: GuideRegion, resolution?: number, maxSamples?: number): HeightGrid;
|
|
34
|
+
/** A single iso-elevation contour traced across a region as a flat list of XZ line segments. */
|
|
35
|
+
export interface ContourLine {
|
|
36
|
+
/** The world elevation (`y`) this contour follows. */
|
|
37
|
+
level: number;
|
|
38
|
+
/** Whether this is a major (emphasised) contour rather than a minor one. */
|
|
39
|
+
major: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Flat segment endpoints `[x0, z0, x1, z1, ...]` — every four numbers is one XZ segment. Draw each
|
|
42
|
+
* at `y = level` to drape it on the surface; the contour is exact iso-height so it hugs terrain.
|
|
43
|
+
*/
|
|
44
|
+
segments: readonly number[];
|
|
45
|
+
}
|
|
46
|
+
/** Shaping for {@link extractContours}: region, vertical spacing, emphasis cadence, and sample budget. */
|
|
47
|
+
export interface ContourOptions {
|
|
48
|
+
region: GuideRegion;
|
|
49
|
+
/** Vertical spacing between adjacent contour lines, in world units. Must be `> 0`. */
|
|
50
|
+
interval: number;
|
|
51
|
+
/** Every Nth line (counting from `y = 0`) is a major contour. Default `5`; `<= 1` makes all major. */
|
|
52
|
+
majorEvery?: number;
|
|
53
|
+
/** Samples per axis for the marching-squares grid. Default `128`, clamped to `[1, maxSamples]`. */
|
|
54
|
+
resolution?: number;
|
|
55
|
+
/** Hard per-axis sample cap so extraction stays within an explicit budget. Default `256`. */
|
|
56
|
+
maxSamples?: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Traces surface-following contour lines from a height field via marching squares: samples a bounded
|
|
60
|
+
* grid over the region, then for every multiple of `interval` strictly inside the sampled height range
|
|
61
|
+
* emits the iso-line as XZ segments (saddle cells disambiguated by the cell-center average). Because a
|
|
62
|
+
* contour is exact constant elevation, drawing each segment at `y = level` makes it hug the terrain —
|
|
63
|
+
* the readable, scale-bearing overlay a flat ground grid cannot give. Pure math, renderer-agnostic.
|
|
64
|
+
* @capability terrain-contours iso-elevation contour lines that drape on sculpted terrain
|
|
65
|
+
* @consumer editor terrain-readability overlay; any map/minimap wanting elevation contours
|
|
66
|
+
*/
|
|
67
|
+
export declare function extractContours(sampleHeight: HeightSampler, options: ContourOptions): ContourLine[];
|
|
68
|
+
/**
|
|
69
|
+
* Picks a human-friendly contour interval — a `1/2/2.5/5 × 10ⁿ` step — so an elevation `range` splits
|
|
70
|
+
* into roughly `targetLines` bands. Drives adaptive contour density: a tall terrain gets a coarse
|
|
71
|
+
* interval, a shallow one a fine interval, without the author choosing a number. Returns `0` when the
|
|
72
|
+
* range is non-positive (nothing to contour).
|
|
73
|
+
* @capability contour-interval readable auto-spacing for elevation contours
|
|
74
|
+
* @consumer editor terrain-readability overlay density control
|
|
75
|
+
*/
|
|
76
|
+
export declare function chooseContourInterval(range: number, targetLines?: number): number;
|
|
77
|
+
/** Measurable elevation readout at a single world point — the cursor/hover feedback value. */
|
|
78
|
+
export interface ElevationReadout {
|
|
79
|
+
x: number;
|
|
80
|
+
z: number;
|
|
81
|
+
/** Ground elevation at the point. */
|
|
82
|
+
height: number;
|
|
83
|
+
/** `height - reference` — signed distance above (+) or below (−) the reference plane. */
|
|
84
|
+
delta: number;
|
|
85
|
+
/** The reference-plane height the delta was measured against. */
|
|
86
|
+
reference: number;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Reads the ground elevation under a world point and its signed delta from a reference plane — the
|
|
90
|
+
* measurable cursor/hover feedback ("+3.4 above the pad") an author needs to judge sculpted height.
|
|
91
|
+
* @capability elevation-readout cursor height and delta-from-reference feedback
|
|
92
|
+
* @consumer editor terrain-readability HUD readout
|
|
93
|
+
*/
|
|
94
|
+
export declare function sampleElevation(sampleHeight: HeightSampler, x: number, z: number, reference?: number): ElevationReadout;
|
|
95
|
+
/** Aggregate elevation statistics over a region — the selection min/max/mean and legend range. */
|
|
96
|
+
export interface ElevationSummary {
|
|
97
|
+
min: number;
|
|
98
|
+
max: number;
|
|
99
|
+
mean: number;
|
|
100
|
+
/** `max - min` — the vertical relief across the region. */
|
|
101
|
+
range: number;
|
|
102
|
+
/** World point where the lowest sample was found. */
|
|
103
|
+
minAt: GroundPoint;
|
|
104
|
+
/** World point where the highest sample was found. */
|
|
105
|
+
maxAt: GroundPoint;
|
|
106
|
+
/** Number of grid samples taken. */
|
|
107
|
+
samples: number;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Summarises elevation across a region on a bounded sample grid: min, max, mean, relief range, and the
|
|
111
|
+
* world points of the extremes — the selection min/max and legend feedback the readability overlay
|
|
112
|
+
* reports, and the input to {@link chooseContourInterval}. Pure math, renderer-agnostic.
|
|
113
|
+
* @capability elevation-summary selection min/max/mean and relief over a region
|
|
114
|
+
* @consumer editor terrain-readability legend and selection stats
|
|
115
|
+
*/
|
|
116
|
+
export declare function summarizeElevation(sampleHeight: HeightSampler, region: GuideRegion, resolution?: number, maxSamples?: number): ElevationSummary;
|
|
117
|
+
/** Shaping for surface draping: subdivision spacing and a lift to keep the line off the ground. */
|
|
118
|
+
export interface DrapeOptions {
|
|
119
|
+
/** Max world spacing between draped vertices; longer spans are subdivided so the line hugs the surface. Default `1`. */
|
|
120
|
+
spacing?: number;
|
|
121
|
+
/** Lift each draped vertex this far above the sampled surface, to avoid z-fighting. Default `0`. */
|
|
122
|
+
offset?: number;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Drapes an XZ polyline onto the surface: subdivides each span to at most `spacing` and lifts every
|
|
126
|
+
* vertex to `sampleHeight + offset`, returning flat `[x, y, z, ...]` world triples. The reusable seam
|
|
127
|
+
* behind surface-following placement guides and grid lines — a straight guide bends to follow terrain.
|
|
128
|
+
* @capability surface-drape lift an XZ polyline onto sculpted terrain
|
|
129
|
+
* @consumer editor placement guides and surface grid overlay
|
|
130
|
+
*/
|
|
131
|
+
export declare function drapePolyline(sampleHeight: HeightSampler, points: readonly GroundPoint[], options?: DrapeOptions): number[];
|
|
132
|
+
/**
|
|
133
|
+
* A closed circle draped on the surface — the surface-following placement guide ring under a cursor or
|
|
134
|
+
* a selected object. Returns flat `[x, y, z, ...]` world triples forming a loop (last vertex repeats
|
|
135
|
+
* the first). `segments` sets the smoothness of the ring.
|
|
136
|
+
* @capability surface-ring surface-following placement guide ring
|
|
137
|
+
* @consumer editor cursor/placement guide
|
|
138
|
+
*/
|
|
139
|
+
export declare function surfaceRing(sampleHeight: HeightSampler, center: GroundPoint, radius: number, segments?: number, options?: DrapeOptions): number[];
|
|
140
|
+
/** One draped grid line from {@link surfaceGridLines}: its axis, emphasis, and draped vertices. */
|
|
141
|
+
export interface SurfaceGridLine {
|
|
142
|
+
/** Which axis the line runs constant along: an `"x"` line holds `x` fixed and spans `z`, and vice versa. */
|
|
143
|
+
axis: "x" | "z";
|
|
144
|
+
/** The constant coordinate value the line holds. */
|
|
145
|
+
at: number;
|
|
146
|
+
/** Whether this is a major (emphasised) grid line. */
|
|
147
|
+
major: boolean;
|
|
148
|
+
/** Flat `[x, y, z, ...]` world triples draped on the surface. */
|
|
149
|
+
points: readonly number[];
|
|
150
|
+
}
|
|
151
|
+
/** Shaping for {@link surfaceGridLines}: region, spacing, emphasis cadence, and draping. */
|
|
152
|
+
export interface SurfaceGridOptions {
|
|
153
|
+
region: GuideRegion;
|
|
154
|
+
/** World distance between adjacent grid lines. Must be `> 0`. */
|
|
155
|
+
spacing: number;
|
|
156
|
+
/** Every Nth line (counting from origin) is a major line. Default `5`; `<= 1` makes all major. */
|
|
157
|
+
majorEvery?: number;
|
|
158
|
+
/** Draping options for each line. */
|
|
159
|
+
drape?: DrapeOptions;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Builds a surface-following major/minor grid over a region: constant-`x` and constant-`z` lines at
|
|
163
|
+
* `spacing`, each draped onto the terrain so the reference grid climbs sculpted surfaces instead of
|
|
164
|
+
* being occluded by them (the flat `y = 0` grid's core failure). Draping subdivides to
|
|
165
|
+
* `drape.spacing`. Pure math, renderer-agnostic.
|
|
166
|
+
* @capability surface-grid terrain-following reference grid that is not occluded by relief
|
|
167
|
+
* @consumer editor terrain-readability grid overlay
|
|
168
|
+
*/
|
|
169
|
+
export declare function surfaceGridLines(sampleHeight: HeightSampler, options: SurfaceGridOptions): SurfaceGridLine[];
|
|
170
|
+
/**
|
|
171
|
+
* Convenience over {@link extractContours} that auto-picks the interval from the field's own relief:
|
|
172
|
+
* summarises the region, chooses a readable interval for `targetLines` bands, and traces the contours —
|
|
173
|
+
* the one call the editor overlay makes to turn a `TerrainField` into ready-to-draw guides. Returns an
|
|
174
|
+
* empty list for flat ground.
|
|
175
|
+
* @capability terrain-guides one-call adaptive contours for a terrain field
|
|
176
|
+
* @consumer editor terrain-readability overlay
|
|
177
|
+
*/
|
|
178
|
+
export declare function terrainContourGuides(field: Pick<TerrainField, "sampleHeight">, region: GuideRegion, targetLines?: number, resolution?: number): {
|
|
179
|
+
interval: number;
|
|
180
|
+
summary: ElevationSummary;
|
|
181
|
+
contours: ContourLine[];
|
|
182
|
+
};
|