@woosh/meep-engine 2.33.62 → 2.33.67

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 (48) hide show
  1. package/core/FilePath.js +28 -2
  2. package/core/binary/BinaryBuffer.js +13 -0
  3. package/core/geom/2d/quad-tree/QuadTreeNode.js +3 -2
  4. package/ecs/grid/pick.js +44 -0
  5. package/editor/tools/GridPaintTool.js +1 -1
  6. package/editor/tools/paint/TerrainPaintTool.js +1 -1
  7. package/editor/view/GridPickCoordinateView.js +1 -1
  8. package/engine/asset/AssetManager.js +1 -1
  9. package/engine/asset/AssetTransformer.js +2 -1
  10. package/engine/asset/loaders/GLTFAssetLoader.js +5 -21
  11. package/engine/asset/loaders/async_traverse_three_object.js +24 -0
  12. package/engine/ecs/attachment/AttachmentSystem.js +3 -51
  13. package/engine/ecs/fow/FogOfWarRevealerSystem.js +1 -1
  14. package/engine/ecs/fow/shader/screenSpaceFogOfWarShader.js +2 -10
  15. package/engine/ecs/grid/NormalMap2AOMap.js +10 -13
  16. package/engine/ecs/team/Team.js +82 -0
  17. package/engine/ecs/terrain/ecs/BuildLightTexture.js +106 -0
  18. package/engine/ecs/terrain/ecs/PromiseSamplerHeight.js +59 -0
  19. package/engine/ecs/terrain/ecs/Terrain.js +14 -153
  20. package/engine/ecs/tooltip/TooltipComponentSystem.js +1 -1
  21. package/engine/graphics/FULL_SCREEN_QUAD_VERTEX_SHADER.js +10 -0
  22. package/engine/graphics/filter/ImageFilter.js +6 -2
  23. package/engine/graphics/geometry/AttributeSpec.d.ts +8 -0
  24. package/engine/graphics/geometry/VertexDataSpec.d.ts +15 -0
  25. package/engine/graphics/geometry/buffered/deinterleaveBufferAttribute.js +39 -0
  26. package/engine/graphics/geometry/buffered/deinterleaveBufferGeometry.js +50 -0
  27. package/engine/graphics/micron/MICRON_GEOMETRY_FIELD.js +1 -0
  28. package/engine/graphics/micron/MICRON_URI_FIELD.js +1 -0
  29. package/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +10 -7
  30. package/engine/graphics/micron/convert_three_object_to_micron.js +31 -5
  31. package/engine/graphics/micron/format/MicronGeometry.d.ts +4 -0
  32. package/engine/graphics/micron/format/MicronGeometry.js +6 -0
  33. package/engine/graphics/micron/plugin/MicronRenderPlugin.js +110 -6
  34. package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +4 -2
  35. package/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +1 -1
  36. package/engine/graphics/render/webgpu/sample/MeshInstance.js +21 -0
  37. package/engine/graphics/render/webgpu/sample/main.js +2 -2
  38. package/engine/graphics/shaders/AmbientOcclusionShader.js +57 -77
  39. package/engine/graphics/shaders/DenoiseShader.js +119 -0
  40. package/engine/graphics/texture/noise_octaves.js +33 -0
  41. package/engine/graphics/texture/sampler/Sampler2D2Texture.js +7 -18
  42. package/engine/graphics/texture/sampler/debug/paintSamplerOnHTML.js +8 -5
  43. package/engine/graphics/texture/sampler/sampler2DToFloat32Texture.js +10 -3
  44. package/engine/graphics/util/modelHitTest.js +63 -0
  45. package/generation/example/filters/SampleGroundMoistureFilter.js +2 -1
  46. package/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +29 -13
  47. package/generation/grid/GridData.js +17 -2
  48. package/package.json +1 -1
