ldr 0.4.1 → 0.5.1

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.
@@ -0,0 +1,17 @@
1
+ /** Vertex-cache + vertex-fetch order (meshoptimizer): reorders triangles for post-transform cache reuse, then vertices by first use. */
2
+ export declare function reorderMesh(P: ArrayLike<number>, N: ArrayLike<number>, C: ArrayLike<number>, I: ArrayLike<number>): {
3
+ P: Float32Array<ArrayBuffer>;
4
+ N: Float32Array<ArrayBuffer>;
5
+ C: Float32Array<ArrayBuffer>;
6
+ I: Uint32Array<ArrayBuffer>;
7
+ };
8
+ /** Welded, flat-shaded mesh: positions / normals (3 per vertex), colours (rgba per vertex), triangle indices. */
9
+ export type LodMesh = {
10
+ P: Float32Array;
11
+ N: Float32Array;
12
+ C: Float32Array;
13
+ I: Uint32Array;
14
+ err: number;
15
+ };
16
+ /** Simplified levels of a welded mesh (positions P, rgba C per vertex, triangles I). Empty when the mesh is too small to benefit. */
17
+ export declare function lodChain(P: ArrayLike<number>, C: ArrayLike<number>, I: ArrayLike<number>): LodMesh[];
package/dist/render.d.ts CHANGED
@@ -12,16 +12,33 @@ export type LdrParams = {
12
12
  condStuds?: boolean;
13
13
  /** Draw textured (!TEXMAP) parts with their PNGs when the pack carries them (pack v2 "tex", `ldr pack --textures`). Default true. */
14
14
  tex?: boolean;
15
+ /** Compact vertex formats (int8 normals, uint8 colours). Default true. */
16
+ quant?: boolean;
17
+ /** Distance LOD: spatial clusters per part, simplified meshes from `lod` packs, studs dropped and edges hidden once sub-pixel. Default true. */
18
+ lod?: boolean;
19
+ /** LOD: max screen-space error in pixels (default 0.5). */
20
+ lodPx?: number;
21
+ /** LOD: draw edge lines only where one stud (20 LDU) spans at least this many pixels (default 0.5; 0 = always). */
22
+ lodEdgePx?: number;
23
+ /** LOD: drop sub-pixel studs (default true). */
24
+ lodStuds?: boolean;
25
+ /** LOD: use simplified meshes from `lod` packs (default true). */
26
+ lodMesh?: boolean;
27
+ /** Global build step per instance (same order as `insts`). Enables `setStep`: steps become instance-buffer compaction with
28
+ * step-aware culling instead of a rebuild. */
29
+ steps?: ArrayLike<number>;
15
30
  };
16
31
  export type Inst = {
17
32
  part: string;
18
33
  color: string;
19
34
  m: number[];
20
35
  };
36
+ /** A decoded parts pack. `buffer` is the raw (uncompressed) pack, used by `mergePacks`. */
21
37
  export type Pack = {
22
38
  header: any;
23
39
  arr: (r: any) => any;
24
40
  bytes: number;
41
+ buffer?: ArrayBuffer;
25
42
  };
26
43
  export declare function loadPack(url: string): Promise<Pack>;
27
44
  /** Decode an uncompressed parts pack (4-byte LE header length, JSON header, then aligned typed-array payload). */
