@woosh/meep-engine 2.41.0 → 2.42.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 (39) hide show
  1. package/core/geom/3d/apply_mat4_transform_to_v3_array.js +2 -4
  2. package/core/geom/3d/sphere/sphere_radius_sqr_from_v3_array_transformed.js +28 -0
  3. package/core/geom/Quaternion.js +14 -0
  4. package/engine/EngineHarness.js +9 -3
  5. package/engine/ecs/transform/Transform.js +23 -3
  6. package/engine/graphics/ecs/decal/v2/Decal.d.ts +11 -0
  7. package/engine/graphics/ecs/decal/v2/Decal.js +50 -0
  8. package/engine/graphics/ecs/decal/v2/FPDecalSystem.d.ts +8 -0
  9. package/engine/graphics/ecs/decal/v2/FPDecalSystem.js +213 -0
  10. package/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +237 -0
  11. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +8 -1
  12. package/engine/graphics/ecs/mesh-v2/build_three_object.js +4 -0
  13. package/engine/graphics/geometry/MikkT/MikkTSpace.js +466 -305
  14. package/engine/graphics/geometry/buffered/computeGeometryEquality.js +1 -1
  15. package/engine/graphics/geometry/buffered/computeGeometryHash.js +1 -1
  16. package/engine/graphics/impostors/octahedral/ImpostorBaker.js +27 -14
  17. package/engine/graphics/impostors/octahedral/ImpostorDescription.js +6 -0
  18. package/engine/graphics/impostors/octahedral/README.md +1 -0
  19. package/engine/graphics/impostors/octahedral/bake/compute_bounding_sphere.js +25 -22
  20. package/engine/graphics/impostors/octahedral/bake/compute_bounding_sphere_radius_only.js +37 -0
  21. package/engine/graphics/impostors/octahedral/bake/prepare_bake_material.js +30 -1
  22. package/engine/graphics/impostors/octahedral/grid/HemiOctahedralUvEncoder.js +1 -1
  23. package/engine/graphics/impostors/octahedral/prototypeBaker.js +121 -22
  24. package/engine/graphics/impostors/octahedral/shader/BakeShaderStandard.js +46 -7
  25. package/engine/graphics/impostors/octahedral/shader/ImpostorShaderV0.js +349 -0
  26. package/engine/graphics/impostors/octahedral/shader/ImpostorShaderV1.js +74 -0
  27. package/engine/graphics/impostors/octahedral/shader/glsl/v1/common.glsl +209 -0
  28. package/engine/graphics/impostors/octahedral/shader/glsl/v1/flagment.glsl +80 -0
  29. package/engine/graphics/impostors/octahedral/shader/glsl/v1/vertex.glsl +350 -0
  30. package/engine/graphics/micron/render/v1/getTransformedPositionsCached.js +1 -1
  31. package/engine/graphics/render/forward_plus/LightManager.js +1 -1
  32. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_ACCUMULATION.js +1 -3
  33. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_PREAMBLE.js +2 -1
  34. package/engine/graphics/render/forward_plus/model/Decal.js +19 -2
  35. package/engine/graphics/texture/sampler/Sampler2D.js +10 -10
  36. package/engine/graphics/texture/sampler/prototypeSamplerFiltering.js +117 -11
  37. package/engine/graphics/texture/sampler/resize/sampler2d_downsample_mipmap.js +66 -0
  38. package/engine/graphics/texture/sampler/sampler2_d_scale_down_lanczos.js +2 -2
  39. package/package.json +1 -1
@@ -6,11 +6,9 @@
6
6
  * @param {number[]|Float32Array|Float64Array} destination
7
7
  * @param {number} destination_offset
8
8
  * @param {number} count
9
- * @param {THREE.Matrix4} matrix
9
+ * @param {mat4|number[]|Float32Array} mat4
10
10
  */
