@developerz.ai/ts23d 0.1.0 → 0.2.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/CHANGELOG.md +11 -0
- package/CLAUDE.md +1 -1
- package/README.md +10 -5
- package/dist/{chunk-a8fxakcj.js → chunk-6b05mnmx.js} +2 -2
- package/dist/{chunk-kgvbpqqw.js → chunk-7rtfjh9f.js} +6 -5
- package/dist/chunk-7rtfjh9f.js.map +10 -0
- package/dist/{chunk-1ypfs7ga.js → chunk-8j4c28jt.js} +790 -276
- package/dist/chunk-8j4c28jt.js.map +46 -0
- package/dist/{chunk-wtqhq529.js → chunk-d1fv6hrm.js} +6 -6
- package/dist/{chunk-wtqhq529.js.map → chunk-d1fv6hrm.js.map} +1 -1
- package/dist/{chunk-gcyp9b4d.js → chunk-dbq4qf52.js} +362 -215
- package/dist/chunk-dbq4qf52.js.map +25 -0
- package/dist/{chunk-xnt2sdhf.js → chunk-drna2rny.js} +2 -2
- package/dist/{chunk-ravbb06q.js → chunk-dxvypr7y.js} +2 -2
- package/dist/{chunk-11v28977.js → chunk-f6yme003.js} +85 -71
- package/dist/{chunk-11v28977.js.map → chunk-f6yme003.js.map} +6 -6
- package/dist/{chunk-4ddzsqtc.js → chunk-hg7pf34j.js} +4 -3
- package/dist/{chunk-4ddzsqtc.js.map → chunk-hg7pf34j.js.map} +5 -5
- package/dist/{chunk-w1zyhj40.js → chunk-jq4e17tj.js} +2 -2
- package/dist/{chunk-kvcep7ft.js → chunk-y63c6zcv.js} +967 -218
- package/dist/chunk-y63c6zcv.js.map +53 -0
- package/dist/cli/args.d.ts +7 -1
- package/dist/cli/bin.js +66 -25
- package/dist/cli/bin.js.map +6 -5
- package/dist/cli/manifest.d.ts +5 -1
- package/dist/cli/texture-cache.d.ts +4 -0
- package/dist/core/definition.d.ts +7 -0
- package/dist/core/errors.d.ts +1 -1
- package/dist/core/index.js +1 -1
- package/dist/export/credits.d.ts +4 -0
- package/dist/export/glb-options.d.ts +48 -0
- package/dist/export/glb.d.ts +5 -35
- package/dist/export/hierarchy.d.ts +23 -0
- package/dist/export/index.d.ts +2 -1
- package/dist/export/index.js +21 -7
- package/dist/export/index.js.map +1 -1
- package/dist/export/lod-coverage.d.ts +12 -0
- package/dist/export/metadata.d.ts +2 -0
- package/dist/export/version.d.ts +2 -2
- package/dist/grammar/index.js +2 -2
- package/dist/index.js +63 -17
- package/dist/index.js.map +1 -1
- package/dist/kinds/head-armour.d.ts +3 -7
- package/dist/kinds/head-bust.d.ts +3 -2
- package/dist/kinds/head-face.d.ts +3 -1
- package/dist/kinds/head-garb.d.ts +4 -0
- package/dist/kinds/head-mesh.d.ts +4 -0
- package/dist/kinds/head-mouth.d.ts +4 -0
- package/dist/kinds/head-params.d.ts +9 -1
- package/dist/kinds/head-tone.d.ts +10 -0
- package/dist/kinds/head-torso.d.ts +35 -0
- package/dist/kinds/index.js +6 -6
- package/dist/material/cc0.d.ts +4 -0
- package/dist/material/define.d.ts +34 -0
- package/dist/material/generator.d.ts +1 -1
- package/dist/material/index.d.ts +8 -3
- package/dist/material/index.js +39 -7
- package/dist/material/index.js.map +1 -1
- package/dist/material/library.d.ts +7 -0
- package/dist/material/material-def.d.ts +30 -0
- package/dist/material/paint/canvas.d.ts +7 -0
- package/dist/material/paint/default-sheet.d.ts +3 -1
- package/dist/material/paint/fabric.d.ts +4 -0
- package/dist/material/paint/image-strip.d.ts +4 -0
- package/dist/material/paint/kit.d.ts +5 -0
- package/dist/material/paint/metal.d.ts +3 -0
- package/dist/material/paint/orm.d.ts +1 -1
- package/dist/material/paint/strip.d.ts +1 -1
- package/dist/material/paint/types.d.ts +32 -2
- package/dist/material/palette.d.ts +2 -0
- package/dist/material/slots.d.ts +5 -0
- package/dist/material/texture-source.d.ts +34 -0
- package/dist/material/trim-sheet.d.ts +20 -4
- package/dist/neural/index.js +2 -2
- package/dist/passes/index.js +2 -2
- package/dist/primitives/index.js +3 -3
- package/dist/qa/index.js +2 -2
- package/dist/render/beauty.d.ts +1 -1
- package/dist/render/index.js +3 -3
- package/dist/render/lighting.d.ts +7 -0
- package/dist/render/shade.d.ts +1 -1
- package/dist/testing/index.js +5 -5
- package/docs/README.md +4 -0
- package/docs/architecture/gltf-capabilities.md +38 -1
- package/docs/architecture/materials.md +151 -0
- package/docs/idea/10-sculpting.md +166 -0
- package/docs/idea/11-materials-authoring.md +132 -0
- package/docs/idea/12-blender-bridge.md +136 -0
- package/docs/idea/13-asset-pipeline-research.md +89 -0
- package/docs/plans/roadmap.md +12 -0
- package/package.json +2 -1
- package/recipes/boxcar/README.md +7 -0
- package/recipes/boxcar/boxcar.ts +118 -34
- package/recipes/goblin_head/README.md +27 -14
- package/recipes/goblin_head/goblin_head.ts +11 -9
- package/recipes/human_head/README.md +8 -4
- package/recipes/human_head/human_head.ts +4 -3
- package/recipes/material_swatches/material_swatches.ts +11 -5
- package/recipes/orc_head/README.md +32 -20
- package/recipes/orc_head/orc_head.ts +9 -7
- package/src/cli/args.ts +16 -3
- package/src/cli/manifest.ts +6 -0
- package/src/cli/run.ts +33 -9
- package/src/cli/texture-cache.ts +24 -0
- package/src/core/asset.ts +1 -0
- package/src/core/definition.ts +7 -0
- package/src/core/errors.ts +6 -1
- package/src/export/credits.ts +25 -0
- package/src/export/glb-options.ts +53 -0
- package/src/export/glb.ts +100 -113
- package/src/export/hierarchy.ts +122 -0
- package/src/export/index.ts +17 -1
- package/src/export/lod-coverage.ts +71 -0
- package/src/export/metadata.ts +3 -0
- package/src/export/version.ts +1 -1
- package/src/kinds/head-armour.ts +103 -73
- package/src/kinds/head-bust.ts +49 -86
- package/src/kinds/head-face.ts +94 -74
- package/src/kinds/head-garb.ts +181 -0
- package/src/kinds/head-hair.ts +74 -33
- package/src/kinds/head-mesh.ts +43 -5
- package/src/kinds/head-mouth.ts +111 -0
- package/src/kinds/head-params.ts +11 -2
- package/src/kinds/head-presets.ts +30 -27
- package/src/kinds/head-tone.ts +52 -0
- package/src/kinds/head-torso.ts +230 -0
- package/src/kinds/head.ts +8 -3
- package/src/material/cc0.ts +41 -0
- package/src/material/define.ts +130 -0
- package/src/material/generator.ts +15 -8
- package/src/material/index.ts +34 -3
- package/src/material/library.ts +196 -0
- package/src/material/material-def.ts +84 -0
- package/src/material/paint/canvas.ts +11 -1
- package/src/material/paint/compose.ts +1 -1
- package/src/material/paint/decode-png.ts +19 -13
- package/src/material/paint/default-sheet.ts +40 -28
- package/src/material/paint/fabric.ts +63 -0
- package/src/material/paint/image-strip.ts +88 -0
- package/src/material/paint/kit.ts +37 -0
- package/src/material/paint/masks.ts +3 -1
- package/src/material/paint/metal.ts +109 -0
- package/src/material/paint/orm.ts +14 -1
- package/src/material/paint/planks.ts +49 -4
- package/src/material/paint/strip.ts +35 -29
- package/src/material/paint/types.ts +45 -2
- package/src/material/paint/validate.ts +19 -3
- package/src/material/palette.ts +3 -0
- package/src/material/slots.ts +18 -0
- package/src/material/texture-source.ts +86 -0
- package/src/material/trim-sheet.ts +79 -13
- package/src/render/beauty.ts +2 -2
- package/src/render/lighting.ts +26 -0
- package/src/render/shade.ts +10 -5
- package/dist/chunk-1ypfs7ga.js.map +0 -42
- package/dist/chunk-gcyp9b4d.js.map +0 -22
- package/dist/chunk-kgvbpqqw.js.map +0 -10
- package/dist/chunk-kvcep7ft.js.map +0 -43
- /package/dist/{chunk-a8fxakcj.js.map → chunk-6b05mnmx.js.map} +0 -0
- /package/dist/{chunk-xnt2sdhf.js.map → chunk-drna2rny.js.map} +0 -0
- /package/dist/{chunk-ravbb06q.js.map → chunk-dxvypr7y.js.map} +0 -0
- /package/dist/{chunk-w1zyhj40.js.map → chunk-jq4e17tj.js.map} +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/export/bin-writer.ts", "../src/export/container.ts", "../src/export/credits.ts", "../src/export/lights.ts", "../src/export/motion.ts", "../src/export/tangents.ts", "../src/export/primitive.ts", "../src/export/hierarchy.ts", "../src/export/lod-coverage.ts", "../src/export/materials.ts", "../src/export/merge-pivots.ts", "../src/export/version.ts", "../src/export/metadata.ts", "../src/export/optimize-parts.ts", "../src/export/textures.ts", "../src/export/glb.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"// Packs typed arrays into one 4-byte-aligned glTF buffer and records bufferViews + accessors.\n\nexport const ARRAY_BUFFER = 34962;\nexport const ELEMENT_ARRAY_BUFFER = 34963;\nconst FLOAT = 5126;\nconst UINT32 = 5125;\nconst UINT16 = 5123;\n\nexport interface Json {\n [key: string]: unknown;\n}\n\nexport class BinWriter {\n private readonly chunks: Uint8Array[] = [];\n length = 0;\n readonly views: Json[] = [];\n readonly accessors: Json[] = [];\n\n private push(bytes: Uint8Array, target?: number): number {\n const pad = (4 - (this.length % 4)) % 4;\n if (pad) {\n this.chunks.push(new Uint8Array(pad));\n this.length += pad;\n }\n this.views.push({\n buffer: 0,\n byteOffset: this.length,\n byteLength: bytes.byteLength,\n ...(target ? { target } : {}),\n });\n this.chunks.push(bytes);\n this.length += bytes.byteLength;\n return this.views.length - 1;\n }\n\n accessor(\n data: Float32Array | Uint32Array | Uint16Array,\n type: 'SCALAR' | 'VEC2' | 'VEC3' | 'VEC4',\n target?: number,\n bounds = false,\n /** Integer data read as 0..1 (vertex colour as normalised unsigned short). */\n normalized = false,\n ): number {\n const view = this.push(new Uint8Array(data.buffer, data.byteOffset, data.byteLength), target);\n const width = { SCALAR: 1, VEC2: 2, VEC3: 3, VEC4: 4 }[type];\n const acc: Json = {\n bufferView: view,\n componentType:\n data instanceof Uint32Array ? UINT32 : data instanceof Uint16Array ? UINT16 : FLOAT,\n count: data.length / width,\n type,\n ...(normalized ? { normalized: true } : {}),\n };\n if (bounds) {\n const min = Array<number>(width).fill(Infinity);\n const max = Array<number>(width).fill(-Infinity);\n for (let i = 0; i < data.length; i++) {\n const k = i % width;\n const v = data[i] ?? 0;\n if (v < (min[k] ?? 0)) min[k] = v;\n if (v > (max[k] ?? 0)) max[k] = v;\n }\n acc['min'] = min;\n acc['max'] = max;\n }\n this.accessors.push(acc);\n return this.accessors.length - 1;\n }\n\n bytes(): Uint8Array {\n const out = new Uint8Array(Math.ceil(this.length / 4) * 4);\n let o = 0;\n for (const c of this.chunks) {\n out.set(c, o);\n o += c.byteLength;\n }\n return out;\n }\n}\n",
|
|
6
|
+
"// The GLB container: 12-byte header, JSON chunk (space-padded), BIN chunk (zero-padded), every\n// length a multiple of 4 [glTF 2.0 §glb-file-format-specification].\n\nimport type { Json } from './bin-writer.ts';\n\nexport function packGlb(gltf: Json, body: Uint8Array): Uint8Array {\n let json = new TextEncoder().encode(JSON.stringify(gltf));\n const jsonPad = (4 - (json.byteLength % 4)) % 4;\n if (jsonPad) {\n const padded = new Uint8Array(json.byteLength + jsonPad).fill(0x20);\n padded.set(json);\n json = padded;\n }\n const total = 12 + 8 + json.byteLength + 8 + body.byteLength;\n const out = new Uint8Array(total);\n const dv = new DataView(out.buffer);\n dv.setUint32(0, 0x46546c67, true);\n dv.setUint32(4, 2, true);\n dv.setUint32(8, total, true);\n dv.setUint32(12, json.byteLength, true);\n dv.setUint32(16, 0x4e4f534a, true);\n out.set(json, 20);\n const binAt = 20 + json.byteLength;\n dv.setUint32(binAt, body.byteLength, true);\n dv.setUint32(binAt + 4, 0x004e4942, true);\n out.set(body, binAt + 8);\n return out;\n}\n\nexport function concat(a: Uint8Array, b: Uint8Array): Uint8Array {\n const out = new Uint8Array(a.byteLength + b.byteLength);\n out.set(a);\n out.set(b, a.byteLength);\n return out;\n}\n",
|
|
7
|
+
"// Texture credits into the GLB: when an asset samples an image strip (a CC0 texture set registered\n// with defineMaterial), its credit line joins the XMP packet's `dc:contributor`. Assets that use\n// only procedural strips get no change, so their bytes stay identical.\n\nimport type { CompiledAsset } from '../core/index.ts';\nimport { stripCredits } from '../material/index.ts';\nimport type { GlbMeta } from './metadata.ts';\n\nexport function creditsOf(asset: CompiledAsset): string[] {\n const out = new Set<string>();\n for (const p of asset.parts) {\n const uv = p.mesh?.uvs;\n if (!uv) continue;\n const v = new Float32Array(uv.length >> 1);\n for (let i = 0; i < v.length; i++) v[i] = uv[i * 2 + 1] ?? 0;\n for (const c of stripCredits(v)) out.add(c);\n }\n return [...out].sort();\n}\n\nexport function withCredits(asset: CompiledAsset, meta: GlbMeta | undefined): GlbMeta | undefined {\n const credits = creditsOf(asset);\n if (!credits.length) return meta;\n return { ...meta, credits: [...(meta?.credits ?? []), ...credits] };\n}\n",
|
|
8
|
+
"// KHR_lights_punctual from light sockets: `ctx.socket('headlamp_l', { kind: 'light', dir,\n// data: { light: 'spot', color: '#ffe8c0', intensity: 200, range: 30, cone: 25 } })` becomes a\n// real light every engine and viewer can switch on. The socket node stays as authored; the light\n// rides a child node `<socket>_light` rotated so its −Z (the glTF light direction) is `dir`.\n\nimport type { Part, Quat, Vec3 } from '../core/index.ts';\nimport { hex } from '../material/index.ts';\nimport type { Json } from './bin-writer.ts';\n\nexport const LIGHTS = 'KHR_lights_punctual';\n\n/** Shortest rotation taking unit `a` onto unit `b`. */\nfunction between(a: Vec3, b: Vec3): Quat {\n const d = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\n if (d < -0.999999) return [1, 0, 0, 0]; // opposite: half turn about X (⊥ to −Z)\n const c: Vec3 = [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];\n const w = 1 + d;\n const n = Math.hypot(c[0], c[1], c[2], w);\n return [c[0] / n, c[1] / n, c[2] / n, w / n];\n}\n\nconst num = (v: unknown, fallback: number): number =>\n typeof v === 'number' && Number.isFinite(v) ? v : fallback;\n\n/** The glTF light for a light socket, or null for any other part. */\nexport function lightOf(part: Part): { light: Json; rotation: Quat } | null {\n const s = part.socket;\n if (s?.kind !== 'light') return null;\n const d = s.data ?? {};\n const type = d['light'] === 'point' || d['light'] === 'directional' ? d['light'] : 'spot';\n const color = typeof d['color'] === 'string' ? hex(d['color']) : [1, 1, 1];\n const dir = s.dir ?? [1, 0, 0];\n const len = Math.hypot(...dir) || 1;\n const outer = (Math.min(89, num(d['cone'], 30)) * Math.PI) / 180;\n const inner = Math.min(outer * 0.999, (num(d['inner'], 0) * Math.PI) / 180);\n const range = num(d['range'], 0);\n return {\n light: {\n name: part.name,\n type,\n color,\n // Spot/point: candela; directional: lux. Defaults suit a vehicle lamp / a sun.\n intensity: num(d['intensity'], type === 'directional' ? 3 : type === 'point' ? 20 : 100),\n ...(range > 0 && type !== 'directional' ? { range } : {}),\n ...(type === 'spot' ? { spot: { innerConeAngle: inner, outerConeAngle: outer } } : {}),\n },\n rotation: between([0, 0, -1], [dir[0] / len, dir[1] / len, dir[2] / len]),\n };\n}\n",
|
|
9
|
+
"// Bakes a part's Motion into one glTF sampler + channel of the looping `run` clip.\n// Seamless by construction: every motion is rounded to a WHOLE number of cycles over the clip,\n// so the last key equals the first (a 0.8 rps wheel over 4 s = 3 turns, not 3.2 — no jump at\n// the loop point). Spins get ≥ 12 keys per turn so LINEAR quaternion interpolation never takes\n// the short way round. Time arrays are shared between channels of equal key count.\n\nimport type { Motion } from '../core/index.ts';\nimport { quatFromAxisAngle } from '../core/index.ts';\nimport type { BinWriter, Json } from './bin-writer.ts';\n\nexport const LOOP_SECONDS = 4;\n\n/** Whole cycles of `rate` (Hz or rev/s) over the clip, at least one. */\nexport const cyclesOf = (rate: number): number =>\n Math.max(1, Math.round(Math.abs(rate) * LOOP_SECONDS)) * Math.sign(rate || 1);\n\nconst timeAccessors = new WeakMap<BinWriter, Map<number, number>>();\nfunction times(bin: BinWriter, keys: number): { input: number; t: Float32Array } {\n const t = new Float32Array(keys + 1).map((_, i) => (i / keys) * LOOP_SECONDS);\n const byBin = timeAccessors.get(bin) ?? new Map<number, number>();\n timeAccessors.set(bin, byBin);\n let input = byBin.get(keys);\n if (input === undefined) {\n input = bin.accessor(t, 'SCALAR', undefined, true);\n byBin.set(keys, input);\n }\n return { input, t };\n}\n\nexport function motionChannel(\n bin: BinWriter,\n motion: Motion,\n node: number,\n rest: readonly number[],\n): { sampler: Json; channel: Json } {\n const rate = motion.kind === 'spin' ? motion.rps : motion.hz;\n const cycles = cyclesOf(rate);\n const keys = Math.max(24, Math.abs(cycles) * (motion.kind === 'spin' ? 12 : 16));\n const { input, t } = times(bin, keys);\n const phase = (time: number): number => (time / LOOP_SECONDS) * cycles * Math.PI * 2;\n // Two-sided: −1..1 around rest. One-way: 0..1, starting and ending at rest (seamless loop).\n const wave = (time: number): number =>\n motion.kind !== 'spin' && motion.oneWay\n ? (1 - Math.cos(phase(time))) / 2\n : Math.sin(phase(time));\n if (motion.kind === 'slide') {\n const values = new Float32Array((keys + 1) * 3);\n t.forEach((time, i) => {\n const s = wave(time);\n values.set(\n [0, 1, 2].map((k) => (rest[k] ?? 0) + (motion.offset[k] ?? 0) * s),\n i * 3,\n );\n });\n return {\n sampler: { input, output: bin.accessor(values, 'VEC3'), interpolation: 'LINEAR' },\n channel: { target: { node, path: 'translation' } },\n };\n }\n const values = new Float32Array((keys + 1) * 4);\n const peak = motion.kind === 'sway' ? (motion.degrees * Math.PI) / 180 : 0;\n t.forEach((time, i) => {\n const angle = motion.kind === 'spin' ? phase(time) : peak * wave(time);\n values.set(quatFromAxisAngle(motion.axis, angle), i * 4);\n });\n return {\n sampler: { input, output: bin.accessor(values, 'VEC4'), interpolation: 'LINEAR' },\n channel: { target: { node, path: 'rotation' } },\n };\n}\n",
|
|
10
|
+
"// Per-vertex tangents (glTF TANGENT, VEC4) for normal-mapped meshes: Lengyel's UV-derivative\n// method, Gram-Schmidt against the vertex normal, w = handedness. The bitangent cross(N, T) · w\n// points toward DECREASING glTF v (the \"green up\" convention the painter writes). Identical to\n// MikkTSpace on flat-shaded quads; close, not bit-equal, on smooth curved surfaces.\n\nimport type { Mesh } from '../core/index.ts';\n\nexport function tangentsOf(m: Mesh): Float32Array {\n const n = m.positions.length / 3;\n const tan = new Float32Array(n * 3);\n const bit = new Float32Array(n * 3);\n const P = m.positions;\n const U = m.uvs;\n for (let t = 0; t < m.indices.length; t += 3) {\n const a = m.indices[t] ?? 0;\n const b = m.indices[t + 1] ?? 0;\n const c = m.indices[t + 2] ?? 0;\n const e1x = (P[b * 3] ?? 0) - (P[a * 3] ?? 0);\n const e1y = (P[b * 3 + 1] ?? 0) - (P[a * 3 + 1] ?? 0);\n const e1z = (P[b * 3 + 2] ?? 0) - (P[a * 3 + 2] ?? 0);\n const e2x = (P[c * 3] ?? 0) - (P[a * 3] ?? 0);\n const e2y = (P[c * 3 + 1] ?? 0) - (P[a * 3 + 1] ?? 0);\n const e2z = (P[c * 3 + 2] ?? 0) - (P[a * 3 + 2] ?? 0);\n const du1 = (U[b * 2] ?? 0) - (U[a * 2] ?? 0);\n const dv1 = -((U[b * 2 + 1] ?? 0) - (U[a * 2 + 1] ?? 0));\n const du2 = (U[c * 2] ?? 0) - (U[a * 2] ?? 0);\n const dv2 = -((U[c * 2 + 1] ?? 0) - (U[a * 2 + 1] ?? 0));\n const det = du1 * dv2 - du2 * dv1;\n if (Math.abs(det) < 1e-12) continue;\n const r = 1 / det;\n const tx = (e1x * dv2 - e2x * dv1) * r;\n const ty = (e1y * dv2 - e2y * dv1) * r;\n const tz = (e1z * dv2 - e2z * dv1) * r;\n const bx = (e2x * du1 - e1x * du2) * r;\n const by = (e2y * du1 - e1y * du2) * r;\n const bz = (e2z * du1 - e1z * du2) * r;\n for (const v of [a, b, c]) {\n tan[v * 3] = (tan[v * 3] ?? 0) + tx;\n tan[v * 3 + 1] = (tan[v * 3 + 1] ?? 0) + ty;\n tan[v * 3 + 2] = (tan[v * 3 + 2] ?? 0) + tz;\n bit[v * 3] = (bit[v * 3] ?? 0) + bx;\n bit[v * 3 + 1] = (bit[v * 3 + 1] ?? 0) + by;\n bit[v * 3 + 2] = (bit[v * 3 + 2] ?? 0) + bz;\n }\n }\n const out = new Float32Array(n * 4);\n for (let v = 0; v < n; v++) {\n const nx = m.normals[v * 3] ?? 0;\n const ny = m.normals[v * 3 + 1] ?? 0;\n const nz = m.normals[v * 3 + 2] ?? 1;\n let tx = tan[v * 3] ?? 0;\n let ty = tan[v * 3 + 1] ?? 0;\n let tz = tan[v * 3 + 2] ?? 0;\n const d = nx * tx + ny * ty + nz * tz;\n tx -= nx * d;\n ty -= ny * d;\n tz -= nz * d;\n let len = Math.hypot(tx, ty, tz);\n if (len < 1e-8) {\n // No usable UV gradient: any unit vector perpendicular to the normal.\n [tx, ty, tz] = Math.abs(nx) < 0.9 ? [0, -nz, ny] : [nz, 0, -nx];\n len = Math.hypot(tx, ty, tz) || 1;\n }\n tx /= len;\n ty /= len;\n tz /= len;\n // Handedness: does cross(N, T) agree with the accumulated bitangent?\n const cx = ny * tz - nz * ty;\n const cy = nz * tx - nx * tz;\n const cz = nx * ty - ny * tx;\n const w = cx * (bit[v * 3] ?? 0) + cy * (bit[v * 3 + 1] ?? 0) + cz * (bit[v * 3 + 2] ?? 0);\n out.set([tx, ty, tz, w < 0 ? -1 : 1], v * 4);\n }\n return out;\n}\n",
|
|
11
|
+
"// One mesh → one glTF primitive: POSITION (with bounds), NORMAL, TEXCOORD_0, COLOR_0 as unorm16\n// RGBA, TANGENT only when a normal map is bound, and the smallest index type that fits.\n\nimport type { Mesh } from '../core/index.ts';\nimport { ARRAY_BUFFER, type BinWriter, ELEMENT_ARRAY_BUFFER, type Json } from './bin-writer.ts';\nimport { tangentsOf } from './tangents.ts';\n\nexport function writePrimitive(bin: BinWriter, m: Mesh, material: number, tangents: boolean): Json {\n // COLOR_0 as normalised unsigned short RGBA: 8 bytes/vertex instead of 16, no banding in\n // darks (8-bit would). VEC4 because vertex attributes must be 4-byte aligned.\n const colors = new Uint16Array((m.colors.length / 3) * 4);\n const q = (v: number): number => Math.round(Math.min(1, Math.max(0, v)) * 65535);\n for (let i = 0; i < m.colors.length / 3; i++)\n colors.set(\n [q(m.colors[i * 3] ?? 1), q(m.colors[i * 3 + 1] ?? 1), q(m.colors[i * 3 + 2] ?? 1), 65535],\n i * 4,\n );\n return {\n attributes: {\n POSITION: bin.accessor(m.positions, 'VEC3', ARRAY_BUFFER, true),\n NORMAL: bin.accessor(m.normals, 'VEC3', ARRAY_BUFFER),\n TEXCOORD_0: bin.accessor(m.uvs, 'VEC2', ARRAY_BUFFER),\n COLOR_0: bin.accessor(colors, 'VEC4', ARRAY_BUFFER, false, true),\n // A bound normal map needs a tangent space (validator S10 / G15).\n ...(tangents ? { TANGENT: bin.accessor(tangentsOf(m), 'VEC4', ARRAY_BUFFER) } : {}),\n },\n // 16-bit indices whenever the primitive allows: half the bytes, every engine reads them.\n indices: bin.accessor(\n m.positions.length / 3 <= 65535 ? Uint16Array.from(m.indices) : m.indices,\n 'SCALAR',\n ELEMENT_ARRAY_BUFFER,\n ),\n material,\n };\n}\n",
|
|
12
|
+
"// Writes one LOD's node tree into a shared glTF document: a root node, one node per (merged) part\n// with its pivot as translation, light nodes under light sockets, meshes, and the part motions as\n// `run` channels. Called once per LOD; the bin, materials, lights and motion samplers are shared,\n// so a single-file GLB stores each identical motion and light only once.\n\nimport type { CompiledAsset, Part } from '../core/index.ts';\nimport { quatFromAxisAngle } from '../core/index.ts';\nimport type { BinWriter, Json } from './bin-writer.ts';\nimport { LIGHTS, lightOf } from './lights.ts';\nimport { motionChannel } from './motion.ts';\nimport { writePrimitive } from './primitive.ts';\n\n/** The growing glTF arrays every LOD appends to. */\nexport interface GltfDoc {\n readonly bin: BinWriter;\n readonly nodes: Json[];\n readonly meshes: Json[];\n readonly lights: Json[];\n readonly samplers: Json[];\n readonly channels: Json[];\n /** motion + rest pose → sampler index: the same wheel spin at LOD0 and LOD1 is one sampler. */\n readonly motionSamplers: Map<string, number>;\n readonly lightIndex: Map<string, number>;\n}\n\nexport const newDoc = (bin: BinWriter): GltfDoc => ({\n bin,\n nodes: [],\n meshes: [],\n lights: [],\n samplers: [],\n channels: [],\n motionSamplers: new Map(),\n lightIndex: new Map(),\n});\n\nexport interface HierarchyOptions {\n /** Material index for a part (trim sheet by surface, or its glow layer). */\n readonly materialOf: (part: Part, i: number) => number;\n readonly withSheet: boolean;\n readonly animations: boolean;\n}\n\nfunction attach(doc: GltfDoc, parentId: number, id: number): void {\n const parent = doc.nodes[parentId];\n if (!parent) return;\n parent['children'] = [...((parent['children'] as number[] | undefined) ?? []), id];\n}\n\nfunction lightIndexOf(doc: GltfDoc, light: Json): number {\n const key = JSON.stringify(light);\n const known = doc.lightIndex.get(key);\n if (known !== undefined) return known;\n doc.lights.push(light);\n doc.lightIndex.set(key, doc.lights.length - 1);\n return doc.lights.length - 1;\n}\n\nfunction addMotion(doc: GltfDoc, part: Part, id: number): void {\n if (!part.motion) return;\n const key = JSON.stringify([part.motion, part.at]);\n let sampler = doc.motionSamplers.get(key);\n let channel: Json;\n if (sampler === undefined) {\n const written = motionChannel(doc.bin, part.motion, id, part.at);\n doc.samplers.push(written.sampler);\n sampler = doc.samplers.length - 1;\n doc.motionSamplers.set(key, sampler);\n channel = written.channel;\n } else {\n channel = {\n target: { node: id, path: part.motion.kind === 'slide' ? 'translation' : 'rotation' },\n };\n }\n doc.channels.push({ ...channel, sampler });\n}\n\n/** Appends `asset`'s tree under a new root named `rootName`; returns the root node index. */\nexport function writeHierarchy(\n doc: GltfDoc,\n asset: CompiledAsset,\n rootName: string,\n o: HierarchyOptions,\n): number {\n doc.nodes.push({ name: rootName, children: [] as number[] });\n const root = doc.nodes.length - 1;\n const index = new Map<string, number>();\n asset.parts.forEach((part: Part, i) => {\n const node: Json = { name: part.name, translation: [...part.at] };\n if (part.yaw) node['rotation'] = [...quatFromAxisAngle([0, 0, 1], part.yaw)];\n if (part.emitter || part.socket) {\n node['extras'] = {\n ts23d: {\n ...(part.emitter ? { emitter: part.emitter } : {}),\n ...(part.socket ? { socket: part.socket } : {}),\n },\n };\n }\n if (part.mesh && part.mesh.indices.length > 0) {\n doc.meshes.push({\n name: part.name,\n primitives: [writePrimitive(doc.bin, part.mesh, o.materialOf(part, i), o.withSheet)],\n });\n node['mesh'] = doc.meshes.length - 1;\n }\n doc.nodes.push(node);\n const id = doc.nodes.length - 1;\n index.set(part.name, id);\n attach(doc, part.parent === null ? root : (index.get(part.parent) ?? root), id);\n const lit = lightOf(part);\n if (lit) {\n doc.nodes.push({\n name: `${part.name}_light`,\n rotation: [...lit.rotation],\n extensions: { [LIGHTS]: { light: lightIndexOf(doc, lit.light) } },\n });\n attach(doc, id, doc.nodes.length - 1);\n }\n if (o.animations) addMotion(doc, part, id);\n });\n return root;\n}\n",
|
|
13
|
+
"// View-distance hints for the single-file GLB: MSFT_lod (vendor extension, node level) on the\n// LOD0 root lists the LOD1/LOD2 roots, and `extras.MSFT_screencoverage` holds, per LOD, the\n// screen-height fraction below which the next LOD (or nothing) takes over — Unity LODGroup's\n// \"screen relative transition height\". Spec: KhronosGroup/glTF extensions/2.0/Vendor/MSFT_lod.\n//\n// Default thresholds match screen-space triangle density: a LOD with r × the triangles looks as\n// dense at √r × the size on screen (triangles per pixel ∝ tris / coverage²). Landmarks (≥ 10 m)\n// cull later than props, so a building stays on the skyline.\n\nimport type { CompiledAsset } from '../core/index.ts';\nimport { Ts23dError, worldMeshes } from '../core/index.ts';\n\nexport const MSFT_LOD = 'MSFT_lod';\nexport const SCREEN_COVERAGE = 'MSFT_screencoverage';\n\nexport type LodCoverage = readonly [number, number, number];\n\nconst tris = (a: CompiledAsset): number =>\n a.parts.reduce((s, p) => s + (p.mesh ? p.mesh.indices.length / 3 : 0), 0);\n\n/** Largest extent in metres: `real` when declared, else the LOD0 world bounds. */\nfunction extent(a: CompiledAsset): number {\n if (a.real) return Math.max(a.real.length, a.real.width, a.real.height);\n const lo = [Infinity, Infinity, Infinity];\n const hi = [-Infinity, -Infinity, -Infinity];\n for (const mesh of worldMeshes(a.parts).values()) {\n const p = mesh.positions;\n for (let i = 0; i < p.length; i++) {\n const k = i % 3;\n const v = p[i] ?? 0;\n lo[k] = Math.min(lo[k] ?? 0, v);\n hi[k] = Math.max(hi[k] ?? 0, v);\n }\n }\n return Math.max(0, ...hi.map((h, k) => h - (lo[k] ?? 0)));\n}\n\nconst clamp = (v: number, lo: number, hi: number): number => Math.min(hi, Math.max(lo, v));\nconst round = (v: number): number => Math.round(v * 1000) / 1000;\n\n/** Default [LOD0→1, LOD1→2, cull] for an asset from its compiled LODs (any subset, LOD0 first). */\nexport function defaultCoverage(lods: readonly CompiledAsset[]): LodCoverage {\n const byLod = new Map<number, number>(lods.map((a) => [a.lod, tris(a)]));\n const top = lods[0];\n const t0 = Math.max(1, top ? tris(top) : 1);\n const ratio = (lod: number): number => (byLod.get(lod) ?? t0) / t0;\n const c1 = round(clamp(Math.sqrt(ratio(1)), 0.1, 0.6));\n const c2 = round(clamp(Math.sqrt(ratio(2)), 0.02, c1 / 2));\n const cull = top && extent(top) >= 10 ? 0.002 : 0.01;\n return [c1, c2, Math.min(cull, round(c2 / 2))];\n}\n\nexport function checkCoverage(c: readonly number[], asset: string): void {\n const [a = -1, b = -1, cull = -1] = c;\n if (c.length !== 3 || !(a < 1 && a > b && b > cull && cull >= 0))\n throw new Ts23dError('T3D_RECIPE_INVALID', {\n cause: `lodCoverage ${JSON.stringify(c)} on '${asset}' is not strictly descending in [0, 1)`,\n fix: 'give [LOD0→LOD1, LOD1→LOD2, cull] screen-height fractions, e.g. [0.5, 0.2, 0.01]; 0 = never cull',\n });\n}\n\n/**\n * MSFT_screencoverage for the LODs actually written (e.g. [0, 2]): entry j is the coverage where\n * LOD j hands over — to the next included LOD's switch point, or to nothing (cull) for the last.\n */\nexport function coverageFor(levels: readonly number[], c: LodCoverage): number[] {\n return levels.map((_, j) => {\n const next = levels[j + 1];\n return next === undefined ? c[2] : (c[next - 1] ?? c[2]);\n });\n}\n",
|
|
14
|
+
"// The (at most) four shared materials, one per Surface in use. All sample the same trim sheet and\n// take tint from COLOR_0, so batching holds; only the shading model differs. Glass/translucent use\n// KHR_materials_transmission + _volume + _ior (three, Babylon, glTFast); engines without them fall\n// back to alpha BLEND via baseColorFactor.a. With a painted sheet bound (textures.ts), every\n// material samples it: baseColor (sRGB, alpha = cutout mask), normal, and ORM in both the\n// occlusion and metallicRoughness slots. Opaque/cutout factors go to 1 so the ORM texture rules;\n// glass/translucent keep theirs as multipliers (clear stays clear whatever strip it maps).\n\nimport type { Surface } from '../core/index.ts';\nimport type { Json } from './bin-writer.ts';\n\nconst MATERIALS: Readonly<Record<Surface, Json>> = {\n opaque: {\n name: 'ts23d_trim',\n pbrMetallicRoughness: {\n baseColorFactor: [1, 1, 1, 1],\n metallicFactor: 0,\n roughnessFactor: 0.8,\n },\n },\n cutout: {\n name: 'ts23d_trim_cutout',\n alphaMode: 'MASK',\n alphaCutoff: 0.5,\n doubleSided: true,\n pbrMetallicRoughness: {\n baseColorFactor: [1, 1, 1, 1],\n metallicFactor: 0,\n roughnessFactor: 0.9,\n },\n },\n glass: {\n name: 'ts23d_glass',\n alphaMode: 'BLEND',\n pbrMetallicRoughness: {\n baseColorFactor: [1, 1, 1, 0.25],\n metallicFactor: 0,\n roughnessFactor: 0.05,\n },\n extensions: {\n KHR_materials_transmission: { transmissionFactor: 1 },\n KHR_materials_volume: { thicknessFactor: 0.01 },\n KHR_materials_ior: { ior: 1.5 },\n },\n },\n translucent: {\n name: 'ts23d_translucent',\n alphaMode: 'BLEND',\n pbrMetallicRoughness: {\n baseColorFactor: [1, 1, 1, 0.6],\n metallicFactor: 0,\n roughnessFactor: 0.35,\n },\n extensions: {\n KHR_materials_transmission: { transmissionFactor: 0.6 },\n KHR_materials_volume: { thicknessFactor: 0.02 },\n KHR_materials_ior: { ior: 1.45 },\n },\n },\n};\n\nconst ORDER: readonly Surface[] = ['opaque', 'cutout', 'glass', 'translucent'];\n\n/** The same material sampling the sheet (texture indices fixed by textures.ts). */\nfunction textured(m: Json, surface: Surface): Json {\n const pbr = m['pbrMetallicRoughness'] as Json;\n const own = surface === 'opaque' || surface === 'cutout';\n return {\n ...m,\n pbrMetallicRoughness: {\n ...pbr,\n baseColorTexture: { index: 0 },\n metallicRoughnessTexture: { index: 2 },\n ...(own ? { metallicFactor: 1, roughnessFactor: 1 } : {}),\n },\n normalTexture: { index: 1 },\n occlusionTexture: { index: 2 },\n };\n}\n\n/** Materials for the surfaces present, plus each surface's index and the extensions used. */\nexport function materialsFor(\n used: ReadonlySet<Surface>,\n withSheet = false,\n): {\n materials: Json[];\n index: Map<Surface, number>;\n extensionsUsed: string[];\n} {\n const present = ORDER.filter((s) => s === 'opaque' || used.has(s));\n const index = new Map(present.map((s, i) => [s, i] as const));\n const ext = new Set<string>();\n for (const s of present)\n for (const e of Object.keys((MATERIALS[s]['extensions'] as Json | undefined) ?? {})) ext.add(e);\n const materials = present.map((s) => (withSheet ? textured(MATERIALS[s], s) : MATERIALS[s]));\n return { materials, index, extensionsUsed: [...ext].sort() };\n}\n\nexport const EMISSIVE_STRENGTH = 'KHR_materials_emissive_strength';\n\n/** A lit surface: lamp lenses, windows at night, panel glow. */\nexport interface GlowRule {\n /** Part names or globs: 'headlamp_*', 'window_*'. */\n readonly parts: readonly string[];\n /** Linear RGB 0..1 (use `hex('#ffd9a0')` from /material). Default warm white. */\n readonly color?: readonly [number, number, number];\n /** Brightness multiplier (KHR_materials_emissive_strength, Ratified); 1 = plain glTF. */\n readonly strength?: number;\n}\n\n/**\n * The opaque trim material plus emission. emissiveFactor caps at 1 in core glTF; anything\n * brighter rides KHR_materials_emissive_strength (engines without it see the clamped glow).\n */\nexport function glowMaterial(rule: GlowRule, i: number, withSheet: boolean): Json {\n const base = withSheet ? textured(MATERIALS.opaque, 'opaque') : MATERIALS.opaque;\n const strength = rule.strength ?? 4;\n return {\n ...base,\n name: `ts23d_glow_${i}`,\n emissiveFactor: [...(rule.color ?? [1, 0.85, 0.6])],\n ...(strength !== 1\n ? { extensions: { [EMISSIVE_STRENGTH]: { emissiveStrength: strength } } }\n : {}),\n };\n}\n",
|
|
15
|
+
"// Batching for engines: every part that is NOT a pivot is merged into its nearest pivot ancestor,\n// so draw calls = pivots with geometry, not parts. A pivot is anything the engine may move: a\n// group (`ctx.group`, a named handle like `turret`, `gun`, `door_l`) or a part with `motion`.\n// Static top-level geometry merges into one `body` part. Names the engine binds to survive.\n// Non-opaque surfaces split into `<pivot>_<surface>` children (one draw call per surface), and\n// glowing parts (GlbOptions.glow) into `<pivot>_glow_<i>` children with their emissive material.\n\nimport {\n type CompiledAsset,\n type Mesh,\n merge,\n type Part,\n rotateZ,\n type Surface,\n toWorld,\n type WorldTransform,\n worldTransforms,\n} from '../core/index.ts';\n\nconst isPivot = (p: Part): boolean => p.mesh === null || p.motion !== null;\n\n/** Merged layer parts that glow → index of the glow rule (read by the GLB writer). */\nexport const glowLayer = new WeakMap<Part, number>();\n\n/** `*`/`?` glob → anchored RegExp (export cannot import /qa: same tier). */\nexport const globRe = (pattern: string): RegExp =>\n new RegExp(\n `^${pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .replaceAll('*', '.*')\n .replaceAll('?', '.')}$`,\n );\nconst SURFACES: readonly Surface[] = ['cutout', 'glass', 'translucent'];\n\n/** Re-express a part's mesh in its pivot's local space. */\nfunction intoPivot(mesh: Mesh, part: WorldTransform, pivot: WorldTransform): Mesh {\n const positions = new Float32Array(mesh.positions.length);\n const normals = new Float32Array(mesh.normals.length);\n for (let i = 0; i < positions.length; i += 3) {\n const w = toWorld(part, [\n mesh.positions[i] ?? 0,\n mesh.positions[i + 1] ?? 0,\n mesh.positions[i + 2] ?? 0,\n ]);\n positions.set(\n rotateZ([w[0] - pivot.origin[0], w[1] - pivot.origin[1], w[2] - pivot.origin[2]], -pivot.yaw),\n i,\n );\n normals.set(\n rotateZ(\n rotateZ(\n [mesh.normals[i] ?? 0, mesh.normals[i + 1] ?? 0, mesh.normals[i + 2] ?? 0],\n part.yaw,\n ),\n -pivot.yaw,\n ),\n i,\n );\n }\n return { ...mesh, positions, normals };\n}\n\nexport function mergeToPivots(\n asset: CompiledAsset,\n glow: readonly (readonly string[])[] = [],\n): CompiledAsset {\n const glowRes = glow.map((globs) => globs.map(globRe));\n const glowOf = (name: string): number => glowRes.findIndex((rs) => rs.some((r) => r.test(name)));\n const byName = new Map(asset.parts.map((p) => [p.name, p]));\n const xf = worldTransforms(asset.parts);\n const ROOT = 'body';\n const identity: WorldTransform = { origin: [0, 0, 0], yaw: 0 };\n const pivotOf = (p: Part): string => {\n let cur = p.parent ? byName.get(p.parent) : undefined;\n while (cur && !isPivot(cur)) cur = cur.parent ? byName.get(cur.parent) : undefined;\n return cur?.name ?? ROOT;\n };\n // Buckets keyed by pivot + surface: opaque merges into the pivot's own mesh; each other\n // surface in use becomes one child `<pivot>_<surface>` so materials never mix in a primitive.\n const extra = new Map<string, Mesh[]>();\n const bucket = (pivot: string, surface: Surface | undefined, mesh: Mesh, g = -1): void => {\n const k = `${pivot}|${g >= 0 ? `glow_${g}` : (surface ?? 'opaque')}`;\n extra.set(k, [...(extra.get(k) ?? []), mesh]);\n };\n for (const p of asset.parts) {\n if (!p.mesh) continue;\n const g = glowOf(p.name);\n if (isPivot(p)) {\n bucket(p.name, p.surface, p.mesh, g);\n continue;\n }\n const pivot = pivotOf(p);\n const t = xf.get(p.name) ?? identity;\n const pt = pivot === ROOT ? identity : (xf.get(pivot) ?? identity);\n bucket(pivot, p.surface, intoPivot(p.mesh, t, pt), g);\n }\n const parts: Part[] = [];\n const layers = (pivot: string, parent: string | null): void => {\n for (const surface of SURFACES) {\n const meshes = extra.get(`${pivot}|${surface}`);\n if (!meshes) continue;\n parts.push({\n name: `${pivot}_${surface}`,\n mesh: merge(meshes),\n at: [0, 0, 0],\n parent,\n yaw: 0,\n motion: null,\n surface,\n });\n }\n glow.forEach((_, g) => {\n const meshes = extra.get(`${pivot}|glow_${g}`);\n if (!meshes) return;\n const part: Part = {\n name: `${pivot}_glow_${g}`,\n mesh: merge(meshes),\n at: [0, 0, 0],\n parent,\n yaw: 0,\n motion: null,\n };\n glowLayer.set(part, g);\n parts.push(part);\n });\n };\n const body = extra.get(`${ROOT}|opaque`);\n if (body)\n parts.push({\n name: ROOT,\n mesh: merge(body),\n at: [0, 0, 0],\n parent: null,\n yaw: 0,\n motion: null,\n });\n layers(ROOT, null);\n for (const p of asset.parts) {\n if (!isPivot(p)) continue;\n const own = extra.get(`${p.name}|opaque`);\n const { surface: _drop, ...rest } = p;\n parts.push({ ...rest, mesh: own ? merge(own) : null });\n layers(p.name, p.name);\n }\n return { ...asset, parts };\n}\n",
|
|
16
|
+
"// The package version written into every GLB (`asset.generator`, XMP CreatorTool). Kept as a\n// constant because the library may not import package.json (rootDir is src); version.test.ts\n// fails the gate when the two disagree, and `bun run release` stamps both.\n\nexport const VERSION = '0.2.0';\nexport const GENERATOR = `@developerz.ai/ts23d ${VERSION}`;\n",
|
|
17
|
+
"// Provenance inside the file: `asset.generator` with the version, `asset.copyright`, and an XMP\n// packet (KHR_xmp_json_ld, Ratified) with title, description, creators, rights, licence and the\n// recipe's sources — what Sketchfab, Blender and asset stores read. No dates: bytes stay\n// deterministic.\n\nimport type { Json } from './bin-writer.ts';\nimport { GENERATOR } from './version.ts';\n\nexport interface GlbMeta {\n /** Default: the asset name. */\n readonly title?: string;\n readonly description?: string;\n readonly creators?: readonly string[];\n /** Goes to `asset.copyright` and `dc:rights`, e.g. \"© 2026 Jane Doe\". */\n readonly copyright?: string;\n /** SPDX id or licence URL → `xmpRights:UsageTerms`, e.g. \"CC-BY-4.0\". */\n readonly license?: string;\n /** Where the numbers came from (the recipe's `sources`) → `dc:relation`. */\n readonly sources?: readonly string[];\n /** Third-party inputs (e.g. CC0 texture sets) → `dc:contributor`. Filled by export. */\n readonly credits?: readonly string[];\n}\n\nconst XMP = 'KHR_xmp_json_ld';\nconst alt = (value: string): Json => ({\n '@type': 'rdf:Alt',\n 'rdf:_1': { '@language': 'x-default', '@value': value },\n});\n\n/** `asset` block, plus root `extensions` and the extension name when an XMP packet is written. */\nexport function metadata(\n name: string,\n meta: GlbMeta | undefined,\n): { asset: Json; extensions?: Json; used: string[] } {\n const asset: Json = {\n version: '2.0',\n generator: GENERATOR,\n ...(meta?.copyright ? { copyright: meta.copyright } : {}),\n };\n if (!meta) return { asset, used: [] };\n const packet: Json = {\n '@context': {\n dc: 'http://purl.org/dc/elements/1.1/',\n rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',\n xmp: 'http://ns.adobe.com/xap/1.0/',\n xmpRights: 'http://ns.adobe.com/xap/1.0/rights/',\n },\n 'dc:title': alt(meta.title ?? name),\n ...(meta.description ? { 'dc:description': alt(meta.description) } : {}),\n ...(meta.creators?.length ? { 'dc:creator': { '@list': [...meta.creators] } } : {}),\n ...(meta.copyright ? { 'dc:rights': alt(meta.copyright) } : {}),\n ...(meta.license ? { 'xmpRights:UsageTerms': alt(meta.license) } : {}),\n ...(meta.sources?.length ? { 'dc:relation': { '@set': [...meta.sources] } } : {}),\n ...(meta.credits?.length ? { 'dc:contributor': { '@set': [...meta.credits] } } : {}),\n 'xmp:CreatorTool': GENERATOR,\n };\n return {\n asset: { ...asset, extensions: { [XMP]: { packet: 0 } } },\n extensions: { [XMP]: { packets: [packet] } },\n used: [XMP],\n };\n}\n",
|
|
18
|
+
"// Runs the mesh optimiser (passes/optimize: weld → vertex cache → vertex fetch) over every part\n// headed for the GLB, and sums what it did into one report the CLI and manifest can print.\n\nimport type { CompiledAsset } from '../core/index.ts';\nimport { type OptimizeOptions, type OptimizeReport, optimize } from '../passes/index.ts';\n\nexport interface PartOptimizeReport extends OptimizeReport {\n readonly part: string;\n}\n\n/** Totals over all parts; ACMR/ATVR are triangle-weighted means. */\nexport interface ExportReport {\n readonly optimized: boolean;\n readonly verticesBefore: number;\n readonly verticesAfter: number;\n readonly trianglesBefore: number;\n readonly trianglesAfter: number;\n readonly degenerate: number;\n readonly duplicate: number;\n readonly acmrBefore: number;\n readonly acmr: number;\n readonly atvrBefore: number;\n readonly atvr: number;\n readonly parts: readonly PartOptimizeReport[];\n}\n\nexport function summarize(parts: readonly PartOptimizeReport[], optimized: boolean): ExportReport {\n const sum = (f: (r: PartOptimizeReport) => number): number => parts.reduce((s, r) => s + f(r), 0);\n const tb = sum((r) => r.trianglesBefore);\n const ta = sum((r) => r.trianglesAfter);\n const mean = (f: (r: PartOptimizeReport) => number, by: number, w: 'b' | 'a'): number =>\n by ? sum((r) => f(r) * (w === 'b' ? r.trianglesBefore : r.trianglesAfter)) / by : 0;\n return {\n optimized,\n verticesBefore: sum((r) => r.verticesBefore),\n verticesAfter: sum((r) => r.verticesAfter),\n trianglesBefore: tb,\n trianglesAfter: ta,\n degenerate: sum((r) => r.degenerate),\n duplicate: sum((r) => r.duplicate),\n acmrBefore: mean((r) => r.acmrBefore, tb, 'b'),\n acmr: mean((r) => r.acmr, ta, 'a'),\n atvrBefore: mean((r) => r.atvrBefore, tb, 'b'),\n atvr: mean((r) => r.atvr, ta, 'a'),\n parts,\n };\n}\n\n/** Optimise every part mesh. `false` passes meshes through and reports them as-is. */\nexport function optimizeParts(\n asset: CompiledAsset,\n o: OptimizeOptions | false,\n): { asset: CompiledAsset; report: ExportReport } {\n const reports: PartOptimizeReport[] = [];\n const parts = asset.parts.map((p) => {\n if (!p.mesh || p.mesh.indices.length === 0) return p;\n if (o === false) {\n const v = p.mesh.positions.length / 3;\n const t = p.mesh.indices.length / 3;\n reports.push({\n part: p.name,\n verticesBefore: v,\n verticesAfter: v,\n trianglesBefore: t,\n trianglesAfter: t,\n degenerate: 0,\n duplicate: 0,\n acmrBefore: 0,\n acmr: 0,\n atvrBefore: 0,\n atvr: 0,\n });\n return p;\n }\n const { mesh, report } = optimize(p.mesh, o);\n reports.push({ part: p.name, ...report });\n return { ...p, mesh };\n });\n return { asset: { ...asset, parts }, report: summarize(reports, o !== false) };\n}\n",
|
|
19
|
+
"// The trim sheet in glTF: three images (albedo sRGB, normal + ORM linear), three textures and one\n// sampler (REPEAT along U so strips tile, CLAMP along V so the atlas never wraps rows, trilinear\n// mips). Embedded: PNGs ride in the BIN chunk after the geometry (self-contained single files).\n// External: images reference `<prefix>_{albedo,normal,orm}.png` by URI, so fifty assets share one\n// texture set on disk and in GPU memory — the point of the trim sheet. Write the PNGs once with\n// `sheetPngs`. Texture indices are fixed: 0 albedo, 1 normal, 2 ORM (materials.ts binds them).\n\nimport { encodePng } from '../core/index.ts';\nimport type { PaintedSheet } from '../material/index.ts';\nimport type { Json } from './bin-writer.ts';\n\nexport type SheetMap = 'albedo' | 'normal' | 'orm';\nexport const SHEET_MAPS: readonly SheetMap[] = ['albedo', 'normal', 'orm'];\n\n/** Reference a shared sheet by URI instead of embedding it. */\nexport interface ExternalSheet {\n readonly external: true;\n /** URI prefix relative to the .glb, e.g. `../textures/trim_sheet`. Default `trim_sheet`. */\n readonly prefix?: string;\n}\n\nexport type SheetBinding = PaintedSheet | ExternalSheet;\n\nexport const sheetFileName = (map: SheetMap, prefix = 'trim_sheet'): string =>\n `${prefix}_${map}.png`;\n\nconst LINEAR = 9729;\nconst LINEAR_MIPMAP_LINEAR = 9987;\nconst REPEAT = 10497;\nconst CLAMP_TO_EDGE = 33071;\n\nconst pngCache = new WeakMap<PaintedSheet, Readonly<Record<SheetMap, Uint8Array>>>();\n\n/** PNG bytes of each map, encoded once per sheet (every LOD's GLB reuses them). */\nexport function sheetPngs(sheet: PaintedSheet): Readonly<Record<SheetMap, Uint8Array>> {\n const hit = pngCache.get(sheet);\n if (hit) return hit;\n const pngs = {\n albedo: encodePng(sheet.size, sheet.size, sheet.albedo),\n normal: encodePng(sheet.size, sheet.size, sheet.normal),\n orm: encodePng(sheet.size, sheet.size, sheet.orm),\n };\n pngCache.set(sheet, pngs);\n return pngs;\n}\n\nconst isExternal = (s: SheetBinding): s is ExternalSheet => 'external' in s;\n\n/**\n * glTF `images` / `textures` / `samplers` for the sheet. Embedded image bytes are returned as\n * `tail`, to append to the BIN chunk at `offset` (4-aligned); their bufferViews go into `views`.\n */\nexport function sheetGltf(\n sheet: SheetBinding,\n views: Json[],\n offset: number,\n): { json: Json; tail: Uint8Array } {\n const textures = SHEET_MAPS.map((_, i) => ({ sampler: 0, source: i }));\n const samplers = [\n { magFilter: LINEAR, minFilter: LINEAR_MIPMAP_LINEAR, wrapS: REPEAT, wrapT: CLAMP_TO_EDGE },\n ];\n if (isExternal(sheet)) {\n const images = SHEET_MAPS.map((m) => ({\n name: `trim_sheet_${m}`,\n uri: sheetFileName(m, sheet.prefix),\n }));\n return { json: { images, textures, samplers }, tail: new Uint8Array() };\n }\n const pngs = sheetPngs(sheet);\n const parts: Uint8Array[] = [];\n const images: Json[] = [];\n let at = offset;\n for (const m of SHEET_MAPS) {\n const png = pngs[m];\n views.push({ buffer: 0, byteOffset: at, byteLength: png.byteLength });\n images.push({ name: `trim_sheet_${m}`, bufferView: views.length - 1, mimeType: 'image/png' });\n const pad = (4 - (png.byteLength % 4)) % 4;\n parts.push(png, new Uint8Array(pad));\n at += png.byteLength + pad;\n }\n const tail = new Uint8Array(at - offset);\n let o = 0;\n for (const p of parts) {\n tail.set(p, o);\n o += p.byteLength;\n }\n return { json: { images, textures, samplers }, tail };\n}\n",
|
|
20
|
+
"// glTF 2.0 binary writer. One material (the trim sheet) for the whole asset, one node per part\n// with its pivot as translation, and each part's motion baked as a looping animation clip.\n// Extras a stock viewer understands: light sockets → KHR_lights_punctual, glowing parts →\n// emissive (+ KHR_materials_emissive_strength), provenance → asset.copyright + KHR_xmp_json_ld.\n// `exportLodGlb` packs several LODs into ONE file (MSFT_lod alternates sharing materials,\n// textures and motion samplers). Zero dependencies and byte-deterministic.\n\nimport type { CompiledAsset, Part } from '../core/index.ts';\nimport { Ts23dError } from '../core/index.ts';\nimport { BinWriter, type Json } from './bin-writer.ts';\nimport { concat, packGlb } from './container.ts';\nimport { withCredits } from './credits.ts';\nimport type { GlbOptions, GlbResult, LodGlbResult } from './glb-options.ts';\nimport { newDoc, writeHierarchy } from './hierarchy.ts';\nimport { LIGHTS } from './lights.ts';\nimport {\n checkCoverage,\n coverageFor,\n defaultCoverage,\n MSFT_LOD,\n SCREEN_COVERAGE,\n} from './lod-coverage.ts';\nimport { EMISSIVE_STRENGTH, type GlowRule, glowMaterial, materialsFor } from './materials.ts';\nimport { globRe, glowLayer, mergeToPivots } from './merge-pivots.ts';\nimport { metadata } from './metadata.ts';\nimport { optimizeParts, summarize } from './optimize-parts.ts';\nimport { sheetGltf } from './textures.ts';\n\n// Viewers auto-play the FIRST clip and glTF has no \"paused\" flag, so the first clip is `rest`: two\n// keys holding the root's rest rotation. The file opens still; pick `run` to play it.\n// Authoring frame: Z up, +X front. glTF: Y up, +Z front, +X = the asset's left. This root\n// rotation maps +X→+Z, +Z→+Y, +Y→+X (verified numerically), so assets face forward in engines.\nconst Z_UP_TO_Y_UP = [-0.5, -0.5, -0.5, 0.5];\nfunction restClip(bin: BinWriter, roots: readonly number[]): Json {\n const input = bin.accessor(new Float32Array([0, 1]), 'SCALAR', undefined, true);\n const output = bin.accessor(new Float32Array([...Z_UP_TO_Y_UP, ...Z_UP_TO_Y_UP]), 'VEC4');\n return {\n name: 'rest',\n samplers: [{ input, output, interpolation: 'STEP' }],\n channels: roots.map((node) => ({ sampler: 0, target: { node, path: 'rotation' } })),\n };\n}\n\nexport type { GlbOptions, GlbResult, LodGlbResult } from './glb-options.ts';\n\nexport function toGlb(input: CompiledAsset, o: GlbOptions = {}): Uint8Array {\n return exportGlb(input, o).glb;\n}\n\nexport function exportGlb(input: CompiledAsset, o: GlbOptions = {}): GlbResult {\n const { glb, reports } = exportLodGlb([input], o);\n return { glb, report: reports[0] ?? summarize([], false) };\n}\n\n/** All LODs in one GLB: LOD0 in the scene, the rest as MSFT_lod alternates outside it. */\nexport function toLodGlb(lods: readonly CompiledAsset[], o: GlbOptions = {}): Uint8Array {\n return exportLodGlb(lods, o).glb;\n}\n\nfunction checkGlow(rules: readonly GlowRule[]): void {\n for (const r of rules)\n if ((r.strength ?? 4) < 0 || (r.color ?? [0, 0, 0]).some((c) => c < 0 || c > 1))\n throw new Ts23dError('T3D_RECIPE_INVALID', {\n cause: `glow rule for ${JSON.stringify(r.parts)} has a colour outside 0..1 or a negative strength`,\n fix: 'colour is linear 0..1 (hex() converts sRGB); brightness goes in `strength`',\n });\n}\n\nfunction checkLods(lods: readonly CompiledAsset[]): void {\n const names = new Set(lods.map((l) => l.name));\n const levels = lods.map((l) => l.lod);\n if (\n lods.length === 0 ||\n names.size !== 1 ||\n levels.some((l, i) => i > 0 && l <= (levels[i - 1] ?? 0))\n )\n throw new Ts23dError('T3D_RECIPE_INVALID', {\n cause: `exportLodGlb got LODs [${levels.join(', ')}] of [${[...names].join(', ')}]`,\n fix: 'pass compile(asset, { lod }) results of ONE asset, highest detail first: LOD0, LOD1, LOD2',\n });\n}\n\n/** One LOD prepared for writing: merged + optimised parts and its glow-layer lookup. */\nfunction prepare(input: CompiledAsset, o: GlbOptions, glow: readonly GlowRule[]) {\n const opt = o.optimize === false ? false : o.optimize === true ? {} : (o.optimize ?? {});\n const merged = o.keepParts\n ? input\n : mergeToPivots(\n input,\n glow.map((g) => g.parts),\n );\n const { asset, report } = optimizeParts(merged, opt);\n // optimizeParts copies parts: carry the glow tag across by position.\n const glowRes = glow.map((g) => g.parts.map(globRe));\n const glowOf = (p: Part, i: number): number =>\n glowLayer.get(merged.parts[i] ?? p) ??\n (o.keepParts ? glowRes.findIndex((rs) => rs.some((r) => r.test(p.name))) : -1);\n return { asset, report, glowOf };\n}\n\nexport function exportLodGlb(lods: readonly CompiledAsset[], o: GlbOptions = {}): LodGlbResult {\n checkLods(lods);\n const top = lods[0] as CompiledAsset;\n const glow = o.glow ?? top.glow ?? [];\n checkGlow(glow);\n const preps = lods.map((l) => prepare(l, o, glow));\n const withSheet = o.sheet !== undefined;\n const mats = materialsFor(\n new Set(preps.flatMap((p) => p.asset.parts.flatMap((q) => (q.surface ? [q.surface] : [])))),\n withSheet,\n );\n const glowAt = mats.materials.length;\n const materials = [...mats.materials, ...glow.map((g, i) => glowMaterial(g, i, withSheet))];\n const doc = newDoc(new BinWriter());\n const roots = preps.map(({ asset, glowOf }, k) =>\n writeHierarchy(doc, asset, k === 0 ? asset.name : `${asset.name}_LOD${asset.lod}`, {\n withSheet,\n animations: o.animations === true,\n materialOf: (part, i) => {\n const g = glowOf(part, i);\n return g >= 0 ? glowAt + g : (mats.index.get(part.surface ?? 'opaque') ?? 0);\n },\n }),\n );\n for (const r of roots) {\n const node = doc.nodes[r];\n if (node) node['rotation'] = Z_UP_TO_Y_UP;\n }\n const coverage: number[] = [];\n const rootNode = doc.nodes[0];\n if (roots.length > 1 && rootNode) {\n const c = o.lodCoverage ?? top.lodCoverage ?? defaultCoverage(lods);\n checkCoverage(c, top.name);\n coverage.push(\n ...coverageFor(\n lods.map((l) => l.lod),\n c,\n ),\n );\n // Alternates stay OUT of the scene's root list: a viewer without MSFT_lod shows LOD0 only.\n rootNode['extensions'] = { [MSFT_LOD]: { ids: roots.slice(1) } };\n rootNode['extras'] = { [SCREEN_COVERAGE]: coverage };\n }\n\n // Every accessor — the rest clip's included — must be written BEFORE the buffer is sealed.\n const { bin, lights, samplers, channels } = doc;\n const animations = channels.length\n ? [restClip(bin, roots), { name: 'run', samplers, channels }]\n : [];\n const geometry = bin.bytes();\n const tex = o.sheet ? sheetGltf(o.sheet, bin.views, geometry.byteLength) : null;\n const body = tex?.tail.byteLength ? concat(geometry, tex.tail) : geometry;\n const meta = metadata(top.name, withCredits(top, o.meta ?? top.meta));\n const used = [\n ...mats.extensionsUsed,\n ...(glow.some((g) => (g.strength ?? 4) !== 1) ? [EMISSIVE_STRENGTH] : []),\n ...(lights.length ? [LIGHTS] : []),\n ...(coverage.length ? [MSFT_LOD] : []),\n ...meta.used,\n ].sort();\n const extensions: Json = {\n ...(lights.length ? { [LIGHTS]: { lights } } : {}),\n ...(meta.extensions ?? {}),\n };\n const gltf: Json = {\n asset: meta.asset,\n extras: {\n kind: top.kind,\n lod: coverage.length ? lods.map((l) => l.lod) : top.lod,\n units: 'metres',\n up: 'Z (rotated to glTF Y-up at the root)',\n },\n ...(used.length ? { extensionsUsed: used } : {}),\n ...(Object.keys(extensions).length ? { extensions } : {}),\n scene: 0,\n scenes: [{ name: top.name, nodes: [0] }],\n nodes: doc.nodes,\n meshes: doc.meshes,\n materials,\n ...(tex ? tex.json : {}),\n buffers: [{ byteLength: body.byteLength }],\n bufferViews: bin.views,\n accessors: bin.accessors,\n ...(animations.length ? { animations } : {}),\n };\n return { glb: packGlb(gltf, body), reports: preps.map((p) => p.report), coverage };\n}\n"
|
|
21
|
+
],
|
|
22
|
+
"mappings": "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",
|
|
23
|
+
"debugId": "48DF0BBA03847F0964756E2164756E21",
|
|
24
|
+
"names": []
|
|
25
|
+
}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
boundsOf2,
|
|
3
3
|
merge2,
|
|
4
4
|
worldMeshes2
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-hg7pf34j.js";
|
|
6
6
|
|
|
7
7
|
// src/passes/ray-grid.ts
|
|
8
8
|
var CELL_SCALE = 0.3;
|
|
@@ -833,4 +833,4 @@ function splitByNormal(m, cornerNormals) {
|
|
|
833
833
|
export { RayGrid2, bakeAo2, bakeAoAsset2, grime2, livery2, optimize2, weightedNormals2 };
|
|
834
834
|
|
|
835
835
|
//# debugId=BEEEAE9C1B221C7564756E2164756E21
|
|
836
|
-
//# sourceMappingURL=chunk-
|
|
836
|
+
//# sourceMappingURL=chunk-drna2rny.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Ts23dError2
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-hg7pf34j.js";
|
|
4
4
|
|
|
5
5
|
// src/grammar/split.ts
|
|
6
6
|
var syntax = (src, why) => new Ts23dError2("T3D_GRAMMAR_SYNTAX", {
|
|
@@ -86,4 +86,4 @@ function parseWhyte2(arrangement) {
|
|
|
86
86
|
export { parseSplit2, layoutSplit2, split2, parseWhyte2 };
|
|
87
87
|
|
|
88
88
|
//# debugId=3FD9805EE52EDB5F64756E2164756E21
|
|
89
|
-
//# sourceMappingURL=chunk-
|
|
89
|
+
//# sourceMappingURL=chunk-dxvypr7y.js.map
|
|
@@ -11,11 +11,11 @@ import {
|
|
|
11
11
|
toWorld2,
|
|
12
12
|
rotateZ2,
|
|
13
13
|
worldMeshes2
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-hg7pf34j.js";
|
|
15
15
|
import {
|
|
16
16
|
DEFAULT_SHEET2,
|
|
17
17
|
paintTrimSheet2
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-y63c6zcv.js";
|
|
19
19
|
|
|
20
20
|
// src/render/camera.ts
|
|
21
21
|
function basis(azDeg, elDeg) {
|
|
@@ -250,6 +250,82 @@ function openness(m, x, y, z, bias, reach) {
|
|
|
250
250
|
return gap <= 0 ? 1 : gap >= reach ? 1 : gap / reach;
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
+
// src/render/lighting.ts
|
|
254
|
+
var unit = (az, el) => {
|
|
255
|
+
const a = az * Math.PI / 180;
|
|
256
|
+
const e = el * Math.PI / 180;
|
|
257
|
+
return [Math.cos(e) * Math.cos(a), Math.cos(e) * Math.sin(a), Math.sin(e)];
|
|
258
|
+
};
|
|
259
|
+
var RINGS = [
|
|
260
|
+
[14, 5],
|
|
261
|
+
[38, 4],
|
|
262
|
+
[64, 2],
|
|
263
|
+
[88, 1]
|
|
264
|
+
];
|
|
265
|
+
function studioRig(cameraAzDeg) {
|
|
266
|
+
const skyDirs = [];
|
|
267
|
+
RINGS.forEach(([el, n], ring) => {
|
|
268
|
+
for (let i = 0;i < n; i++)
|
|
269
|
+
skyDirs.push(unit(360 * (i + ring * 0.37) / n, el));
|
|
270
|
+
});
|
|
271
|
+
return {
|
|
272
|
+
sun: unit(cameraAzDeg - 50, 55),
|
|
273
|
+
sunColor: [0.95, 0.91, 0.84],
|
|
274
|
+
sky: [0.3, 0.33, 0.4],
|
|
275
|
+
bounce: [0.16, 0.15, 0.13],
|
|
276
|
+
skyDirs,
|
|
277
|
+
exposure: 1
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
var HORIZON = [0.82, 0.8, 0.76];
|
|
281
|
+
var ZENITH = [0.3, 0.34, 0.44];
|
|
282
|
+
var FLOOR = [0.3, 0.28, 0.26];
|
|
283
|
+
var BAND = 0.12;
|
|
284
|
+
function envRadiance(rz, rough, k) {
|
|
285
|
+
const h = HORIZON[k] ?? 0;
|
|
286
|
+
const sharp = rz >= 0 ? h + ((ZENITH[k] ?? 0) - h) * Math.sqrt(rz) : rz > -0.3 ? h * BAND + ((FLOOR[k] ?? 0) - h * BAND) * Math.min(1, -rz / 0.3) ** 0.5 : FLOOR[k] ?? 0;
|
|
287
|
+
const blurred = 0.5 * h + 0.25 * (ZENITH[k] ?? 0) + 0.25 * (FLOOR[k] ?? 0);
|
|
288
|
+
const tilt = 1 + 0.25 * Math.max(-1, Math.min(1, rz * 2));
|
|
289
|
+
const t = Math.min(1, rough * 1.6);
|
|
290
|
+
return sharp + (blurred * tilt - sharp) * t;
|
|
291
|
+
}
|
|
292
|
+
var DISC = [
|
|
293
|
+
[-0.94, -0.4],
|
|
294
|
+
[0.95, -0.77],
|
|
295
|
+
[-0.09, -0.93],
|
|
296
|
+
[0.34, 0.29],
|
|
297
|
+
[-0.92, 0.46],
|
|
298
|
+
[-0.38, -0.06],
|
|
299
|
+
[0.79, 0.19],
|
|
300
|
+
[-0.24, 0.78],
|
|
301
|
+
[0.44, -0.3],
|
|
302
|
+
[0.55, 0.85],
|
|
303
|
+
[-0.66, -0.87],
|
|
304
|
+
[0.06, 0.37]
|
|
305
|
+
];
|
|
306
|
+
function pcfTaps(radius) {
|
|
307
|
+
return [0, 1, 2, 3].map((k) => {
|
|
308
|
+
const a = k * Math.PI / 8;
|
|
309
|
+
const c = Math.cos(a) * radius;
|
|
310
|
+
const s = Math.sin(a) * radius;
|
|
311
|
+
const out = new Float32Array(DISC.length * 2);
|
|
312
|
+
DISC.forEach(([x, y], i) => {
|
|
313
|
+
out[i * 2] = x * c - y * s;
|
|
314
|
+
out[i * 2 + 1] = x * s + y * c;
|
|
315
|
+
});
|
|
316
|
+
return out;
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
function tone(x) {
|
|
320
|
+
if (x <= 0)
|
|
321
|
+
return 0;
|
|
322
|
+
if (x <= 0.6)
|
|
323
|
+
return x;
|
|
324
|
+
return 0.6 + 0.4 * (1 - Math.exp(-(x - 0.6) / 0.4));
|
|
325
|
+
}
|
|
326
|
+
var toSrgb8 = (v) => Math.round(255 * (v <= 0.0031308 ? v * 12.92 : 1.055 * Math.min(1, v) ** (1 / 2.4) - 0.055));
|
|
327
|
+
var fromSrgb = (v) => v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4;
|
|
328
|
+
|
|
253
329
|
// src/render/texture.ts
|
|
254
330
|
var SRGB = new Float32Array(256).map((_, i) => {
|
|
255
331
|
const v = i / 255;
|
|
@@ -448,7 +524,9 @@ function shadeSample(c, t, b1, b2, mip, set, out) {
|
|
|
448
524
|
const shin = Math.min(2048, 2 / (rough * rough * rough * rough) - 2);
|
|
449
525
|
const lobe = (shin + 8) / 25.13 * ndh ** shin;
|
|
450
526
|
const fr = (1 - vdh) ** 5;
|
|
451
|
-
const
|
|
527
|
+
const fv = (1 - ndv) ** 5;
|
|
528
|
+
const rz = 2 * ndv * n2 - vz;
|
|
529
|
+
const specOcc = open * (0.4 + 0.6 * occ);
|
|
452
530
|
const ch = [ar, ag, ab];
|
|
453
531
|
for (let k = 0;k < 3; k++) {
|
|
454
532
|
const al = ch[k] ?? 0;
|
|
@@ -456,7 +534,7 @@ function shadeSample(c, t, b1, b2, mip, set, out) {
|
|
|
456
534
|
const sky = (r.bounce[k] ?? 0) * (1 - hemi) + (r.sky[k] ?? 0) * hemi;
|
|
457
535
|
const diffuse = al * dk * ((r.sunColor[k] ?? 0) * lit + sky * amb);
|
|
458
536
|
const spec = (f0 + (1 - f0) * fr) * lobe * lit * (r.sunColor[k] ?? 0) * 0.8;
|
|
459
|
-
const env = (f0 + (1 - f0) *
|
|
537
|
+
const env = glass ? (f0 + (1 - f0) * fv * (1 - rough) * (1 - rough)) * (r.sky[k] ?? 0) * open * 2.5 : (f0 + (Math.max(1 - rough, f0) - f0) * fv) * envRadiance(rz, rough, k) * specOcc;
|
|
460
538
|
out[k] = (diffuse + spec + env) * r.exposure;
|
|
461
539
|
}
|
|
462
540
|
}
|
|
@@ -523,70 +601,6 @@ function floorLight(g, cam, px, py) {
|
|
|
523
601
|
return (L[o] ?? 1) * (1 - fx) * (1 - fy) + (L[o + 1] ?? 1) * fx * (1 - fy) + (L[o + g.size] ?? 1) * (1 - fx) * fy + (L[o + g.size + 1] ?? 1) * fx * fy;
|
|
524
602
|
}
|
|
525
603
|
|
|
526
|
-
// src/render/lighting.ts
|
|
527
|
-
var unit = (az, el) => {
|
|
528
|
-
const a = az * Math.PI / 180;
|
|
529
|
-
const e = el * Math.PI / 180;
|
|
530
|
-
return [Math.cos(e) * Math.cos(a), Math.cos(e) * Math.sin(a), Math.sin(e)];
|
|
531
|
-
};
|
|
532
|
-
var RINGS = [
|
|
533
|
-
[14, 5],
|
|
534
|
-
[38, 4],
|
|
535
|
-
[64, 2],
|
|
536
|
-
[88, 1]
|
|
537
|
-
];
|
|
538
|
-
function studioRig(cameraAzDeg) {
|
|
539
|
-
const skyDirs = [];
|
|
540
|
-
RINGS.forEach(([el, n], ring) => {
|
|
541
|
-
for (let i = 0;i < n; i++)
|
|
542
|
-
skyDirs.push(unit(360 * (i + ring * 0.37) / n, el));
|
|
543
|
-
});
|
|
544
|
-
return {
|
|
545
|
-
sun: unit(cameraAzDeg - 50, 55),
|
|
546
|
-
sunColor: [0.95, 0.91, 0.84],
|
|
547
|
-
sky: [0.3, 0.33, 0.4],
|
|
548
|
-
bounce: [0.16, 0.15, 0.13],
|
|
549
|
-
skyDirs,
|
|
550
|
-
exposure: 1
|
|
551
|
-
};
|
|
552
|
-
}
|
|
553
|
-
var DISC = [
|
|
554
|
-
[-0.94, -0.4],
|
|
555
|
-
[0.95, -0.77],
|
|
556
|
-
[-0.09, -0.93],
|
|
557
|
-
[0.34, 0.29],
|
|
558
|
-
[-0.92, 0.46],
|
|
559
|
-
[-0.38, -0.06],
|
|
560
|
-
[0.79, 0.19],
|
|
561
|
-
[-0.24, 0.78],
|
|
562
|
-
[0.44, -0.3],
|
|
563
|
-
[0.55, 0.85],
|
|
564
|
-
[-0.66, -0.87],
|
|
565
|
-
[0.06, 0.37]
|
|
566
|
-
];
|
|
567
|
-
function pcfTaps(radius) {
|
|
568
|
-
return [0, 1, 2, 3].map((k) => {
|
|
569
|
-
const a = k * Math.PI / 8;
|
|
570
|
-
const c = Math.cos(a) * radius;
|
|
571
|
-
const s = Math.sin(a) * radius;
|
|
572
|
-
const out = new Float32Array(DISC.length * 2);
|
|
573
|
-
DISC.forEach(([x, y], i) => {
|
|
574
|
-
out[i * 2] = x * c - y * s;
|
|
575
|
-
out[i * 2 + 1] = x * s + y * c;
|
|
576
|
-
});
|
|
577
|
-
return out;
|
|
578
|
-
});
|
|
579
|
-
}
|
|
580
|
-
function tone(x) {
|
|
581
|
-
if (x <= 0)
|
|
582
|
-
return 0;
|
|
583
|
-
if (x <= 0.6)
|
|
584
|
-
return x;
|
|
585
|
-
return 0.6 + 0.4 * (1 - Math.exp(-(x - 0.6) / 0.4));
|
|
586
|
-
}
|
|
587
|
-
var toSrgb8 = (v) => Math.round(255 * (v <= 0.0031308 ? v * 12.92 : 1.055 * Math.min(1, v) ** (1 / 2.4) - 0.055));
|
|
588
|
-
var fromSrgb = (v) => v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4;
|
|
589
|
-
|
|
590
604
|
// src/render/options.ts
|
|
591
605
|
function need(ok, cause, fix) {
|
|
592
606
|
if (!ok)
|
|
@@ -902,7 +916,7 @@ var defaultSheet;
|
|
|
902
916
|
var sheetOf = (o) => {
|
|
903
917
|
if (o.sheet)
|
|
904
918
|
return o.sheet;
|
|
905
|
-
defaultSheet ??= paintTrimSheet2({ ...DEFAULT_SHEET2, size:
|
|
919
|
+
defaultSheet ??= paintTrimSheet2({ ...DEFAULT_SHEET2, size: 1024 });
|
|
906
920
|
return defaultSheet;
|
|
907
921
|
};
|
|
908
922
|
function cameraFor2(asset, o = {}) {
|
|
@@ -1571,5 +1585,5 @@ function thumbnail2(asset, o = {}) {
|
|
|
1571
1585
|
}
|
|
1572
1586
|
export { checkBeautyOptions2, parseSize2, cameraFor2, renderBeauty2, beauty2, lodStrip2, viewFrame2, silhouette2, maskIoU2, poolMask2, maskStats2, exposure2, photoMatch2, REVIEW_THRESHOLDS2, VIEWS2, contactSheet2, detailWindows2, reviewPack2, thumbnail2 };
|
|
1573
1587
|
|
|
1574
|
-
//# debugId=
|
|
1575
|
-
//# sourceMappingURL=chunk-
|
|
1588
|
+
//# debugId=276D71BEBA755B0464756E2164756E21
|
|
1589
|
+
//# sourceMappingURL=chunk-f6yme003.js.map
|