@ludic-labs/assembly 0.0.0-stage → 0.4.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 +78 -0
- package/LICENSE +2 -0
- package/README.md +50 -2
- package/dist/bake.d.ts +80 -0
- package/dist/bake.js +214 -0
- package/dist/browser.d.ts +89 -0
- package/dist/browser.js +534 -0
- package/dist/compat.d.ts +17 -0
- package/dist/compat.js +153 -0
- package/dist/compiler.d.ts +18 -0
- package/dist/compiler.js +1264 -0
- package/dist/diagnostics.d.ts +5 -0
- package/dist/diagnostics.js +8 -0
- package/dist/export.d.ts +54 -0
- package/dist/export.js +272 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/legacy.d.ts +36 -0
- package/dist/legacy.js +180 -0
- package/dist/math.d.ts +16 -0
- package/dist/math.js +62 -0
- package/dist/mesh.d.ts +11 -0
- package/dist/mesh.js +153 -0
- package/dist/motion.d.ts +63 -0
- package/dist/motion.js +1476 -0
- package/dist/pixel.d.ts +268 -0
- package/dist/pixel.js +942 -0
- package/dist/required.d.ts +2 -0
- package/dist/required.js +6 -0
- package/dist/shapes.d.ts +71 -0
- package/dist/shapes.js +396 -0
- package/dist/sprite-brief.d.ts +5 -0
- package/dist/sprite-brief.js +47 -0
- package/dist/sprite-compiler.d.ts +62 -0
- package/dist/sprite-compiler.js +1745 -0
- package/dist/sprite-decompile.d.ts +68 -0
- package/dist/sprite-decompile.js +786 -0
- package/dist/sprite-format.d.ts +4 -0
- package/dist/sprite-format.js +155 -0
- package/dist/sprite-guide.d.ts +40 -0
- package/dist/sprite-guide.js +330 -0
- package/dist/sprite-scene.d.ts +277 -0
- package/dist/sprite-scene.js +664 -0
- package/dist/sprite-types.d.ts +110 -0
- package/dist/sprite-types.js +1 -0
- package/dist/sprite.d.ts +8 -0
- package/dist/sprite.js +8 -0
- package/dist/svg/schema.d.ts +71 -0
- package/dist/svg/schema.js +217 -0
- package/dist/svg/types.d.ts +148 -0
- package/dist/svg/types.js +1 -0
- package/dist/svg.d.ts +26 -0
- package/dist/svg.js +539 -0
- package/dist/text.d.ts +12 -0
- package/dist/text.js +75 -0
- package/dist/types.d.ts +478 -0
- package/dist/types.js +1 -0
- package/docs/svg/README.md +150 -0
- package/docs/svg/specification.md +108 -0
- package/examples/svg/arcane-shield.json +261 -0
- package/examples/svg/aurora-ribbon.json +158 -0
- package/examples/svg/bouncing-ember.json +76 -0
- package/examples/svg/ember-fountain.json +224 -0
- package/examples/svg/lantern-keeper.json +1159 -0
- package/examples/svg/night-workshop.json +1120 -0
- package/examples/svg/waygate-platform.json +64 -0
- package/examples/svg/waygate-spark.json +92 -0
- package/examples/svg/waygate-wisp.json +105 -0
- package/examples/svg/waygate.json +485 -0
- package/package.json +132 -4
- package/schemas/asset-assembly-0.1.schema.json +354 -0
- package/schemas/asset-assembly-0.2.schema.json +429 -0
- package/schemas/asset-assembly-0.3.schema.json +572 -0
- package/schemas/motion-set-0.1.schema.json +178 -0
- package/schemas/pixel-sprite-0.1.schema.json +892 -0
- package/schemas/pixel-sprite-scene-0.1.schema.json +149 -0
- package/schemas/svg-asset-0.1.schema.json +1157 -0
- package/tools/svg-asset.mjs +106 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import type { AssetSpec, CompiledAsset, Vec3 } from "./types.js";
|
|
2
|
+
import type { PixelCamera } from "./pixel.js";
|
|
3
|
+
import type { SpriteView, SpriteResult, SpriteDocument } from "./sprite-types.js";
|
|
4
|
+
export interface SpriteSceneDocument {
|
|
5
|
+
format: "pixel-sprite-scene/0.1";
|
|
6
|
+
id?: string;
|
|
7
|
+
title?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
units?: "meters";
|
|
10
|
+
notes?: unknown;
|
|
11
|
+
pixelsPerMetre: number;
|
|
12
|
+
outline: string;
|
|
13
|
+
assets: Record<string, {
|
|
14
|
+
sprite: string;
|
|
15
|
+
states?: Record<string, {
|
|
16
|
+
clip: string;
|
|
17
|
+
phase: number;
|
|
18
|
+
}>;
|
|
19
|
+
}>;
|
|
20
|
+
placements: SpriteScenePlacement[];
|
|
21
|
+
views: Record<string, {
|
|
22
|
+
camera: SpriteView["camera"];
|
|
23
|
+
hide?: string[];
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
export interface SpriteScenePlacement {
|
|
27
|
+
id: string;
|
|
28
|
+
asset: string;
|
|
29
|
+
position: Vec3;
|
|
30
|
+
yaw?: number;
|
|
31
|
+
tint?: string | null;
|
|
32
|
+
order?: "back";
|
|
33
|
+
states?: string[];
|
|
34
|
+
}
|
|
35
|
+
export interface SpriteSceneAsset {
|
|
36
|
+
ref: string;
|
|
37
|
+
spec: AssetSpec;
|
|
38
|
+
compiled: CompiledAsset;
|
|
39
|
+
motion: unknown;
|
|
40
|
+
sprite: string;
|
|
41
|
+
states: Record<string, {
|
|
42
|
+
clip: string;
|
|
43
|
+
phase: number;
|
|
44
|
+
}>;
|
|
45
|
+
}
|
|
46
|
+
export type SpriteSceneResolver = (ref: string) => {
|
|
47
|
+
spec: AssetSpec;
|
|
48
|
+
motion?: unknown;
|
|
49
|
+
};
|
|
50
|
+
export interface SpriteScene {
|
|
51
|
+
scene: SpriteSceneDocument;
|
|
52
|
+
assets: Map<string, SpriteSceneAsset>;
|
|
53
|
+
placements: (SpriteScenePlacement & {
|
|
54
|
+
yaw: number;
|
|
55
|
+
tint: string | null;
|
|
56
|
+
})[];
|
|
57
|
+
}
|
|
58
|
+
export interface SpriteSceneOptions {
|
|
59
|
+
states?: Record<string, string>;
|
|
60
|
+
background?: string | null;
|
|
61
|
+
depth?: "parts" | "placements";
|
|
62
|
+
}
|
|
63
|
+
export interface SpriteSceneImage {
|
|
64
|
+
view: string;
|
|
65
|
+
width: number;
|
|
66
|
+
height: number;
|
|
67
|
+
rgba: Uint8Array;
|
|
68
|
+
owner: Int32Array;
|
|
69
|
+
part: (string | null)[];
|
|
70
|
+
placed: {
|
|
71
|
+
id: string;
|
|
72
|
+
asset: string;
|
|
73
|
+
state: string;
|
|
74
|
+
cel: string;
|
|
75
|
+
at: [number, number];
|
|
76
|
+
size: [number, number];
|
|
77
|
+
mask: number[];
|
|
78
|
+
}[];
|
|
79
|
+
skipped: string[];
|
|
80
|
+
}
|
|
81
|
+
export interface SpriteScenePalette {
|
|
82
|
+
palette: {
|
|
83
|
+
lock: boolean;
|
|
84
|
+
colors: Record<string, string>;
|
|
85
|
+
ramps: Record<string, string[]>;
|
|
86
|
+
};
|
|
87
|
+
materials: Record<string, Record<string, string>>;
|
|
88
|
+
}
|
|
89
|
+
/** Prepare a scene using caller-owned asset JSON; performs no IO. */
|
|
90
|
+
export declare function prepareSpriteScene(scene: SpriteSceneDocument, resolve: SpriteSceneResolver): SpriteScene;
|
|
91
|
+
export declare const cameraOf: (camera: SpriteView["camera"]) => PixelCamera;
|
|
92
|
+
/** Name of the asset view for a scene view and state ("dimetric", "dimetric-open"). */
|
|
93
|
+
export declare const assetViewName: (view: string, state?: string) => string;
|
|
94
|
+
/** Cel id a placement shows in a scene view and state. */
|
|
95
|
+
export declare const celIdFor: (view: string, state?: string) => string;
|
|
96
|
+
/**
|
|
97
|
+
* The asset-local view a placement needs: a placement with yaw ψ seen by a
|
|
98
|
+
* camera of yaw φ is its asset seen from yaw φ − ψ at the same pitch.
|
|
99
|
+
*/
|
|
100
|
+
export declare function placementView(loaded: SpriteScene, placement: SpriteScene["placements"][number], view: string, state?: string): SpriteView;
|
|
101
|
+
/** The states an asset offers, idle first. */
|
|
102
|
+
export declare const statesOf: (loaded: SpriteScene, ref: string) => string[];
|
|
103
|
+
/** The `views` object an asset's sprite document must declare, and the cels it must contain. */
|
|
104
|
+
export declare function assetViews(loaded: SpriteScene, ref: string): {
|
|
105
|
+
views: Record<string, SpriteView>;
|
|
106
|
+
cels: string[];
|
|
107
|
+
};
|
|
108
|
+
/** Scene instances for a view (cutaways applied), optionally only some placements, with states. */
|
|
109
|
+
export declare function sceneInstances(loaded: SpriteScene, view: string, { only, states }?: {
|
|
110
|
+
only?: string[] | null;
|
|
111
|
+
states?: Record<string, string>;
|
|
112
|
+
}): import("./pixel.js").PixelInstance[];
|
|
113
|
+
/**
|
|
114
|
+
* The scene's pixel grid in a view: canvas size and the world position of its
|
|
115
|
+
* top-left corner along camera right and up, fitted to every placement at rest.
|
|
116
|
+
*/
|
|
117
|
+
export declare function sceneFrame(loaded: SpriteScene, view: string, margin?: number): {
|
|
118
|
+
camera: PixelCamera;
|
|
119
|
+
ppm: number;
|
|
120
|
+
width: number;
|
|
121
|
+
height: number;
|
|
122
|
+
originX: number;
|
|
123
|
+
originY: number;
|
|
124
|
+
frame: {
|
|
125
|
+
center: Vec3;
|
|
126
|
+
width: number;
|
|
127
|
+
height: number;
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
/** 3D reference render (arcade profile) of the scene, or of some placements, on the scene grid. */
|
|
131
|
+
export declare function sceneRender(loaded: SpriteScene, view: string, { only, states, background, }?: {
|
|
132
|
+
only?: string[] | null;
|
|
133
|
+
states?: Record<string, string>;
|
|
134
|
+
background?: string | null;
|
|
135
|
+
}): import("./pixel.js").PixelImage;
|
|
136
|
+
/** Screen offset (pixels, unrounded) of a placement's asset-local origin on the scene grid. */
|
|
137
|
+
export declare function placementOffset(loaded: SpriteScene, placement: SpriteScene["placements"][number], view: string): {
|
|
138
|
+
x: number;
|
|
139
|
+
y: number;
|
|
140
|
+
depth: number;
|
|
141
|
+
};
|
|
142
|
+
/** Materials closer than this in OKLab share one ramp. */
|
|
143
|
+
export declare const MERGE_DISTANCE = 0.015;
|
|
144
|
+
/**
|
|
145
|
+
* One locked palette for the whole scene: four tones (deep, shadow, mid,
|
|
146
|
+
* light) per material colour as placed (tints applied), from the /pixel arcade
|
|
147
|
+
* ramp, with near-identical materials merged, plus the shared outline `line`.
|
|
148
|
+
* Returns the palette, and per asset the ramp of each material.
|
|
149
|
+
*/
|
|
150
|
+
export declare function scenePalette(loaded: SpriteScene): SpriteScenePalette;
|
|
151
|
+
/**
|
|
152
|
+
* A short descriptive name for a colour from its OKLab value ("pale-teal",
|
|
153
|
+
* "dark-red", "cream", "charcoal"), so ramps read as what they look like.
|
|
154
|
+
*/
|
|
155
|
+
export declare function colourName([L, a, b]: Vec3): string;
|
|
156
|
+
/** The palette subset an asset's document uses: its materials' ramps and the outline. */
|
|
157
|
+
export declare function assetPalette(shared: SpriteScenePalette, ref: string): SpriteScenePalette["palette"];
|
|
158
|
+
/** Per part of an asset: its material and the scene ramp that material uses. */
|
|
159
|
+
export declare function partRamps(loaded: SpriteScene, shared: SpriteScenePalette, ref: string): Record<string, {
|
|
160
|
+
material: string;
|
|
161
|
+
ramp: string | null;
|
|
162
|
+
}>;
|
|
163
|
+
/** Compiles one asset's document with the kitchen resolvers and checks it against the scene's contract. */
|
|
164
|
+
export declare function compileAssetSprite(loaded: SpriteScene, shared: SpriteScenePalette, ref: string, input: SpriteDocument): {
|
|
165
|
+
result: SpriteResult;
|
|
166
|
+
problems: string[];
|
|
167
|
+
cels: string[];
|
|
168
|
+
};
|
|
169
|
+
/** Share of two placements' 3D overlap that must disagree before their draw order is reported as wrong. */
|
|
170
|
+
export declare const ORDER_SHARE = 0.25;
|
|
171
|
+
/** Back-to-front order: "back" placements (the room) first, then by bounds-centre depth. */
|
|
172
|
+
export declare function drawOrder(loaded: SpriteScene, view: string, states?: Record<string, string>): (SpriteScenePlacement & {
|
|
173
|
+
yaw: number;
|
|
174
|
+
tint: string | null;
|
|
175
|
+
})[];
|
|
176
|
+
/** One placement's drawn cel, placed on a scene grid with a depth per pixel. */
|
|
177
|
+
export interface SpriteSceneLayer {
|
|
178
|
+
id: string;
|
|
179
|
+
asset: string;
|
|
180
|
+
state: string;
|
|
181
|
+
cel: string;
|
|
182
|
+
/** Top-left of the cel on the scene grid. */
|
|
183
|
+
at: [number, number];
|
|
184
|
+
width: number;
|
|
185
|
+
height: number;
|
|
186
|
+
rgba: Uint8Array;
|
|
187
|
+
/** Per cel pixel: index into `parts`, or -1. */
|
|
188
|
+
owners: Int32Array;
|
|
189
|
+
parts: string[];
|
|
190
|
+
/** Per cel pixel: distance toward the camera (larger is nearer); NaN where empty. */
|
|
191
|
+
depth: Float64Array;
|
|
192
|
+
/** "back" placements (a room) are behind everything. */
|
|
193
|
+
back: boolean;
|
|
194
|
+
/** Draw-order key: depth of the placement's (posed) bounds centre. */
|
|
195
|
+
order: number;
|
|
196
|
+
}
|
|
197
|
+
export interface SpriteSceneLayers {
|
|
198
|
+
view: string;
|
|
199
|
+
width: number;
|
|
200
|
+
height: number;
|
|
201
|
+
layers: SpriteSceneLayer[];
|
|
202
|
+
skipped: string[];
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* The layers of one view: per placement, its cel for the state in `states`
|
|
206
|
+
* (or, with `allStates`, one layer for idle and each state the placement
|
|
207
|
+
* offers in its `states` list), placed
|
|
208
|
+
* by its guide's origin, with a 3D depth per pixel. `depth: "parts"` (default)
|
|
209
|
+
* takes the depth of the guide's projected surface under each pixel (plus the
|
|
210
|
+
* placement's translation), else the mean depth of the part that owns it, else
|
|
211
|
+
* the nearest among its neighbours (outlines, details drawn beyond the
|
|
212
|
+
* projection), else the placement's centre. `depth: "placements"` gives every
|
|
213
|
+
* pixel the placement's centre depth. Placements without a compiled sprite are
|
|
214
|
+
* skipped and listed. The result can be composed many times, with different
|
|
215
|
+
* states, by `composeSpriteLayers` (for example in a browser).
|
|
216
|
+
*/
|
|
217
|
+
export declare function spriteSceneLayers(loaded: SpriteScene, view: string, sprites: Map<string, SpriteResult>, { states, depth, allStates }?: SpriteSceneOptions & {
|
|
218
|
+
allStates?: boolean;
|
|
219
|
+
}): SpriteSceneLayers;
|
|
220
|
+
/**
|
|
221
|
+
* Composes layers (from `spriteSceneLayers`) with a depth buffer: per
|
|
222
|
+
* placement the layer for its state in `states` (default "idle"), drawn
|
|
223
|
+
* "back" placements first, then by the order key and id, keeping the nearest
|
|
224
|
+
* pixel (later layers win ties). Host independent and cheap enough to run on
|
|
225
|
+
* every toggle in a browser.
|
|
226
|
+
*/
|
|
227
|
+
export declare function composeSpriteLayers(built: SpriteSceneLayers, { states, background }?: {
|
|
228
|
+
states?: Record<string, string>;
|
|
229
|
+
background?: string | null;
|
|
230
|
+
}): SpriteSceneImage;
|
|
231
|
+
/**
|
|
232
|
+
* Composes one view. `sprites` maps an asset ref to its compiled result;
|
|
233
|
+
* `states` maps a placement id to a state ("open"). Equivalent to
|
|
234
|
+
* `composeSpriteLayers(spriteSceneLayers(...))`: pixels sort by the 3D depth
|
|
235
|
+
* under them, so a non-convex object such as an open door sorts pixel by
|
|
236
|
+
* pixel; "back" placements are always behind; `depth: "placements"` is plain
|
|
237
|
+
* back-to-front drawing by bounds centre.
|
|
238
|
+
*/
|
|
239
|
+
export declare function composeSpriteScene(loaded: SpriteScene, view: string, sprites: Map<string, SpriteResult>, { states, background, depth }?: SpriteSceneOptions): SpriteSceneImage;
|
|
240
|
+
/** Placement and part under a scene pixel, or null. */
|
|
241
|
+
export declare function pickScene(composed: SpriteSceneImage, x: number, y: number): {
|
|
242
|
+
placement: string;
|
|
243
|
+
part: string | null;
|
|
244
|
+
} | null;
|
|
245
|
+
/**
|
|
246
|
+
* Footprint report: per placed sprite, overlap with the placement's own
|
|
247
|
+
* (unoccluded) 3D mask, the integer shift within ±3 px that maximises it, and
|
|
248
|
+
* draw-order disagreements with the 3D scene render.
|
|
249
|
+
*/
|
|
250
|
+
export declare function spriteSceneFootprint(loaded: SpriteScene, composed: SpriteSceneImage, { states }?: {
|
|
251
|
+
states?: Record<string, string>;
|
|
252
|
+
}): SpriteSceneFootprint;
|
|
253
|
+
export interface SpriteSceneFootprint {
|
|
254
|
+
view: string;
|
|
255
|
+
placements: {
|
|
256
|
+
placement: string;
|
|
257
|
+
asset: string;
|
|
258
|
+
state: string;
|
|
259
|
+
spritePixels: number;
|
|
260
|
+
modelPixels: number;
|
|
261
|
+
iou: number;
|
|
262
|
+
bestShift: number[];
|
|
263
|
+
bestIou: number;
|
|
264
|
+
misaligned: boolean;
|
|
265
|
+
index: number;
|
|
266
|
+
}[];
|
|
267
|
+
orderDisagreements: {
|
|
268
|
+
pair: string;
|
|
269
|
+
pixels: number;
|
|
270
|
+
share: number;
|
|
271
|
+
}[];
|
|
272
|
+
wrongOrder: {
|
|
273
|
+
pair: string;
|
|
274
|
+
pixels: number;
|
|
275
|
+
share: number;
|
|
276
|
+
}[];
|
|
277
|
+
}
|