11
- export function apply_mat4_transform_to_v3_array(source, source_offset, destination, destination_offset, count, matrix) {
12
-
13
- const mat4 = matrix.elements;
11
+ export function apply_mat4_transform_to_v3_array(source, source_offset, destination, destination_offset, count, mat4) {
14
12
 
15
13
  const a0 = mat4[0];
16
14
  const a1 = mat4[1];
@@ -0,0 +1,28 @@
1
+ /**
2
+ *
3
+ * @param {number[]|ArrayLike<number>} input
4
+ * @param {number} input_length
5
+ * @param {ArrayLike<number>|number[]|Float32Array} e 4x4 transformation matrix
6
+ * @returns {number}
7
+ */
8
+ export function sphere_radius_sqr_from_v3_array_transformed(input, input_length, e) {
9
+ let result = 0;
10
+
11
+ for (let i = 0; i < input_length; i += 3) {
12
+ const x = input[i];
13
+ const y = input[i + 1];
14
+ const z = input[i + 2];
15
+
16
+ const _x = e[0] * x + e[4] * y + e[8] * z + e[12];
17
+ const _y = e[1] * x + e[5] * y + e[9] * z + e[13];
18
+ const _z = e[2] * x + e[6] * y + e[10] * z + e[14];
19
+
20
+ const l2 = _x * _x + _y * _y + _z * _z;
21
+
22
+ if (l2 > result) {
23
+ result = l2;
24
+ }
25
+ }
26
+
27
+ return result;
28
+ }
@@ -1705,6 +1705,20 @@ class Quaternion {
1705
1705
  return result;
1706
1706
  }
1707
1707
 
1708
+ /**
1709
+ *
1710
+ * @param {number} x
1711
+ * @param {number} y
1712
+ * @param {number} z
1713
+ * @returns {Quaternion}
1714
+ */
1715
+ static fromEulerAngles(x, y, z) {
1716
+ const r = new Quaternion();
1717
+
1718
+ r.fromEulerAnglesXYZ(x, y, z);
1719
+
1720
+ return r;
1721
+ }
1708
1722
 
1709
1723
  /**
1710
1724
  * Behaves similarly to Unity's Quaternion `RotateToward` method
@@ -153,6 +153,7 @@ export class EngineHarness {
153
153
  * @param {boolean} [autoClip]
154
154
  * @param {number} [distanceMin]
155
155
  * @param {number} [distanceMax]
156
+ * @param {number} [fieldOfView] in degrees
156
157
  * @returns {EntityBuilder}
157
158
  */
158
159
  static buildCamera(
@@ -163,9 +164,10 @@ export class EngineHarness {
163
164
  distance = 10,
164
165
  pitch = 1.4,
165
166
  yaw = 0,
166
- autoClip = true,
167
+ autoClip = false,
167
168
  distanceMin = 0,
168
- distanceMax = 1000
169
+ distanceMax = 1000,
170
+ fieldOfView = 45
169
171
  }
170
172
  ) {
171
173
  const em = engine.entityManager;
@@ -199,6 +201,7 @@ export class EngineHarness {
199
201
 
200
202
  camera.active.set(true);
201
203
  camera.autoClip = autoClip;
204
+ camera.fov.set(fieldOfView);
202
205
 
203
206
  const entityBuilder = new EntityBuilder();
204
207
 
@@ -229,6 +232,7 @@ export class EngineHarness {
229
232
  * @param {boolean} [enableWater]
230
233
  * @param {boolean} [enableTerrain]
231
234
  * @param {boolean} [enableLights=true]
235
+ * @param {number} [cameraFieldOfView]
232
236
  * @param {boolean} [cameraController=true]
233
237
  */
234
238
  static async buildBasics({
@@ -244,6 +248,7 @@ export class EngineHarness {
244
248
  enableWater = true,
245
249
  enableTerrain = true,
246
250
  enableLights = true,
251
+ cameraFieldOfView,
247
252
  cameraController = true
248
253
  }) {
249
254
 
@@ -256,7 +261,8 @@ export class EngineHarness {
256
261
  target: focus,
257
262
  pitch,
258
263
  yaw,
259
- distance
264
+ distance,
265
+ fieldOfView: cameraFieldOfView
260
266
  });
261
267
 
262
268
  const cameraEntity = camera.entity;
@@ -63,9 +63,29 @@ export class Transform {
63
63
  this.flags = FLAGS_DEFAULT;
64
64
 
65
65
  // watch changes
66
- this.position.onChanged.add(this.__handle_component_change, this);
67
- this.rotation.onChanged.add(this.__handle_component_change, this);
68
- this.scale.onChanged.add(this.__handle_component_change, this);
66
+ this.subscribeAllChanges(this.__handle_component_change, this);
67
+ }
68
+
69
+ /**
70
+ *
71
+ * @param {function} handler
72
+ * @param {*} [thisArg]
73
+ */
74
+ subscribeAllChanges(handler, thisArg) {
75
+ this.position.onChanged.add(handler, thisArg);
76
+ this.rotation.onChanged.add(handler, thisArg);
77
+ this.scale.onChanged.add(handler, thisArg);
78
+ }
79
+
80
+ /**
81
+ *
82
+ * @param {function} handler
83
+ * @param {*} [thisArg]
84
+ */
85
+ unsubscribeAllChanges(handler, thisArg) {
86
+ this.position.onChanged.remove(handler, thisArg);
87
+ this.rotation.onChanged.remove(handler, thisArg);
88
+ this.scale.onChanged.scale(handler, thisArg);
69
89
  }
70
90
 
71
91
  /**
@@ -0,0 +1,11 @@
1
+ export class Decal {
2
+ /**
3
+ * Path to image
4
+ */
5
+ uri: string
6
+
7
+ /**
8
+ * Draw order, higher values will be drawn on top of lower values when there's an overlap
9
+ */
10
+ priority: number
11
+ }
@@ -0,0 +1,50 @@
1
+ export class Decal {
2
+ constructor() {
3
+ /**
4
+ * Asset URL
5
+ * @type {string}
6
+ */
7
+ this.uri = "";
8
+
9
+ /**
10
+ * Controls draw order
11
+ * @type {number}
12
+ */
13
+ this.priority = 0;
14
+
15
+ /**
16
+ * Internal transient reference to loaded asset
17
+ * @type {Sampler2D|null}
18
+ * @private
19
+ */
20
+ this.__cached_sampler = null;
21
+ /**
22
+ *
23
+ * @type {String|null}
24
+ * @private
25
+ */
26
+ this.__cached_uri = null;
27
+ }
28
+
29
+ toJSON() {
30
+ return {
31
+ uri: this.uri,
32
+ priority: this.priority
33
+ };
34
+ }
35
+
36
+ fromJSON({
37
+ uri, priority = 0
38
+ }) {
39
+ this.uri = uri;
40
+ this.priority = priority;
41
+
42
+ if (uri !== this.__cached_uri) {
43
+ // reset sampler
44
+ this.__cached_sampler = null;
45
+ this.__cached_uri = null;
46
+ }
47
+ }
48
+ }
49
+
50
+ Decal.typeName = 'Decal';
@@ -0,0 +1,8 @@
1
+ import {System} from "../../../../ecs/System";
2
+ import {Decal} from "./Decal";
3
+ import {Transform} from "../../../../ecs/transform/Transform";
4
+ import Engine from "../../../../Engine";
5
+
6
+ export class FPDecalSystem extends System<Decal, Transform> {
7
+ constructor(engine: Engine)
8
+ }
@@ -0,0 +1,213 @@
1
+ import { AbstractContextSystem } from "../../../../ecs/system/AbstractContextSystem.js";
2
+ import { SystemEntityContext } from "../../../../ecs/system/SystemEntityContext.js";
3
+ import { Decal } from "./Decal.js";
4
+ import { Transform } from "../../../../ecs/transform/Transform.js";
5
+ import { ForwardPlusRenderingPlugin } from "../../../render/forward_plus/plugin/ForwardPlusRenderingPlugin.js";
6
+ import { Reference } from "../../../../reference/v2/Reference.js";
7
+ import { Decal as FPDecal } from '../../../render/forward_plus/model/Decal.js';
8
+ import { AssetManager } from "../../../../asset/AssetManager.js";
9
+ import { Sampler2D } from "../../../texture/sampler/Sampler2D.js";
10
+ import { GameAssetType } from "../../../../asset/GameAssetType.js";
11
+
12
+ const placeholder_texture = Sampler2D.uint8(4, 1, 1);
13
+ placeholder_texture.data.fill(255);
14
+
15
+ class Context extends SystemEntityContext {
16
+ constructor() {
17
+ super();
18
+
19
+ /**
20
+ *
21
+ * @type {FPDecal|null}
22
+ * @private
23
+ */
24
+ this.__fp_decal = null;
25
+ }
26
+
27
+ /**
28
+ * @return {ForwardPlusRenderingPlugin}
29
+ * @private
30
+ */
31
+ getPlugin() {
32
+ return this.system.__fp_plugin.getValue();
33
+ }
34
+
35
+ /**
36
+ *
37
+ * @returns {Transform}
38
+ */
39
+ getTransform() {
40
+ return this.components[1];
41
+ }
42
+
43
+ __update_transform() {
44
+ /**
45
+ *
46
+ * @type {Transform}
47
+ */
48
+ const transform = this.getTransform();
49
+
50
+ this.__fp_decal.setTransform(transform.matrix);
51
+ }
52
+
53
+ async __load_texture() {
54
+
55
+ /**
56
+ *
57
+ * @type {Decal}
58
+ */
59
+ const decal_spec = this.components[0];
60
+
61
+ const _uri = decal_spec.uri;
62
+
63
+ if (decal_spec.__cached_sampler !== null && decal_spec.__cached_uri === _uri) {
64
+ // cached asset is still relevant
65
+ return;
66
+ }
67
+
68
+
69
+ const loaded_texture = await this.system.internal_loadTexture(_uri);
70
+
71
+ decal_spec.__cached_sampler = loaded_texture;
72
+ decal_spec.__cached_uri = _uri;
73
+ }
74
+
75
+ link() {
76
+ const plugin = this.getPlugin();
77
+
78
+ const lm = plugin.getLightManager();
79
+
80
+ const fpDecal = new FPDecal();
81
+
82
+ this.__fp_decal = fpDecal;
83
+
84
+
85
+ this.__update_transform();
86
+
87
+ const transform = this.getTransform();
88
+ transform.subscribeAllChanges(this.__update_transform, this);
89
+
90
+ /**
91
+ *
92
+ * @type {Decal}
93
+ */
94
+ const decal_spec = this.components[0];
95
+
96
+ this.__load_texture().then(() => {
97
+
98
+ if (!this.__is_linked) {
99
+ // not linked anymore
100
+ return;
101
+ }
102
+
103
+ const sampler = decal_spec.__cached_sampler;
104
+
105
+ if (sampler === null) {
106
+ return;
107
+ }
108
+
109
+ fpDecal.texture_diffuse = sampler;
110
+
111
+ if (this.__fp_decal === fpDecal) {
112
+ lm.addLight(fpDecal);
113
+ }
114
+ });
115
+
116
+
117
+ super.link();
118
+ }
119
+
120
+ unlink() {
121
+
122
+ this.getPlugin()
123
+ .getLightManager()
124
+ .removeLight(this.__fp_decal);
125
+
126
+ this.__fp_decal = null;
127
+
128
+ const transform = this.getTransform();
129
+ transform.subscribeAllChanges(this.__update_transform, this);
130
+
131
+ super.unlink();
132
+ }
133
+ }
134
+
135
+ export class FPDecalSystem extends AbstractContextSystem {
136
+ /**
137
+ *
138
+ * @param {Engine} engine
139
+ */
140
+ constructor(engine) {
141
+ super(Context);
142
+
143
+ this.dependencies = [Decal, Transform];
144
+
145
+ /**
146
+ *
147
+ * @type {Map<string, Sampler2D>}
148
+ * @private
149
+ */
150
+ this.__texture_cache = new Map();
151
+
152
+ /**
153
+ *
154
+ * @type {AssetManager}
155
+ * @private
156
+ */
157
+ this.__assets = engine.assetManager;
158
+
159
+ /**
160
+ *
161
+ * @type {Engine}
162
+ * @private
163
+ */
164
+ this.__engine = engine;
165
+
166
+ /**
167
+ *
168
+ * @type {Reference<ForwardPlusRenderingPlugin>|null}
169
+ * @private
170
+ */
171
+ this.__fp_plugin = Reference.NULL;
172
+ }
173
+
174
+ /**
175
+ *
176
+ * @param {string} uri
177
+ * @returns {Promise<void>}
178
+ */
179
+ async internal_loadTexture(uri) {
180
+ const cached = this.__texture_cache.get(uri);
181
+
182
+ if (cached !== undefined) {
183
+ return cached;
184
+ }
185
+
186
+ const asset = await this.__assets.promise(uri, GameAssetType.Image);
187
+
188
+ // check cache again, in case another request has succeeded
189
+ const cached_v2 = this.__texture_cache.get(uri);
190
+
191
+ if (cached_v2 !== undefined) {
192
+ return cached_v2;
193
+ }
194
+
195
+ const sampler = asset.create();
196
+
197
+ this.__texture_cache.set(uri, sampler);
198
+
199
+ return sampler;
200
+ }
201
+
202
+ async startup(em, ready_callback, error_callback) {
203
+ this.__fp_plugin = await this.__engine.plugins.acquire(ForwardPlusRenderingPlugin);
204
+
205
+ super.startup(em, ready_callback, error_callback);
206
+ }
207
+
208
+ shutdown(em, ready_callback, error_callback) {
209
+ this.__fp_plugin.release();
210
+
211
+ super.shutdown(em, ready_callback, error_callback);
212
+ }
213
+ }