@driftengine/assets 3.61.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.
Files changed (100) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +9 -0
  3. package/README.md +9 -0
  4. package/dist/assetPath.d.ts +51 -0
  5. package/dist/assetPath.js +59 -0
  6. package/dist/coarseLevel.d.ts +94 -0
  7. package/dist/coarseLevel.js +606 -0
  8. package/dist/dds.d.ts +41 -0
  9. package/dist/dds.js +425 -0
  10. package/dist/drawKey.d.ts +64 -0
  11. package/dist/drawKey.js +42 -0
  12. package/dist/drftLoader.d.ts +420 -0
  13. package/dist/drftLoader.js +996 -0
  14. package/dist/drftTextures.d.ts +87 -0
  15. package/dist/drftTextures.js +138 -0
  16. package/dist/fbx.d.ts +86 -0
  17. package/dist/fbx.js +792 -0
  18. package/dist/fbxHarness.d.ts +68 -0
  19. package/dist/fbxHarness.js +185 -0
  20. package/dist/fbxInflate.d.ts +60 -0
  21. package/dist/fbxInflate.js +204 -0
  22. package/dist/fbxMaterial.d.ts +87 -0
  23. package/dist/fbxMaterial.js +345 -0
  24. package/dist/fbxRig.d.ts +130 -0
  25. package/dist/fbxRig.js +601 -0
  26. package/dist/gltf.d.ts +242 -0
  27. package/dist/gltf.js +904 -0
  28. package/dist/gltfAccessor.d.ts +2 -0
  29. package/dist/gltfAccessor.js +106 -0
  30. package/dist/gltfSkin.d.ts +32 -0
  31. package/dist/gltfSkin.js +144 -0
  32. package/dist/iesPhotometry.d.ts +44 -0
  33. package/dist/iesPhotometry.js +94 -0
  34. package/dist/imageInfo.d.ts +31 -0
  35. package/dist/imageInfo.js +119 -0
  36. package/dist/index.d.ts +58 -0
  37. package/dist/index.js +132 -0
  38. package/dist/kn5.d.ts +158 -0
  39. package/dist/kn5.js +557 -0
  40. package/dist/loadProgress.d.ts +118 -0
  41. package/dist/loadProgress.js +1 -0
  42. package/dist/localise.d.ts +35 -0
  43. package/dist/localise.js +253 -0
  44. package/dist/obj.d.ts +54 -0
  45. package/dist/obj.js +335 -0
  46. package/dist/orient.d.ts +104 -0
  47. package/dist/orient.js +241 -0
  48. package/dist/radianceHdr.d.ts +36 -0
  49. package/dist/radianceHdr.js +172 -0
  50. package/dist/readModel.d.ts +153 -0
  51. package/dist/readModel.js +386 -0
  52. package/dist/recognise.d.ts +38 -0
  53. package/dist/recognise.js +97 -0
  54. package/dist/stl.d.ts +22 -0
  55. package/dist/stl.js +131 -0
  56. package/dist/tangentOrder.d.ts +24 -0
  57. package/dist/tangentOrder.js +31 -0
  58. package/dist/threemf.d.ts +46 -0
  59. package/dist/threemf.js +254 -0
  60. package/dist/uploadBudget.d.ts +82 -0
  61. package/dist/uploadBudget.js +86 -0
  62. package/dist/usd.d.ts +49 -0
  63. package/dist/usd.js +542 -0
  64. package/dist/weld.d.ts +44 -0
  65. package/dist/weld.js +237 -0
  66. package/dist/zip.d.ts +35 -0
  67. package/dist/zip.js +110 -0
  68. package/package.json +61 -0
  69. package/src/assetPath.ts +79 -0
  70. package/src/coarseLevel.ts +720 -0
  71. package/src/dds.ts +507 -0
  72. package/src/drawKey.ts +91 -0
  73. package/src/drftLoader.ts +1197 -0
  74. package/src/drftTextures.ts +153 -0
  75. package/src/fbx.ts +934 -0
  76. package/src/fbxHarness.ts +215 -0
  77. package/src/fbxInflate.ts +258 -0
  78. package/src/fbxMaterial.ts +410 -0
  79. package/src/fbxRig.ts +652 -0
  80. package/src/gltf.ts +1161 -0
  81. package/src/gltfAccessor.ts +127 -0
  82. package/src/gltfSkin.ts +210 -0
  83. package/src/iesPhotometry.ts +136 -0
  84. package/src/imageInfo.ts +130 -0
  85. package/src/index.ts +162 -0
  86. package/src/kn5.ts +705 -0
  87. package/src/loadProgress.ts +131 -0
  88. package/src/localise.ts +275 -0
  89. package/src/obj.ts +386 -0
  90. package/src/orient.ts +262 -0
  91. package/src/radianceHdr.ts +195 -0
  92. package/src/readModel.ts +515 -0
  93. package/src/recognise.ts +124 -0
  94. package/src/stl.ts +147 -0
  95. package/src/tangentOrder.ts +32 -0
  96. package/src/threemf.ts +303 -0
  97. package/src/uploadBudget.ts +90 -0
  98. package/src/usd.ts +642 -0
  99. package/src/weld.ts +264 -0
  100. package/src/zip.ts +130 -0