package/core/FilePath.js CHANGED
@@ -1,3 +1,5 @@
1
+ const PATH_SEPARATOR = '/';
2
+
1
3
  /**
2
4
  * Strips all directories from the path.
3
5
  * @example 'a/b/c' -> 'c'
@@ -9,7 +11,7 @@ function computePathBase(path) {
9
11
  throw new Error('path is not a string');
10
12
  }
11
13
 
12
- const lastSlashIndex = path.lastIndexOf('/');
14
+ const lastSlashIndex = path.lastIndexOf(PATH_SEPARATOR);
13
15
 
14
16
  if (lastSlashIndex !== -1) {
15
17
  return path.substring(lastSlashIndex + 1);
@@ -18,6 +20,30 @@ function computePathBase(path) {
18
20
  }
19
21
  }
20
22
 
23
+ /**
24
+ * Returns the directory name of a path, similar to the Unix dirname command.
25
+ * @param {string} path
26
+ * @return {string}
27
+ */
28
+ export function computePathDirectory(path) {
29
+ if (typeof path !== "string") {
30
+ throw new Error('path is not a string');
31
+ }
32
+
33
+ let lastSlashIndex = path.lastIndexOf(PATH_SEPARATOR);
34
+
35
+ //rewind in case of trailing slashes
36
+ while (lastSlashIndex > 0 && path.charAt(lastSlashIndex - 1) === PATH_SEPARATOR) {
37
+ lastSlashIndex--;
38
+ }
39
+
40
+ if (lastSlashIndex !== -1) {
41
+ return path.substring(0, lastSlashIndex);
42
+ } else {
43
+ return path;
44
+ }
45
+ }
46
+
21
47
  /**
22
48
  *
23
49
  * @param {string} path
@@ -44,4 +70,4 @@ function computeFileExtension(path) {
44
70
  export {
45
71
  computePathBase,
46
72
  computeFileExtension
47
- };
73
+ };
@@ -57,6 +57,19 @@ BinaryBuffer.prototype.fromArrayBuffer = function (arrayBuffer) {
57
57
  this.position = 0;
58
58
  };
59
59
 
60
+ /**
61
+ *
62
+ * @param {ArrayBuffer} v
63
+ * @return {BinaryBuffer}
64
+ */
65
+ BinaryBuffer.fromArrayBuffer = function (v) {
66
+ const r = new BinaryBuffer();
67
+
68
+ r.fromArrayBuffer(v);
69
+
70
+ return r;
71
+ };
72
+
60
73
  /**
61
74
  *
62
75
  * @returns {BinaryBuffer}
@@ -315,8 +315,9 @@ export class QuadTreeNode extends AABB2 {
315
315
  const x1 = this.x1;
316
316
  const y1 = this.y1;
317
317
 
318
- const xm = (x0 + x1) / 2;
319
- const ym = (y0 + y1) / 2;
318
+ // get center point
319
+ const xm = (x0 + x1) * 0.5;
320
+ const ym = (y0 + y1) * 0.5;
320
321
 
321
322
  for (; i < dataLength; i++) {
322
323
  const datum = data[i];
@@ -0,0 +1,44 @@
1
+ import { assert } from "../../core/assert.js";
2
+ import Vector3 from "../../core/geom/Vector3.js";
3
+ import { SurfacePoint3 } from "../../core/geom/3d/SurfacePoint3.js";
4
+ import Vector2 from "../../core/geom/Vector2.js";
5
+
6
+ /**
7
+ *
8
+ * @param {number} x
9
+ * @param {number} y
10
+ * @param {GraphicsEngine} graphicsEngine
11
+ * @param {Terrain} terrain
12
+ * @param {function(gridPosition:Vector2,worldPosition:Vector3,normal:Vector3)} callback
13
+ */
14
+ export function pick(x, y, graphicsEngine, terrain, callback) {
15
+
16
+ assert.isNumber(x, 'x');
17
+ assert.isNumber(y, 'y');
18
+
19
+ assert.defined(terrain, 'terrain');
20
+ assert.notNull(terrain, 'terrain');
21
+
22
+ assert.isFunction(callback, 'callback');
23
+
24
+ const vSource = new Vector3(x, y, 0);
25
+ const vTarget = new Vector3();
26
+
27
+ graphicsEngine.normalizeViewportPoint(vSource, vSource);
28
+ graphicsEngine.viewportProjectionRay(vSource.x, vSource.y, vSource, vTarget);
29
+
30
+ const surfacePoint3 = new SurfacePoint3();
31
+
32
+ const hitFound = terrain.raycastFirstSync(surfacePoint3, vSource.x, vSource.y, vSource.z, vTarget.x, vTarget.y, vTarget.z);
33
+
34
+ if (!hitFound) {
35
+ // nothing found
36
+ } else {
37
+
38
+ const gridPosition = new Vector2();
39
+ terrain.mapPointWorld2Grid(surfacePoint3.position, gridPosition);
40
+ gridPosition._add(0.5, 0.5);
41
+ callback(gridPosition, surfacePoint3.position, surfacePoint3.normal);
42
+ }
43
+
44
+ }
@@ -1,7 +1,6 @@
1
1
  import Tool from "./engine/Tool.js";
