@woosh/meep-engine 2.35.8 → 2.35.12

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 (28) hide show
  1. package/core/binary/BinaryBuffer.js +65 -18
  2. package/engine/graphics/ecs/camera/Camera.d.ts +3 -0
  3. package/engine/graphics/ecs/camera/Camera.js +39 -1
  4. package/engine/graphics/ecs/camera/CameraSystem.js +25 -6
  5. package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +8 -2
  6. package/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +19 -4
  7. package/engine/graphics/ecs/path/PathDisplaySystem.js +1 -1
  8. package/engine/graphics/ecs/path/testPathDisplaySystem.js +13 -12
  9. package/engine/graphics/ecs/path/tube/TubePathStyle.d.ts +2 -0
  10. package/engine/graphics/ecs/path/tube/TubePathStyle.js +43 -1
  11. package/engine/graphics/ecs/path/tube/build/TubePathBuilder.js +138 -0
  12. package/engine/graphics/ecs/path/tube/build/build_geometry_catmullrom.js +32 -0
  13. package/engine/graphics/ecs/path/tube/build/build_geometry_linear.js +16 -0
  14. package/engine/graphics/ecs/path/tube/build/computeFrenetFrames.js +153 -0
  15. package/engine/graphics/ecs/path/tube/build/estimatePathLength.js +17 -0
  16. package/engine/graphics/ecs/path/tube/build/estimatePathViaIterativeIntegral.js +37 -0
  17. package/engine/graphics/ecs/path/tube/build/makeTubeGeometry.js +156 -0
  18. package/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +1 -1
  19. package/engine/graphics/micron/plugin/shaded_geometry/MicronShadedGeometryRenderAdapter.js +45 -76
  20. package/engine/graphics/micron/render/VirtualGeometryBuilder.js +19 -24
  21. package/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +1 -1
  22. package/engine/graphics/micron/render/v1/MaterialContext.js +1 -11
  23. package/engine/graphics/micron/render/v1/MaterialVertexSpec.js +55 -2
  24. package/engine/graphics/micron/render/v1/MicronRenderContext.js +151 -0
  25. package/engine/graphics/micron/render/v1/VGThreeRenderer.js +24 -117
  26. package/engine/graphics/particles/particular/engine/utils/volume/ParticleVolume.js +1 -0
  27. package/package.json +1 -1
  28. package/engine/graphics/ecs/path/tube/TubePathBuilder.js +0 -522
@@ -1,17 +1,10 @@
1
1
  import { array_copy } from "../../../../core/collection/array/copyArray.js";
2
2
  import Vector2 from "../../../../core/geom/Vector2.js";
3
3
  import { RefinementSpec } from "./refinement/RefinementSpec.js";
4
- import { ActivePatchList } from "./refinement/ActivePatchList.js";
5
4
  import { mat4 } from "gl-matrix";
6
5
  import { get_geometry_patch_cut } from "./refinement/get_geometry_patch_cut.js";
7
6
  import { traverseThreeObject } from "../../ecs/highlight/renderer/traverseThreeObject.js";
8
7
 
