@drawcall/lod 0.0.0-stage → 0.1.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 (175) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +83 -2
  3. package/dist/baked/codec.d.ts +10 -0
  4. package/dist/baked/codec.js +291 -0
  5. package/dist/baked/codec.js.map +1 -0
  6. package/dist/baked/index.d.ts +51 -0
  7. package/dist/baked/index.js +183 -0
  8. package/dist/baked/index.js.map +1 -0
  9. package/dist/baked/interior/faces.d.ts +26 -0
  10. package/dist/baked/interior/faces.js +105 -0
  11. package/dist/baked/interior/faces.js.map +1 -0
  12. package/dist/baked/interior/material.d.ts +31 -0
  13. package/dist/baked/interior/material.js +157 -0
  14. package/dist/baked/interior/material.js.map +1 -0
  15. package/dist/baked/interior/rooms.d.ts +22 -0
  16. package/dist/baked/interior/rooms.js +78 -0
  17. package/dist/baked/interior/rooms.js.map +1 -0
  18. package/dist/baked/low.d.ts +20 -0
  19. package/dist/baked/low.js +75 -0
  20. package/dist/baked/low.js.map +1 -0
  21. package/dist/baked/raster.d.ts +20 -0
  22. package/dist/baked/raster.js +71 -0
  23. package/dist/baked/raster.js.map +1 -0
  24. package/dist/baked/transfer.d.ts +36 -0
  25. package/dist/baked/transfer.js +243 -0
  26. package/dist/baked/transfer.js.map +1 -0
  27. package/dist/baked/unwrap.d.ts +9 -0
  28. package/dist/baked/unwrap.js +167 -0
  29. package/dist/baked/unwrap.js.map +1 -0
  30. package/dist/baked/xatlas.d.ts +2 -0
  31. package/dist/baked/xatlas.js +31 -0
  32. package/dist/baked/xatlas.js.map +1 -0
  33. package/dist/bounds.d.ts +33 -0
  34. package/dist/bounds.js +127 -0
  35. package/dist/bounds.js.map +1 -0
  36. package/dist/dispose.d.ts +5 -0
  37. package/dist/dispose.js +28 -0
  38. package/dist/dispose.js.map +1 -0
  39. package/dist/fade.d.ts +44 -0
  40. package/dist/fade.js +78 -0
  41. package/dist/fade.js.map +1 -0
  42. package/dist/impostor/bake/atlas.d.ts +51 -0
  43. package/dist/impostor/bake/atlas.js +190 -0
  44. package/dist/impostor/bake/atlas.js.map +1 -0
  45. package/dist/impostor/bake/index.d.ts +50 -0
  46. package/dist/impostor/bake/index.js +221 -0
  47. package/dist/impostor/bake/index.js.map +1 -0
  48. package/dist/impostor/bake/materials.d.ts +29 -0
  49. package/dist/impostor/bake/materials.js +156 -0
  50. package/dist/impostor/bake/materials.js.map +1 -0
  51. package/dist/impostor/bake/source.d.ts +3 -0
  52. package/dist/impostor/bake/source.js +23 -0
  53. package/dist/impostor/bake/source.js.map +1 -0
  54. package/dist/impostor/cache.d.ts +15 -0
  55. package/dist/impostor/cache.js +44 -0
  56. package/dist/impostor/cache.js.map +1 -0
  57. package/dist/impostor/codec.d.ts +14 -0
  58. package/dist/impostor/codec.js +137 -0
  59. package/dist/impostor/codec.js.map +1 -0
  60. package/dist/impostor/impostor.d.ts +67 -0
  61. package/dist/impostor/impostor.js +79 -0
  62. package/dist/impostor/impostor.js.map +1 -0
  63. package/dist/impostor/mesh/card.d.ts +38 -0
  64. package/dist/impostor/mesh/card.js +79 -0
  65. package/dist/impostor/mesh/card.js.map +1 -0
  66. package/dist/impostor/mesh/index.d.ts +66 -0
  67. package/dist/impostor/mesh/index.js +174 -0
  68. package/dist/impostor/mesh/index.js.map +1 -0
  69. package/dist/impostor/mesh/material.d.ts +63 -0
  70. package/dist/impostor/mesh/material.js +199 -0
  71. package/dist/impostor/mesh/material.js.map +1 -0
  72. package/dist/impostor/mesh/surface.d.ts +63 -0
  73. package/dist/impostor/mesh/surface.js +162 -0
  74. package/dist/impostor/mesh/surface.js.map +1 -0
  75. package/dist/impostor/mesh/textures.d.ts +4 -0
  76. package/dist/impostor/mesh/textures.js +37 -0
  77. package/dist/impostor/mesh/textures.js.map +1 -0
  78. package/dist/impostor/octahedral.d.ts +29 -0
  79. package/dist/impostor/octahedral.js +83 -0
  80. package/dist/impostor/octahedral.js.map +1 -0
  81. package/dist/index.d.ts +15 -0
  82. package/dist/index.js +16 -0
  83. package/dist/index.js.map +1 -0
  84. package/dist/instanced/args.d.ts +20 -0
  85. package/dist/instanced/args.js +77 -0
  86. package/dist/instanced/args.js.map +1 -0
  87. package/dist/instanced/bounds.d.ts +50 -0
  88. package/dist/instanced/bounds.js +271 -0
  89. package/dist/instanced/bounds.js.map +1 -0
  90. package/dist/instanced/dirty.d.ts +12 -0
  91. package/dist/instanced/dirty.js +61 -0
  92. package/dist/instanced/dirty.js.map +1 -0
  93. package/dist/instanced/index.d.ts +116 -0
  94. package/dist/instanced/index.js +573 -0
  95. package/dist/instanced/index.js.map +1 -0
  96. package/dist/instanced/meshes.d.ts +14 -0
  97. package/dist/instanced/meshes.js +54 -0
  98. package/dist/instanced/meshes.js.map +1 -0
  99. package/dist/instanced/select.d.ts +84 -0
  100. package/dist/instanced/select.js +264 -0
  101. package/dist/instanced/select.js.map +1 -0
  102. package/dist/lazy.d.ts +64 -0
  103. package/dist/lazy.js +187 -0
  104. package/dist/lazy.js.map +1 -0
  105. package/dist/levels.d.ts +72 -0
  106. package/dist/levels.js +146 -0
  107. package/dist/levels.js.map +1 -0
  108. package/dist/loader/cache.d.ts +15 -0
  109. package/dist/loader/cache.js +37 -0
  110. package/dist/loader/cache.js.map +1 -0
  111. package/dist/loader/dispose.d.ts +3 -0
  112. package/dist/loader/dispose.js +25 -0
  113. package/dist/loader/dispose.js.map +1 -0
  114. package/dist/loader.d.ts +99 -0
  115. package/dist/loader.js +234 -0
  116. package/dist/loader.js.map +1 -0
  117. package/dist/lod.d.ts +78 -0
  118. package/dist/lod.js +211 -0
  119. package/dist/lod.js.map +1 -0
  120. package/dist/material.d.ts +12 -0
  121. package/dist/material.js +52 -0
  122. package/dist/material.js.map +1 -0
  123. package/dist/pause.d.ts +6 -0
  124. package/dist/pause.js +20 -0
  125. package/dist/pause.js.map +1 -0
  126. package/dist/renderer.d.ts +21 -0
  127. package/dist/renderer.js +83 -0
  128. package/dist/renderer.js.map +1 -0
  129. package/dist/simplify.d.ts +24 -0
  130. package/dist/simplify.js +148 -0
  131. package/dist/simplify.js.map +1 -0
  132. package/dist/source/error.d.ts +14 -0
  133. package/dist/source/error.js +94 -0
  134. package/dist/source/error.js.map +1 -0
  135. package/dist/source/frame.d.ts +11 -0
  136. package/dist/source/frame.js +25 -0
  137. package/dist/source/frame.js.map +1 -0
  138. package/dist/source/shading.d.ts +96 -0
  139. package/dist/source/shading.js +224 -0
  140. package/dist/source/shading.js.map +1 -0
  141. package/dist/source/source.d.ts +23 -0
  142. package/dist/source/source.js +50 -0
  143. package/dist/source/source.js.map +1 -0
  144. package/dist/source/surface.d.ts +31 -0
  145. package/dist/source/surface.js +110 -0
  146. package/dist/source/surface.js.map +1 -0
  147. package/dist/source/texels.d.ts +45 -0
  148. package/dist/source/texels.js +191 -0
  149. package/dist/source/texels.js.map +1 -0
  150. package/dist/source/trace.d.ts +42 -0
  151. package/dist/source/trace.js +153 -0
  152. package/dist/source/trace.js.map +1 -0
  153. package/dist/three.d.ts +55 -0
  154. package/dist/three.js +103 -0
  155. package/dist/three.js.map +1 -0
  156. package/dist/tsl.d.ts +45 -0
  157. package/dist/tsl.js +99 -0
  158. package/dist/tsl.js.map +1 -0
  159. package/dist/view.d.ts +30 -0
  160. package/dist/view.js +75 -0
  161. package/dist/view.js.map +1 -0
  162. package/dist/wind/bounds.d.ts +3 -0
  163. package/dist/wind/bounds.js +47 -0
  164. package/dist/wind/bounds.js.map +1 -0
  165. package/dist/wind/hooks.d.ts +5 -0
  166. package/dist/wind/hooks.js +3 -0
  167. package/dist/wind/hooks.js.map +1 -0
  168. package/dist/wind/index.d.ts +57 -0
  169. package/dist/wind/index.js +196 -0
  170. package/dist/wind/index.js.map +1 -0
  171. package/dist/wind/sway.d.ts +29 -0
  172. package/dist/wind/sway.js +71 -0
  173. package/dist/wind/sway.js.map +1 -0
  174. package/package.json +69 -3
  175. package/skills/lod/SKILL.md +137 -0