@@ -47,6 +64,24 @@ export declare function conditionalLineVisible(cond: ArrayLike<number>, i: numbe
47
64
  * `cond` is part-space stride 12 (p0, p1, c0, c1), e.g. from `conditionalLines(pack, pack.header.parts[name])`.
48
65
  * GPU cost: 2 vertices x 13 floats per line (104 B/line), per part, not per instance. Keep `geometry.instanceCount` in sync with `im.count`. */
49
66
  export declare function createInstancedConditionalEdges(cond: ArrayLike<number>, im: THREE.InstancedMesh, material?: THREE.Material): THREE.LineSegments;
67
+ /** Culling result in flat arrays. Studs are enumerated in instance order, then each part's `studs` order (the order `forEachStud` visits). */
68
+ export type CullResult = {
69
+ nStuds: number;
70
+ studHidden: Uint8Array;
71
+ studUp: Uint8Array;
72
+ underHidden: Uint8Array;
73
+ studsHidden: number;
74
+ /** With `steps`: the first build step at which each stud / underside is hidden (STEP_NEVER = never), for step-aware culling. */
75
+ studHideStep?: Int32Array;
76
+ underHideStep?: Int32Array;
77
+ };
78
+ /** `studHideStep` / `underHideStep` value for "never hidden". */
79
+ export declare const STEP_NEVER = 2147483647;
80
+ /** Visit every stud (instance order, then part stud order) with its world matrix `w` (scratch; copy to keep). */
81
+ export declare function forEachStud(insts: Inst[], H: any, fn: (j: number, inst: number, w: Float64Array, kind: string, color: string, stud: number) => void): void;
82
+ /** `steps` (optional, per instance): also compute when each stud / underside becomes hidden as the model is built step by step. */
83
+ export declare function cullCore(insts: Inst[], H: any, steps?: ArrayLike<number>): CullResult;
84
+ /** Object-shaped culling result (one entry per stud with its world matrix). Kept for API compatibility; `buildLdrScene` uses `cullCore`. */
50
85
  export declare function computeCulling(insts: Inst[], H: any): {
51
86
  studs: {
52
87
  kind: string;
@@ -57,13 +92,20 @@ export declare function computeCulling(insts: Inst[], H: any): {
57
92
  underHidden: boolean[];
58
93
  };
59
94
  export declare function buildLdrScene(insts: Inst[], pack: Pack, P: LdrParams, color: (c: string) => THREE.Color, mark: (k: string) => void): {
60
- root: THREE.Group<THREE.Object3DEventMap>;
95
+ root: THREE.Group;
61
96
  stats: any;
62
97
  setCull: (studs: boolean, under: boolean) => void;
63
98
  setSide: (front: boolean) => void;
64
99
  setEdges: (v: boolean) => void;
65
100
  setCond: (v: boolean) => void;
66
101
  swapStuds: (alt: any) => () => void;
102
+ setLod: (on: boolean) => void;
103
+ setStep: (s: number | null) => {
104
+ studsTotal: number;
105
+ studsHidden: number;
106
+ undersTotal: number;
107
+ undersHidden: number;
108
+ };
67
109
  box: THREE.Box3;
68
110
  texturesReady: Promise<void>;
69
111
  };
package/dist/scene.d.ts CHANGED
@@ -33,6 +33,15 @@ export interface LdrObjectOptions {
33
33
  scale?: number;
34
34
  /** Initial step (inclusive, 0-based global sequence from `sequenceSteps`). Default: show all. */
35
35
  step?: number;
36
+ /** Distance LOD, re-selected for each camera you render with. Default true. Batches are split into spatial clusters (so off-screen
37
+ * ones are frustum-culled); each cluster draws the coarsest simplified mesh (from `lod` packs, the `buildPack` default) whose error
38
+ * stays under `lodPx`, drops studs whose 12-LDU disc is under `lodPx`, and hides edge lines where a stud spans under `lodEdgePx`.
39
+ * Datsville 100k on an M4 Pro: 22 -> 6.3 ms per frame (57 -> 9.7 ms with edges); <=1.6% of pixels differ, mostly stud moire. */
40
+ lod?: boolean;
41
+ /** LOD: max screen-space error in pixels. Default 0.5. */
42
+ lodPx?: number;
43
+ /** LOD: draw edge / conditional lines only where one stud (20 LDU) spans at least this many pixels. Default 0.5; 0 = always. */
44
+ lodEdgePx?: number;
36
45
  }
37
46
  export interface LdrStats {
38
47
  instances: number;
@@ -48,6 +57,8 @@ export interface LdrStats {
48
57
  /** Textured batches (one per part x texture) and distinct textures; 0 for packs without textures. */
49
58
  texBatches?: number;
50
59
  textures?: number;
60
+ /** Drawable clusters (LOD / frustum-culling units). */
61
+ clusters?: number;
51
62
  }
52
63
  export interface LdrObject {
53
64
  /** Add this to your scene. */
@@ -58,15 +69,18 @@ export interface LdrObject {
58
69
  /** Per build step, the view rotation set by MLCad `0 ROTSTEP` (null = default view). Get the 3x3 (LDraw space, row-major) with
59
70
  * `stepViewMatrix(view, yourDefaultView)`; in three.js terms rotate the model by it inside the object's -Y-up flip. */
60
71
  stepViews: (StepView | null)[];
61
- /** Show instances up to and including `step` (null = all). Rebuilds batches; culling is recomputed for the partial model. */
72
+ /** Show instances up to and including `step` (null = all). No rebuild: instance buffers are compacted, and culling is step-aware
73
+ * (a stud covered only by a later step's part stays visible). `stats` reflect the shown step. */
62
74
  setStep(step: number | null): void;
63
75
  setEdges(on: boolean): void;
64
- /** Resolves when the pack's textures (if any) are decoded and ready to render. Replaced by a new promise after `setStep`. */
76
+ /** Resolves when the pack's textures (if any) are decoded and ready to render. */
65
77
  texturesReady: Promise<void>;
66
78
  /** Toggle conditional lines (only visible while edges are on). */
67
79
  setConditionalLines(on: boolean): void;
68
80
  setCulling(studs: boolean, undersides: boolean): void;
69
81
  setSide(side: "front" | "double"): void;
82
+ /** Turn distance LOD on/off (off = full detail and edges everywhere). Only has an effect if the object was built with `lod` (default). */
83
+ setLod(on: boolean): void;
70
84
  /** Bounding box in the object's parent space. */
71
85
  getBox(target?: THREE.Box3): THREE.Box3;
72
86
  dispose(): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ldr",
3
- "version": "0.4.1",
3
+ "version": "0.5.1",
4
4
  "description": "High-performance LEGO (LDraw) rendering for three.js: instanced parts packs, hidden stud/tube culling, low-detail studs, indexed edges, build steps.",
5
5
  "license": "MIT",
6
6
  "author": "Evan Bacon",
@@ -41,7 +41,7 @@
41
41
  "./package.json": "./package.json"
42
42
  },
43
43
  "bin": {
44
- "ldr": "./dist/cli.js"
44
+ "ldr": "dist/cli.js"
45
45
  },
46
46
  "files": [
47
47
  "dist",
@@ -49,15 +49,16 @@
49
49
  "LICENSE"
50
50
  ],
51
51
  "scripts": {
52
- "build": "rm -rf dist && bun build src/index.ts --outdir dist --target browser --format esm --external three --external fzstd && bun build src/node/index.ts src/cli.ts --outdir dist --root src --target node --format esm --external three --external fzstd && tsc -p tsconfig.build.json && bun scripts/postbuild.ts",
52
+ "build": "rm -rf dist && bun scripts/build.ts && tsc -p tsconfig.build.json && bun scripts/postbuild.ts && node scripts/check-dist.mjs",
53
53
  "test": "bun test",
54
54
  "prepublishOnly": "bun run build && bun test"
55
55
  },
56
56
  "dependencies": {
57
- "fzstd": "^0.1.1"
57
+ "fzstd": "^0.1.1",
58
+ "meshoptimizer": "1.2.0"
58
59
  },
59
60
  "peerDependencies": {
60
- "three": ">=0.160.0"
61
+ "three": ">=0.151.0"
61
62
  },
62
63
  "devDependencies": {
63
64
  "@types/bun": "latest",