package/dist/index.js ADDED
@@ -0,0 +1,132 @@
1
+ /*! DriftEngine | Copyright 2026 Drift Technologies | Apache-2.0 | https://github.com/drftrun/driftengine */
2
+ /**
3
+ * Reading a model, and getting it onto the GPU.
4
+ *
5
+ * Separate from `@driftengine/drft` because these need a renderer: the loader uploads, and
6
+ * the readers exist to produce something the loader can upload. A procedurally generated
7
+ * world imports none of this and pays for none of it.
8
+ */
9
+ /*
10
+ * And the whole load as one object: streamed, uploaded within a per-frame budget, faded in, and
11
+ * merged down to one draw per material at the end. What it reports is *phases as data* — a
12
+ * consumer writes the words, because what to call a stage is a decision about an audience.
13
+ */
14
+ export { DrftLoader } from './drftLoader.js';
15
+ /*
16
+ * The loader's own draw-call grouping, exported because a consumer counting draws needs it and was
17
+ * keeping a copy that could not be kept in step. See `drawKey.ts`.
18
+ */
19
+ export { drawKeyOf, resolveDrawGrouping } from './drawKey.js';
20
+ /* Addressing a texture by name, so a consumer never holds an ordinal. */
21
+ export { TextureSet, textureColorSpaces } from './drftTextures.js';
22
+ export { assetCandidates, basenameOf } from './assetPath.js';
23
+ /* An image identified from its own header, because a declared mime type is optional in glTF
24
+ and wrong often enough that reading the bytes is the only reliable answer. */
25
+ export { describeImage } from './imageInfo.js';
26
+ export { readGlb, gltfToMeshes } from './gltf.js';
27
+ export { parseObj, parseMtl } from './obj.js';
28
+ export { parseStl } from './stl.js';
29
+ /*
30
+ * Radiance RGBE, for an environment a scene did not photograph.
31
+ *
32
+ * Opt-in on exactly the terms SDF text is: a consumer that never loads an environment never
33
+ * imports this, ships none of it, and the engine still carries no image of its own. That is what
34
+ * keeps the zero-texture-files rule met on its own terms rather than waived.
35
+ */
36
+ export { readRadianceHdr } from './radianceHdr.js';
37
+ /* IESNA LM-63, on the same opt-in terms: a consumer that loads no profile ships no parser. */
38
+ export { readIesProfile } from './iesPhotometry.js';
39
+ /*
40
+ * The zip-container formats and the recognise-only tier, exported for the same reason as
41
+ * the readers above: every one of them is pure, takes its decompressor as a parameter and
42
+ * touches no filesystem, so a consumer that wants to open a dropped file in a worker can.
43
+ * See docs/FORMAT.md §3.3 for what that costs and why it is not the default.
44
+ */
45
+ export { parseUsda, usdzToMeshes } from './usd.js';
46
+ export { parseThreeMfModel, threeMfToMeshes } from './threemf.js';
47
+ export { readZip, findEntry } from './zip.js';
48
+ export { recognise, describeRecognised } from './recognise.js';
49
+ export { fbxToMeshes } from './fbx.js';
50
+ /*
51
+ * One dispatcher from a file to meshes, so a browser and the baker cannot disagree about which
52
+ * reader a `.glb` needs. Every capability it may want is a parameter: the filesystem, the two
53
+ * decompressors and the resolution of a name a file states are all the caller's to supply.
54
+ */
55
+ export { readModel, readerFor, extensionOf, MODEL_FORMATS } from './readModel.js';
56
+ /*
57
+ * The browser's decompressor, and the two-pass trick that makes an async one usable by a
58
+ * synchronous parser. `DecompressionStream` is all a page has and it only works as a stream, so
59
+ * every compressed span is recorded on one walk, expanded concurrently, and looked up on the
60
+ * next. See `fbxInflate.ts` for why neither making the reader async nor shipping a DEFLATE
61
+ * implementation was the answer.
62
+ */
63
+ export { browserInflate, browserInflateRaw, prepareFbxInflate, prepareZipInflate, } from './fbxInflate.js';
64
+ /*
65
+ * Turning what a reader produced into what the GPU wants: one vertex per distinct corner, and
66
+ * no array holding one repeated number. An importer emits a vertex per triangle corner, which
67
+ * on a real asset is roughly six times more than the model has.
68
+ */
69
+ export { weldMesh, dropDefaultAttributes } from './weld.js';
70
+ /*
71
+ * The frame is derived after the weld and not inside a reader, for the reason `tangentOrder.ts`
72
+ * measures: a soup carrying a frame per corner has nothing left to merge.
73
+ */
74
+ export { deriveTangentsFor } from './tangentOrder.js';
75
+ /*
76
+ * One coarse mesh standing in for a whole asset, so a load can open on an outline rather than on
77
+ * nothing. Baked, because a coarse model has to exist as geometry before it can be drawn, and
78
+ * built for the whole subject at once: a decimated body reads as a car, 187 coarse parts do not.
79
+ */
80
+ export { buildCoarseLevel, isOutlineWorthWriting, DEFAULT_COARSE_CELLS } from './coarseLevel.js';
81
+ /*
82
+ * Which way is up, applied as one format-agnostic turn on the shared intermediate. Told rather
83
+ * than guessed: every rule for measuring it from the geometry is wrong on something ordinary,
84
+ * and guessing is what put a car upside down and reported it as verified.
85
+ */
86
+ export { orientMeshes, parseUpAxis, describeUpAxis } from './orient.js';
87
+ /* Skins and clips out of a glTF document. See the module for why it is not part of `gltf.ts`. */
88
+ export { readGltfSkins } from './gltfSkin.js';
89
+ /*
90
+ * The tier 2 vehicle-container reader is deliberately **not** re-exported here.
91
+ *
92
+ * The barrel is the documented public surface, and `readModel` is how every format in this
93
+ * directory is meant to be reached: it dispatches by content, applies the orientation and
94
+ * handedness the file declared, and returns one shape whichever reader answered. Exporting a
95
+ * single format's entry point would document a second way in that no consumer needs, and this
96
+ * one has a further reason to stay behind the dispatcher. `scripts/kn5-check.mjs` imports the
97
+ * module directly, which is what an in-repo probe is for.
98
+ */
99
+ /*
100
+ * The mirror an up-axis rotation deliberately cannot express, kept beside the rotations so the
101
+ * next left-handed format gets the same conversion instead of writing its own.
102
+ */
103
+ export { convertHandedness } from './orient.js';
104
+ /*
105
+ * The hierarchy's half of the up-axis turn. Kept beside `orientMeshes` because calling one
106
+ * without the other leaves a file whose graph and geometry disagree about where every part is.
107
+ */
108
+ export { orientNodes } from './orient.js';
109
+ /*
110
+ * And the hierarchy's half of a mirror, which is the same pairing one step further out: a format
111
+ * that declares itself left-handed gets `convertHandedness` over its meshes and this over its
112
+ * graph, or the two desynchronise while each stays individually well formed.
113
+ */
114
+ export { mirrorNodes } from './orient.js';
115
+ /*
116
+ * **World-space meshes into parts a consumer can turn, and `docs/HANDBOOK.md` §10.1 has told
117
+ * people to import it from here since it was written.** It was not exported, so the one consumer
118
+ * that followed the handbook reached the module by sub-path — the exception this repository
119
+ * reserves for the chemistry library — and `scripts/docs.test.mjs` now checks every import the
120
+ * documentation prints against the barrel it names.
121
+ */
122
+ export { localiseNodes } from './localise.js';
123
+ /*
124
+ * The collision hull a vehicle folder ships beside its model, found by convention so a consumer
125
+ * does not have to know the convention.
126
+ */
127
+ export { colliderBeside, levelsBeside } from './readModel.js';
128
+ /*
129
+ * DDS block decoding, for the block-compressed textures a vehicle model carries. Baker work: RGBA
130
+ * is larger than the source and nothing ships a block decoder into a frame.
131
+ */
132
+ export { ddsToRgba, isDds } from './dds.js';
package/dist/kn5.d.ts ADDED
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Assetto Corsa's `.kn5`. Tier 2: a real attempt, and explicitly not a guarantee.
3
+ *
4
+ * The format has no published specification. What is implemented here was verified against three
5
+ * files from a production car mod, each of which parses to *exact EOF* — a binary walk that
6
+ * consumes a 44 MB file to its last byte has no field misread anywhere in it, because a single
7
+ * wrong width desynchronises everything after it. That is the evidence this reader rests on, and
8
+ * `scripts/kn5-check.mjs` re-establishes it on demand.
9
+ *
10
+ * **It needs nothing from its host.** A `.kn5` embeds every texture it uses, so unlike a `.gltf`
11
+ * naming external buffers or an `.fbx` storing deflated arrays, there is no capability to inject
12
+ * and no sidecar to resolve. It is the one binary format here that reads from bytes alone.
13
+ *
14
+ * It reports what the file says and corrects none of it: the frame comes back as `declaredHand`
15
+ * and `orient.ts` is what would transform it, for the same reason every other reader here reports
16
+ * `declaredUp` instead of standing its own models up.
17
+ */
18
+ import type { DrftMaterial, DrftNode, MeshData } from '@driftengine/drft';
19
+ import type { AssetReference } from './assetPath.ts';
20
+ import type { Handedness, UpAxis } from './orient.ts';
21
+ /** A texture the file carried inline. Every `.kn5` texture is inline; none are named only. */
22
+ export interface Kn5Texture {
23
+ readonly name: string;
24
+ readonly bytes: Uint8Array;
25
+ }
26
+ /** One entry of the shared material palette, as the file states it. */
27
+ export interface Kn5Material {
28
+ readonly name: string;
29
+ readonly shader: string;
30
+ /**
31
+ * 0 opaque, 1 alpha blended, 2 alpha to coverage. **The file's own statement about the pass.**
32
+ *
33
+ * Read where the walk previously skipped two bytes it called "the flags". Measured across a
34
+ * shipped car and its three levels of detail plus its collider, it takes only the values the
35
+ * format defines — 61 and 9 in the full model, 33/6, 26/3, 16/2, and one opaque collider — and
36
+ * it agrees with the *node's* transparency flag on 171 of 172 meshes, which is the cross-check
37
+ * that says the field is being read and not merely decoded.
38
+ */
39
+ readonly blendMode: number;
40
+ /** Whether `ksAlphaRef` is a live alpha test. Zero in every file measured here. */
41
+ readonly alphaTested: boolean;
42
+ /** `ksDiffuse`, `ksSpecularEXP`, `ksAlphaRef` and the rest, unmapped. */
43
+ readonly props: ReadonlyMap<string, number>;
44
+ /** Sampler name to texture name: `txDiffuse`, `txNormal`, `txMaps`, `txDetail`. */
45
+ readonly textures: ReadonlyMap<string, string>;
46
+ }
47
+ /** `Kn5Material.blendMode` when the surface belongs in the blended pass. */
48
+ export declare const KN5_ALPHA_BLEND = 1;
49
+ /**
50
+ * A position in the file that refuses instead of running off the end.
51
+ *
52
+ * Every read goes through here so that a malformed file fails with an offset somebody can look
53
+ * at, which is the whole difference between a tier 2 refusal and a parser crash.
54
+ */
55
+ export declare class Cursor {
56
+ readonly view: DataView;
57
+ readonly bytes: Uint8Array;
58
+ at: number;
59
+ constructor(buffer: ArrayBuffer);
60
+ /** Refuses when `count` bytes are not there, naming where it ran out. */
61
+ need(count: number, what: string): void;
62
+ i32(what?: string): number;
63
+ u32(what?: string): number;
64
+ f32(what?: string): number;
65
+ u16(what?: string): number;
66
+ u8(what?: string): number;
67
+ skip(count: number, what: string): void;
68
+ take(count: number, what: string): Uint8Array;
69
+ /** i32 length, then that many UTF-8 bytes. */
70
+ str(what?: string): string;
71
+ }
72
+ /** What the file says before its node tree begins. */
73
+ export interface Kn5Header {
74
+ readonly version: number;
75
+ readonly textures: Kn5Texture[];
76
+ readonly materials: Kn5Material[];
77
+ /** Where the node tree starts, so the caller carries on from here. */
78
+ readonly cursor: Cursor;
79
+ }
80
+ /**
81
+ * The magic, the version, the texture block and the material palette.
82
+ *
83
+ * Split from the node walk because it is the half that is pure data: no recursion, no transforms,
84
+ * and nothing that needs a `MeshData` to exist.
85
+ */
86
+ export declare function readKn5Header(buffer: ArrayBuffer): Kn5Header;
87
+ /**
88
+ * One node of the file's own graph.
89
+ *
90
+ * `matrix` is the node's **local** transform, row-major with the translation in row 3, which is
91
+ * the row-vector convention the format inherits from DirectX. The world matrix is not stored
92
+ * here: it is accumulated during the walk and applied to the geometry, because `MESH` is
93
+ * world-space by the rule in the design's §5.1.
94
+ */
95
+ export interface Kn5Node {
96
+ readonly type: number;
97
+ readonly name: string;
98
+ readonly parent: number;
99
+ readonly matrix: Float32Array;
100
+ /** Index into the returned meshes, or -1 for a node that draws nothing. */
101
+ readonly mesh: number;
102
+ readonly castShadows: boolean;
103
+ readonly isVisible: boolean;
104
+ /** The author's own statement that this surface belongs in the blended pass. */
105
+ readonly isTransparent: boolean;
106
+ /** Zero in every car measured; non-zero in track models. Carried, never relied upon. */
107
+ readonly lodIn: number;
108
+ readonly lodOut: number;
109
+ }
110
+ /** Geometry as the file stores it, already carried into world space. */
111
+ export interface Kn5Mesh {
112
+ readonly positions: Float32Array;
113
+ readonly normals: Float32Array;
114
+ readonly uvs: Float32Array;
115
+ readonly tangents: Float32Array;
116
+ readonly indices: Uint32Array;
117
+ /** Index into the material palette from `readKn5Header`. */
118
+ readonly material: number;
119
+ /** Index into the returned nodes, so a mesh can name the node that placed it. */
120
+ readonly node: number;
121
+ }
122
+ /**
123
+ * Walk the node tree depth first, which is the order the file stores it in.
124
+ *
125
+ * **Every node is kept, including the `AC_`-prefixed ones.** The community converter skips them,
126
+ * correctly for its purpose, since they carry no geometry an OBJ can hold. They are placement
127
+ * anchors and convention markers, and this reader exists to preserve exactly that.
128
+ */
129
+ export declare function readKn5Nodes(header: Kn5Header): {
130
+ nodes: Kn5Node[];
131
+ meshes: Kn5Mesh[];
132
+ };
133
+ /** What a `.kn5` yields, in the shape every other reader in this directory returns. */
134
+ export interface Kn5Import {
135
+ meshes: MeshData[];
136
+ materials: DrftMaterial[];
137
+ textures: AssetReference[];
138
+ nodes: Kn5Node[];
139
+ warnings: string[];
140
+ declaredUp: UpAxis;
141
+ declaredHand: Handedness;
142
+ }
143
+ /**
144
+ * Read a `.kn5` into meshes, materials and the hierarchy that placed them.
145
+ *
146
+ * Materials are duplicated per mesh because `MATL` is parallel to `MESH` by ordinal while `.kn5`
147
+ * addresses a shared palette — 70 entries against 172 meshes in the car this was built against.
148
+ * The palette entry keeps its name, so nothing is lost by the duplication.
149
+ */
150
+ export declare function kn5ToMeshes(buffer: ArrayBuffer): Kn5Import;
151
+ /**
152
+ * Decompose each node's row-vector 4x4 into the translation, rotation and scale `DrftNode` holds.
153
+ *
154
+ * The container stores a hierarchy as TRS and not as a matrix, which is what lets a consumer
155
+ * animate one channel without disturbing the other two — a wheel spins about its own axis while
156
+ * its suspension travel writes only the translation.
157
+ */
158
+ export declare function toDrftNodes(nodes: readonly Kn5Node[]): DrftNode[];