@@ -0,0 +1,78 @@
1
+ import { Box3, Ray, Vector3 } from "three/webgpu";
2
+ import { forEachVertex } from "../../bounds.js";
3
+ import { isLight } from "../../three.js";
4
+ /** Most rooms an interior may have: six faces each in texture arrays of at most 256 layers. */
5
+ const MAX_ROOMS = 42;
6
+ /** Share of the smaller box two rooms may overlap by: walls that meet, not rooms inside rooms. */
7
+ const OVERLAP = 0.02;
8
+ /**
9
+ * The boxes of `interior`'s rooms, in the source's own space: one per direct child, the
10
+ * bounds of what it draws. `placement` puts the interior in the source's space.
11
+ *
12
+ * Lights are refused: wherever the source draws they would be scene lights, so every
13
+ * switch to or from it changes the scene's light count (and recompiles every lit
14
+ * material), and an InstancedLod's templates light nothing. Lamps glow with emissive
15
+ * materials instead.
16
+ */
17
+ export function readBoxes(interior, placement) {
18
+ interior.traverse((node) => {
19
+ if (isLight(node))
20
+ throw new Error(`bakeMesh: the interior has a light ("${node.name}"); give lamps emissive materials instead`);
21
+ });
22
+ const rooms = interior.children;
23
+ if (rooms.length === 0)
24
+ throw new Error("bakeMesh: the interior has no rooms: each direct child of it is one room");
25
+ if (rooms.length > MAX_ROOMS)
26
+ throw new Error(`bakeMesh: the interior has ${rooms.length} rooms, at most ${MAX_ROOMS} are supported`);
27
+ const boxes = rooms.map((room, i) => {
28
+ if (room.matrixAutoUpdate)
29
+ room.updateMatrix();
30
+ const matrix = placement.clone().multiply(room.matrix);
31
+ const box = new Box3();
32
+ forEachVertex(room, (p) => box.expandByPoint(p.applyMatrix4(matrix)));
33
+ if (box.isEmpty())
34
+ throw new Error(`bakeMesh: room ${i} ("${room.name}") of the interior draws nothing`);
35
+ return box;
36
+ });
37
+ boxes.forEach((a, i) => boxes.slice(i + 1).forEach((b, k) => {
38
+ const shared = volume(a.clone().intersect(b));
39
+ if (shared > OVERLAP * Math.min(volume(a), volume(b)))
40
+ throw new Error(`bakeMesh: rooms ${i} ("${rooms[i]?.name}") and ${i + k + 1} ("${rooms[i + k + 1]?.name}") of the interior overlap: each room fills a box of its own`);
41
+ }));
42
+ return boxes;
43
+ }
44
+ function volume(box) {
45
+ if (box.isEmpty())
46
+ return 0;
47
+ const { x, y, z } = box.getSize(new Vector3());
48
+ return x * y * z;
49
+ }
50
+ /**
51
+ * How far behind glass a room may begin: half the thinnest room's smallest side. A wall
52
+ * between glass and room is thinner than any room; a ray that met no room within half a
53
+ * room's size is not looking into one through this glass.
54
+ */
55
+ export function windowDepth(boxes) {
56
+ const size = new Vector3();
57
+ return Math.min(...boxes.map((box) => Math.min(...box.getSize(size).toArray()))) / 2;
58
+ }
59
+ const ray = new Ray();
60
+ const enter = new Vector3();
61
+ /**
62
+ * The room a ray from `origin` along unit `direction` is in or enters first within
63
+ * `far`: the room behind a window. -1 for none.
64
+ */
65
+ export function roomAlong(boxes, origin, direction, far) {
66
+ ray.set(origin, direction);
67
+ let nearest = -1;
68
+ let best = far;
69
+ boxes.forEach((box, i) => {
70
+ const distance = box.containsPoint(origin) ? 0 : ray.intersectBox(box, enter)?.distanceTo(origin);
71
+ if (distance === undefined || distance > best)
72
+ return;
73
+ best = distance;
74
+ nearest = i;
75
+ });
76
+ return nearest;
77
+ }
78
+ //# sourceMappingURL=rooms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rooms.js","sourceRoot":"","sources":["../../../src/baked/interior/rooms.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { type Object3D } from "three/webgpu";
2
+ import type { Source } from "../source/source.js";
3
+ import { type Surface } from "../source/surface.js";
4
+ import { type Raster } from "./raster.js";
5
+ /** The surface a bake writes onto, laid out in its UVs. */
6
+ export interface Low extends Surface {
7
+ uvs: Float32Array;
8
+ raster: Raster;
9
+ /** How far the low surface is from the source's, in the source's units: see `measureError`. */
10
+ error: number;
11
+ widest: number;
12
+ }
13
+ /** The source simplified to `ratio` of its triangles, welded first: seams and materials do not matter to a bake. */
14
+ export declare function simplified(source: Source, ratio: number): Promise<Object3D>;
15
+ /**
16
+ * `object`'s triangles (in its own space, which must be the source's) with UVs to bake
17
+ * into: its own when they are usable — inside 0..1, no two triangles on one texel and a
18
+ * texel of free border between charts — else a fresh xatlas atlas.
19
+ */
20
+ export declare function layOut(object: Object3D, source: Source, size: number): Promise<Low>;
@@ -0,0 +1,75 @@
1
+ import { BufferAttribute, BufferGeometry, Mesh } from "three/webgpu";
2
+ import { mergeVertices } from "three/addons/utils/BufferGeometryUtils.js";
3
+ import { decimate } from "../simplify.js";
4
+ import { measureError } from "../source/error.js";
5
+ import { merge } from "../source/surface.js";
6
+ import { rasterize } from "./raster.js";
7
+ import { unwrap } from "./unwrap.js";
8
+ /** The source simplified to `ratio` of its triangles, welded first: seams and materials do not matter to a bake. */
9
+ export function simplified(source, ratio) {
10
+ const geometry = new BufferGeometry();
11
+ geometry.setAttribute("position", new BufferAttribute(source.positions, 3));
12
+ geometry.setIndex(new BufferAttribute(source.index, 1));
13
+ return decimate(new Mesh(mergeVertices(geometry)), ratio);
14
+ }
15
+ /**
16
+ * `object`'s triangles (in its own space, which must be the source's) with UVs to bake
17
+ * into: its own when they are usable — inside 0..1, no two triangles on one texel and a
18
+ * texel of free border between charts — else a fresh xatlas atlas.
19
+ */
20
+ export async function layOut(object, source, size) {
21
+ const surface = merge(object, "bakeMesh");
22
+ const { error, widest } = measureError(source, surface);
23
+ const { uvs, index } = surface;
24
+ if (surface.hasUvs && uvs.every((x) => x >= 0 && x <= 1)) {
25
+ const raster = rasterize(uvs, index, size);
26
+ if (raster.overlaps === 0 && raster.covered > 0 && separated(raster, charts(uvs, index)))
27
+ return { ...surface, raster, error, widest };
28
+ }
29
+ const atlas = await unwrap(surface, size);
30
+ return { ...atlas, raster: rasterize(atlas.uvs, atlas.index, size), error, widest };
31
+ }
32
+ /** Per triangle, its chart: triangles that share a UV point are in one. */
33
+ function charts(uvs, index) {
34
+ const parent = Int32Array.from({ length: index.length / 3 }, (_, i) => i);
35
+ const root = (i) => {
36
+ while (parent[i] !== i)
37
+ i = parent[i] = parent[parent[i] ?? i] ?? i;
38
+ return i;
39
+ };
40
+ const owner = new Map();
41
+ for (let i = 0; i < index.length; i++) {
42
+ const v = index[i] ?? 0;
43
+ const key = `${uvs[v * 2]},${uvs[v * 2 + 1]}`;
44
+ const triangle = Math.floor(i / 3);
45
+ const other = owner.get(key);
46
+ if (other === undefined)
47
+ owner.set(key, triangle);
48
+ else
49
+ parent[root(triangle)] = root(other);
50
+ }
51
+ return parent.map((_, i) => root(i));
52
+ }
53
+ /** Whether no texel of one chart touches a texel of another (8 neighbours). */
54
+ function separated({ size, triangles }, chart) {
55
+ for (let y = 0; y < size; y++)
56
+ for (let x = 0; x < size; x++) {
57
+ const t = triangles[y * size + x] ?? -1;
58
+ if (t < 0)
59
+ continue;
60
+ for (let dy = 0; dy <= 1; dy++)
61
+ for (let dx = -1; dx <= 1; dx++) {
62
+ if (dy === 0 && dx <= 0)
63
+ continue;
64
+ const nx = x + dx;
65
+ const ny = y + dy;
66
+ if (nx < 0 || nx >= size || ny >= size)
67
+ continue;
68
+ const u = triangles[ny * size + nx] ?? -1;
69
+ if (u >= 0 && chart[u] !== chart[t])
70
+ return false;
71
+ }
72
+ }
73
+ return true;
74
+ }
75
+ //# sourceMappingURL=low.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"low.js","sourceRoot":"","sources":["../../src/baked/low.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,IAAI,EAAiB,MAAM,cAAc,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,KAAK,EAAgB,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAe,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAWrC,oHAAoH;AACpH,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,KAAa;IACtD,MAAM,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC;IACtC,QAAQ,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,eAAe,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5E,QAAQ,CAAC,QAAQ,CAAC,IAAI,eAAe,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IACxD,OAAO,QAAQ,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AAC5D,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAgB,EAAE,MAAc,EAAE,IAAY;IACzE,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC1C,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxD,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC;IAC/B,IAAI,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QACzD,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC3C,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC,IAAI,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAAE,OAAO,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACzI,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC1C,OAAO,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACtF,CAAC;AAED,2EAA2E;AAC3E,SAAS,MAAM,CAAC,GAAiB,EAAE,KAAkB;IACnD,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1E,MAAM,IAAI,GAAG,CAAC,CAAS,EAAU,EAAE;QACjC,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;YAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;QACpE,OAAO,CAAC,CAAC;IACX,CAAC,CAAC;IACF,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACxB,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACnC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,KAAK,KAAK,SAAS;YAAE,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;;YAC7C,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACvC,CAAC;AAED,+EAA+E;AAC/E,SAAS,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAU,EAAE,KAAiB;IAC/D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9B,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACxC,IAAI,CAAC,GAAG,CAAC;gBAAE,SAAS;YACpB,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE;gBAC5B,KAAK,IAAI,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC;oBAChC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;wBAAE,SAAS;oBAClC,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;oBAClB,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC;oBAClB,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI;wBAAE,SAAS;oBACjD,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,GAAG,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;oBAC1C,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;wBAAE,OAAO,KAAK,CAAC;gBACpD,CAAC;QACL,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * A triangle list laid out in its UVs on a `size`² texel grid: per texel, the triangle
3
+ * covering its centre (-1 for none) and that point's weights for the triangle's second
4
+ * and third corners.
5
+ */
6
+ export interface Raster {
7
+ size: number;
8
+ triangles: Int32Array;
9
+ weights: Float32Array;
10
+ /** texels covered */
11
+ covered: number;
12
+ /** texels whose centre more than one triangle covers: UVs that overlap */
13
+ overlaps: number;
14
+ }
15
+ /**
16
+ * Rasterize `index`'s triangles at their `uvs` on the CPU. A texel centre on an edge two
17
+ * triangles share belongs to exactly one of them (a fill rule), so a clean layout has no
18
+ * overlaps; folded or stacked UVs do. Where triangles overlap, the first keeps the texel.
19
+ */
20
+ export declare function rasterize(uvs: Float32Array, index: Uint32Array, size: number): Raster;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Rasterize `index`'s triangles at their `uvs` on the CPU. A texel centre on an edge two
3
+ * triangles share belongs to exactly one of them (a fill rule), so a clean layout has no
4
+ * overlaps; folded or stacked UVs do. Where triangles overlap, the first keeps the texel.
5
+ */
6
+ export function rasterize(uvs, index, size) {
7
+ const triangles = new Int32Array(size * size).fill(-1);
8
+ const weights = new Float32Array(size * size * 2);
9
+ let covered = 0;
10
+ let overlaps = 0;
11
+ const p = new Float64Array(6);
12
+ for (let t = 0; t < index.length / 3; t++) {
13
+ for (let k = 0; k < 3; k++) {
14
+ const v = index[t * 3 + k] ?? 0;
15
+ p[k * 2] = (uvs[v * 2] ?? 0) * size;
16
+ p[k * 2 + 1] = (uvs[v * 2 + 1] ?? 0) * size;
17
+ }
18
+ const [ax = 0, ay = 0, bx = 0, by = 0, cx = 0, cy = 0] = p;
19
+ const area = edge(ax, ay, bx, by, cx, cy);
20
+ if (area === 0)
21
+ continue;
22
+ // Corners in counter-clockwise order for the fill rule; weights stay the input's.
23
+ const sign = area > 0 ? 1 : -1;
24
+ const ownA = owns(bx, by, cx, cy, sign);
25
+ const ownB = owns(cx, cy, ax, ay, sign);
26
+ const ownC = owns(ax, ay, bx, by, sign);
27
+ const x0 = Math.max(0, Math.ceil(Math.min(ax, bx, cx) - 0.5));
28
+ const x1 = Math.min(size - 1, Math.floor(Math.max(ax, bx, cx) - 0.5));
29
+ const y0 = Math.max(0, Math.ceil(Math.min(ay, by, cy) - 0.5));
30
+ const y1 = Math.min(size - 1, Math.floor(Math.max(ay, by, cy) - 0.5));
31
+ for (let y = y0; y <= y1; y++)
32
+ for (let x = x0; x <= x1; x++) {
33
+ const qx = x + 0.5;
34
+ const qy = y + 0.5;
35
+ const wa = edge(bx, by, cx, cy, qx, qy) * sign;
36
+ const wb = edge(cx, cy, ax, ay, qx, qy) * sign;
37
+ const wc = edge(ax, ay, bx, by, qx, qy) * sign;
38
+ if (wa < 0 || wb < 0 || wc < 0)
39
+ continue;
40
+ if ((wa === 0 && !ownA) || (wb === 0 && !ownB) || (wc === 0 && !ownC))
41
+ continue;
42
+ const texel = y * size + x;
43
+ if (triangles[texel] !== -1) {
44
+ overlaps++;
45
+ continue;
46
+ }
47
+ covered++;
48
+ triangles[texel] = t;
49
+ weights[texel * 2] = (wb * sign) / area;
50
+ weights[texel * 2 + 1] = (wc * sign) / area;
51
+ }
52
+ }
53
+ return { size, triangles, weights, covered, overlaps };
54
+ }
55
+ /**
56
+ * Twice the signed area of (p, q, r). Computed from the edge's lexicographically smaller
57
+ * end, so two triangles sharing the edge get exactly opposite values: the fill rule
58
+ * relies on that.
59
+ */
60
+ function edge(px, py, qx, qy, rx, ry) {
61
+ if (px > qx || (px === qx && py > qy))
62
+ return -((px - qx) * (ry - qy) - (py - qy) * (rx - qx));
63
+ return (qx - px) * (ry - py) - (qy - py) * (rx - px);
64
+ }
65
+ /** Whether the edge p → q (reversed for clockwise triangles) owns centres exactly on it. */
66
+ function owns(px, py, qx, qy, sign) {
67
+ const dx = (qx - px) * sign;
68
+ const dy = (qy - py) * sign;
69
+ return dy > 0 || (dy === 0 && dx < 0);
70
+ }
71
+ //# sourceMappingURL=raster.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raster.js","sourceRoot":"","sources":["../../src/baked/raster.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { Box3 } from "three/webgpu";
2
+ import type { Source } from "../source/source.js";
3
+ import type { Low } from "./low.js";
4
+ /** The baked maps, RGBA8 each, row 0 at v = 0. */
5
+ interface Maps {
6
+ /** sRGB base colour; alpha 255 where the surface is, 0 where it is cut out */
7
+ color: Uint8ClampedArray;
8
+ /** tangent-space normal, in the frame three derives from the low mesh's UVs */
9
+ normal: Uint8ClampedArray;
10
+ /** R occlusion, G roughness, B metalness */
11
+ orm: Uint8ClampedArray;
12
+ /**
13
+ * RG8: R the room behind the nearest window texel + 1 (0 without rooms), G the share of
14
+ * a window texel through which its room shows (0 elsewhere)
15
+ */
16
+ windows: Uint8Array;
17
+ }
18
+ /**
19
+ * Transfer `source`'s surface onto `low`'s texels. For each covered texel, a ray is cast
20
+ * from P + reach·N to P - reach·N (N the smoothed low normal) against the source; the
21
+ * first hit that is opaque and faces the same way as the low triangle (or is on a
22
+ * double-sided material) is shaded. With none, the ray goes on through the whole source:
23
+ * over open sources such as a canopy of leaves it finds the leaves lower down that a
24
+ * viewer sees through the gap. A texel whose ray finds nothing at all is open: cut out if
25
+ * the source cuts out anywhere, as the source shows nothing there either, else (an
26
+ * opaque low mesh cannot show a hole) coloured like its neighbours. The nearest source
27
+ * point would be the wrong colour there: over a canopy it is whatever stands highest,
28
+ * such as the tassels of corn, which then cover the bake in pale blobs. Texels no surface
29
+ * was baked into are filled from their neighbours, so filtering and mips do not pull in
30
+ * black at chart edges.
31
+ *
32
+ * With room `boxes`, a texel whose surface is glass is a window into the room the ray
33
+ * enters after passing it (see `windowDepth`).
34
+ */
35
+ export declare function transfer(source: Source, low: Low, reach: number, texelSize: number, boxes: readonly Box3[] | null): Promise<Maps>;
36
+ export {};
@@ -0,0 +1,243 @@
1
+ import { Box3, Matrix3, Vector3 } from "three/webgpu";
2
+ import { pause } from "../pause.js";
3
+ import { tangentFrame } from "../source/frame.js";
4
+ import { Shading } from "../source/shading.js";
5
+ import { linearToSrgb } from "../source/texels.js";
6
+ import { Tracer } from "../source/trace.js";
7
+ import { roomAlong, windowDepth } from "./interior/rooms.js";
8
+ /**
9
+ * What a texel became: no low triangle covers it, a surface was baked, or its ray found
10
+ * no surface (cut out where the source cuts out, else its neighbours' colour).
11
+ */
12
+ const EMPTY = 0;
13
+ const BAKED = 1;
14
+ const OPEN = 2;
15
+ /**
16
+ * Transfer `source`'s surface onto `low`'s texels. For each covered texel, a ray is cast
17
+ * from P + reach·N to P - reach·N (N the smoothed low normal) against the source; the
18
+ * first hit that is opaque and faces the same way as the low triangle (or is on a
19
+ * double-sided material) is shaded. With none, the ray goes on through the whole source:
20
+ * over open sources such as a canopy of leaves it finds the leaves lower down that a
21
+ * viewer sees through the gap. A texel whose ray finds nothing at all is open: cut out if
22
+ * the source cuts out anywhere, as the source shows nothing there either, else (an
23
+ * opaque low mesh cannot show a hole) coloured like its neighbours. The nearest source
24
+ * point would be the wrong colour there: over a canopy it is whatever stands highest,
25
+ * such as the tassels of corn, which then cover the bake in pale blobs. Texels no surface
26
+ * was baked into are filled from their neighbours, so filtering and mips do not pull in
27
+ * black at chart edges.
28
+ *
29
+ * With room `boxes`, a texel whose surface is glass is a window into the room the ray
30
+ * enters after passing it (see `windowDepth`).
31
+ */
32
+ export async function transfer(source, low, reach, texelSize, boxes) {
33
+ const { size, triangles, weights } = low.raster;
34
+ const count = size * size;
35
+ const color = new Uint8ClampedArray(count * 4);
36
+ const normal = new Uint8ClampedArray(count * 4);
37
+ const orm = new Uint8ClampedArray(count * 4);
38
+ const state = new Uint8Array(count);
39
+ const windows = new Uint8Array(count * 2);
40
+ const depth = boxes ? windowDepth(boxes) : 0;
41
+ const hit = new Vector3();
42
+ const shading = new Shading(source, texelSize);
43
+ const tracer = new Tracer(source, shading);
44
+ const P = new Vector3();
45
+ const N = new Vector3();
46
+ const F = new Vector3();
47
+ const R = new Vector3();
48
+ const origin = new Vector3();
49
+ const direction = new Vector3();
50
+ const e1 = new Vector3();
51
+ const e2 = new Vector3();
52
+ const tangent = new Vector3();
53
+ const bitangent = new Vector3();
54
+ const frame = new Matrix3();
55
+ const local = new Vector3();
56
+ // Far enough to pass through the whole source from anywhere on the low mesh.
57
+ const through = 2 * reach + source.bvh.getBoundingBox(new Box3()).getSize(new Vector3()).length();
58
+ const { positions, normals, uvs, index } = low;
59
+ let w0 = 0;
60
+ let w1 = 0;
61
+ let w2 = 0;
62
+ let a = 0;
63
+ let b = 0;
64
+ let c = 0;
65
+ const lerp = (array, k) => (array[a * 3 + k] ?? 0) * w0 + (array[b * 3 + k] ?? 0) * w1 + (array[c * 3 + k] ?? 0) * w2;
66
+ const edge = (to, k) => (positions[to * 3 + k] ?? 0) - (positions[a * 3 + k] ?? 0);
67
+ const uv = (corner, k) => uvs[corner * 2 + k] ?? 0;
68
+ let yielded = performance.now();
69
+ for (let texel = 0; texel < count; texel++) {
70
+ if ((texel & 1023) === 0 && performance.now() - yielded > 30) {
71
+ await pause();
72
+ yielded = performance.now();
73
+ }
74
+ const triangle = triangles[texel] ?? -1;
75
+ if (triangle < 0)
76
+ continue;
77
+ a = index[triangle * 3] ?? 0;
78
+ b = index[triangle * 3 + 1] ?? 0;
79
+ c = index[triangle * 3 + 2] ?? 0;
80
+ w1 = weights[texel * 2] ?? 0;
81
+ w2 = weights[texel * 2 + 1] ?? 0;
82
+ w0 = 1 - w1 - w2;
83
+ P.set(lerp(positions, 0), lerp(positions, 1), lerp(positions, 2));
84
+ N.set(lerp(normals, 0), lerp(normals, 1), lerp(normals, 2)).normalize();
85
+ e1.set(edge(b, 0), edge(b, 1), edge(b, 2));
86
+ e2.set(edge(c, 0), edge(c, 1), edge(c, 2));
87
+ F.crossVectors(e1, e2).normalize();
88
+ // Rays follow the smoothed normal, so creases leave no gaps, unless smoothing broke
89
+ // down (back-to-back cards welded). Which side faces out is the low triangle's.
90
+ R.copy(N.dot(F) > 0.2 ? N : F);
91
+ origin.copy(P).addScaledVector(R, reach);
92
+ direction.copy(R).negate();
93
+ // From outside in: the outermost surface is what a viewer sees of the source here.
94
+ if (tracer.cast(origin, direction, through, F) !== "opaque") {
95
+ state[texel] = OPEN;
96
+ continue;
97
+ }
98
+ shading.shade(tracer.triangle, tracer.w1, tracer.w2, false);
99
+ const { transmittance } = shading.material(tracer.triangle);
100
+ if (boxes && transmittance > 0) {
101
+ const room = roomAlong(boxes, pointOf(source, tracer.triangle, tracer.w1, tracer.w2, hit), direction, depth);
102
+ if (room >= 0) {
103
+ windows[texel * 2] = room + 1;
104
+ windows[texel * 2 + 1] = Math.round(transmittance * 255);
105
+ }
106
+ }
107
+ state[texel] = BAKED;
108
+ const o = texel * 4;
109
+ color[o] = linearToSrgb(shading.r) * 255;
110
+ color[o + 1] = linearToSrgb(shading.g) * 255;
111
+ color[o + 2] = linearToSrgb(shading.b) * 255;
112
+ orm[o] = shading.ao * 255;
113
+ orm[o + 1] = shading.roughness * 255;
114
+ orm[o + 2] = shading.metalness * 255;
115
+ // The normal in the frame three will rebuild here from the mesh's own normal: solve
116
+ // (T B N) · m = n for m.
117
+ tangentFrame(e1, e2, uv(b, 0) - uv(a, 0), uv(b, 1) - uv(a, 1), uv(c, 0) - uv(a, 0), uv(c, 1) - uv(a, 1), N, tangent, bitangent);
118
+ frame.set(tangent.x, bitangent.x, N.x, tangent.y, bitangent.y, N.y, tangent.z, bitangent.z, N.z);
119
+ if (frame.determinant() === 0)
120
+ local.set(0, 0, 1);
121
+ else
122
+ local.copy(shading.normal).applyMatrix3(frame.invert()).normalize();
123
+ normal[o] = (local.x * 0.5 + 0.5) * 255;
124
+ normal[o + 1] = (local.y * 0.5 + 0.5) * 255;
125
+ normal[o + 2] = (local.z * 0.5 + 0.5) * 255;
126
+ }
127
+ // Colours spread over everything not baked, open texels included, so coverage edges
128
+ // do not fringe; coverage spreads only into texels no triangle covers.
129
+ dilate(state, (texel) => texel === BAKED, [color, normal, orm], 0, 3, size);
130
+ for (let texel = 0; texel < count; texel++)
131
+ color[texel * 4 + 3] = state[texel] === BAKED ? 255 : 0;
132
+ if (source.cutout) {
133
+ dilate(state, (texel) => texel !== EMPTY, [color], 3, 1, size);
134
+ // Coverage stays a decision: in or out, at 0.5.
135
+ for (let i = 3; i < color.length; i += 4)
136
+ color[i] = (color[i] ?? 0) >= 128 ? 255 : 0;
137
+ }
138
+ else
139
+ for (let i = 3; i < color.length; i += 4)
140
+ color[i] = 255;
141
+ for (let i = 3; i < color.length; i += 4)
142
+ normal[i] = orm[i] = 255;
143
+ spreadRooms(windows, size);
144
+ return { color, normal, orm, windows };
145
+ }
146
+ /**
147
+ * Give every texel of `windows` without a room the room of the nearest one with (by
148
+ * 4-neighbour steps): the share filters across window edges and mip levels, and wherever
149
+ * it does the texel read there must name the window's room.
150
+ */
151
+ function spreadRooms(windows, size) {
152
+ let ring = [];
153
+ for (let i = 0; i < size * size; i++)
154
+ if (windows[i * 2])
155
+ ring.push(i);
156
+ while (ring.length > 0) {
157
+ const next = [];
158
+ for (const i of ring) {
159
+ const x = i % size;
160
+ const room = windows[i * 2] ?? 0;
161
+ for (const j of [x > 0 ? i - 1 : -1, x < size - 1 ? i + 1 : -1, i - size, i + size]) {
162
+ if (j < 0 || j >= size * size || windows[j * 2])
163
+ continue;
164
+ windows[j * 2] = room;
165
+ next.push(j);
166
+ }
167
+ }
168
+ ring = next;
169
+ }
170
+ }
171
+ /** The point at weights (`w1`, `w2`) of `source`'s triangle `triangle`, into `out`. */
172
+ function pointOf({ positions, index }, triangle, w1, w2, out) {
173
+ const corner = (k, c) => positions[(index[triangle * 3 + k] ?? 0) * 3 + c] ?? 0;
174
+ return out.set(corner(0, 0) * (1 - w1 - w2) + corner(1, 0) * w1 + corner(2, 0) * w2, corner(0, 1) * (1 - w1 - w2) + corner(1, 1) * w1 + corner(2, 1) * w2, corner(0, 2) * (1 - w1 - w2) + corner(1, 2) * w1 + corner(2, 2) * w2);
175
+ }
176
+ /**
177
+ * Fill every texel `known` rejects with the mean of its known 8 neighbours, ring by ring
178
+ * outwards until the whole texture is filled: `channels` channels from `first` of each
179
+ * layer.
180
+ */
181
+ function dilate(state, known, layers, first, channels, size) {
182
+ const done = new Uint8Array(state.length);
183
+ const queued = new Uint8Array(state.length);
184
+ let ring = new Int32Array(state.length);
185
+ let next = new Int32Array(state.length);
186
+ let length = 0;
187
+ for (let i = 0; i < state.length; i++)
188
+ done[i] = known(state[i] ?? EMPTY) ? 1 : 0;
189
+ const enqueue = (i) => {
190
+ const x = i % size;
191
+ const y = (i - x) / size;
192
+ for (let dy = -1; dy <= 1; dy++)
193
+ for (let dx = -1; dx <= 1; dx++) {
194
+ const nx = x + dx;
195
+ const ny = y + dy;
196
+ if (nx < 0 || ny < 0 || nx >= size || ny >= size)
197
+ continue;
198
+ const j = ny * size + nx;
199
+ if (done[j] || queued[j])
200
+ continue;
201
+ queued[j] = 1;
202
+ next[length++] = j;
203
+ }
204
+ };
205
+ for (let i = 0; i < state.length; i++)
206
+ if (done[i])
207
+ enqueue(i);
208
+ while (length > 0) {
209
+ [ring, next] = [next, ring];
210
+ const count = length;
211
+ length = 0;
212
+ for (let r = 0; r < count; r++) {
213
+ const i = ring[r] ?? 0;
214
+ const x = i % size;
215
+ const y = (i - x) / size;
216
+ for (const layer of layers)
217
+ for (let c = first; c < first + channels; c++) {
218
+ let sum = 0;
219
+ let n = 0;
220
+ for (let dy = -1; dy <= 1; dy++)
221
+ for (let dx = -1; dx <= 1; dx++) {
222
+ const nx = x + dx;
223
+ const ny = y + dy;
224
+ if (nx < 0 || ny < 0 || nx >= size || ny >= size)
225
+ continue;
226
+ const j = ny * size + nx;
227
+ if (!done[j])
228
+ continue;
229
+ sum += layer[j * 4 + c] ?? 0;
230
+ n++;
231
+ }
232
+ if (n > 0)
233
+ layer[i * 4 + c] = sum / n;
234
+ }
235
+ }
236
+ // A ring becomes a source only for the next one.
237
+ for (let r = 0; r < count; r++)
238
+ done[ring[r] ?? 0] = 1;
239
+ for (let r = 0; r < count; r++)
240
+ enqueue(ring[r] ?? 0);
241
+ }
242
+ }
243
+ //# sourceMappingURL=transfer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer.js","sourceRoot":"","sources":["../../src/baked/transfer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { Surface } from "../source/surface.js";
2
+ /**
3
+ * `surface` with a fresh UV atlas for a `size`² texture: xatlas cuts it into charts and
4
+ * packs them with a bilinear-safe padding. Vertices on chart seams are split; the result's
5
+ * attributes follow its new vertices.
6
+ */
7
+ export declare function unwrap(surface: Surface, size: number): Promise<Surface & {
8
+ uvs: Float32Array;
9
+ }>;