9
- /**
10
- * @readonly
11
- * @type {RefinementSpec}
12
- */
13
- const refinement_spec = new RefinementSpec();
14
-
15
8
  export class VirtualGeometryBuilder {
16
9
  constructor() {
17
10
 
@@ -60,13 +53,6 @@ export class VirtualGeometryBuilder {
60
53
  */
61
54
  this.resolution = new Vector2();
62
55
 
63
- /**
64
- *
65
- * @type {ActivePatchList}
66
- * @private
67
- */
68
- this.__acl = new ActivePatchList();
69
-
70
56
  /**
71
57
  * How much error to accept when deciding to subdivide a cluster
72
58
  * Measured in pixels
@@ -74,10 +60,15 @@ export class VirtualGeometryBuilder {
74
60
  * @type {number}
75
61
  */
76
62
  this.error_bias = 2;
63
+
64
+ /**
65
+ *
66
+ * @type {RefinementSpec}
67
+ */
68
+ this.refinement_spec = new RefinementSpec();
77
69
  }
78
70
 
79
71
  dropCache() {
80
- this.__acl.clear();
81
72
  }
82
73
 
83
74
  /**
@@ -103,7 +94,7 @@ export class VirtualGeometryBuilder {
103
94
  mat4.multiply(this.view_projection_matrix, this.matrix_projection, this.matrix_world_inverse);
104
95
 
105
96
  //
106
- refinement_spec.focal_length = camera.fov / 180;
97
+ this.refinement_spec.focal_length = camera.fov / 180;
107
98
  }
108
99
 
109
100
  /**
@@ -121,17 +112,15 @@ export class VirtualGeometryBuilder {
121
112
  * @type {MicronGeometry|undefined}
122
113
  */
123
114
  const micron_geometry = object.geometry;
124
- if (micron_geometry !== undefined) {
125
- // get acl
126
- const acl = this.__acl;
127
115
 
116
+ if (micron_geometry !== undefined) {
128
117
 
129
118
  this.buildForMesh(
130
119
  object.instance_id,
131
120
  micron_geometry,
132
- object.matrixWorld.elements,
133
- acl
121
+ object.matrixWorld.elements
134
122
  );
123
+
135
124
  }
136
125
  }
137
126
  }
@@ -147,6 +136,8 @@ export class VirtualGeometryBuilder {
147
136
  geometry,
148
137
  transform
149
138
  ) {
139
+ const refinement_spec = this.refinement_spec;
140
+
150
141
  refinement_spec.build(transform, this.view_projection_matrix);
151
142
 
152
143
  const output = this.output;
@@ -183,17 +174,21 @@ export class VirtualGeometryBuilder {
183
174
  this.input_scene_length += object_count;
184
175
  }
185
176
 
186
- build() {
177
+ initialize_build() {
187
178
 
188
179
  // update refinement spec
189
- refinement_spec.error_threshold = this.error_bias;
180
+ this.refinement_spec.error_threshold = this.error_bias;
190
181
 
191
182
  const resolution = this.resolution;
192
183
 
193
- refinement_spec.setResolution(resolution.x, resolution.y);
184
+ this.refinement_spec.setResolution(resolution.x, resolution.y);
194
185
 
195
186
  // clear output
196
187
  this.output.clear();
188
+ }
189
+
190
+ build() {
191
+ this.initialize_build();
197
192
 
198
193
 
199
194
  const n = this.input_scene_length;
@@ -125,7 +125,7 @@ export class ThreeInstancedAdapter {
125
125
 
126
126
  /**
127
127
  *
128
- * @param {Uint32Array[]} patches
128
+ * @param {Uint32Array} patches
129
129
  * @param {number} patch_count
130
130
  * @param {VirtualGeometry} virtual_geometry
131
131
  */
@@ -52,7 +52,7 @@ export class MaterialContext {
52
52
 
53
53
  /**
54
54
  *
55
- * @type {MicronGeometryPatchOccurrence[]}
55
+ * @type {Uint32Array|number[]}
56
56
  */
57
57
  this.__patches = [];
58
58
 
@@ -63,16 +63,6 @@ export class MaterialContext {
63
63
  this.__patch_count = 0;
64
64
  }
65
65
 
66
-
67
- /**
68
- *
69
- * @param {MicronGeometryPatchOccurrence} occurrence
70
- * @returns {boolean}
71
- */
72
- filter(occurrence) {
73
- return this.instances.has(occurrence.instance_id);
74
- }
75
-
76
66
  init() {
77
67
 
78
68
  const material = this.material.clone();
@@ -1,3 +1,8 @@
1
+ export const MaterialVertexSpecFlags = {
2
+ CastShadow: 1,
3
+ ReceiveShadow: 2
4
+ };
5
+
1
6
  export class MaterialVertexSpec {
2
7
  constructor() {
3
8
  /**
@@ -10,6 +15,52 @@ export class MaterialVertexSpec {
10
15
  * @type {THREE.Material|null}
11
16
  */
12
17
  this.material = null;
18
+
19
+ /**
20
+ *
21
+ * @type {number}
22
+ */
23
+ this.flags = 0;
24
+ }
25
+
26
+ /**
27
+ *
28
+ * @param {number|MaterialVertexSpecFlags} flag
29
+ * @returns {void}
30
+ */
31
+ setFlag(flag) {
32
+ this.flags |= flag;
33
+ }
34
+
35
+ /**
36
+ *
37
+ * @param {number|MaterialVertexSpecFlags} flag
38
+ * @returns {void}
39
+ */
40
+ clearFlag(flag) {
41
+ this.flags &= ~flag;
42
+ }
43
+
44
+ /**
45
+ *
46
+ * @param {number|MaterialVertexSpecFlags} flag
47
+ * @param {boolean} value
48
+ */
49
+ writeFlag(flag, value) {
50
+ if (value) {
51
+ this.setFlag(flag);
52
+ } else {
53
+ this.clearFlag(flag);
54
+ }
55
+ }
56
+
57
+ /**
58
+ *
59
+ * @param {number|MaterialVertexSpecFlags} flag
60
+ * @returns {boolean}
61
+ */
62
+ getFlag(flag) {
63
+ return (this.flags & flag) === flag;
13
64
  }
14
65
 
15
66
  /**
@@ -19,6 +70,7 @@ export class MaterialVertexSpec {
19
70
  copy(other) {
20
71
  this.spec = other.spec;
21
72
  this.material = other.material;
73
+ this.flags = other.flags;
22
74
  }
23
75
 
24
76
  /**
@@ -47,7 +99,7 @@ export class MaterialVertexSpec {
47
99
  }
48
100
 
49
101
  hash() {
50
- return this.spec.hash() ^ this.material.id;
102
+ return this.spec.hash() ^ this.material.id ^ this.flags;
51
103
  }
52
104
 
53
105
  equals(other) {
@@ -55,8 +107,9 @@ export class MaterialVertexSpec {
55
107
  return true;
56
108
  }
57
109
 
58
- return this.spec.equals(other.spec)
110
+ return this.flags === other.flags
59
111
  && this.material === other.material
112
+ && this.spec.equals(other.spec)
60
113
  ;
61
114
  }
62
115
  }
@@ -0,0 +1,151 @@
1
+ import { VirtualGeometry } from "../../format/VirtualGeometry.js";
2
+ import { VirtualGeometryBuilder } from "../VirtualGeometryBuilder.js";
3
+ import { HashMap } from "../../../../../core/collection/HashMap.js";
4
+ import Signal from "../../../../../core/events/signal/Signal.js";
5
+ import { MaterialContext } from "./MaterialContext.js";
6
+ import { MaterialVertexSpec, MaterialVertexSpecFlags } from "./MaterialVertexSpec.js";
7
+
8
+ /**
9
+ *
10
+ * @type {MaterialVertexSpec}
11
+ */
12
+ const scratch_mvc = new MaterialVertexSpec();
13
+
14
+ export class MicronRenderContext {
15
+ constructor() {
16
+
17
+ this.geometry = new VirtualGeometry();
18
+
19
+ this.builder = new VirtualGeometryBuilder();
20
+
21
+ /**
22
+ *
23
+ * @type {Map<MaterialVertexSpec, MaterialContext>}
24
+ */
25
+ this.material_contexts = new HashMap();
26
+
27
+ /**
28
+ *
29
+ * @type {MaterialContext[]}
30
+ * @private
31
+ */
32
+ this.__contexts_array = [];
33
+
34
+ this.on = {
35
+ /**
36
+ * @type {Signal<MaterialContext>}
37
+ */
38
+ contextAdded: new Signal()
39
+ };
40
+ }
41
+
42
+ /**
43
+ *
44
+ * @returns {MaterialContext[]}
45
+ */
46
+ get contexts_array() {
47
+ return this.__contexts_array;
48
+ }
49
+
50
+ /**
51
+ * Enable/disable wireframe rendering
52
+ * @param {boolean} x
53
+ */
54
+ set wireframe(x) {
55
+ this.material_contexts.forEach((ctx, mv) => {
56
+
57
+
58
+ ctx.compiled_material.wireframe = x;
59
+
60
+ });
61
+ }
62
+
63
+
64
+ /**
65
+ *
66
+ * @param {MaterialVertexSpec} descriptor
67
+ * @returns {MaterialContext}
68
+ */
69
+ obtain_material(descriptor) {
70
+
71
+ const existing = this.material_contexts.get(descriptor);
72
+
73
+ if (existing !== undefined) {
74
+ return existing;
75
+ }
76
+
77
+ // create a separate instance to be stored alongside the context
78
+ const key = descriptor.clone();
79
+
80
+ const ctx = new MaterialContext(descriptor.spec, descriptor.material);
81
+
82
+ ctx.init();
83
+
84
+ ctx.mesh.castShadow = descriptor.getFlag(MaterialVertexSpecFlags.CastShadow);
85
+ ctx.mesh.receiveShadow = descriptor.getFlag(MaterialVertexSpecFlags.ReceiveShadow);
86
+
87
+ this.material_contexts.set(key, ctx);
88
+ this.__contexts_array.push(ctx);
89
+
90
+ this.on.contextAdded.send1(ctx);
91
+
92
+ return ctx;
93
+ }
94
+
95
+ render() {
96
+ const render_context = this;
97
+ const contexts = render_context.__contexts_array;
98
+ const context_count = contexts.length;
99
+
100
+ /**
101
+ *
102
+ * @type {Map<number, MaterialContext>}
103
+ */
104
+ const instance_to_ctx = new Map();
105
+
106
+ let i = 0;
107
+
108
+ for (i = 0; i < context_count; i++) {
109
+ const ctx = contexts[i];
110
+ ctx.__patch_count = 0;
111
+
112
+ for (const instance of ctx.instances) {
113
+ instance_to_ctx.set(instance, ctx);
114
+ }
115
+ }
116
+
117
+ // sort patches into relevant contexts
118
+ const geometry = render_context.geometry;
119
+ const patch_count = geometry.patch_count;
120
+ const patches = geometry.patches;
121
+
122
+ for (i = 0; i < patch_count; i++) {
123
+ const i3 = i * 3;
124
+
125
+ const instance_id = patches[i3];
126
+ const geometry_id = patches[i3 + 1];
127
+ const patch_id = patches[i3 + 2];
128
+
129
+ const ctx = instance_to_ctx.get(instance_id);
130
+
131
+ const target_index = ctx.__patch_count;
132
+ const target_address = target_index * 3;
133
+
134
+ ctx.__patch_count++;
135
+
136
+ const ctx_patches = ctx.__patches;
137
+
138
+ ctx_patches[target_address] = instance_id;
139
+ ctx_patches[target_address + 1] = geometry_id;
140
+ ctx_patches[target_address + 2] = patch_id;
141
+ }
142
+
143
+ // build each context
144
+ for (i = 0; i < context_count; i++) {
145
+ const ctx = contexts[i];
146
+
147
+ ctx.build(geometry);
148
+ }
149
+ }
150
+
151
+ }
@@ -1,11 +1,8 @@
1
- import { VirtualGeometryBuilder } from "../VirtualGeometryBuilder.js";
2
1
  import Vector2 from "../../../../../core/geom/Vector2.js";
3
- import { VirtualGeometry } from "../../format/VirtualGeometry.js";
4
2
  import { MaterialContext } from "./MaterialContext.js";
5
- import { MaterialVertexSpec } from "./MaterialVertexSpec.js";
6
- import { HashMap } from "../../../../../core/collection/HashMap.js";
7
- import Signal from "../../../../../core/events/signal/Signal.js";
8
3
  import { array_copy } from "../../../../../core/collection/array/copyArray.js";
4
+ import { MicronRenderContext } from "./MicronRenderContext.js";
5
+ import { MaterialVertexSpec, MaterialVertexSpecFlags } from "./MaterialVertexSpec.js";
9
6
 
10
7
  /**
11
8
  *
@@ -15,23 +12,6 @@ const scratch_mvc = new MaterialVertexSpec();
15
12
 
16
13
  export class VGThreeRenderer {
17
14
  constructor() {
18
- this.geometry = new VirtualGeometry();
19
-
20
- this.builder = new VirtualGeometryBuilder();
21
-
22
- /**
23
- *
24
- * @type {Map<MaterialVertexSpec, MaterialContext>}
25
- */
26
- this.material_contexts = new HashMap();
27
-
28
- /**
29
- *
30
- * @type {MaterialContext[]}
31
- * @private
32
- */
33
- this.__contexts_array = [];
34
-
35
15
  /**
36
16
  *
37
17
  * @type {Object3D[]}
@@ -39,82 +19,51 @@ export class VGThreeRenderer {
39
19
  */
40
20
  this.__inputs = [];
41
21
 
22
+ this.ctx = new MicronRenderContext();
23
+
42
24
  this.on = {
43
25
  /**
44
26
  * @type {Signal<MaterialContext>}
45
27
  */
46
- contextAdded: new Signal()
28
+ contextAdded: this.ctx.on.contextAdded
47
29
  };
48
30
  }
49
31
 
32
+ get geometry() {
33
+ return this.ctx.geometry;
34
+ }
35
+
50
36
  /**
51
37
  * Enable/disable wireframe rendering
52
38
  * @param {boolean} x
53
39
  */
54
40
  set wireframe(x) {
55
- this.material_contexts.forEach((ctx, mv) => {
56
-
57
-
58
- ctx.compiled_material.wireframe = x;
59
-
60
- });
41
+ this.ctx.wireframe = x;
61
42
  }
62
43
 
63
- /**
64
- *
65
- * @param {VertexDataSpec} spec
66
- * @param {Material} m
67
- * @returns {MaterialContext}
68
- * @private
69
- */
70
- __obtain_material(spec, m) {
71
- scratch_mvc.material = m;
72
- scratch_mvc.spec = spec;
73
-
74
- const existing = this.material_contexts.get(scratch_mvc);
75
-
76
- if (existing !== undefined) {
77
- return existing;
78
- }
79
-
80
- // create a separate instance to be stored alongside the context
81
- const key = scratch_mvc.clone();
82
-
83
- const ctx = new MaterialContext(spec, m);
84
-
85
- ctx.init();
86
-
87
- this.material_contexts.set(key, ctx);
88
- this.__contexts_array.push(ctx);
89
-
90
- this.on.contextAdded.send1(ctx);
91
-
92
- return ctx;
93
- }
94
-
95
-
96
44
  /**
97
45
  *
98
46
  * @param {THREE.Scene} scene
99
47
  */
100
48
  attach(scene) {
101
49
  this.__inputs.push(scene);
102
- this.builder.appendToScene([scene]);
50
+ this.ctx.builder.appendToScene([scene]);
103
51
  }
104
52
 
105
53
  attachMany(objects) {
106
54
  array_copy(objects, 0, this.__inputs, this.__inputs.length, objects.length);
107
- this.builder.appendToScene(objects);
55
+ this.ctx.builder.appendToScene(objects);
108
56
  }
109
57
 
110
58
  clear() {
111
59
  this.__inputs = [];
112
- this.builder.clearScene();
60
+ this.ctx.builder.clearScene();
113
61
  }
114
62
 
115
63
  __prepare_contexts() {
116
64
  // clear contexts
117
- const contexts = this.__contexts_array;
65
+ const render_context = this.ctx;
66
+ const contexts = render_context.__contexts_array;
118
67
  const context_count = contexts.length;
119
68
 
120
69
  for (let i = 0; i < context_count; i++) {
@@ -131,7 +80,12 @@ export class VGThreeRenderer {
131
80
  */
132
81
  const m = o;
133
82
 
134
- const ctx = this.__obtain_material(m.geometry.vertex_spec, m.material);
83
+ scratch_mvc.material = m.material;
84
+ scratch_mvc.spec = m.geometry.vertex_spec;
85
+ scratch_mvc.writeFlag(MaterialVertexSpecFlags.CastShadow, m.castShadow);
86
+ scratch_mvc.writeFlag(MaterialVertexSpecFlags.ReceiveShadow, m.receiveShadow);
87
+
88
+ const ctx = render_context.obtain_material(scratch_mvc);
135
89
 
136
90
  ctx.instances.add(o.instance_id);
137
91
  }
@@ -149,54 +103,7 @@ export class VGThreeRenderer {
149
103
  }
150
104
 
151
105
  render() {
152
- const contexts = this.__contexts_array;
153
- const context_count = contexts.length;
154
-
155
- /**
156
- *
157
- * @type {Map<number, MaterialContext>}
158
- */
159
- const instance_to_ctx = new Map();
160
-
161
- for (let i = 0; i < context_count; i++) {
162
- const ctx = contexts[i];
163
- ctx.__patch_count = 0;
164
-
165
- for (const instance of ctx.instances) {
166
- instance_to_ctx.set(instance, ctx);
167
- }
168
- }
169
-
170
- // sort patches into relevant contexts
171
- const geometry = this.geometry;
172
- const patch_count = geometry.patch_count;
173
- const patches = geometry.patches;
174
-
175
- for (let i = 0; i < patch_count; i++) {
176
- const i3 = i * 3;
177
-
178
- const instance_id = patches[i3];
179
- const geometry_id = patches[i3 + 1];
180
- const patch_id = patches[i3 + 2];
181
-
182
- const ctx = instance_to_ctx.get(instance_id);
183
-
184
- const target_address = ctx.__patch_count * 3;
185
- ctx.__patch_count++;
186
-
187
- const ctx_patches = ctx.__patches;
188
-
189
- ctx_patches[target_address] = instance_id;
190
- ctx_patches[target_address + 1] = geometry_id;
191
- ctx_patches[target_address + 2] = patch_id;
192
- }
193
-
194
- // build each context
195
- for (let i = 0; i < context_count; i++) {
196
- const ctx = contexts[i];
197
-
198
- ctx.build(this.geometry);
199
- }
106
+ this.ctx.render();
200
107
  }
201
108
 
202
109
 
@@ -224,11 +131,11 @@ export class VGThreeRenderer {
224
131
  pixelRatio = renderer.getPixelRatio();
225
132
  }
226
133
 
227
- const vg_builder = this.builder;
134
+ const vg_builder = this.ctx.builder;
228
135
 
229
136
  vg_builder.resolution.set(resolution.x * pixelRatio, resolution.y * pixelRatio);
230
137
  vg_builder.setMatricesFromCamera(camera);
231
- vg_builder.setOutput(this.geometry);
138
+ vg_builder.setOutput(this.ctx.geometry);
232
139
 
233
140
  vg_builder.build();
234
141
  }
@@ -390,6 +390,7 @@ export class ParticleVolume {
390
390
 
391
391
  // request bounds update
392
392
  emitter.setFlag(ParticleEmitterFlag.ParticleBoundsNeedUpdate);
393
+ emitter.computeBoundingBox();
393
394
  }
394
395
 
395
396
  /**
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "productName": "Meep",
6
6
  "description": "production-ready JavaScript game engine based on Entity Component System Architecture",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.35.8",
8
+ "version": "2.35.12",
9
9
  "dependencies": {
10
10
  "gl-matrix": "3.4.3",
11
11
  "fast-levenshtein": "2.0.6",