@ludra/three 0.0.0-stage → 0.92.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ludra contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,87 @@
1
+ import * as THREE from "three";
2
+ import { type Entity, type GameEvent, type RenderContext, type SceneDef } from "@ludra/core";
3
+ import type { Renderer3D, Renderer3DFactory } from "@ludra/core/browser";
4
+ /**
5
+ * The 3D renderer for Ludra: Three.js draws every entity with a `mesh` and lights the scene
6
+ * with its `light` entities, seen through a `camera3d`. It only reads the world, so it can
7
+ * never change what tests verified.
8
+ */
9
+ /** The World as the renderer needs it: what to draw, its events, and its render hooks. */
10
+ interface WorldView {
11
+ readonly entities: readonly Entity[];
12
+ readonly events?: readonly GameEvent[];
13
+ readonly time?: number;
14
+ callRenderHook?(entity: Entity, extras: Omit<RenderContext, "self" | "world" | "params">): void;
15
+ }
16
+ /** Creates the 3D renderer for a scene. Pass it to startGame as `loadRenderer3D`. */
17
+ export declare const createRenderer3D: Renderer3DFactory;
18
+ export declare class ThreeRenderer implements Renderer3D {
19
+ readonly canvas: HTMLCanvasElement;
20
+ debug: boolean;
21
+ /** Three.js itself, for render hooks and anything else (step 4 hands these to scripts). */
22
+ readonly renderer: THREE.WebGLRenderer;
23
+ readonly scene: THREE.Scene<THREE.Object3DEventMap>;
24
+ readonly camera: THREE.PerspectiveCamera;
25
+ private readonly objects;
26
+ private readonly lights;
27
+ private readonly textures;
28
+ /** Loaded glTF files by path; null when one failed to load (its entities fall back to a shape). */
29
+ private readonly gltfs;
30
+ private readonly gltfLoads;
31
+ private gltfLoader;
32
+ private readonly models;
33
+ /** Entities drawn with a placeholder while their model loads. */
34
+ private readonly waiting;
35
+ /**
36
+ * The clips each modelled entity played, recorded once per simulation step (not per frame), so a
37
+ * pose depends only on the simulation: a screenshot shows what the live game shows at that moment.
38
+ */
39
+ private readonly clipHistory;
40
+ private readonly debugGroup;
41
+ private readonly defaultLights;
42
+ private rig;
43
+ /** Each render-hook entity's own group, and its ctx.local. */
44
+ private readonly hookGroups;
45
+ private readonly hookLocals;
46
+ /** A render hook's own way of drawing the frame (an EffectComposer), if one set it. */
47
+ private customRender;
48
+ /** Addons render hooks are still loading. */
49
+ private readonly pending;
50
+ private readonly def;
51
+ private readonly assetBase;
52
+ constructor(def: SceneDef, width: number, height: number, assetBase: string);
53
+ /** Loads every texture and model the scene (and its prefabs) names, so the first frame (and screenshots) are complete. */
54
+ load(): Promise<void>;
55
+ /** Loads a glTF file once. Draco and meshopt compressed files work too. */
56
+ private loadModel;
57
+ private applyEnvironment;
58
+ step(world: WorldView): void;
59
+ reset(world: WorldView): void;
60
+ render(world: WorldView): void;
61
+ /** Waits for every addon render hooks asked for, and for what their callbacks start in turn. */
62
+ settle(): Promise<void>;
63
+ private track;
64
+ /** Scripts' render hooks: the real three.js, this entity's group, the scene, camera and renderer. */
65
+ private runRenderHooks;
66
+ dispose(): void;
67
+ /** Notes which clip every modelled entity should play now, and when that clip started. */
68
+ private recordClips;
69
+ /** Poses every model for this moment: a pure function of simulation time and the clip history. */
70
+ private poseModels;
71
+ private modelHandle;
72
+ /** Brings Three's scene in line with the world: new entities, removed ones, every transform. */
73
+ private sync;
74
+ private addDefaultLights;
75
+ private createMesh;
76
+ /**
77
+ * A copy of the model (bones included), turned, fitted to the entity and offset. The returned group
78
+ * is placed like any mesh; inside it a pivot holds the fit, so scripts can still move the root.
79
+ */
80
+ private createModel;
81
+ private placeLight;
82
+ /** Where the camera wants to be this step, eased by its smoothing. Deterministic per step. */
83
+ private updateRig;
84
+ /** Colliders as wireframes in their body's color, drawn over everything, and light positions. */
85
+ private syncDebug;
86
+ }
87
+ export {};