2
2
  import GridPosition from "../../engine/grid/components/GridPosition.js";
3
3
  import GridObstacle from "../../engine/grid/components/GridObstacle.js";
4
- import { pick } from "../../../model/game/util/ScreenGridPicker.js";
5
4
  import Vector4 from "../../core/geom/Vector4.js";
6
5
  import ObservedValue from "../../core/model/ObservedValue.js";
7
6
  import Vector1 from "../../core/geom/Vector1.js";
@@ -12,6 +11,7 @@ import Vector2 from "../../core/geom/Vector2.js";
12
11
  import TopDownCameraControllerSystem from "../../engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js";
13
12
  import { parseHex } from "../../core/color/parseHex.js";
14
13
  import { obtainTerrain } from "../../engine/ecs/terrain/util/obtainTerrain.js";
14
+ import { pick } from "../../ecs/grid/pick.js";
15
15
 
16
16
  class GridPaintTool extends Tool {
17
17
  constructor() {
@@ -3,12 +3,12 @@ import Tool from "../engine/Tool.js";
3
3
  import { Color } from "../../../core/color/Color.js";
4
4
  import { Sampler2D } from "../../../engine/graphics/texture/sampler/Sampler2D.js";
5
5
  import Vector2 from "../../../core/geom/Vector2.js";
6
- import { pick } from "../../../../model/game/util/ScreenGridPicker.js";
7
6
  import convertSampler2D2Canvas from "../../../engine/graphics/texture/sampler/Sampler2D2Canvas.js";
8
7
  import ObservedString from "../../../core/model/ObservedString.js";
9
8
  import { GameAssetType } from "../../../engine/asset/GameAssetType.js";
10
9
  import Vector1 from "../../../core/geom/Vector1.js";
11
10
  import { obtainTerrain } from "../../../engine/ecs/terrain/util/obtainTerrain.js";
11
+ import { pick } from "../../../ecs/grid/pick.js";
12
12
 
13
13
  export class TerrainPaintTool extends Tool {
14
14
  constructor() {
@@ -1,8 +1,8 @@
1
1
  import View from "../../view/View.js";
2
- import { pick } from "../../../model/game/util/ScreenGridPicker.js";
3
2
  import domify from "../../view/DOM.js";
4
3
  import { PointerDevice } from "../../engine/input/devices/PointerDevice.js";
5
4
  import { obtainTerrain } from "../../engine/ecs/terrain/util/obtainTerrain.js";
5
+ import { pick } from "../../ecs/grid/pick.js";
6
6
 
7
7
  class GridPickCoordinateView extends View {
8
8
  /**
@@ -231,7 +231,7 @@ AssetManager.prototype.submitRequest = function (path, type, request) {
231
231
  for (let i = 0; i < transformer_count; i++) {
232
232
  const transformer = transformers[i];
233
233
 
234
- const transformed_asset = await transformer.transform(asset);
234
+ const transformed_asset = await transformer.transform(asset, assetDescription);
235
235
 
236
236
  if (typeof transformed_asset !== "object") {
237
237
  console.error('Transformer produced invalid result. Ignoring result.', transformer, assetDescription);
@@ -7,9 +7,10 @@
7
7
  export class AssetTransformer {
8
8
  /**
9
9
  * @param {A} source
10
+ * @param {AssetDescription} asset_description
10
11
  * @returns {A}
11
12
  */
12
- async transform(source) {
13
+ async transform(source, asset_description) {
13
14
  throw new Error('Not Implemented');
14
15
  }
15
16
  }
@@ -25,6 +25,8 @@ import { computeGeometryEquality } from "./geometry/geometry/computeGeometryEqua
25
25
  import { traverseThreeObject } from "../../graphics/ecs/highlight/renderer/traverseThreeObject.js";
26
26
  import { computeTextureHash } from "./material/computeTextureHash.js";
27
27
  import { computeTextureEquality } from "./material/computeTextureEquality.js";
28
+ import { async_traverse_three_object } from "./async_traverse_three_object.js";
29
+ import { deinterleaveBufferGeometry } from "../../graphics/geometry/buffered/deinterleaveBufferGeometry.js";
28
30
 
29
31
  const animationOptimizer = new AnimationOptimizer();
30
32
  const materialCache = StaticMaterialCache.Global;
@@ -130,26 +132,6 @@ function buildDracoDecoderPath() {
130
132
  return `${pathname}/libs/draco/`;
131
133
  }
132
134
 
133
- /**
134
- *
135
- * @param {THREE.Object3D} object
136
- * @param {function} callback
137
- * @param {*} [thisArg]
138
- */
139
- async function async_traverse(object, callback, thisArg) {
140
- await callback.call(thisArg, object);
141
-
142
- const children = object.children;
143
- const n = children.length;
144
-
145
- for (let i = 0; i < n; i++) {
146
- const child = children[i];
147
-
148
- // TODO we can parallelize this if necessary
149
- await async_traverse(child, callback, thisArg);
150
- }
151
- }
152
-
153
135
  export class GLTFAssetLoader extends AssetLoader {
154
136
 
155
137
  constructor() {
@@ -312,6 +294,8 @@ export class GLTFAssetLoader extends AssetLoader {
312
294
  mesh.geometry = geometry;
313
295
  }
314
296
 
297
+ mesh.geometry = deinterleaveBufferGeometry(geometry);
298
+
315
299
 
316
300
  if (this.__enable_texture_cache) {
317
301
  // replace textures from cache
@@ -387,7 +371,7 @@ export class GLTFAssetLoader extends AssetLoader {
387
371
  }
388
372
 
389
373
 
390
- await async_traverse(root, process_object);
374
+ await async_traverse_three_object(root, process_object);
391
375
 
392
376
 
393
377
  // compute object bounding sphere
@@ -0,0 +1,24 @@
1
+ /**
2
+ *
3
+ * @param {THREE.Object3D} object
4
+ * @param {function} callback
5
+ * @param {*} [thisArg]
6
+ * @param {*} [ctx]
7
+ */
8
+ export async function async_traverse_three_object(object, callback, thisArg, ctx) {
9
+ await callback.call(thisArg, object, ctx);
10
+
11
+ const children = object.children;
12
+ const n = children.length;
13
+
14
+ const child_promises = [];
15
+
16
+ for (let i = 0; i < n; i++) {
17
+ const child = children[i];
18
+
19
+ child_promises.push(async_traverse_three_object(child, callback, thisArg, ctx));
20
+ }
21
+
22
+ // wait for all children at the same time
23
+ await Promise.all(child_promises);
24
+ }
@@ -7,38 +7,6 @@ import Mesh from "../../graphics/ecs/mesh/Mesh.js";
7
7
  import { BoneAttachmentBinding } from "./BoneAttachmentBinding.js";
8
8
  import { TransformAttachmentBinding } from "./TransformAttachmentBinding.js";
9
9
 
10
- /**
11
- * @readonly
12
- * @enum {number}
13
- */
14
- const WaitingType = {
15
- Entity: 0,
16
- Socket: 1,
17
- Mesh: 2,
18
- Transform: 3
19
- };
20
-
21
- class WaitingEntry {
22
- /**
23
- *
24
- * @param {number} entity
25
- * @param {WaitingType} type
26
- */
27
- constructor(entity, type) {
28
- /**
29
- *
30
- * @type {number}
31
- */
32
- this.entity = entity;
33
- /**
34
- *
35
- * @type {WaitingType}
36
- */
37
- this.type = type;
38
- }
39
- }
40
-
41
-
42
10
  export class AttachmentSystem extends System {
43
11
  constructor() {
44
12
  super();
@@ -315,17 +283,10 @@ export class AttachmentSystem extends System {
315
283
  }
316
284
  }
317
285
 
318
- /**
319
- *
320
- * @param {number} entity
321
- * @private
322
- */
323
- __update_entity(entity) {
324
- const bindings = this.parentBindingIndex.get(entity);
286
+ __updateAll() {
287
+ for (const [entity, bindings] of this.parentBindingIndex) {
325
288
 
326
- if (bindings !== undefined) {
327
289
  const n = bindings.length;
328
-
329
290
  for (let i = 0; i < n; i++) {
330
291
  const binding = bindings[i];
331
292
 
@@ -334,15 +295,6 @@ export class AttachmentSystem extends System {
334
295
  }
335
296
  }
336
297
 
337
- /**
338
- *
339
- * @param {Mesh} mesh
340
- * @param {number} entity
341
- */
342
- visitComponent(mesh, entity) {
343
- this.__update_entity(entity);
344
- }
345
-
346
298
  update(timeDelta) {
347
299
  //process wait queue
348
300
  this.processWaiting();
@@ -355,6 +307,6 @@ export class AttachmentSystem extends System {
355
307
  return;
356
308
  }
357
309
 
358
- ecd.traverseComponents(Attachment, this.visitComponent, this);
310
+ this.__updateAll();
359
311
  }
360
312
  }
@@ -2,7 +2,7 @@ import { System } from "../System.js";
2
2
  import { FogOfWarRevealer } from "./FogOfWarRevealer.js";
3
3
  import { SignalBinding } from "../../../core/events/signal/SignalBinding.js";
4
4
  import { FogOfWar } from "./FogOfWar.js";
5
- import Team from "../../../../model/game/ecs/component/Team.js";
5
+ import Team from "../team/Team.js";
6
6
  import { Transform } from "../transform/Transform.js";
7
7
  import Vector2 from "../../../core/geom/Vector2.js";
8
8
  import { obtainTerrain } from "../terrain/util/obtainTerrain.js";
@@ -1,4 +1,5 @@
1
1
  import { Matrix4, NormalBlending, ShaderMaterial, Vector2, Vector4 } from "three";
2
+ import { FULL_SCREEN_QUAD_VERTEX_SHADER } from "../../../graphics/FULL_SCREEN_QUAD_VERTEX_SHADER.js";
2
3
 
3
4
  /**
4
5
  Shader for drawing fog of war as a screen-space post-process effect
@@ -6,16 +7,7 @@ import { Matrix4, NormalBlending, ShaderMaterial, Vector2, Vector4 } from "three
6
7
  */
7
8
  export function buildScreenSpaceFogOfWarShader() {
8
9
  function vertexShader() {
9
- return `
10
- varying vec2 vUv;
11
-
12
- void main() {
13
-
14
- vUv = uv;
15
-
16
- gl_Position = vec4( (uv - 0.5)*2.0, 0.0, 1.0 );
17
-
18
- }`;
10
+ return FULL_SCREEN_QUAD_VERTEX_SHADER;
19
11
  }
20
12
 
21
13
  function fragmentShader() {
@@ -5,11 +5,10 @@
5
5
 
6
6
  import { ClampToEdgeWrapping, DataTexture, RGBAFormat, UnsignedByteType, Vector2 } from 'three';
7
7
  import { Sampler2D } from '../../graphics/texture/sampler/Sampler2D.js';
8
- import sampler2D2Texture from '../../graphics/texture/sampler/Sampler2D2Texture.js';
9
8
  import AmbientOcclusionShader from '../../graphics/shaders/AmbientOcclusionShader.js';
10
- import GaussianBlurShader from '../../graphics/shaders/GaussianBlurShader.js';
11
9
  import ImageFilter from '../../graphics/filter/ImageFilter.js';
12
10
  import { sampler2DtoFloat32Texture } from "../../graphics/texture/sampler/sampler2DToFloat32Texture.js";
11
+ import { DenoiseShader } from "../../graphics/shaders/DenoiseShader.js";
13
12
 
14
13
  function filterResult2Texture(data, width, height) {
15
14
  const result = new DataTexture();
@@ -37,6 +36,7 @@ function filterResult2Texture(data, width, height) {
37
36
  * @param {Sampler2D} heightMap
38
37
  * @param {Sampler2D} normalMap
39
38
  * @param {Vector2} resultSize
39
+ * @param worldSize
40
40
  * @param {number} [rayLength]
41
41
  * @returns {Sampler2D}
42
42
  */
@@ -45,13 +45,13 @@ function normalMap2OcclusionMap(
45
45
  heightMap,
46
46
  normalMap,
47
47
  resultSize,
48
+ worldSize = new Vector2(heightMap.width, heightMap.width),
48
49
  rayLength = 17
49
50
  ) {
50
51
  const width = resultSize.x;
51
52
  const height = resultSize.y;
52
- const resolution = new Vector2(heightMap.width, heightMap.height);
53
53
  //
54
- const normalTexture = sampler2D2Texture(normalMap, 255, 0.5);
54
+ const normalTexture = sampler2DtoFloat32Texture(normalMap);
55
55
 
56
56
  const heightTexture = sampler2DtoFloat32Texture(heightMap);
57
57
 
@@ -60,17 +60,16 @@ function normalMap2OcclusionMap(
60
60
  const shaderAO = new AmbientOcclusionShader();
61
61
  shaderAO.uniforms.heightMap.value = heightTexture;
62
62
  shaderAO.uniforms.normalMap.value = normalTexture;
63
- shaderAO.uniforms.resolution.value = resolution;
63
+ shaderAO.uniforms.world_size.value.set(worldSize.x, worldSize.y);
64
64
  shaderAO.uniforms.rayLength.value = rayLength;
65
65
  //perform filtering
66
66
  const rawAO = ImageFilter(renderer, width, height, shaderAO);
67
67
 
68
- const shaderBlur = new GaussianBlurShader();
69
- shaderBlur.uniforms.resolution.value = resolution;
70
- shaderBlur.uniforms.tDiffuse.value = filterResult2Texture(rawAO.array, width, height);
71
- shaderBlur.uniforms.sigma.value.set(1.3, 1.3);
68
+ const shaderDenoise = new DenoiseShader(2);
69
+ shaderDenoise.uniforms.source.value = filterResult2Texture(rawAO.array, width, height);
70
+ shaderDenoise.uniforms.pixelOffset.value.set(1 / width, 1 / height);
72
71
 
73
- const smoothAO = ImageFilter(renderer, width, height, shaderBlur);
72
+ const smoothAO = ImageFilter(renderer, width, height, shaderDenoise);
74
73
 
75
74
  //create the sampler
76
75
  const result = new Sampler2D(new Uint8ClampedArray(width * height), 1, width, height);
@@ -79,9 +78,7 @@ function normalMap2OcclusionMap(
79
78
  const size = width * height;
80
79
 
81
80
  for (let i = 0; i < size; i++) {
82
- const i4 = i * 4;
83
-
84
- result.data[i] = smoothAO.array[i4];
81
+ result.data[i] = smoothAO.array[i * 4];
85
82
  }
86
83
 
87
84
  return result;
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Created by Alex on 13/04/2016.
3
+ */
4
+ import ObservedInteger from "../../../core/model/ObservedInteger.js";
5
+ import { BinaryClassSerializationAdapter } from "../storage/binary/BinaryClassSerializationAdapter.js";
6
+
7
+ class Team extends ObservedInteger {
8
+ /**
9
+ *
10
+ * @param value
11
+ * @constructor
12
+ */
13
+ constructor(value = 0) {
14
+ super(value);
15
+ }
16
+
17
+ clone() {
18
+ return new Team(this.getValue());
19
+ }
20
+
21
+ /**
22
+ *
23
+ * @param {object} json
24
+ * @returns {Team}
25
+ */
26
+ static fromJSON(json) {
27
+ const t = new Team();
28
+
29
+ t.fromJSON(json);
30
+
31
+ return t;
32
+ }
33
+ }
34
+
35
+ Team.typeName = "Team";
36
+
37
+
38
+ export default Team;
39
+
40
+ export class TeamSerializationAdapter extends BinaryClassSerializationAdapter{
41
+ constructor(){
42
+ super();
43
+
44
+ this.klass = Team;
45
+ this.version = 0;
46
+ }
47
+
48
+ /**
49
+ *
50
+ * @param {BinaryBuffer} buffer
51
+ * @param {Team} value
52
+ */
53
+ serialize(buffer, value) {
54
+ const v = value.getValue();
55
+
56
+ if (v === Infinity) {
57
+ buffer.writeInt32(2147483647);
58
+ } else if (v === -Infinity) {
59
+ buffer.writeInt32(-2147483648);
60
+ } else {
61
+ //TODO it's possible to write encoded Infinity values by accident
62
+ buffer.writeInt32(v);
63
+ }
64
+ }
65
+
66
+ /**
67
+ *
68
+ * @param {BinaryBuffer} buffer
69
+ * @param {Team} value
70
+ */
71
+ deserialize(buffer, value) {
72
+ const v = buffer.readInt32();
73
+
74
+ if (v === 2147483647) {
75
+ value.set(Infinity);
76
+ } else if (v === -2147483648) {
77
+ value.set(-Infinity);
78
+ } else {
79
+ value.set(v);
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,106 @@
1
+ import normalMap2AOMap from "../../grid/NormalMap2AOMap.js";
2
+ import heightMap2NormalMap from "../../grid/HeightMap2NormalMap.js";
3
+ import { WebGLRendererPool } from "../../../graphics/render/RendererPool.js";
4
+ import Vector2 from "../../../../core/geom/Vector2.js";
5
+ import { writeSample2DDataToDataTexture } from "../../../graphics/texture/sampler/writeSampler2DDataToDataTexture.js";
6
+
7
+ /**
8
+ *
9
+ * @param {WebGLRenderer} renderer
10
+ * @param {Sampler2D} sampler
11
+ * @returns {Promise<Sampler2D>}
12
+ */
13
+ function promiseSamplerNormal(renderer, sampler) {
14
+
15
+ console.time("generating normal map");
16
+ const normalSampler = heightMap2NormalMap(renderer, sampler);
17
+ console.timeEnd("generating normal map");
18
+
19
+
20
+ return Promise.resolve(normalSampler);
21
+ }
22
+
23
+ /**
24
+ *
25
+ * @param {WebGLRenderer} renderer
26
+ * @param {Promise<Sampler2D>} pSamplerNormal
27
+ * @param {Sampler2D} samplerHeight
28
+ * @param {Vector2} resolution
29
+ * @param {Vector2} [wordSize]
30
+ * @param {number} rayLength
31
+ * @returns {Promise<unknown>}
32
+ */
33
+ function promiseSamplerAO(
34
+ {
35
+ renderer,
36
+ pSamplerNormal,
37
+ samplerHeight,
38
+ resolution,
39
+ wordSize = resolution,
40
+ rayLength
41
+ }
42
+ ) {
43
+ return new Promise(function (resolve, reject) {
44
+ Promise.all([pSamplerNormal]).then(function (values) {
45
+ const samplerNormal = values[0];
46
+ console.time("generating AO map");
47
+ const occlusionSampler = normalMap2AOMap(
48
+ renderer,
49
+ samplerHeight,
50
+ samplerNormal,
51
+ wordSize,
52
+ resolution,
53
+ rayLength
54
+ );
55
+ console.timeEnd("generating AO map");
56
+ //console.info(occlusionSampler);
57
+ //
58
+ // paintSamplerOnHTML(samplerHeight, 0, 0, 40, 3);
59
+ // paintSamplerOnHTML(samplerNormal, 1, 0, 128, 1);
60
+ // paintSamplerOnHTML(occlusionSampler, 2, 0, 1, 0);
61
+ //
62
+ //
63
+ resolve(occlusionSampler);
64
+ }, reject);
65
+ });
66
+ }
67
+
68
+ /**
69
+ *
70
+ * @param {THREE.DataTexture} texture
71
+ * @param {Vector2} [resolution]
72
+ * @param {Sampler2D} heightSampler
73
+ * @param {number} [rayLength]
74
+ * @param {Vector2} [worldSize]
75
+ * @returns {Promise}
76
+ */
77
+ export function buildLightTexture({
78
+ texture,
79
+ heightSampler,
80
+ resolution= new Vector2(texture.image.width, texture.image.height),
81
+ rayLength = 11,
82
+ worldSize = resolution
83
+ }) {
84
+
85
+ const renderer = WebGLRendererPool.global.get();
86
+
87
+ const normal = promiseSamplerNormal(renderer, heightSampler);
88
+ const ao = promiseSamplerAO({
89
+ renderer: renderer,
90
+ pSamplerNormal: normal,
91
+ samplerHeight: heightSampler,
92
+ resolution: resolution,
93
+ rayLength: rayLength,
94
+ worldSize
95
+ });
96
+
97
+ const promise = ao.then(sampler => {
98
+ writeSample2DDataToDataTexture(sampler, texture);
99
+ });
100
+
101
+ Promise.all([normal, ao]).finally(() => {
102
+ WebGLRendererPool.global.release(renderer);
103
+ });
104
+
105
+ return promise;
106
+ }