lecodes-sdk 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.
- package/README.md +114 -0
- package/dist/global.d.ts +503 -0
- package/dist/host.d.ts +61 -0
- package/dist/inject.js +4730 -0
- package/dist/types/animate/animate.d.ts +20 -0
- package/dist/types/animate/bezier.d.ts +2 -0
- package/dist/types/animate/easings.d.ts +21 -0
- package/dist/types/canvas/Canvas.d.ts +168 -0
- package/dist/types/core/Aspect.d.ts +171 -0
- package/dist/types/core/InspectorUI.d.ts +88 -0
- package/dist/types/core/StateMachine.d.ts +81 -0
- package/dist/types/core/color.d.ts +13 -0
- package/dist/types/core/compWrite.d.ts +11 -0
- package/dist/types/core/events.d.ts +11 -0
- package/dist/types/core/fields.d.ts +58 -0
- package/dist/types/core/registry.d.ts +7 -0
- package/dist/types/core/signals.d.ts +29 -0
- package/dist/types/core/time.d.ts +31 -0
- package/dist/types/g2/Camera2D.d.ts +19 -0
- package/dist/types/g2/CharacterController2D.d.ts +134 -0
- package/dist/types/g2/Node2D.d.ts +91 -0
- package/dist/types/g2/OneWay2D.d.ts +24 -0
- package/dist/types/g2/Physics2D.d.ts +147 -0
- package/dist/types/g2/Scene2D.d.ts +72 -0
- package/dist/types/g2/Shape2D.d.ts +58 -0
- package/dist/types/g2/Sprite.d.ts +51 -0
- package/dist/types/g2/SpriteAnimation.d.ts +50 -0
- package/dist/types/g2/SpriteSheet.d.ts +69 -0
- package/dist/types/g2/Texture2D.d.ts +16 -0
- package/dist/types/g2/Tilemap.d.ts +20 -0
- package/dist/types/g2/Tileset.d.ts +32 -0
- package/dist/types/g2/Trigger2D.d.ts +20 -0
- package/dist/types/g2/autotile.d.ts +133 -0
- package/dist/types/g2/cells.d.ts +14 -0
- package/dist/types/g2/defineScene2d.d.ts +141 -0
- package/dist/types/g2/groups2d.d.ts +16 -0
- package/dist/types/g2/loop.d.ts +4 -0
- package/dist/types/g2/scenarios2d.d.ts +30 -0
- package/dist/types/g2/touch.d.ts +2 -0
- package/dist/types/gl/Camera.d.ts +79 -0
- package/dist/types/gl/CameraPlace.d.ts +26 -0
- package/dist/types/gl/CharacterController.d.ts +98 -0
- package/dist/types/gl/Gearbox.d.ts +86 -0
- package/dist/types/gl/Geometry.d.ts +39 -0
- package/dist/types/gl/IK.d.ts +53 -0
- package/dist/types/gl/InstancedMesh.d.ts +46 -0
- package/dist/types/gl/Light.d.ts +73 -0
- package/dist/types/gl/Lightmap.d.ts +85 -0
- package/dist/types/gl/Locomotion.d.ts +279 -0
- package/dist/types/gl/Material.d.ts +100 -0
- package/dist/types/gl/Mesh.d.ts +33 -0
- package/dist/types/gl/Model.d.ts +53 -0
- package/dist/types/gl/NavAgent.d.ts +99 -0
- package/dist/types/gl/NavMesh.d.ts +169 -0
- package/dist/types/gl/Node.d.ts +99 -0
- package/dist/types/gl/Noise.d.ts +20 -0
- package/dist/types/gl/Particles.d.ts +277 -0
- package/dist/types/gl/Physics.d.ts +91 -0
- package/dist/types/gl/Plane.d.ts +19 -0
- package/dist/types/gl/Ragdoll.d.ts +86 -0
- package/dist/types/gl/Ray.d.ts +8 -0
- package/dist/types/gl/Scene.d.ts +221 -0
- package/dist/types/gl/Shape.d.ts +122 -0
- package/dist/types/gl/Terrain.d.ts +280 -0
- package/dist/types/gl/Texture.d.ts +27 -0
- package/dist/types/gl/Trigger.d.ts +10 -0
- package/dist/types/gl/Vehicle.d.ts +191 -0
- package/dist/types/gl/Wheel.d.ts +95 -0
- package/dist/types/gl/animation/AnimationClip.d.ts +60 -0
- package/dist/types/gl/animation/Animator.d.ts +219 -0
- package/dist/types/gl/animation/Layer.d.ts +31 -0
- package/dist/types/gl/animation/Loop.d.ts +17 -0
- package/dist/types/gl/animation/Playback.d.ts +36 -0
- package/dist/types/gl/animation/core.d.ts +367 -0
- package/dist/types/gl/controls.d.ts +19 -0
- package/dist/types/gl/physicsEvents.d.ts +1 -0
- package/dist/types/gl/scenarios.d.ts +98 -0
- package/dist/types/gl/state.d.ts +5 -0
- package/dist/types/gl/terrainMesh.d.ts +46 -0
- package/dist/types/gl/touch.d.ts +2 -0
- package/dist/types/inject.d.ts +123 -0
- package/dist/types/math/Mathf.d.ts +39 -0
- package/dist/types/math/mat4.d.ts +66 -0
- package/dist/types/math/quat.d.ts +53 -0
- package/dist/types/math/vec.d.ts +129 -0
- package/dist/types/net/codec.d.ts +25 -0
- package/dist/types/net/core.d.ts +106 -0
- package/dist/types/net/index.d.ts +80 -0
- package/dist/types/net/replication.d.ts +101 -0
- package/dist/types/plugins/camera.d.ts +25 -0
- package/dist/types/plugins/geolocation.d.ts +39 -0
- package/dist/types/plugins/oauth.d.ts +25 -0
- package/dist/types/plugins/permission.d.ts +1 -0
- package/dist/types/plugins/push.d.ts +46 -0
- package/dist/types/plugins/qr.d.ts +21 -0
- package/dist/types/plugins/service.d.ts +33 -0
- package/dist/types/runtime/app.d.ts +67 -0
- package/dist/types/runtime/appEvents.d.ts +7 -0
- package/dist/types/runtime/channel.d.ts +1 -0
- package/dist/types/runtime/clipboard.d.ts +7 -0
- package/dist/types/runtime/datetime.d.ts +80 -0
- package/dist/types/runtime/device.d.ts +126 -0
- package/dist/types/runtime/fetch.d.ts +31 -0
- package/dist/types/runtime/files.d.ts +33 -0
- package/dist/types/runtime/input.d.ts +121 -0
- package/dist/types/runtime/media.d.ts +46 -0
- package/dist/types/runtime/misc.d.ts +11 -0
- package/dist/types/runtime/net.d.ts +15 -0
- package/dist/types/runtime/rpc.d.ts +44 -0
- package/dist/types/runtime/service.d.ts +1 -0
- package/dist/types/runtime/share.d.ts +2 -0
- package/dist/types/runtime/storage.d.ts +5 -0
- package/dist/types/runtime/touch.d.ts +56 -0
- package/dist/types/scene/defineScene.d.ts +296 -0
- package/dist/types/scene/editorPlugins.d.ts +82 -0
- package/dist/types/scene/gizmos.d.ts +56 -0
- package/dist/types/scene/grammar.d.ts +56 -0
- package/dist/types/scene/level.d.ts +98 -0
- package/dist/types/scene/material.d.ts +76 -0
- package/dist/types/server/auth/appConfig.d.ts +16 -0
- package/dist/types/server/auth/global.d.ts +56 -0
- package/dist/types/server/auth/models.d.ts +164 -0
- package/dist/types/server/auth/types.d.ts +56 -0
- package/dist/types/server/channel.d.ts +28 -0
- package/dist/types/server/context.d.ts +27 -0
- package/dist/types/server/db/defineDb.d.ts +36 -0
- package/dist/types/server/db/fields.d.ts +146 -0
- package/dist/types/server/db/index.d.ts +6 -0
- package/dist/types/server/db/marci/query.d.ts +326 -0
- package/dist/types/server/db/types.d.ts +163 -0
- package/dist/types/server/errors.d.ts +8 -0
- package/dist/types/server/inject.d.ts +5 -0
- package/dist/types/ui/NativeView.d.ts +38 -0
- package/dist/types/ui/UI.d.ts +27 -0
- package/dist/types/ui/UIBottomSheet.d.ts +71 -0
- package/dist/types/ui/UIButton.d.ts +30 -0
- package/dist/types/ui/UIContainer.d.ts +33 -0
- package/dist/types/ui/UIImage.d.ts +35 -0
- package/dist/types/ui/UIInput.d.ts +110 -0
- package/dist/types/ui/UIModal.d.ts +70 -0
- package/dist/types/ui/UINode.d.ts +363 -0
- package/dist/types/ui/UIPager.d.ts +123 -0
- package/dist/types/ui/UIPopover.d.ts +39 -0
- package/dist/types/ui/UIScreen.d.ts +57 -0
- package/dist/types/ui/UIScrollable.d.ts +40 -0
- package/dist/types/ui/UISpacer.d.ts +9 -0
- package/dist/types/ui/UITabs.d.ts +96 -0
- package/dist/types/ui/UIText.d.ts +19 -0
- package/dist/types/ui/UIVideo.d.ts +28 -0
- package/dist/types/ui/UIVirtualizedList.d.ts +97 -0
- package/dist/types/ui/UIWidget.d.ts +65 -0
- package/dist/types/ui/fonts.d.ts +9 -0
- package/dist/types/ui/presentable.d.ts +68 -0
- package/dist/types/ui/router.d.ts +40 -0
- package/dist/types/ui/theme.d.ts +26 -0
- package/dist/types.json +1 -0
- package/package.json +46 -0
- package/prompts/2d.md +395 -0
- package/prompts/3d-scene-files.md +113 -0
- package/prompts/3d-scene.md +119 -0
- package/prompts/3d.md +303 -0
- package/prompts/README.md +142 -0
- package/prompts/ar.md +109 -0
- package/prompts/canvas.md +27 -0
- package/prompts/compose.ts +46 -0
- package/prompts/concept.md +49 -0
- package/prompts/core-design.md +75 -0
- package/prompts/core.md +264 -0
- package/prompts/design.md +218 -0
- package/prompts/dist/2d-game.md +1530 -0
- package/prompts/dist/3d-app.md +1672 -0
- package/prompts/dist/ar-app.md +1548 -0
- package/prompts/dist/concept.md +49 -0
- package/prompts/dist/design.md +498 -0
- package/prompts/dist/ui-app.md +1134 -0
- package/prompts/index.md +37 -0
- package/prompts/intake-prompt.md +33 -0
- package/prompts/namer-prompt.md +12 -0
- package/prompts/router-prompt.md +50 -0
- package/prompts/select.ts +111 -0
- package/prompts/ui-design.md +203 -0
- package/prompts/ui.md +803 -0
- package/src/animate/animate.ts +238 -0
- package/src/animate/bezier.ts +138 -0
- package/src/animate/easings.ts +126 -0
- package/src/bridges.d.ts +1345 -0
- package/src/canvas/Canvas.ts +305 -0
- package/src/compile/__tests__/assetIconMacro.test.ts +219 -0
- package/src/compile/__tests__/assetMacro.test.ts +74 -0
- package/src/compile/__tests__/assetName.test.ts +55 -0
- package/src/compile/__tests__/compile.test.ts +287 -0
- package/src/compile/__tests__/detectEntry.test.ts +132 -0
- package/src/compile/__tests__/fontMacro.test.ts +199 -0
- package/src/compile/aspectMacro.ts +86 -0
- package/src/compile/assetIconMacro.ts +384 -0
- package/src/compile/assetMacro.ts +146 -0
- package/src/compile/assetName.ts +50 -0
- package/src/compile/bundler.ts +287 -0
- package/src/compile/compileProject.ts +127 -0
- package/src/compile/detectEntry.ts +128 -0
- package/src/compile/fontMacro.ts +459 -0
- package/src/compile/fontRegistry.ts +78 -0
- package/src/compile/header.ts +67 -0
- package/src/compile/index.ts +100 -0
- package/src/compile/libraryImports.ts +52 -0
- package/src/compile/liteMaterial.ts +247 -0
- package/src/compile/sceneEditor.ts +88 -0
- package/src/compile/serverSplit.ts +233 -0
- package/src/compile/serverTypes.ts +227 -0
- package/src/compile/sfnt.ts +98 -0
- package/src/compile/shaderSchema.ts +202 -0
- package/src/compile/shaderTargets.ts +77 -0
- package/src/compile/sourcemap.ts +25 -0
- package/src/core/Aspect.ts +568 -0
- package/src/core/InspectorUI.ts +212 -0
- package/src/core/StateMachine.ts +308 -0
- package/src/core/__tests__/stateMachine.test.ts +132 -0
- package/src/core/color.ts +66 -0
- package/src/core/compWrite.ts +42 -0
- package/src/core/events.ts +38 -0
- package/src/core/fields.ts +120 -0
- package/src/core/registry.ts +23 -0
- package/src/core/signals.ts +277 -0
- package/src/core/time.ts +84 -0
- package/src/g2/Camera2D.ts +40 -0
- package/src/g2/CharacterController2D.ts +276 -0
- package/src/g2/Node2D.ts +267 -0
- package/src/g2/OneWay2D.ts +66 -0
- package/src/g2/Physics2D.ts +346 -0
- package/src/g2/Scene2D.ts +209 -0
- package/src/g2/Shape2D.ts +259 -0
- package/src/g2/Sprite.ts +89 -0
- package/src/g2/SpriteAnimation.ts +171 -0
- package/src/g2/SpriteSheet.ts +166 -0
- package/src/g2/Texture2D.ts +47 -0
- package/src/g2/Tilemap.ts +41 -0
- package/src/g2/Tileset.ts +71 -0
- package/src/g2/Trigger2D.ts +77 -0
- package/src/g2/autotile.ts +433 -0
- package/src/g2/cells.ts +91 -0
- package/src/g2/defineScene2d.ts +381 -0
- package/src/g2/groups2d.ts +106 -0
- package/src/g2/loop.ts +50 -0
- package/src/g2/scenarios2d.ts +69 -0
- package/src/g2/touch.ts +83 -0
- package/src/gl/Camera.ts +160 -0
- package/src/gl/CameraPlace.ts +52 -0
- package/src/gl/CharacterController.ts +238 -0
- package/src/gl/Gearbox.ts +212 -0
- package/src/gl/Geometry.ts +279 -0
- package/src/gl/IK.ts +193 -0
- package/src/gl/InstancedMesh.ts +132 -0
- package/src/gl/Light.ts +135 -0
- package/src/gl/Lightmap.ts +402 -0
- package/src/gl/Locomotion.ts +498 -0
- package/src/gl/Material.ts +279 -0
- package/src/gl/Mesh.ts +83 -0
- package/src/gl/Model.ts +124 -0
- package/src/gl/NavAgent.ts +337 -0
- package/src/gl/NavMesh.ts +397 -0
- package/src/gl/Node.ts +350 -0
- package/src/gl/Noise.ts +30 -0
- package/src/gl/Particles.ts +676 -0
- package/src/gl/Physics.ts +222 -0
- package/src/gl/Plane.ts +53 -0
- package/src/gl/Ragdoll.ts +270 -0
- package/src/gl/Ray.ts +16 -0
- package/src/gl/Scene.ts +505 -0
- package/src/gl/Shape.ts +409 -0
- package/src/gl/Terrain.ts +1092 -0
- package/src/gl/Texture.ts +63 -0
- package/src/gl/Trigger.ts +45 -0
- package/src/gl/Vehicle.ts +473 -0
- package/src/gl/Wheel.ts +240 -0
- package/src/gl/animation/AnimationClip.ts +204 -0
- package/src/gl/animation/Animator.ts +329 -0
- package/src/gl/animation/Layer.ts +39 -0
- package/src/gl/animation/Loop.ts +31 -0
- package/src/gl/animation/Playback.ts +52 -0
- package/src/gl/animation/core.ts +670 -0
- package/src/gl/controls.ts +95 -0
- package/src/gl/physicsEvents.ts +20 -0
- package/src/gl/scenarios.ts +291 -0
- package/src/gl/state.ts +6 -0
- package/src/gl/terrainMesh.ts +219 -0
- package/src/gl/touch.ts +68 -0
- package/src/host.d.ts +61 -0
- package/src/inject.ts +203 -0
- package/src/math/Mathf.ts +118 -0
- package/src/math/mat4.ts +278 -0
- package/src/math/quat.ts +232 -0
- package/src/math/vec.ts +255 -0
- package/src/net/codec.ts +119 -0
- package/src/net/core.ts +384 -0
- package/src/net/index.ts +181 -0
- package/src/net/replication.ts +622 -0
- package/src/plugins/camera.ts +81 -0
- package/src/plugins/geolocation.ts +123 -0
- package/src/plugins/oauth.ts +61 -0
- package/src/plugins/permission.ts +7 -0
- package/src/plugins/push.ts +132 -0
- package/src/plugins/qr.ts +73 -0
- package/src/plugins/service.ts +47 -0
- package/src/runtime/app.ts +101 -0
- package/src/runtime/appEvents.ts +54 -0
- package/src/runtime/channel.ts +61 -0
- package/src/runtime/clipboard.ts +20 -0
- package/src/runtime/datetime.ts +329 -0
- package/src/runtime/device.ts +293 -0
- package/src/runtime/fetch.ts +77 -0
- package/src/runtime/files.ts +108 -0
- package/src/runtime/input.ts +175 -0
- package/src/runtime/media.ts +111 -0
- package/src/runtime/misc.ts +16 -0
- package/src/runtime/net.ts +36 -0
- package/src/runtime/rpc.ts +218 -0
- package/src/runtime/service.ts +83 -0
- package/src/runtime/share.ts +9 -0
- package/src/runtime/storage.ts +13 -0
- package/src/runtime/touch.ts +76 -0
- package/src/scene/defineScene.ts +1396 -0
- package/src/scene/editorPlugins.ts +110 -0
- package/src/scene/gizmos.ts +148 -0
- package/src/scene/grammar.ts +120 -0
- package/src/scene/level.ts +296 -0
- package/src/scene/material.ts +188 -0
- package/src/server/auth/appConfig.ts +12 -0
- package/src/server/auth/global.ts +80 -0
- package/src/server/auth/host.ts +318 -0
- package/src/server/auth/models.ts +83 -0
- package/src/server/auth/types.ts +50 -0
- package/src/server/channel.ts +56 -0
- package/src/server/context.ts +36 -0
- package/src/server/db/defineDb.ts +237 -0
- package/src/server/db/fields.ts +132 -0
- package/src/server/db/httpTransport.ts +93 -0
- package/src/server/db/index.ts +7 -0
- package/src/server/db/marci/query.ts +412 -0
- package/src/server/db/types.ts +202 -0
- package/src/server/errors.ts +12 -0
- package/src/server/host.ts +74 -0
- package/src/server/inject.ts +13 -0
- package/src/server/runtime.ts +133 -0
- package/src/server/validate.ts +87 -0
- package/src/ui/NativeView.ts +142 -0
- package/src/ui/UI.ts +39 -0
- package/src/ui/UIBottomSheet.ts +139 -0
- package/src/ui/UIButton.ts +101 -0
- package/src/ui/UIContainer.ts +60 -0
- package/src/ui/UIImage.ts +83 -0
- package/src/ui/UIInput.ts +185 -0
- package/src/ui/UIModal.ts +139 -0
- package/src/ui/UINode.ts +830 -0
- package/src/ui/UIPager.ts +362 -0
- package/src/ui/UIPopover.ts +100 -0
- package/src/ui/UIScreen.ts +123 -0
- package/src/ui/UIScrollable.ts +87 -0
- package/src/ui/UISpacer.ts +14 -0
- package/src/ui/UITabs.ts +236 -0
- package/src/ui/UIText.ts +51 -0
- package/src/ui/UIVideo.ts +88 -0
- package/src/ui/UIVirtualizedList.ts +241 -0
- package/src/ui/UIWidget.ts +127 -0
- package/src/ui/fonts.ts +13 -0
- package/src/ui/presentable.ts +117 -0
- package/src/ui/router.ts +132 -0
- package/src/ui/theme.ts +84 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Vec3 } from "../math/vec";
|
|
2
|
+
import { Node } from "./Node";
|
|
3
|
+
import { Ray } from "./Ray";
|
|
4
|
+
/** Projection every host starts a scene with (creator-gl scene.cpp / the lite core agree on these). */
|
|
5
|
+
export declare const CAMERA_DEFAULTS: {
|
|
6
|
+
fov: number;
|
|
7
|
+
near: number;
|
|
8
|
+
far: number;
|
|
9
|
+
};
|
|
10
|
+
export declare class Camera extends Node {
|
|
11
|
+
private _sceneId;
|
|
12
|
+
/** Live projection matrix (updated by the host when the viewport/fov changes). */
|
|
13
|
+
readonly projectionMatrix: Float32Array<ArrayBuffer>;
|
|
14
|
+
private _fov;
|
|
15
|
+
private _near;
|
|
16
|
+
private _far;
|
|
17
|
+
/** Stay quiet until the app actually sets something — hosts may be configured with their own
|
|
18
|
+
* defaults (the headless core takes a `fov` option) and a blind push would overwrite them. */
|
|
19
|
+
private _projSet;
|
|
20
|
+
private _exposure;
|
|
21
|
+
private _ev;
|
|
22
|
+
private _exposureSet;
|
|
23
|
+
/** Exposure compensation in stops (default 0): +1 doubles how bright the scene renders, −2
|
|
24
|
+
* quarters it. The one exposure knob most games need — a dark interior, a flash of white, or eye
|
|
25
|
+
* adaptation when the sun swings into view (drop it, and the sun stays at the display's peak
|
|
26
|
+
* while everything else darkens). Scene light follows it; particle `emissive` is post-exposure
|
|
27
|
+
* and does not, so a fireball keeps its on-screen brightness. Cheap to animate every frame. */
|
|
28
|
+
get exposureCompensation(): number;
|
|
29
|
+
set exposureCompensation(stops: number);
|
|
30
|
+
/** The physical camera: `aperture` in f-stops, `shutterSpeed` in seconds, `iso`, plus the same
|
|
31
|
+
* `compensation` in stops — any subset, one call. `camera.setExposure({ iso: 400 })` is two stops
|
|
32
|
+
* brighter than the default f/16 · 1/125 · ISO 100. */
|
|
33
|
+
setExposure(exposure: {
|
|
34
|
+
aperture?: number;
|
|
35
|
+
shutterSpeed?: number;
|
|
36
|
+
iso?: number;
|
|
37
|
+
compensation?: number;
|
|
38
|
+
}): this;
|
|
39
|
+
/** Hosts that predate the call keep the fixed default (older wasm / native builds). */
|
|
40
|
+
private _applyExposure;
|
|
41
|
+
/** Vertical field of view in degrees (default 60) — a smaller angle is a longer lens. */
|
|
42
|
+
get fov(): number;
|
|
43
|
+
set fov(degrees: number);
|
|
44
|
+
get horizontalFov(): number;
|
|
45
|
+
/** Near clip distance (default 0.01) — nothing closer than this draws. */
|
|
46
|
+
get near(): number;
|
|
47
|
+
set near(distance: number);
|
|
48
|
+
/** Far clip distance / view range (default 1000) — geometry past it is culled. Shadows keep
|
|
49
|
+
* their own (shorter) range, so a long view distance doesn't cost shadow sharpness. */
|
|
50
|
+
get far(): number;
|
|
51
|
+
set far(distance: number);
|
|
52
|
+
/** Set any of fov / near / far in one call: `camera.setProjection({ fov: 45, far: 5000 })`. */
|
|
53
|
+
setProjection(projection: {
|
|
54
|
+
fov?: number;
|
|
55
|
+
near?: number;
|
|
56
|
+
far?: number;
|
|
57
|
+
}): this;
|
|
58
|
+
/** Hosts that predate the call keep the fixed defaults (older wasm / native builds). */
|
|
59
|
+
private _applyProjection;
|
|
60
|
+
private _following;
|
|
61
|
+
/** The node the camera currently follows (`follow()`), or null. */
|
|
62
|
+
get following(): Node | null;
|
|
63
|
+
/**
|
|
64
|
+
* Make the camera ride a node: every late frame the camera takes the node's WORLD pose (−Z =
|
|
65
|
+
* view direction), so movement aspects / animation on that node are camera moves — dolly shots,
|
|
66
|
+
* a cutscene path, a `CameraPlace` in a scene file. A node carrying a `CameraPlace` also hands
|
|
67
|
+
* over its projection (fov / near / far). `follow(null)` releases the camera where it is.
|
|
68
|
+
* One camera per scene: following a new node stops following the previous one.
|
|
69
|
+
*/
|
|
70
|
+
follow(target: Node | {
|
|
71
|
+
node: Node;
|
|
72
|
+
applyTo(camera: Camera): void;
|
|
73
|
+
} | null): this;
|
|
74
|
+
get displaySize(): [number, number];
|
|
75
|
+
/** World-space ray direction through a screen pixel. */
|
|
76
|
+
getViewDirection(screenX: number, screenY: number): Vec3;
|
|
77
|
+
/** A pick ray from the camera through a screen pixel. */
|
|
78
|
+
getRay(screenX: number, screenY: number): Ray;
|
|
79
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Aspect } from "../core/Aspect";
|
|
2
|
+
import type { FieldMeta } from "../core/fields";
|
|
3
|
+
import type { Camera } from "./Camera";
|
|
4
|
+
import type { Node } from "./Node";
|
|
5
|
+
export declare class CameraPlace extends Aspect<"cameraPlace", Node> {
|
|
6
|
+
static readonly aspect = "cameraPlace";
|
|
7
|
+
/** Vertical field of view in degrees (default 60) — smaller is a longer lens. */
|
|
8
|
+
fov: number;
|
|
9
|
+
/** Near clip distance. */
|
|
10
|
+
near: number;
|
|
11
|
+
/** Far clip distance = view range. */
|
|
12
|
+
far: number;
|
|
13
|
+
/** The place that drives `scene.camera` when the file declaring it RUNS. Exactly one per file;
|
|
14
|
+
* ignored inside prefabs / instantiated subtrees (the host scene owns its camera). */
|
|
15
|
+
active: boolean;
|
|
16
|
+
/** Aspect ratio of the frustum gizmo only (the real aspect is the viewport's). */
|
|
17
|
+
static fields: FieldMeta<CameraPlace>;
|
|
18
|
+
static editor: {
|
|
19
|
+
rebuild: boolean;
|
|
20
|
+
};
|
|
21
|
+
/** Copy this place's projection onto a camera (`camera.follow(place)` does it for you). */
|
|
22
|
+
applyTo(camera: Camera): void;
|
|
23
|
+
/** Edit mode: the frustum marker (−Z = view), anchored on the node so it follows drags live and
|
|
24
|
+
* clicking it selects the node. Play mode never calls this. */
|
|
25
|
+
rebuild(): void;
|
|
26
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Aspect } from "../core/Aspect";
|
|
2
|
+
import type { FieldMeta } from "../core/fields";
|
|
3
|
+
import { Vec3, type Vec2Like, type Vec3Like } from "../math/vec";
|
|
4
|
+
import type { CompWriter } from "../core/compWrite";
|
|
5
|
+
import type { Node } from "./Node";
|
|
6
|
+
/** Where the character's feet are, as reported by the solver after the last step. */
|
|
7
|
+
export type GroundState = "ground" | "slope" | "unsupported" | "air";
|
|
8
|
+
export declare class CharacterController extends Aspect<"controller", Node> implements CompWriter {
|
|
9
|
+
static readonly aspect = "controller";
|
|
10
|
+
static fields: FieldMeta<CharacterController>;
|
|
11
|
+
private _charId;
|
|
12
|
+
private _gravityScale;
|
|
13
|
+
private _maxSlope;
|
|
14
|
+
onAttach(): void;
|
|
15
|
+
onDetach(): void;
|
|
16
|
+
/** Native character id (0 until attached / no physics support). */
|
|
17
|
+
get id(): number;
|
|
18
|
+
/**
|
|
19
|
+
* This frame's movement command, in world units/s — NOT normalized, NOT a per-frame displacement
|
|
20
|
+
* (that is what Unity's `Move` takes; passing `v * dt` here gives a character 60× too slow).
|
|
21
|
+
*
|
|
22
|
+
* Two components = horizontal `(x, z)`, the everyday call. Three = the whole velocity, for free mode
|
|
23
|
+
* (`gravityScale = 0`); with gravity on, the vertical component fights the ballistic one and the
|
|
24
|
+
* character barely falls, so that combination warns.
|
|
25
|
+
*
|
|
26
|
+
* Sticky only within the frame: the command expires once the engine consumes it. It also **takes the
|
|
27
|
+
* axis back from a latched `velocity`** — commanding is claiming ownership, which is what keeps the
|
|
28
|
+
* two horizontal sources from ever fighting.
|
|
29
|
+
*/
|
|
30
|
+
move(x: number, z: number): void;
|
|
31
|
+
move(v: Vec2Like | Vec3Like): void;
|
|
32
|
+
/** Vertical velocity (world units/s) — LATCHED: gravity works on it, you seed it. `= 7` to jump,
|
|
33
|
+
* `+= 3` to stack an explosion on top of the current motion. No ground check: guard it yourself
|
|
34
|
+
* with `grounded` (or don't, for a double jump). Overridden every frame by a 3-component `move()`.
|
|
35
|
+
* `velocity.y = 7` is the same channel — pick whichever reads better. */
|
|
36
|
+
get velocityY(): number;
|
|
37
|
+
set velocityY(v: number);
|
|
38
|
+
/** Multiplier over the world gravity (`Physics.configure({ gravity })`); default 2, for the snappier
|
|
39
|
+
* fall games want. **0 = free mode**: no gravity, no stick-to-floor, no stair stepping — a swimmer
|
|
40
|
+
* or a drone, driven by the 3-component `move()`. */
|
|
41
|
+
get gravityScale(): number;
|
|
42
|
+
set gravityScale(v: number);
|
|
43
|
+
/** Max ground slope (degrees) the character treats as walkable; default 45. Live. */
|
|
44
|
+
get maxSlope(): number;
|
|
45
|
+
set maxSlope(v: number);
|
|
46
|
+
/**
|
|
47
|
+
* True while a requested collider resize hasn't taken — you asked to stand up and there is something
|
|
48
|
+
* overhead. Resizing goes through the `Shape` aspect itself:
|
|
49
|
+
*
|
|
50
|
+
* hero.aspect(Shape, { capsule: CROUCHED }) // always fits — you are shrinking
|
|
51
|
+
* hero.aspect(Shape, { capsule: STANDING }) // may be refused under a low ceiling
|
|
52
|
+
* if (hero.controller.resizing) … // still crouched; call it again next frame
|
|
53
|
+
*
|
|
54
|
+
* A refusal changes nothing, so the retry is just the same call again — and it is an exact headroom
|
|
55
|
+
* test against the real capsule, unlike a hand-rolled raycast (a ray is a line; a capsule has girth).
|
|
56
|
+
* The FEET stay planted across a resize, so the character neither hovers nor sinks.
|
|
57
|
+
*/
|
|
58
|
+
get resizing(): boolean;
|
|
59
|
+
/** True while standing on walkable ground. */
|
|
60
|
+
get grounded(): boolean;
|
|
61
|
+
/** Where the feet are after the last step: on walkable ground, on too-steep ground, touching
|
|
62
|
+
* something that can't support it, or in the air. */
|
|
63
|
+
get groundState(): GroundState;
|
|
64
|
+
/**
|
|
65
|
+
* READ — the velocity the solver ended up with after the most recent step (world units/s, fresh
|
|
66
|
+
* Vec3): what HAPPENED, not what you asked for. Walking into a wall reads ~0, sliding along one
|
|
67
|
+
* reads the tangent. Unlike Unity's synchronous `Move`, our step runs later in the frame, so a read
|
|
68
|
+
* is up to one frame old — irrelevant for animation speed, fall damage or "am I blocked", which is
|
|
69
|
+
* what it is for. (Exact wall contact would need a contact normal; the engine has none yet.)
|
|
70
|
+
*
|
|
71
|
+
* WRITE — LATCH the whole velocity: a knockback, a wall jump, a launch pad. Unlike `move()` it does
|
|
72
|
+
* not expire, so the character keeps flying, and gravity still pulls the vertical down into a real
|
|
73
|
+
* ballistic arc. It stays until `move()` takes the axis back — so a game simply doesn't call
|
|
74
|
+
* `move()` while the throw lasts, and ends it on its own terms:
|
|
75
|
+
*
|
|
76
|
+
* hero.controller.velocity = [dir.x * 12, 6, dir.z * 12] // hit by the blast
|
|
77
|
+
* // …in the loop:
|
|
78
|
+
* if (thrown) { if (hero.controller.grounded) thrown = false } // landing ends it
|
|
79
|
+
* else hero.controller.move(ix * SPEED, iz * SPEED) // …and this reclaims the axis
|
|
80
|
+
*
|
|
81
|
+
* Note nothing clears the latch by itself, landing included — so a thrown character that never gets
|
|
82
|
+
* a `move()` keeps sliding along the ground (a kinematic controller has no friction).
|
|
83
|
+
*
|
|
84
|
+
* Reading is not the inverse of writing: `c.velocity = c.velocity` is NOT a no-op, because the read
|
|
85
|
+
* reports the measured result (against a wall it is ~0 and would cancel the throw). In flight the
|
|
86
|
+
* two agree closely, so read-modify-write mid-air behaves as expected.
|
|
87
|
+
*
|
|
88
|
+
* `c.velocity.y = 7` (the direct spelling) is a jump — the compiler routes it to the exact
|
|
89
|
+
* `velocityY` channel via `_writeComp` below, no vector allocated — and `c.velocity.x = 3` latches
|
|
90
|
+
* the whole vector with the measured velocity filling in the other two, i.e. the read-modify-write
|
|
91
|
+
* above spelled naturally. A STORED copy is still a copy: `const v = c.velocity; v.y = 7` does nothing.
|
|
92
|
+
*/
|
|
93
|
+
get velocity(): Vec3;
|
|
94
|
+
set velocity(v: Vec3Like);
|
|
95
|
+
/** Compile-time list (chisel reads it, then strips it): the getters whose `c.<getter>.<axis> = v`
|
|
96
|
+
* spelling is routed to `_writeComp` below. See core/compWrite.ts. */
|
|
97
|
+
static _comps: string[];
|
|
98
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Aspect } from "../core/Aspect";
|
|
2
|
+
import type { FieldMeta } from "../core/fields";
|
|
3
|
+
import type { Node } from "./Node";
|
|
4
|
+
import type { Vehicle } from "./Vehicle";
|
|
5
|
+
export declare class Gearbox extends Aspect<"gearbox", Node> {
|
|
6
|
+
static readonly aspect = "gearbox";
|
|
7
|
+
/** Forward gear ratios, first gear first. Engine RPM = wheel speed × ratio × the differential. */
|
|
8
|
+
ratios: number[];
|
|
9
|
+
/** Reverse ratio — negative, because a ratio's SIGN is what reverse means to the engine. */
|
|
10
|
+
reverse: number;
|
|
11
|
+
/** Shift up when the engine passes this fraction of its redline. */
|
|
12
|
+
shiftUp: number;
|
|
13
|
+
/** Shift down when it falls below this fraction. */
|
|
14
|
+
shiftDown: number;
|
|
15
|
+
/** How long a shift takes, in seconds — the clutch is out for this long. */
|
|
16
|
+
shiftTime: number;
|
|
17
|
+
/** How long the clutch takes to re-engage afterwards. */
|
|
18
|
+
clutchTime: number;
|
|
19
|
+
/** How long to wait after a shift before another is allowed — without it a car sitting on a
|
|
20
|
+
* threshold hunts between two gears. */
|
|
21
|
+
latency: number;
|
|
22
|
+
/** How far the clutch bites the instant drive is asked for from rest, 0..1. It only has to COUPLE
|
|
23
|
+
* the shafts — how much torque that passes is the engine's business, so a feathered throttle
|
|
24
|
+
* still pulls away gently at the same bite point. */
|
|
25
|
+
bite: number;
|
|
26
|
+
static fields: FieldMeta<Gearbox>;
|
|
27
|
+
/** Current gear: −1 reverse, 0 neutral, 1… forward. Read it for a HUD. */
|
|
28
|
+
gear: number;
|
|
29
|
+
/** True while a shift is in progress — the clutch is out and the engine is not driving the wheels. */
|
|
30
|
+
get shifting(): boolean;
|
|
31
|
+
private _shiftLeft;
|
|
32
|
+
private _engageLeft;
|
|
33
|
+
private _waitLeft;
|
|
34
|
+
private _take;
|
|
35
|
+
/** EARLY phase: the pair has to be latched before this frame's step consumes it. */
|
|
36
|
+
updateBefore(dt: number): void;
|
|
37
|
+
/**
|
|
38
|
+
* The driver's left foot: where the clutch pedal is, ignoring shifts. Returns the new engagement.
|
|
39
|
+
*
|
|
40
|
+
* A driver does not compute anything. They watch the tacho: **revs sinking to idle means the
|
|
41
|
+
* wheels are about to drag the engine under, and that is when you push the clutch in.** That
|
|
42
|
+
* single test replaces every ratio and threshold — the crossover it finds is the exact speed where
|
|
43
|
+
* engine braking stops and the engine would start PUSHING instead, and it finds it per gear
|
|
44
|
+
* without being told the gear.
|
|
45
|
+
*
|
|
46
|
+
* The pedal comes back UP only for the throttle. Healthy revs are not on their own a reason to
|
|
47
|
+
* engage: a car standing still shows healthy revs too — the wheels simply are not turning to say
|
|
48
|
+
* otherwise — and a clutch dropped on that evidence lurches the car off with no throttle at all.
|
|
49
|
+
*
|
|
50
|
+
* Three things fall out of it for free:
|
|
51
|
+
*
|
|
52
|
+
* - **A braked car stops.** The engine cannot stall, so a clutch left in at 0 km/h feeds idle
|
|
53
|
+
* torque to the wheels forever and the car creeps against its own brakes. Here the revs pin at
|
|
54
|
+
* idle, so the pedal goes down and the brakes have nothing to fight.
|
|
55
|
+
* - **Reverse is not a special case.** No ratio takes part, so it needs no separate number — which
|
|
56
|
+
* is exactly why a fixed road-speed threshold got reverse wrong.
|
|
57
|
+
* - **Hill starts judder instead of stalling.** Let the pedal out, the load pulls the revs down,
|
|
58
|
+
* the rule pushes it straight back in, and the clutch sits slipping at the bite point until the
|
|
59
|
+
* car moves. So the test deliberately ignores the throttle — gating it on "no throttle" would
|
|
60
|
+
* stall the car under load. Throttle only holds the floor at `bite`.
|
|
61
|
+
*
|
|
62
|
+
* The cost is honest and small: once the pedal is down the revs sit at idle and cannot rise on
|
|
63
|
+
* their own, so **coasting downhill gives no engine braking until you touch the throttle** — which
|
|
64
|
+
* is precisely what a car with the clutch in does. Slipping it permanently to keep listening would
|
|
65
|
+
* bring the creep straight back.
|
|
66
|
+
*/
|
|
67
|
+
protected takeUp(v: Vehicle, dt: number): number;
|
|
68
|
+
/**
|
|
69
|
+
* Which gear the car should be in. The default is an ordinary automatic: pull away from neutral in
|
|
70
|
+
* the direction of the throttle, shift up past `shiftUp` of the redline and down below `shiftDown`,
|
|
71
|
+
* and refuse to shift again for `latency` seconds. Override this and nothing else.
|
|
72
|
+
*/
|
|
73
|
+
select(v: Vehicle): number;
|
|
74
|
+
/** Change gear now, with the clutch envelope. Safe to call from `select()` or from game code
|
|
75
|
+
* (a sequential manual is `if (Input.key('KeyE')) car.gearbox.shift(car.gearbox.gear + 1)`). */
|
|
76
|
+
shift(gear: number): void;
|
|
77
|
+
/** The ratio the engine should be running: 0 in neutral, negative in reverse. */
|
|
78
|
+
get ratio(): number;
|
|
79
|
+
/**
|
|
80
|
+
* The clutch scalar 0..1 the engine is given: the SHIFT envelope (out during a shift, ramping back
|
|
81
|
+
* over `clutchTime`) times the driver's pedal (`takeUp`). Two independent reasons for the clutch
|
|
82
|
+
* to be out, so they multiply: mid-shift is out however healthy the revs are, and an engine being
|
|
83
|
+
* dragged to idle is out whatever gear it just picked.
|
|
84
|
+
*/
|
|
85
|
+
get clutch(): number;
|
|
86
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type Vec3Like } from "../math/vec";
|
|
2
|
+
export type MeshKind = "triangles" | "vertices" | "edges";
|
|
3
|
+
export declare class Geometry {
|
|
4
|
+
vertices: Float32Array;
|
|
5
|
+
normals: Float32Array;
|
|
6
|
+
indices: Uint16Array;
|
|
7
|
+
uv: Float32Array;
|
|
8
|
+
/** Lightmap UV set (2 floats per vertex, non-overlapping, inside the unit square) — the
|
|
9
|
+
* `Lightmap` atlas samples a Mesh through it. The box and cylinder builders fill it (their `uv`
|
|
10
|
+
* tiles per face, which would fold every face onto the same texels); absent = the host reuses
|
|
11
|
+
* `uv`, which is right for a plane. */
|
|
12
|
+
uv1?: Float32Array;
|
|
13
|
+
constructor(vertices: Float32Array, normals: Float32Array, indices: Uint16Array, uv: Float32Array);
|
|
14
|
+
translate(x: number, y: number, z: number): this;
|
|
15
|
+
scale(x: number, y: number, z: number): this;
|
|
16
|
+
scaleUV(x: number, y: number): this;
|
|
17
|
+
set kind(kind: MeshKind);
|
|
18
|
+
/** A box; `size` (default 1) scales the vertices AND lays the lightmap chart out in proportion to
|
|
19
|
+
* the faces' areas (a floor's top face gets the texels, not its 1 m side strips). */
|
|
20
|
+
static box(size?: Vec3Like | number): Geometry;
|
|
21
|
+
static sphere(options?: SphereOptions): Geometry;
|
|
22
|
+
static cylinder(options?: CylinderOptions): Geometry;
|
|
23
|
+
static plane(options?: PlaneOptions): Geometry;
|
|
24
|
+
}
|
|
25
|
+
export type SphereOptions = {
|
|
26
|
+
radius?: number;
|
|
27
|
+
widthSegments?: number;
|
|
28
|
+
heightSegments?: number;
|
|
29
|
+
};
|
|
30
|
+
export type CylinderOptions = {
|
|
31
|
+
radius?: number;
|
|
32
|
+
radiusTop?: number;
|
|
33
|
+
radiusBottom?: number;
|
|
34
|
+
edges?: number;
|
|
35
|
+
smooth?: boolean;
|
|
36
|
+
};
|
|
37
|
+
export type PlaneOptions = {
|
|
38
|
+
normal?: Vec3Like;
|
|
39
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Aspect } from "../core/Aspect";
|
|
2
|
+
import { type Vec3Like } from "../math/vec";
|
|
3
|
+
import { Quat } from "../math/quat";
|
|
4
|
+
import type { Node } from "./Node";
|
|
5
|
+
type Target = Node | Vec3Like;
|
|
6
|
+
/** Two-bone analytic IK (limbs). Attach to the END bone: `foot.aspect(IK.TwoBone, { target })`
|
|
7
|
+
* solves upper (grandparent) + mid (parent) so the end reaches `target`; `pole` steers the bend
|
|
8
|
+
* (knee/elbow) — a Node or world point. */
|
|
9
|
+
declare class TwoBone extends Aspect<"ik", Node> {
|
|
10
|
+
static readonly aspect = "ik";
|
|
11
|
+
/** Where the end bone should be (Node or world position). */
|
|
12
|
+
target?: Target;
|
|
13
|
+
/** Bend hint — the mid joint is pulled toward it (Node or world position). */
|
|
14
|
+
pole?: Target;
|
|
15
|
+
/** World rotation the END bone takes after the solve — a Node (its world rotation) or a Quat.
|
|
16
|
+
* Unset = the end bone keeps its animated local rotation (a hand on a grip, a foot on a slope
|
|
17
|
+
* want it set). Blended by `weight · rotationWeight`. */
|
|
18
|
+
rotation?: Node | Quat;
|
|
19
|
+
/** 0–1 contribution of `rotation` (on top of `weight`). */
|
|
20
|
+
rotationWeight: number;
|
|
21
|
+
/** 0–1 contribution (blend in/out, e.g. foot planting only while grounded). */
|
|
22
|
+
weight: number;
|
|
23
|
+
/** Solve every frame (default). Set false to drive `solve()` yourself. */
|
|
24
|
+
enabled: boolean;
|
|
25
|
+
update(): void;
|
|
26
|
+
/** One solve at the current pose. Safe to call manually (e.g. from a later-ordered aspect). */
|
|
27
|
+
solve(): void;
|
|
28
|
+
}
|
|
29
|
+
/** Aim a bone at a target (head / eyes / turret). Attach to the bone itself:
|
|
30
|
+
* `head.aspect(IK.LookAt, { target: camera, limit: 70 })`. `axis` is the bone's LOCAL forward
|
|
31
|
+
* (the direction that should point at the target) — rigs differ; default −Z, Mixamo heads look
|
|
32
|
+
* along +Z of the head bone in most exports, so pass `axis: [0, 0, 1]` there if it faces backwards. */
|
|
33
|
+
declare class LookAt extends Aspect<"lookAt", Node> {
|
|
34
|
+
static readonly aspect = "lookAt";
|
|
35
|
+
target?: Target;
|
|
36
|
+
/** The bone's local axis that should point at the target. */
|
|
37
|
+
axis: Vec3Like;
|
|
38
|
+
/** Max deflection from the animated direction, in degrees (default 80). */
|
|
39
|
+
limit: number;
|
|
40
|
+
/** 0–1 contribution. */
|
|
41
|
+
weight: number;
|
|
42
|
+
enabled: boolean;
|
|
43
|
+
update(): void;
|
|
44
|
+
solve(): void;
|
|
45
|
+
}
|
|
46
|
+
/** Inverse kinematics aspects — attach to bones (see file header). */
|
|
47
|
+
export declare const IK: {
|
|
48
|
+
TwoBone: typeof TwoBone;
|
|
49
|
+
LookAt: typeof LookAt;
|
|
50
|
+
};
|
|
51
|
+
export type IKTwoBone = TwoBone;
|
|
52
|
+
export type IKLookAt = LookAt;
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Mat4, type Mat4Like } from "../math/mat4";
|
|
2
|
+
import { type QuatLike } from "../math/quat";
|
|
3
|
+
import { type Vec3Like } from "../math/vec";
|
|
4
|
+
import type { Geometry } from "./Geometry";
|
|
5
|
+
import { Material } from "./Material";
|
|
6
|
+
import type { MeshOptions } from "./Mesh";
|
|
7
|
+
import { Node } from "./Node";
|
|
8
|
+
/** One instance's placement, local to the InstancedMesh node. Omitted fields mean identity. */
|
|
9
|
+
export type InstanceTransform = {
|
|
10
|
+
position?: Vec3Like;
|
|
11
|
+
/** Quaternion; wins over `eulerAngles`. */
|
|
12
|
+
rotation?: QuatLike;
|
|
13
|
+
/** Degrees (YXZ), like `Node.eulerAngles`. */
|
|
14
|
+
eulerAngles?: Vec3Like;
|
|
15
|
+
scale?: Vec3Like | number;
|
|
16
|
+
};
|
|
17
|
+
export declare class InstancedMesh extends Node {
|
|
18
|
+
/** Instance capacity, fixed at construction. Unset instances are hidden. */
|
|
19
|
+
readonly count: number;
|
|
20
|
+
private _geometry;
|
|
21
|
+
private _material;
|
|
22
|
+
private _data;
|
|
23
|
+
private _lo;
|
|
24
|
+
private _hi;
|
|
25
|
+
constructor(geometry: Geometry, count: number, options?: MeshOptions);
|
|
26
|
+
get geometry(): Geometry;
|
|
27
|
+
get material(): Material;
|
|
28
|
+
set material(m: Material);
|
|
29
|
+
/** Shadow flags for all instances (both at once — the engine sets them per draw). */
|
|
30
|
+
setShadows(cast: boolean, receive?: boolean): this;
|
|
31
|
+
private _touch;
|
|
32
|
+
/** Place instance `i`. Pending until `commit()`. */
|
|
33
|
+
setAt(i: number, t: InstanceTransform): this;
|
|
34
|
+
/** Place instance `i` from a 4×4 column-major matrix (local to this node). */
|
|
35
|
+
setMatrixAt(i: number, m: Mat4Like): this;
|
|
36
|
+
/** Hide instance `i` (a zero matrix — no geometry is emitted for it). */
|
|
37
|
+
hideAt(i: number): this;
|
|
38
|
+
/** Bulk write: `matrices` holds 16 floats per instance, starting at instance `offset`. */
|
|
39
|
+
setMatrices(matrices: ArrayLike<number>, offset?: number): this;
|
|
40
|
+
/** The 4×4 of instance `i` as stored (a copy). */
|
|
41
|
+
matrixAt(i: number): Mat4;
|
|
42
|
+
/** Upload every change since the last commit (one bridge call covering the dirty range). */
|
|
43
|
+
commit(): this;
|
|
44
|
+
/** Whether edits are waiting for `commit()`. */
|
|
45
|
+
get dirty(): boolean;
|
|
46
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { type ColorInput } from "../core/color";
|
|
2
|
+
import type { Vec3Like } from "../math/vec";
|
|
3
|
+
import { Node } from "./Node";
|
|
4
|
+
export type SunOptions = {
|
|
5
|
+
/** Light direction (points where the light travels). Defaults to a typical key-light angle. */
|
|
6
|
+
direction?: Vec3Like;
|
|
7
|
+
/** Luminous intensity. */
|
|
8
|
+
intensity?: number;
|
|
9
|
+
color?: ColorInput;
|
|
10
|
+
/**
|
|
11
|
+
* Shadow quality (default 1):
|
|
12
|
+
* 0 - no shadows
|
|
13
|
+
* 1 - 1024 map, hard edges (one filtered tap; the cheap level, ~3 % of a frame on an iGPU)
|
|
14
|
+
* 2 - 1024 map, soft edges (variance shadows + blur; ~+15 % of a frame on an iGPU)
|
|
15
|
+
* 3 - 2048 map, contact-hardening soft edges (PCSS: sharp where the caster touches, softer
|
|
16
|
+
* away; discrete-GPU territory, ~+60 % of a frame on an iGPU)
|
|
17
|
+
* A lightmapped level already carries every static shadow, so 0 is a legitimate choice there.
|
|
18
|
+
*/
|
|
19
|
+
shadowsQuality?: 0 | 1 | 2 | 3;
|
|
20
|
+
/**
|
|
21
|
+
* Metres from the camera within which the sun casts shadows (default 100). Shadows fade out by
|
|
22
|
+
* this distance and the shadow map covers only this range, so a shorter distance is crisper for
|
|
23
|
+
* the same quality and puts fewer casters in the shadow pass. 30-40 is plenty in first person.
|
|
24
|
+
*/
|
|
25
|
+
shadowDistance?: number;
|
|
26
|
+
};
|
|
27
|
+
export type PointOptions = {
|
|
28
|
+
/**
|
|
29
|
+
* Luminous POWER in lumens — the same physical scale as the sun's lux and `environmentIntensity`,
|
|
30
|
+
* so a light keeps its look when the scene's exposure changes. A candle is ~12 lm, a bare 60 W
|
|
31
|
+
* bulb ~800, a car headlight ~1500, a fireball millions. Default 1000.
|
|
32
|
+
*/
|
|
33
|
+
intensity?: number;
|
|
34
|
+
color?: ColorInput;
|
|
35
|
+
/**
|
|
36
|
+
* Metres of influence — past it the light contributes nothing. This is the performance knob:
|
|
37
|
+
* overlapping point lights are the expensive case, so keep it as small as the look allows.
|
|
38
|
+
* Default 10.
|
|
39
|
+
*/
|
|
40
|
+
range?: number;
|
|
41
|
+
/** Point-light shadows are a cubemap render per light; off by default. */
|
|
42
|
+
castShadows?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Whether `lecodes lightmap bake` bakes this light into the level's lightmap (docs/lightmap-plan.md).
|
|
45
|
+
* A baked light is switched OFF at runtime once the bake applies — statics read it from the atlas,
|
|
46
|
+
* movers from the light volume — so it costs nothing per frame; a light that must stay live (a
|
|
47
|
+
* flicker, a lamp the player can shoot out) says `baked: false` and is kept out of the bake.
|
|
48
|
+
* Lights created after the level loads (a muzzle flash) are never in a bake. Default true.
|
|
49
|
+
*/
|
|
50
|
+
baked?: boolean;
|
|
51
|
+
};
|
|
52
|
+
export declare class Light extends Node {
|
|
53
|
+
private _intensity;
|
|
54
|
+
/** The most recently created sun — what `Lightmap.load` uses unless told otherwise. */
|
|
55
|
+
static lastSun: Light | null;
|
|
56
|
+
/** A directional sun light. */
|
|
57
|
+
static sun(options?: SunOptions): Light;
|
|
58
|
+
/**
|
|
59
|
+
* A point light — a lamp, a muzzle flash, a fireball. Position it like any node.
|
|
60
|
+
*
|
|
61
|
+
* Feature-detected: hosts that predate it create the node and light nothing, which keeps a scene
|
|
62
|
+
* that adds atmosphere on top of its sun renderable everywhere. Check `Light.supportsPoint`
|
|
63
|
+
* before making one carry the scene.
|
|
64
|
+
*/
|
|
65
|
+
static point(options?: PointOptions): Light;
|
|
66
|
+
/** Whether this host can create point lights at all. */
|
|
67
|
+
static get supportsPoint(): boolean;
|
|
68
|
+
/** Live intensity (sun: lux, point: lumens) — animate a flash without rebuilding the light. */
|
|
69
|
+
get intensity(): number;
|
|
70
|
+
set intensity(value: number);
|
|
71
|
+
destroy(): void;
|
|
72
|
+
set color(value: ColorInput);
|
|
73
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Node } from "./Node";
|
|
2
|
+
import type { Scene } from "./Scene";
|
|
3
|
+
export type LightmapLoadOptions = {
|
|
4
|
+
/** 1 = baked sun shadows at full strength, 0 = ambient occlusion only. Default 1. */
|
|
5
|
+
sunStrength?: number;
|
|
6
|
+
/** Multiplier on the ambient (IBL) share in the shadow math — how bright a fully shadowed texel
|
|
7
|
+
* stays. 1 reproduces filament's own real-time shadow darkness (the shader reads the scene's sun
|
|
8
|
+
* and IBL from filament's per-frame uniforms); raise it for lighter shadows, lower for deeper. Default 1. */
|
|
9
|
+
ambientScale?: number;
|
|
10
|
+
/** How much of the baked ambient occlusion applies: 1 = all of it, 0 = none. An interior lit by
|
|
11
|
+
* its ambient probe alone can want less than the geometric truth. Default 1. */
|
|
12
|
+
aoStrength?: number;
|
|
13
|
+
/** Multiplier on the baked point lights' irradiance (default 1). Purely ARTISTIC: the bake is
|
|
14
|
+
* physical (verified against the analytic 1/d^2 sum over the level's lamps - where line of sight
|
|
15
|
+
* is clear the two agree within ~17 %), and a room lit to its real illuminance simply reads dim
|
|
16
|
+
* against an ambient fill. This dials the lamps up without a re-bake, since their irradiance is
|
|
17
|
+
* IN the atlas and `--lamp-gain` would cost a full one.
|
|
18
|
+
* It scales the atlas AND the light volume together, so statics and movers stay consistent - but
|
|
19
|
+
* note they are NOT equally forgiving: a static surface carries the bake's own cosine and
|
|
20
|
+
* shadowing, while a mover reads the volume through a flat half-cosine, so a large boost blows
|
|
21
|
+
* movers out long before it blows out the level. Past ~x100 expect to light the movers
|
|
22
|
+
* separately. */
|
|
23
|
+
lightBoost?: number;
|
|
24
|
+
/** Multiplier on the light VOLUME's irradiance alone — the movers' own `lightBoost`. Default =
|
|
25
|
+
* `lightBoost`, and since 2026-08-31 that default is the right one: the volume is an ambient cube
|
|
26
|
+
* (irradiance per axis face, blended by the pixel's normal), so a mover's top takes a lamp above it
|
|
27
|
+
* and its underside does not — the same shading the atlas gives the statics. Before that the volume
|
|
28
|
+
* was one flat 0.5·E on every face and this knob was the workaround. Kept as a trim. */
|
|
29
|
+
volumeBoost?: number;
|
|
30
|
+
};
|
|
31
|
+
export type LightmapInfo = {
|
|
32
|
+
size: number;
|
|
33
|
+
texel: number;
|
|
34
|
+
/** Atlas pages the bake took (`texture` lists them in order). */
|
|
35
|
+
pages: number;
|
|
36
|
+
/** The light volume, when one was loaded: grid dims + cell size in metres. */
|
|
37
|
+
volume?: {
|
|
38
|
+
dims: number[];
|
|
39
|
+
cell: number;
|
|
40
|
+
};
|
|
41
|
+
/** Point lights the bake carries and this load switched off (statics read them from the atlas,
|
|
42
|
+
* movers from the volume); 0 without a `light` atlas. */
|
|
43
|
+
lights: number;
|
|
44
|
+
/** keys applied / keys in the file / registered statics without a rect */
|
|
45
|
+
applied: number;
|
|
46
|
+
total: number;
|
|
47
|
+
missing: string[];
|
|
48
|
+
};
|
|
49
|
+
export type LightmapFiles = {
|
|
50
|
+
data: string;
|
|
51
|
+
/** The atlas — one page, or every page in order for a bake that took several. */
|
|
52
|
+
texture: string | string[];
|
|
53
|
+
/** The point lights' baked irradiance (pages like `texture`). */
|
|
54
|
+
light?: string | string[];
|
|
55
|
+
volume?: string;
|
|
56
|
+
};
|
|
57
|
+
export declare class Lightmap {
|
|
58
|
+
/** True while `lecodes lightmap bake` runs the app — skip menus and build the scene straight away. */
|
|
59
|
+
static get baking(): boolean;
|
|
60
|
+
private static entries;
|
|
61
|
+
private static dynamics;
|
|
62
|
+
private static ordinals;
|
|
63
|
+
private static warned;
|
|
64
|
+
private static switchedOff;
|
|
65
|
+
/** Register static geometry — a Model, a Mesh, or any node whose subtree holds them. Statics are
|
|
66
|
+
* both receivers and occluders in the bake. `key` names the entry in lightmap.bake (default:
|
|
67
|
+
* the node's name + a running number, `container#3`); pass one when names are not stable. */
|
|
68
|
+
static add(node: Node, key?: string): Node;
|
|
69
|
+
private static next;
|
|
70
|
+
/** Forget every registration (a scene rebuild); baked-off lights come back to the real-time path. */
|
|
71
|
+
static clear(): void;
|
|
72
|
+
/** Apply a bake — or, under `lecodes lightmap bake`, run it. Resolves to null when nothing was
|
|
73
|
+
* applied (no bake yet, a host without the feature, bake mode). */
|
|
74
|
+
static load(scene: Scene, files: LightmapFiles, options?: LightmapLoadOptions): Promise<LightmapInfo | null>;
|
|
75
|
+
/** Every live point light within 5 cm of a baked one is held dark (a moved lamp keeps lighting live
|
|
76
|
+
* — and double, until the next bake, which is the honest state of a stale bake). */
|
|
77
|
+
private static switchOffBaked;
|
|
78
|
+
/** lightmap.volume → the engine's 3D textures → THE volume for every dynamic lightmap-material instance,
|
|
79
|
+
* plus the registered dynamic Meshes. Null when the file is a placeholder or the host lacks the feature. */
|
|
80
|
+
private static loadVolume;
|
|
81
|
+
/** A Mesh keeps its look (colour / map / roughness / metallic) but moves to the lightmap material. */
|
|
82
|
+
private static meshMaterial;
|
|
83
|
+
private static swapMeshMaterial;
|
|
84
|
+
private static bake;
|
|
85
|
+
}
|