@woosh/meep-engine 2.138.16 → 2.138.18

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 (54) hide show
  1. package/editor/Editor.d.ts.map +1 -1
  2. package/editor/SelectionVisualizer.d.ts.map +1 -1
  3. package/editor/actions/concrete/ComponentAddAction.d.ts.map +1 -1
  4. package/editor/actions/concrete/EntityCreateAction.d.ts.map +1 -1
  5. package/editor/actions/concrete/SelectionAddAction.d.ts.map +1 -1
  6. package/editor/enableEditor.d.ts.map +1 -1
  7. package/package.json +1 -1
  8. package/src/engine/ecs/grid/HeightMap2AOMap.d.ts +25 -0
  9. package/src/engine/ecs/grid/HeightMap2AOMap.d.ts.map +1 -0
  10. package/src/engine/ecs/grid/HeightMap2AOMap.js +96 -0
  11. package/src/engine/ecs/terrain/ecs/BuildLightTexture.d.ts +15 -7
  12. package/src/engine/ecs/terrain/ecs/BuildLightTexture.d.ts.map +1 -1
  13. package/src/engine/ecs/terrain/ecs/BuildLightTexture.js +44 -99
  14. package/src/engine/ecs/terrain/ecs/Terrain.d.ts.map +1 -1
  15. package/src/engine/ecs/terrain/ecs/Terrain.js +36 -0
  16. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.d.ts +1 -1
  17. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.d.ts.map +1 -1
  18. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +3 -1
  19. package/src/engine/ecs/terrain/tiles/TerrainTileManager.d.ts +12 -1
  20. package/src/engine/ecs/terrain/tiles/TerrainTileManager.d.ts.map +1 -1
  21. package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +21 -0
  22. package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderDepthV0.d.ts.map +1 -1
  23. package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderDepthV0.js +2 -14
  24. package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderLitV0.d.ts.map +1 -1
  25. package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderLitV0.js +1 -7
  26. package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderNormalsV0.d.ts.map +1 -1
  27. package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderNormalsV0.js +1 -6
  28. package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderViewportDepthV0.d.ts.map +1 -1
  29. package/src/engine/graphics/impostors/octahedral/shader/ImpostorShaderViewportDepthV0.js +1 -6
  30. package/src/engine/graphics/material/TerrainDepthMaterial.d.ts +36 -0
  31. package/src/engine/graphics/material/TerrainDepthMaterial.d.ts.map +1 -0
  32. package/src/engine/graphics/material/TerrainDepthMaterial.js +65 -0
  33. package/src/engine/graphics/shaders/AmbientOcclusionShader.d.ts +69 -12
  34. package/src/engine/graphics/shaders/AmbientOcclusionShader.d.ts.map +1 -1
  35. package/src/engine/graphics/shaders/AmbientOcclusionShader.js +386 -128
  36. package/src/engine/graphics/util/build_max_height_pyramid.d.ts +32 -0
  37. package/src/engine/graphics/util/build_max_height_pyramid.d.ts.map +1 -0
  38. package/src/engine/graphics/util/build_max_height_pyramid.js +143 -0
  39. package/editor/ecs/component/FieldDescriptor.d.ts +0 -27
  40. package/editor/ecs/component/FieldDescriptor.d.ts.map +0 -1
  41. package/editor/ecs/component/FieldValueAdapter.d.ts +0 -7
  42. package/editor/ecs/component/FieldValueAdapter.d.ts.map +0 -1
  43. package/editor/ecs/component/createFieldEditor.d.ts +0 -9
  44. package/editor/ecs/component/createFieldEditor.d.ts.map +0 -1
  45. package/editor/ecs/component/createObjectEditor.d.ts +0 -14
  46. package/editor/ecs/component/createObjectEditor.d.ts.map +0 -1
  47. package/editor/ecs/component/findNearestRegisteredType.d.ts +0 -8
  48. package/editor/ecs/component/findNearestRegisteredType.d.ts.map +0 -1
  49. package/src/engine/ecs/grid/HeightMap2NormalMap.d.ts +0 -10
  50. package/src/engine/ecs/grid/HeightMap2NormalMap.d.ts.map +0 -1
  51. package/src/engine/ecs/grid/HeightMap2NormalMap.js +0 -72
  52. package/src/engine/ecs/grid/NormalMap2AOMap.d.ts +0 -15
  53. package/src/engine/ecs/grid/NormalMap2AOMap.d.ts.map +0 -1
  54. package/src/engine/ecs/grid/NormalMap2AOMap.js +0 -82
