TextureSpec ​Contract 2.0.0 · package sha256
a857eca95b35921109faf997094bb4192f12527d9d0fcd4be7e97f06425bad6e· generated fromconfigurator-runtime.d.tsbyservices/onsite-scripter/scripts/build-contract-docs.mjs; edit the source, not this file.
Interface · import type { TextureSpec } from '@holostep-configurators/runtime-client/contract'; · stable · since 2.0.0 · section 8. Materials and textures
At most one of url and image. With neither, inside a partial MaterialSpec, the spec changes
only placement and sampling (uv, scale, offset, rotationDeg, sizeM, wrap, sampling)
of the texture the slot shows now, whether it comes from the GLB, the scene model or an earlier
rule. It never pins the image, so a later select() or undo changes the image and keeps your
placement. On a slot that shows no texture it does nothing.
With url or image it is a new texture, placed by its own fields: every field it omits
(uv, scale, offset, rotationDeg, sizeM, wrap, sampling, colorSpace, enabled)
takes its default below, never the value of the texture it covers (its texCoord,
KHR_texture_transform or a stored …TextureEnabled: false), and only a URL-less spec above it
lays fields over it, while the GLB's own image keeps its authored placement. Successive writes to one rule merge first (spec section 6.10, R10), so a scale
an earlier write to that rule gave stays.
Every texture, url, optimizedUrl and image alike, is sampled with the glTF convention:
row 0 of the image is v = 0, never flipped.
| Member | Kind | Summary |
|---|---|---|
url? |
property | png, jpg, webp, avif, ktx2, hdr. |
image? |
property | A canvas or bitmap, copied at the call. |
optimizedUrl? |
property | The optimized twin the runtime prefers when present (stored opt…TextureUrl). |
enabled? |
property | false keeps the URL but shows no map (stored …TextureEnabled: false). |
uv? |
property | UV channel (glTF's TEXCOORD_n). |
scale? |
property | Repeats per UV unit (KHR_texture_transform). |
offset? |
property | In UV units. |
rotationDeg? |
property | Degrees, about the UV origin. |
sizeM? |
property | Physical size one image covers, metres. |
wrap? |
property | One mode, or [u, v]. |
sampling? |
property | How the image is filtered when drawn smaller or larger than its pixels: 'pixel' for pixel art and data maps, a lower anisotropy to save GPU time on a slot seen face-on. |
colorSpace? |
property | How the image's values decode. |
export interface TextureSpec {
url?: string;
image?: HTMLCanvasElement | OffscreenCanvas | ImageBitmap | ImageRef;
optimizedUrl?: string;
enabled?: boolean;
uv?: 0 | 1 | 2 | 3;
scale?: number | Point2;
offset?: Point2;
rotationDeg?: number;
sizeM?: number | Point2;
wrap?: Wrap | readonly [
Wrap,
Wrap
];
sampling?: TextureSampling;
colorSpace?: 'srgb' | 'linear';
}
Imports: values (has, validate, the Holo*Error classes, the pure helpers) from @holostep-configurators/runtime-client, types from @holostep-configurators/runtime-client/contract, /math and /testing names from those entries; boot from the runtime module the root's loadRuntimeAtFloor resolves to. A type your page defines is your app's: declare it there, never import it from the package.
Compiled under the contract's strict settings (examples/declaration/08-TextureSpec.ts):
import type { Session } from '@holostep-configurators/runtime-client/contract';
declare const session: Session;
declare const signal: AbortSignal;
declare const fabricGroup: string;
// Tile whatever fabric the shopper picks: no url, so only the placement is written.
await session.find({ slot: 'fabric' }).set({ material: { maps: {
baseColor: { scale: 16 }, normal: { scale: 16 }, roughness: { scale: 16 },
} } });
// the image changes; the tiling stays
await session.select(fabricGroup, 'linen', { actor: 'shopper' });
| Rule | Result |
|---|---|
| 1. Neutral name | pass: TextureSpec names no product |
| 2. A precedent | pass: glTF KHR_texture_transform (row G34) |
| 3. Two apps, or labs | pass: 4 apps (ledger: app-0c773a4ee3, app-f3598fad77; fleet cross-check: app-59c5b5751e, app-e61a0b42ad, app-f3598fad77) |
| 4. The cheaper fix first | decided per need in Appendix B: rows G34 at tier stable (a member only where no rule, data, asset or app code serves the need) |