@threenative/core 0.3.2 → 0.3.4
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/capabilities.json +1891 -101
- package/dist/{assets-kyoF7JlJ.d.ts → assets-CqvE429w.d.ts} +52 -3
- package/dist/{audio-BFiGneTL.d.ts → audio-7i3Xl0l3.d.ts} +32 -1
- package/dist/{canvas-layer-BLVijiUJ.d.ts → canvas-layer-DDmC_VVF.d.ts} +1 -1
- package/dist/{game-XGrTzapq.d.ts → game-CljaDv4D.d.ts} +503 -11
- package/dist/{gpu-readback-D2iRvoe9.d.ts → gpu-readback-CqJEfWNQ.d.ts} +16 -6
- package/dist/hot.d.ts +5 -5
- package/dist/hot.js +20 -3
- package/dist/index.d.ts +1496 -43
- package/dist/index.js +8345 -753
- package/dist/playtest.d.ts +11 -5
- package/dist/playtest.js +96 -11
- package/dist/react.d.ts +2 -2
- package/dist/{renderer-C6hqZpoG.d.ts → renderer-CfsS2hxi.d.ts} +436 -14
- package/dist/ui-layer.d.ts +15 -7
- package/dist/ui-layer.js +2 -1
- package/dist/world.d.ts +900 -14
- package/dist/world.js +10876 -126
- package/gpl/fixtures/make_world_fixture.py +184 -0
- package/gpl/recipes/_common.py +11 -0
- package/gpl/recipes/decimate.py +11 -5
- package/gpl/recipes/export_world.py +682 -0
- package/mcp/blender-server.mjs +55 -1
- package/mcp/engine-server.mjs +84 -22
- package/mcp/servers.mjs +3 -3
- package/package.json +6 -6
- package/patches/three@0.185.1.patch +2228 -105
- package/scripts/apply-three-patch.mjs +61 -37
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Texture, Object3D, AnimationClip } from 'three';
|
|
1
|
+
import { Texture, Wrapping, Object3D, AnimationClip } from 'three';
|
|
2
2
|
|
|
3
3
|
interface IAssetLoaderOptions {
|
|
4
4
|
readonly basePath?: string;
|
|
@@ -49,10 +49,41 @@ interface ICompressedTextureSupport {
|
|
|
49
49
|
readonly loader: Promise<IKTX2LoaderLike | undefined>;
|
|
50
50
|
readonly ready: Promise<void>;
|
|
51
51
|
}
|
|
52
|
+
/** Which pipeline served a logical path: the compile step's manifest, or the project's own files. */
|
|
53
|
+
type AssetSource = "manifest" | "source";
|
|
54
|
+
/** Where one settled load's bytes actually came from. */
|
|
55
|
+
interface IResolvedAsset {
|
|
56
|
+
readonly url: string;
|
|
57
|
+
readonly via: AssetSource;
|
|
58
|
+
}
|
|
59
|
+
interface ITextureOptions {
|
|
60
|
+
/**
|
|
61
|
+
* The pixels are data, not colour: a normal map, a roughness map, a mask. Data textures are
|
|
62
|
+
* sampled without a colour-space conversion, which is wrong for an albedo and right for these.
|
|
63
|
+
* Left out, the copy is sRGB — the space an image file is authored in. A loader leaves a plain
|
|
64
|
+
* image linear, which washes out every albedo, so an options call never inherits that.
|
|
65
|
+
*/
|
|
66
|
+
readonly data?: boolean;
|
|
67
|
+
/** Both axes at once. Absent leaves the loaded texture's own wrapping. */
|
|
68
|
+
readonly wrap?: Wrapping;
|
|
69
|
+
/** Tiling counts, one for both axes or one per axis. Absent leaves the loaded texture's own. */
|
|
70
|
+
readonly repeat?: number | readonly [number, number];
|
|
71
|
+
/** Samples to take at grazing angles. Absent leaves the loaded texture's own. */
|
|
72
|
+
readonly anisotropy?: number;
|
|
73
|
+
}
|
|
52
74
|
interface IAssetLoader {
|
|
53
75
|
readonly compressedTextures?: ICompressedTextureSupport;
|
|
54
76
|
model<T = unknown>(path: string): Promise<T>;
|
|
55
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Load a texture, optionally configured in one call.
|
|
79
|
+
*
|
|
80
|
+
* @situation set color space, wrap, repeat or anisotropy on a loaded texture
|
|
81
|
+
*
|
|
82
|
+
* With no options this is the shared cached instance, exactly as before. With options it is a
|
|
83
|
+
* copy of it: the cached texture is shared by every other caller of that path, and a wrap or a
|
|
84
|
+
* colour-space write on it would silently change how another material draws.
|
|
85
|
+
*/
|
|
86
|
+
texture(path: string, options?: ITextureOptions): Promise<Texture>;
|
|
56
87
|
audio(path: string): Promise<AudioBuffer>;
|
|
57
88
|
release(kind: "audio" | "model" | "texture", path: string): boolean;
|
|
58
89
|
/**
|
|
@@ -74,11 +105,29 @@ interface IAssetLoader {
|
|
|
74
105
|
* stay 0 for a game with no manifest, where no size is knowable before the bytes arrive.
|
|
75
106
|
*/
|
|
76
107
|
readonly progress: {
|
|
108
|
+
/**
|
|
109
|
+
* The logical paths asked for and not yet settled, in request order. A loading screen that
|
|
110
|
+
* only shows a ratio cannot say *what* it is waiting for, which is the difference between
|
|
111
|
+
* "still loading" and "stuck on `akagi.glb`" — and a stall report that names nothing is a
|
|
112
|
+
* bug report nobody can act on.
|
|
113
|
+
*/
|
|
114
|
+
readonly pending: readonly string[];
|
|
77
115
|
readonly requested: number;
|
|
78
116
|
readonly requestedBytes: number;
|
|
79
117
|
readonly settled: number;
|
|
80
118
|
readonly settledBytes: number;
|
|
81
119
|
};
|
|
120
|
+
/**
|
|
121
|
+
* Where each settled load was actually served from, keyed by the logical path asked for.
|
|
122
|
+
*
|
|
123
|
+
* `progress` counts loads and cannot say which of a path's candidate urls answered, so a game
|
|
124
|
+
* whose manifest 404s and a game whose manifest named the output look identical from the game's
|
|
125
|
+
* own side — which is how an unreadable manifest became a silent uncompiled fallback on the
|
|
126
|
+
* native hosts, where a failed read arrives as a rejected fetch rather than a 404. `via` is
|
|
127
|
+
* `"manifest"` only for the compiled output the manifest named; `"source"` is the verbatim or
|
|
128
|
+
* source-directory path, and an external url, which no manifest governs.
|
|
129
|
+
*/
|
|
130
|
+
readonly resolved: ReadonlyMap<string, IResolvedAsset>;
|
|
82
131
|
clear(): void;
|
|
83
132
|
}
|
|
84
133
|
/**
|
|
@@ -100,4 +149,4 @@ interface IAssetLoader {
|
|
|
100
149
|
declare function reconcileMirroredClips(root: Object3D, clips: readonly AnimationClip[]): boolean;
|
|
101
150
|
declare function createAssetLoader(options?: IAssetLoaderOptions): IAssetLoader;
|
|
102
151
|
|
|
103
|
-
export { type IAssetLoader as I, type IAssetLoaderOptions as a, createAssetLoader as c, reconcileMirroredClips as r };
|
|
152
|
+
export { type IAssetLoader as I, type IAssetLoaderOptions as a, type ITextureOptions as b, createAssetLoader as c, reconcileMirroredClips as r };
|
|
@@ -14,6 +14,15 @@ interface IAudioBusOptions {
|
|
|
14
14
|
readonly maxVoices?: number;
|
|
15
15
|
}
|
|
16
16
|
interface IAudioPlayOptions {
|
|
17
|
+
/**
|
|
18
|
+
* What this cue is, for anything reading back what the game played — a playtest above all.
|
|
19
|
+
*
|
|
20
|
+
* Nothing about the sound changes. Every other audio check answers "is the file right": that it
|
|
21
|
+
* exists, decodes, and is inside its byte budget. None of them can answer "did the game say the
|
|
22
|
+
* general-quarters line twice", which is the class of defect players actually report, so the bus
|
|
23
|
+
* keeps a ledger of the labels it was given.
|
|
24
|
+
*/
|
|
25
|
+
readonly cue?: string;
|
|
17
26
|
readonly fade?: number;
|
|
18
27
|
readonly loop?: boolean;
|
|
19
28
|
readonly volume?: number;
|
|
@@ -49,6 +58,21 @@ interface IAudioPlayOptions {
|
|
|
49
58
|
readonly lowpassHz?: number;
|
|
50
59
|
}
|
|
51
60
|
interface IAudioRuntimeSnapshot {
|
|
61
|
+
/**
|
|
62
|
+
* How many times each labelled cue has sounded, across every live bus.
|
|
63
|
+
*
|
|
64
|
+
* This is the only observation that can answer "what did the game actually say, and how often".
|
|
65
|
+
* Every other audio check in the repository is about the *file* — that it exists, decodes and is
|
|
66
|
+
* inside its budget — and all of them stay green while a one-shot line plays a second time
|
|
67
|
+
* halfway through a match, which is the defect players report. A game opts a cue in by passing
|
|
68
|
+
* `cue` to `play`/`playAt`; unlabelled sounds never appear here.
|
|
69
|
+
*/
|
|
70
|
+
readonly cues: Readonly<Record<string, number>>;
|
|
71
|
+
/** The most recent labelled cues in the order they sounded, bounded per bus. */
|
|
72
|
+
readonly recentCues: ReadonlyArray<{
|
|
73
|
+
readonly atMs: number;
|
|
74
|
+
readonly cue: string;
|
|
75
|
+
}>;
|
|
52
76
|
readonly queued: number;
|
|
53
77
|
readonly voices: number;
|
|
54
78
|
/** Retired voices held for reuse. Bounded by peak concurrency, never by session length. */
|
|
@@ -67,6 +91,13 @@ interface IAudioRuntimeSnapshot {
|
|
|
67
91
|
*/
|
|
68
92
|
readonly unsupported: readonly string[];
|
|
69
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Forgets every recorded cue.
|
|
96
|
+
*
|
|
97
|
+
* @situation clear the recorded audio cue counts between tests so one test cannot read another's plays
|
|
98
|
+
* @example resetAudioCueLedger();
|
|
99
|
+
*/
|
|
100
|
+
declare function resetAudioCueLedger(): void;
|
|
70
101
|
declare class AudioBus {
|
|
71
102
|
#private;
|
|
72
103
|
readonly listener: AudioListener;
|
|
@@ -153,4 +184,4 @@ declare class AudioBus {
|
|
|
153
184
|
}
|
|
154
185
|
declare function audioRuntimeSnapshot(): IAudioRuntimeSnapshot;
|
|
155
186
|
|
|
156
|
-
export { AudioBus as A, type IAudioBusOptions as I, audioRuntimeSnapshot as a, type IAudioPlayOptions as b };
|
|
187
|
+
export { AudioBus as A, type IAudioBusOptions as I, audioRuntimeSnapshot as a, type IAudioPlayOptions as b, resetAudioCueLedger as r };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as three from 'three';
|
|
2
2
|
import { Camera, Vector2, Vector3, Scene, OrthographicCamera } from 'three';
|
|
3
|
-
import { I as IRendererLike } from './renderer-
|
|
3
|
+
import { I as IRendererLike } from './renderer-CfsS2hxi.js';
|
|
4
4
|
|
|
5
5
|
interface IViewportSize {
|
|
6
6
|
readonly aspect: number;
|