@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
@@ -0,0 +1,153 @@
1
+ /**
2
+ * A loaded asset's textures, addressed by name. One responsibility: which image is which.
3
+ *
4
+ * **A caller must never hold a texture index.** An index is a position in whatever order a
5
+ * reader met its records, which is an accident of parsing rather than anything the asset
6
+ * promised, and code holding one is coupled to a decision nobody meant to publish. Reorder
7
+ * the source, re-export it, or regroup the meshes for drawing, and the index still resolves
8
+ * — to the wrong surface, with no error anywhere. That is the failure this exists to remove.
9
+ *
10
+ * So a consumer says `set('Tire_05_DM.jpg', bitmap)` and an unknown name **throws at the
11
+ * call**, naming what it has. Failing loudly at the moment of the mistake is the whole
12
+ * difference from an index, which fails silently at some later frame.
13
+ *
14
+ * Names come from `TEXS`, which stores what the source called each image. Matching is on the
15
+ * basename as well as the full declared path, because a material may name
16
+ * `textures\Tire_05_DM.jpg` while a person reasonably says `Tire_05_DM.jpg`, and requiring
17
+ * the exact original spelling would put the ordinal problem back with extra steps.
18
+ */
19
+
20
+ import type { DrftTexture } from '@driftengine/drft';
21
+ import { basenameOf } from './assetPath.ts';
22
+ import { DrftError } from '@driftengine/drft';
23
+
24
+ /**
25
+ * Whatever a consumer creates from a decoded texture, kept as it was handed over.
26
+ *
27
+ * Generic because this module must not know what a GPU texture is: `src/asset/` describes
28
+ * files and `src/render/` owns the context. A caller parameterises this with its own handle
29
+ * and gets its own type back.
30
+ */
31
+ /**
32
+ * How each of an asset's images should be sampled, decided from what its materials call them.
33
+ *
34
+ * **A colour map and a data map need opposite treatment and the container does not say which is
35
+ * which** — it says only that material *n* names image *k* as its albedo, or its ORM, or its
36
+ * normal. So the roles are read off the materials, and an image nothing names falls to `linear`,
37
+ * which is the harmless answer for an image nothing samples.
38
+ *
39
+ * `srgb` for a base colour and an emissive map: glTF specifies both as sRGB-encoded, and handing
40
+ * those bytes to a shader undecoded treats display values as light — mid-tones arrive far brighter
41
+ * than the author's, and it stays invisible until an output transform washes the surface out.
42
+ *
43
+ * `linear` for a normal or ORM map, whose numbers *are* the data. Decoding a direction or a
44
+ * roughness as though it were a colour bends every one of them toward its floor.
45
+ *
46
+ * **A conflict resolves to `linear`.** An image named as a colour map by one material and as a
47
+ * data map by another is a file nobody meant to write, and of the two ways to be wrong this is the
48
+ * milder: an sRGB-decoded ORM map bends roughness and metallic toward zero and turns the surface
49
+ * to polished chrome, where an undecoded colour map is merely pale.
50
+ */
51
+ export function textureColorSpaces(
52
+ materials: readonly {
53
+ readonly albedo: number;
54
+ readonly normalMap: number;
55
+ readonly ormMap: number;
56
+ readonly emissiveMap: number;
57
+ }[],
58
+ count: number,
59
+ ): ('srgb' | 'linear')[] {
60
+ const colour = new Set<number>();
61
+ const data = new Set<number>();
62
+ for (const material of materials) {
63
+ if (material.albedo >= 0) colour.add(material.albedo);
64
+ if (material.emissiveMap >= 0) colour.add(material.emissiveMap);
65
+ if (material.normalMap >= 0) data.add(material.normalMap);
66
+ if (material.ormMap >= 0) data.add(material.ormMap);
67
+ }
68
+ const out: ('srgb' | 'linear')[] = [];
69
+ for (let at = 0; at < count; at++) {
70
+ out.push(colour.has(at) && !data.has(at) ? 'srgb' : 'linear');
71
+ }
72
+ return out;
73
+ }
74
+
75
+ export class TextureSet<T> {
76
+ private readonly byName = new Map<string, T>();
77
+ /**
78
+ * By the texture's index **in the file**, with a gap where one did not decode.
79
+ *
80
+ * Sparse on purpose. A material stores the index the file gave its map, so packing the
81
+ * successes together would shift every texture after a failed one and repaint the model
82
+ * with its neighbours' images. That is the ordinal hazard this class exists to remove,
83
+ * reappearing inside the thing removing it, which is exactly where it would be missed.
84
+ */
85
+ private readonly byIndex: (T | null)[] = [];
86
+
87
+ /**
88
+ * Build the lookup as the textures are created, in file order.
89
+ *
90
+ * `create` returning null means that image could not be decoded, which is survivable: the
91
+ * surface draws untextured and the slot stays addressable, so a later `replace` can still
92
+ * put something there. Dropping the entry instead would renumber everything after it.
93
+ */
94
+ static from<T>(
95
+ textures: readonly DrftTexture[],
96
+ create: (texture: DrftTexture, at: number) => T | null,
97
+ ): TextureSet<T> {
98
+ const set = new TextureSet<T>();
99
+ for (let at = 0; at < textures.length; at++) {
100
+ const texture = textures[at];
101
+ if (texture === undefined) continue;
102
+ const made = create(texture, at);
103
+ /* The slot is kept either way, so the indices materials carry stay true. */
104
+ set.byIndex[at] = made;
105
+ if (made === null) continue;
106
+ /*
107
+ * Both spellings, so a caller may use either. The full path wins a collision because
108
+ * it is what the file actually said; a basename is a convenience over it.
109
+ */
110
+ const base = basenameOf(texture.name);
111
+ if (base !== '' && !set.byName.has(base)) set.byName.set(base, made);
112
+ if (texture.name !== '') set.byName.set(texture.name, made);
113
+ }
114
+ return set;
115
+ }
116
+
117
+ /** How many textures were created, which is not the number the file carried. */
118
+ get size(): number {
119
+ return this.byIndex.filter((t) => t !== null).length;
120
+ }
121
+
122
+ /** Every created texture, for disposal rather than for addressing. */
123
+ all(): readonly T[] {
124
+ return this.byIndex.filter((t): t is T => t !== null);
125
+ }
126
+
127
+ /** The texture a material named, by its index in the file, or null. */
128
+ at(index: number): T | null {
129
+ return index >= 0 ? (this.byIndex[index] ?? null) : null;
130
+ }
131
+
132
+ /** Whether a name resolves, for a caller that wants to ask rather than to handle a throw. */
133
+ has(name: string): boolean {
134
+ return this.byName.has(name) || this.byName.has(basenameOf(name));
135
+ }
136
+
137
+ /**
138
+ * The texture called this, or a refusal naming every texture the asset does have.
139
+ *
140
+ * Throwing beats returning null. A caller asking by name has a specific image in mind, and
141
+ * a null it forgets to check is the silent-wrong-surface failure that indices already had.
142
+ */
143
+ get(name: string): T {
144
+ const found = this.byName.get(name) ?? this.byName.get(basenameOf(name));
145
+ if (found === undefined) {
146
+ const known = [...this.byName.keys()].join(', ');
147
+ throw new DrftError(
148
+ `no texture called "${name}" in this asset. It carries: ${known === '' ? 'none' : known}`,
149
+ );
150
+ }
151
+ return found;
152
+ }
153
+ }