@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.
- package/LICENSE +202 -0
- package/NOTICE +9 -0
- package/README.md +9 -0
- package/dist/assetPath.d.ts +51 -0
- package/dist/assetPath.js +59 -0
- package/dist/coarseLevel.d.ts +94 -0
- package/dist/coarseLevel.js +606 -0
- package/dist/dds.d.ts +41 -0
- package/dist/dds.js +425 -0
- package/dist/drawKey.d.ts +64 -0
- package/dist/drawKey.js +42 -0
- package/dist/drftLoader.d.ts +420 -0
- package/dist/drftLoader.js +996 -0
- package/dist/drftTextures.d.ts +87 -0
- package/dist/drftTextures.js +138 -0
- package/dist/fbx.d.ts +86 -0
- package/dist/fbx.js +792 -0
- package/dist/fbxHarness.d.ts +68 -0
- package/dist/fbxHarness.js +185 -0
- package/dist/fbxInflate.d.ts +60 -0
- package/dist/fbxInflate.js +204 -0
- package/dist/fbxMaterial.d.ts +87 -0
- package/dist/fbxMaterial.js +345 -0
- package/dist/fbxRig.d.ts +130 -0
- package/dist/fbxRig.js +601 -0
- package/dist/gltf.d.ts +242 -0
- package/dist/gltf.js +904 -0
- package/dist/gltfAccessor.d.ts +2 -0
- package/dist/gltfAccessor.js +106 -0
- package/dist/gltfSkin.d.ts +32 -0
- package/dist/gltfSkin.js +144 -0
- package/dist/iesPhotometry.d.ts +44 -0
- package/dist/iesPhotometry.js +94 -0
- package/dist/imageInfo.d.ts +31 -0
- package/dist/imageInfo.js +119 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.js +132 -0
- package/dist/kn5.d.ts +158 -0
- package/dist/kn5.js +557 -0
- package/dist/loadProgress.d.ts +118 -0
- package/dist/loadProgress.js +1 -0
- package/dist/localise.d.ts +35 -0
- package/dist/localise.js +253 -0
- package/dist/obj.d.ts +54 -0
- package/dist/obj.js +335 -0
- package/dist/orient.d.ts +104 -0
- package/dist/orient.js +241 -0
- package/dist/radianceHdr.d.ts +36 -0
- package/dist/radianceHdr.js +172 -0
- package/dist/readModel.d.ts +153 -0
- package/dist/readModel.js +386 -0
- package/dist/recognise.d.ts +38 -0
- package/dist/recognise.js +97 -0
- package/dist/stl.d.ts +22 -0
- package/dist/stl.js +131 -0
- package/dist/tangentOrder.d.ts +24 -0
- package/dist/tangentOrder.js +31 -0
- package/dist/threemf.d.ts +46 -0
- package/dist/threemf.js +254 -0
- package/dist/uploadBudget.d.ts +82 -0
- package/dist/uploadBudget.js +86 -0
- package/dist/usd.d.ts +49 -0
- package/dist/usd.js +542 -0
- package/dist/weld.d.ts +44 -0
- package/dist/weld.js +237 -0
- package/dist/zip.d.ts +35 -0
- package/dist/zip.js +110 -0
- package/package.json +61 -0
- package/src/assetPath.ts +79 -0
- package/src/coarseLevel.ts +720 -0
- package/src/dds.ts +507 -0
- package/src/drawKey.ts +91 -0
- package/src/drftLoader.ts +1197 -0
- package/src/drftTextures.ts +153 -0
- package/src/fbx.ts +934 -0
- package/src/fbxHarness.ts +215 -0
- package/src/fbxInflate.ts +258 -0
- package/src/fbxMaterial.ts +410 -0
- package/src/fbxRig.ts +652 -0
- package/src/gltf.ts +1161 -0
- package/src/gltfAccessor.ts +127 -0
- package/src/gltfSkin.ts +210 -0
- package/src/iesPhotometry.ts +136 -0
- package/src/imageInfo.ts +130 -0
- package/src/index.ts +162 -0
- package/src/kn5.ts +705 -0
- package/src/loadProgress.ts +131 -0
- package/src/localise.ts +275 -0
- package/src/obj.ts +386 -0
- package/src/orient.ts +262 -0
- package/src/radianceHdr.ts +195 -0
- package/src/readModel.ts +515 -0
- package/src/recognise.ts +124 -0
- package/src/stl.ts +147 -0
- package/src/tangentOrder.ts +32 -0
- package/src/threemf.ts +303 -0
- package/src/uploadBudget.ts +90 -0
- package/src/usd.ts +642 -0
- package/src/weld.ts +264 -0
- 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
|
+
}
|