@@ -0,0 +1,143 @@
1
+ import {
2
+ ClampToEdgeWrapping,
3
+ DataTexture2DArray,
4
+ FloatType,
5
+ NearestFilter,
6
+ RedFormat
7
+ } from "three";
8
+
9
+ /**
10
+ * Build a max-reduction Hi-Z height pyramid from a single-channel float
11
+ * heightmap sampler.
12
+ *
13
+ * Each pyramid level k holds, per texel, the maximum height across the 2×2
14
+ * block of level k-1 it covers. A ray trace can then skip whole cells
15
+ * safely: if the ray's height is strictly above the cell's max-height at
16
+ * any level, the cell can be advanced past without checking any finer level.
17
+ *
18
+ * Storage layout — **DataTexture2DArray, one mip per layer**, all layers at
19
+ * full mip-0 resolution. Smaller mips are nearest-upscaled into their layer.
20
+ * The shader samples mip k via `texture(heightMap, vec3(uv, float(k)))`.
21
+ *
22
+ * This sidesteps the three.js r136 bug in `WebGLTextures.uploadTexture`
23
+ * where DataTexture custom mipmap chains are uploaded with `texSubImage2D`
24
+ * called with level hardcoded to 0 — every "mip" smashes the previous one
25
+ * into level 0 and the actual mip levels 1..N are left uninitialized. The
26
+ * 2DArray upload path uses one `texSubImage3D` call to level 0 covering
27
+ * all layers, so it works correctly.
28
+ *
29
+ * Memory cost is (mip_count × W × H × 4) bytes versus (≈ 4/3 × W × H × 4)
30
+ * for a true mip pyramid — about a 3× overhead, traded for correctness.
31
+ *
32
+ * Non-power-of-two heightmaps are handled by halving with floor and stopping
33
+ * once both dimensions reach 1.
34
+ *
35
+ * @param {Sampler2D} sampler single-channel Float32 heightmap (itemSize=1)
36
+ * @returns {DataTexture2DArray} R32F array texture; depth = mip count
37
+ */
38
+ export function build_max_height_pyramid(sampler) {
39
+ const w0 = sampler.width;
40
+ const h0 = sampler.height;
41
+
42
+ // Step 1: build the conventional mip pyramid in JS
43
+ /** @type {Array<{data: Float32Array, width: number, height: number}>} */
44
+ const mips = [];
45
+ mips.push({ data: sampler.data, width: w0, height: h0 });
46
+
47
+ {
48
+ let prevW = w0;
49
+ let prevH = h0;
50
+ let prevData = sampler.data;
51
+
52
+ while (prevW > 1 || prevH > 1) {
53
+ const curW = Math.max(1, prevW >> 1);
54
+ const curH = Math.max(1, prevH >> 1);
55
+ const curData = new Float32Array(curW * curH);
56
+
57
+ const lastSrcX = prevW - 1;
58
+ const lastSrcY = prevH - 1;
59
+
60
+ for (let y = 0; y < curH; y++) {
61
+ const sy0 = y << 1;
62
+ const sy1 = Math.min(sy0 + 1, lastSrcY);
63
+ const row0 = sy0 * prevW;
64
+ const row1 = sy1 * prevW;
65
+
66
+ for (let x = 0; x < curW; x++) {
67
+ const sx0 = x << 1;
68
+ const sx1 = Math.min(sx0 + 1, lastSrcX);
69
+
70
+ const a = prevData[row0 + sx0];
71
+ const b = prevData[row0 + sx1];
72
+ const c = prevData[row1 + sx0];
73
+ const d = prevData[row1 + sx1];
74
+
75
+ let m = a > b ? a : b;
76
+ if (c > m) m = c;
77
+ if (d > m) m = d;
78
+
79
+ curData[y * curW + x] = m;
80
+ }
81
+ }
82
+
83
+ mips.push({ data: curData, width: curW, height: curH });
84
+
85
+ prevW = curW;
86
+ prevH = curH;
87
+ prevData = curData;
88
+ }
89
+ }
90
+
91
+ // Step 2: pack each mip nearest-upscaled to w0 × h0 as a layer of the
92
+ // array texture. Layer k holds mip k blown up; sampling with NearestFilter
93
+ // at any uv returns mip k's value at that uv exactly.
94
+ const depth = mips.length;
95
+ const layerSize = w0 * h0;
96
+ const layered = new Float32Array(depth * layerSize);
97
+
98
+ for (let k = 0; k < depth; k++) {
99
+ const mip = mips[k];
100
+ const mw = mip.width;
101
+ const mh = mip.height;
102
+ const mdata = mip.data;
103
+
104
+ const layerOffset = k * layerSize;
105
+
106
+ if (mw === w0 && mh === h0) {
107
+ // Level 0 — direct copy
108
+ layered.set(mdata, layerOffset);
109
+ continue;
110
+ }
111
+
112
+ // Nearest-upscale: dst (x, y) → src (floor(x * mw / w0), floor(y * mh / h0))
113
+ // Works for both POT and NPO2 reductions.
114
+ for (let y = 0; y < h0; y++) {
115
+ const sy = Math.min(mh - 1, ((y * mh) / h0) | 0);
116
+ const srcRow = sy * mw;
117
+ const dstRow = layerOffset + y * w0;
118
+
119
+ for (let x = 0; x < w0; x++) {
120
+ const sx = Math.min(mw - 1, ((x * mw) / w0) | 0);
121
+ layered[dstRow + x] = mdata[srcRow + sx];
122
+ }
123
+ }
124
+ }
125
+
126
+ const tex = new DataTexture2DArray(layered, w0, h0, depth);
127
+ tex.format = RedFormat;
128
+ tex.type = FloatType;
129
+ tex.internalFormat = 'R32F';
130
+ tex.minFilter = NearestFilter;
131
+ tex.magFilter = NearestFilter;
132
+ tex.wrapS = ClampToEdgeWrapping;
133
+ tex.wrapT = ClampToEdgeWrapping;
134
+ tex.generateMipmaps = false;
135
+ tex.flipY = false;
136
+ tex.needsUpdate = true;
137
+
138
+ // Expose the depth so callers can plumb `maxMipLevel` to the shader
139
+ // without re-deriving it
140
+ tex.userData.mipCount = depth;
141
+
142
+ return tex;
143
+ }
@@ -1,27 +0,0 @@
1
- /**
2
- * @template T
3
- */
4
- export class FieldDescriptor<T> {
5
- /**
6
- *
7
- * @type {string}
8
- */
9
- name: string;
10
- /**
11
- * typeof field
12
- * @type {Class<T>}
13
- */
14
- type: Class<T>;
15
- /**
16
- *
17
- * @type {FieldValueAdapter|null}
18
- */
19
- adapter: FieldValueAdapter | null;
20
- /**
21
- *
22
- * @type {{}|undefined}
23
- */
24
- schema: {} | undefined;
25
- toString(): string;
26
- }
27
- //# sourceMappingURL=FieldDescriptor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FieldDescriptor.d.ts","sourceRoot":"","sources":["FieldDescriptor.js"],"names":[],"mappings":"AAAA;;GAEG;AACH;IAEQ;;;OAGG;IACH,MAFU,MAAM,CAEF;IAEd;;;OAGG;IACH,eAAgB;IAEhB;;;OAGG;IACH,SAFU,oBAAkB,IAAI,CAEb;IAEnB;;;OAGG;IACH,QAFU,EAAE,GAAC,SAAS,CAEC;IAG3B,mBAEC;CACJ"}
@@ -1,7 +0,0 @@
1
- export class FieldValueAdapter {
2
- writable: boolean;
3
- readable: boolean;
4
- read(object: any, field_name: any): any;
5
- write(object: any, field_name: any, value: any): void;
6
- }
7
- //# sourceMappingURL=FieldValueAdapter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FieldValueAdapter.d.ts","sourceRoot":"","sources":["FieldValueAdapter.js"],"names":[],"mappings":"AAEA;IAEQ,kBAAoB;IACpB,kBAAoB;IAIxB,wCAKC;IAED,sDAEC;CACJ"}
@@ -1,9 +0,0 @@
1
- /**
2
- * @template CTX
3
- * @param {Object} object
4
- * @param {FieldDescriptor} field
5
- * @param {Map<*, TypeEditor>} registry
6
- */
7
- export function createFieldEditor<CTX>(object: any, field: FieldDescriptor, registry: Map<any, TypeEditor>): EmptyView;
8
- import EmptyView from "../../../src/view/elements/EmptyView.js";
9
- //# sourceMappingURL=createFieldEditor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createFieldEditor.d.ts","sourceRoot":"","sources":["createFieldEditor.js"],"names":[],"mappings":"AAUA;;;;;GAKG;AACH,sFAFW,oBAAkB,aA6E5B;sBA3FqB,yCAAyC"}
@@ -1,14 +0,0 @@
1
- /**
2
- * @param {Object} object
3
- * @param {Map<*, TypeEditor>} registry
4
- * @param {FieldDescriptor} [field_descriptor]
5
- */
6
- export function buildObjectEditorFromRegistry(object: any, registry: Map<any, TypeEditor>, field_descriptor?: FieldDescriptor<any>): any;
7
- /**
8
- * @param {Object} object
9
- * @param {Map<*, TypeEditor>} registry
10
- */
11
- export function createObjectEditor(object: any, registry: Map<any, TypeEditor>): EmptyView;
12
- import { FieldDescriptor } from "./FieldDescriptor.js";
13
- import EmptyView from "../../../src/view/elements/EmptyView.js";
14
- //# sourceMappingURL=createObjectEditor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"createObjectEditor.d.ts","sourceRoot":"","sources":["createObjectEditor.js"],"names":[],"mappings":"AA8QA;;;;GAIG;AACH,qEAHW,oBAAkB,gDA0B5B;AAID;;;GAGG;AACH,0DAFW,oBAAkB,aA0D5B;gCAvW+B,sBAAsB;sBAFhC,yCAAyC"}
@@ -1,8 +0,0 @@
1
- /**
2
- *
3
- * @param {Map<*, TypeEditor>} registry
4
- * @param {*} value
5
- * @returns {TypeEditor|void}
6
- */
7
- export function findNearestRegisteredType(registry: Map<any, TypeEditor>, value: any): TypeEditor | void;
8
- //# sourceMappingURL=findNearestRegisteredType.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"findNearestRegisteredType.d.ts","sourceRoot":"","sources":["findNearestRegisteredType.js"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,oDAJW,oBAAkB,eAEhB,aAAW,IAAI,CAsD3B"}
@@ -1,10 +0,0 @@
1
- export default heightMap2NormalMap;
2
- /**
3
- *
4
- * @param {WebGLRenderer} renderer
5
- * @param {Sampler2D} sampler
6
- * @returns {Sampler2D}
7
- */
8
- declare function heightMap2NormalMap(renderer: WebGLRenderer, sampler: Sampler2D): Sampler2D;
9
- import { Sampler2D } from '../../graphics/texture/sampler/Sampler2D.js';
10
- //# sourceMappingURL=HeightMap2NormalMap.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"HeightMap2NormalMap.d.ts","sourceRoot":"","sources":["../../../../../src/engine/ecs/grid/HeightMap2NormalMap.js"],"names":[],"mappings":";AA0CA;;;;;GAKG;AACH,uEAHW,SAAS,GACP,SAAS,CAuBrB;0BAnEyB,6CAA6C"}
@@ -1,72 +0,0 @@
1
- import ImageFilter from '../../graphics/filter/ImageFilter.js';
2
- import NormalMapShader from '../../graphics/shaders/NormalMapShader2.js';
3
- import { Sampler2D } from '../../graphics/texture/sampler/Sampler2D.js';
4
- import { sampler2d_to_float32_texture } from "../../graphics/texture/sampler/sampler2d_to_float32_texture.js";
5
-
6
-
7
- function convertChannel(v) {
8
- return (v) / 255 - 0.5;
9
- }
10
-
11
- /**
12
- *
13
- * @param {number[]|Uint8Array} source
14
- * @returns {Float32Array}
15
- */
16
- function rgbaArray2RGB(source) {
17
- const length = source.length;
18
- const numPixels = Math.floor(length / 4);
19
- const target = new Float32Array(numPixels * 3);
20
- //
21
- let h;
22
- for (let i = 0; i < numPixels; i++) {
23
- const j = i * 4;
24
- const k = i * 3;
25
- //normalize source to normal vectors
26
- let x = convertChannel(source[j]);
27
- let y = convertChannel(source[j + 1]);
28
- let z = convertChannel(source[j + 2]);
29
- //
30
- h = Math.sqrt(x * x + y * y + z * z);
31
-
32
- x /= h;
33
- y /= h;
34
- z /= h;
35
- //
36
- target[k] = x;
37
- target[k + 1] = y;
38
- target[k + 2] = z;
39
- }
40
- return target;
41
- }
42
-
43
- /**
44
- *
45
- * @param {WebGLRenderer} renderer
46
- * @param {Sampler2D} sampler
47
- * @returns {Sampler2D}
48
- */
49
- function heightMap2NormalMap(renderer, sampler) {
50
-
51
- const width = sampler.width;
52
- const height = sampler.height;
53
-
54
- const texture = sampler2d_to_float32_texture(sampler);
55
-
56
- //construct shader
57
- const shader = new NormalMapShader();
58
- shader.uniforms.heightMap.value = texture;
59
- shader.uniforms.resolution.value.set(width, height);
60
-
61
- //perform filtering
62
- const result = ImageFilter(renderer, width, height, shader);
63
-
64
- //create the sampler
65
- const array = result.array;
66
- const rgb = rgbaArray2RGB(array);
67
-
68
- //reduce array's alpha component
69
- return new Sampler2D(rgb, 3, width, height);
70
- }
71
-
72
- export default heightMap2NormalMap;
@@ -1,15 +0,0 @@
1
- export default normalMap2OcclusionMap;
2
- /**
3
- *
4
- * @param {WebGLRenderer} renderer
5
- * @param {Sampler2D} heightMap
6
- * @param {Sampler2D} normalMap
7
- * @param {Vector2} resultSize
8
- * @param worldSize
9
- * @param {number} [rayLength]
10
- * @returns {Sampler2D}
11
- */
12
- declare function normalMap2OcclusionMap(renderer: WebGLRenderer, heightMap: Sampler2D, normalMap: Sampler2D, resultSize: Vector2, worldSize?: Vector2, rayLength?: number): Sampler2D;
13
- import { Sampler2D } from '../../graphics/texture/sampler/Sampler2D.js';
14
- import { Vector2 } from 'three';
15
- //# sourceMappingURL=NormalMap2AOMap.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"NormalMap2AOMap.d.ts","sourceRoot":"","sources":["../../../../../src/engine/ecs/grid/NormalMap2AOMap.js"],"names":[],"mappings":";AA2BA;;;;;;;;;GASG;AACH,4EAPW,SAAS,aACT,SAAS,cACT,OAAO,mCAEP,MAAM,GACJ,SAAS,CA4CrB;0BA3EyB,6CAA6C;wBAJiB,OAAO"}
@@ -1,82 +0,0 @@
1
- import { ClampToEdgeWrapping, DataTexture, RGBAFormat, UnsignedByteType, Vector2 } from 'three';
2
- import ImageFilter from '../../graphics/filter/ImageFilter.js';
3
- import AmbientOcclusionShader from '../../graphics/shaders/AmbientOcclusionShader.js';
4
- import { DenoiseShader } from "../../graphics/shaders/DenoiseShader.js";
5
- import { Sampler2D } from '../../graphics/texture/sampler/Sampler2D.js';
6
- import { sampler2d_to_float32_texture } from "../../graphics/texture/sampler/sampler2d_to_float32_texture.js";
7
-
8
- function filterResult2Texture(data, width, height) {
9
- const result = new DataTexture();
10
- result.format = RGBAFormat;
11
-
12
-
13
- result.type = UnsignedByteType;
14
- result.flipY = false;
15
- result.image = { data: data, width: width, height: height };
16
-
17
- result.wrapS = ClampToEdgeWrapping;
18
- result.wrapT = ClampToEdgeWrapping;
19
-
20
- result.repeat.set(1, 1);
21
- result.needsUpdate = true;
22
-
23
- result.anisotropy = 4;
24
-
25
- return result;
26
- }
27
-
28
- /**
29
- *
30
- * @param {WebGLRenderer} renderer
31
- * @param {Sampler2D} heightMap
32
- * @param {Sampler2D} normalMap
33
- * @param {Vector2} resultSize
34
- * @param worldSize
35
- * @param {number} [rayLength]
36
- * @returns {Sampler2D}
37
- */
38
- function normalMap2OcclusionMap(
39
- renderer,
40
- heightMap,
41
- normalMap,
42
- resultSize,
43
- worldSize = new Vector2(heightMap.width, heightMap.width),
44
- rayLength = 17
45
- ) {
46
- const width = resultSize.x;
47
- const height = resultSize.y;
48
- //
49
- const normalTexture = sampler2d_to_float32_texture(normalMap);
50
-
51
- const heightTexture = sampler2d_to_float32_texture(heightMap);
52
-
53
-
54
- //construct shader
55
- const shaderAO = new AmbientOcclusionShader();
56
- shaderAO.uniforms.heightMap.value = heightTexture;
57
- shaderAO.uniforms.normalMap.value = normalTexture;
58
- shaderAO.uniforms.world_size.value.set(worldSize.x, worldSize.y);
59
- shaderAO.uniforms.rayLength.value = rayLength;
60
- //perform filtering
61
- const rawAO = ImageFilter(renderer, width, height, shaderAO);
62
-
63
- const shaderDenoise = new DenoiseShader(2);
64
- shaderDenoise.uniforms.source.value = filterResult2Texture(rawAO.array, width, height);
65
- shaderDenoise.uniforms.pixelOffset.value.set(1 / width, 1 / height);
66
-
67
- const smoothAO = ImageFilter(renderer, width, height, shaderDenoise);
68
-
69
- //create the sampler
70
- const result = new Sampler2D(new Uint8ClampedArray(width * height), 1, width, height);
71
-
72
- //populate samples
73
- const size = width * height;
74
-
75
- for (let i = 0; i < size; i++) {
76
- result.data[i] = smoothAO.array[i * 4];
77
- }
78
-
79
- return result;
80
- }
81
-
82
- export default normalMap2OcclusionMap;