@woosh/meep-engine 2.35.9 → 2.35.10

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.
@@ -0,0 +1,156 @@
1
+ import { BufferGeometry, Float32BufferAttribute, Vector3 } from "three";
2
+
3
+ /**
4
+ * @see https://github.com/mrdoob/three.js/blob/master/src/geometries/TubeGeometry.js
5
+ * @param {Vector3[]} points
6
+ * @param {Vector3[]} _normals
7
+ * @param {Vector3[]} binormals
8
+ * @param {number} radius
9
+ * @param {number} radialSegments
10
+ * @param {boolean} [closed]
11
+ * @returns {BufferGeometry}
12
+ */
13
+ export function makeTubeGeometry(points, _normals, binormals, radius, radialSegments, closed = false) {
14
+ const geometry = new BufferGeometry();
15
+ // helper variables
16
+
17
+ const vertex = new Vector3();
18
+ const normal = new Vector3();
19
+
20
+ // buffer
21
+
22
+ const vertices = [];
23
+ const normals = [];
24
+ const uvs = [];
25
+ const indices = [];
26
+
27
+ const tubularSegments = points.length - 1;
28
+
29
+ // create buffer data
30
+
31
+ generateBufferData();
32
+
33
+ // build geometry
34
+
35
+ geometry.setIndex(indices);
36
+ geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
37
+ geometry.setAttribute('normal', new Float32BufferAttribute(normals, 3));
38
+ geometry.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
39
+
40
+ // functions
41
+
42
+ function generateBufferData() {
43
+
44
+ for (let i = 0; i < tubularSegments; i++) {
45
+
46
+ generateSegment(i);
47
+
48
+ }
49
+
50
+ // if the geometry is not closed, generate the last row of vertices and normals
51
+ // at the regular position on the given path
52
+ //
53
+ // if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)
54
+
55
+ generateSegment((closed === false) ? tubularSegments : 0);
56
+
57
+ // uvs are generated in a separate function.
58
+ // this makes it easy compute correct values for closed geometries
59
+
60
+ generateUVs();
61
+
62
+ // finally create faces
63
+
64
+ generateIndices();
65
+
66
+ }
67
+
68
+ function generateSegment(i) {
69
+
70
+ // we use getPointAt to sample evenly distributed points from the given path
71
+
72
+ const P = points[i];
73
+
74
+ // retrieve corresponding normal and binormal
75
+
76
+ const N = _normals[i];
77
+ const B = binormals[i];
78
+
79
+ // generate normals and vertices for the current segment
80
+
81
+ const angular_step = (Math.PI * 2) / radialSegments;
82
+
83
+ for (let j = 0; j <= radialSegments; j++) {
84
+ const v = j * angular_step;
85
+
86
+ const sin = Math.sin(v);
87
+ const cos = -Math.cos(v);
88
+
89
+ // normal
90
+
91
+ normal.x = (cos * N.x + sin * B.x);
92
+ normal.y = (cos * N.y + sin * B.y);
93
+ normal.z = (cos * N.z + sin * B.z);
94
+ normal.normalize();
95
+
96
+ normals.push(normal.x, normal.y, normal.z);
97
+
98
+ // vertex
99
+
100
+ vertex.x = P.x + radius * normal.x;
101
+ vertex.y = P.y + radius * normal.y;
102
+ vertex.z = P.z + radius * normal.z;
103
+
104
+ vertices.push(vertex.x, vertex.y, vertex.z);
105
+
106
+ }
107
+
108
+ }
109
+
110
+ function generateIndices() {
111
+ let i = 0, j = 0;
112
+
113
+ for (j = 1; j <= tubularSegments; j++) {
114
+
115
+ for (i = 1; i <= radialSegments; i++) {
116
+
117
+ const s_1 = radialSegments + 1;
118
+
119
+ const a = s_1 * (j - 1) + (i - 1);
120
+ const b = s_1 * j + (i - 1);
121
+ const c = s_1 * j + i;
122
+ const d = s_1 * (j - 1) + i;
123
+
124
+ // faces
125
+
126
+ indices.push(a, b, d);
127
+ indices.push(b, c, d);
128
+
129
+ }
130
+
131
+ }
132
+
133
+ }
134
+
135
+ function generateUVs() {
136
+ let i = 0, j = 0;
137
+
138
+ for (i = 0; i <= tubularSegments; i++) {
139
+
140
+ const u = i / tubularSegments;
141
+
142
+ for (j = 0; j <= radialSegments; j++) {
143
+
144
+ const v = j / radialSegments;
145
+
146
+ uvs.push(u, v);
147
+
148
+ }
149
+
150
+ }
151
+
152
+ }
153
+
154
+
155
+ return geometry;
156
+ }
@@ -1,42 +1,16 @@
1
1
  import { AbstractRenderAdapter } from "../../../ecs/mesh-v2/render/adapters/AbstractRenderAdapter.js";
2
2
  import Vector2 from "../../../../../core/geom/Vector2.js";
3
- import { MaterialVertexSpec } from "../../render/v1/MaterialVertexSpec.js";
4
-
5
- /**
6
- *
7
- * @type {MaterialVertexSpec}
8
- */
9
- const scratch_mvc = new MaterialVertexSpec();
10
-
11
- class MicronRenderContext {
12
-
13
- }
14
3
 
15
4
  export class MicronShadedGeometryRenderAdapter extends AbstractRenderAdapter {
16
- constructor({
17
- vgtr
18
- }) {
19
- super();
20
-
21
- /**
22
- * @type {VGThreeRenderer}
23
- * @private
24
- */
25
- this.__vgtr = vgtr;
26
5
 
27
- /**
28
- *
29
- * @type {VirtualGeometry|null}
30
- * @private
31
- */
32
- this.__vg = null;
6
+ constructor() {
7
+ super();
33
8
 
34
9
  /**
35
10
  *
36
- * @type {VirtualGeometryBuilder|null}
37
- * @private
11
+ * @type {MicronRenderContext|null}
38
12
  */
39
- this.__vgb = null;
13
+ this.ctx = null;
40
14
 
41
15
  /**
42
16
  *
@@ -58,7 +32,7 @@ export class MicronShadedGeometryRenderAdapter extends AbstractRenderAdapter {
58
32
  const micron_geometry = this.__geometry_map.get(sg.geometry.id);
59
33
 
60
34
  // populate virtual geometry for this instance
61
- this.__vgb.buildForMesh(sg.entity, micron_geometry, sg.transform);
35
+ this.ctx.builder.buildForMesh(sg.entity, micron_geometry, sg.transform);
62
36
 
63
37
  }
64
38
 
@@ -84,67 +58,20 @@ export class MicronShadedGeometryRenderAdapter extends AbstractRenderAdapter {
84
58
  pixelRatio = renderer.getPixelRatio();
85
59
  }
86
60
 
87
- const vg_builder = this.__vgb;
61
+ const vg_builder = this.ctx.builder;
88
62
 
89
63
  vg_builder.resolution.set(resolution.x * pixelRatio, resolution.y * pixelRatio);
90
64
  vg_builder.setMatricesFromCamera(view.camera);
91
- vg_builder.setOutput(this.__vg);
65
+ vg_builder.setOutput(this.ctx.geometry);
92
66
 
93
- vg_builder.build();
67
+ vg_builder.initialize_build();
94
68
  }
95
69
 
96
70
  build_end() {
97
- const contexts = this.__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
- for (let i = 0; i < context_count; i++) {
107
- const ctx = contexts[i];
108
- ctx.__patch_count = 0;
109
-
110
- for (const instance of ctx.instances) {
111
- instance_to_ctx.set(instance, ctx);
112
- }
113
- }
114
-
115
- // sort patches into relevant contexts
116
- const geometry = this.geometry;
117
- const patch_count = geometry.patch_count;
118
- const patches = geometry.patches;
119
-
120
- for (let i = 0; i < patch_count; i++) {
121
- const i3 = i * 3;
122
-
123
- const instance_id = patches[i3];
124
- const geometry_id = patches[i3 + 1];
125
- const patch_id = patches[i3 + 2];
126
-
127
- const ctx = instance_to_ctx.get(instance_id);
128
-
129
- const target_address = ctx.__patch_count * 3;
130
- ctx.__patch_count++;
131
-
132
- const ctx_patches = ctx.__patches;
133
-
134
- ctx_patches[target_address] = instance_id;
135
- ctx_patches[target_address + 1] = geometry_id;
136
- ctx_patches[target_address + 2] = patch_id;
137
- }
138
-
139
- // build each context
140
- for (let i = 0; i < context_count; i++) {
141
- const ctx = contexts[i];
142
-
143
- ctx.build(this.geometry);
144
- }
71
+ this.ctx.render();
145
72
  }
146
73
 
147
74
  dispose() {
148
-
75
+ // rendering context is not owned, do nothing
149
76
  }
150
77
  }
@@ -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;
@@ -0,0 +1,139 @@
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 } 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
+ * Enable/disable wireframe rendering
44
+ * @param {boolean} x
45
+ */
46
+ set wireframe(x) {
47
+ this.material_contexts.forEach((ctx, mv) => {
48
+
49
+
50
+ ctx.compiled_material.wireframe = x;
51
+
52
+ });
53
+ }
54
+
55
+
56
+ /**
57
+ *
58
+ * @param {VertexDataSpec} spec
59
+ * @param {Material} m
60
+ * @returns {MaterialContext}
61
+ */
62
+ obtain_material(spec, m) {
63
+ scratch_mvc.material = m;
64
+ scratch_mvc.spec = spec;
65
+
66
+ const existing = this.material_contexts.get(scratch_mvc);
67
+
68
+ if (existing !== undefined) {
69
+ return existing;
70
+ }
71
+
72
+ // create a separate instance to be stored alongside the context
73
+ const key = scratch_mvc.clone();
74
+
75
+ const ctx = new MaterialContext(spec, m);
76
+
77
+ ctx.init();
78
+
79
+ this.material_contexts.set(key, ctx);
80
+ this.__contexts_array.push(ctx);
81
+
82
+ this.on.contextAdded.send1(ctx);
83
+
84
+ return ctx;
85
+ }
86
+
87
+ render() {
88
+ const render_context = this;
89
+ const contexts = render_context.__contexts_array;
90
+ const context_count = contexts.length;
91
+
92
+ /**
93
+ *
94
+ * @type {Map<number, MaterialContext>}
95
+ */
96
+ const instance_to_ctx = new Map();
97
+
98
+ for (let i = 0; i < context_count; i++) {
99
+ const ctx = contexts[i];
100
+ ctx.__patch_count = 0;
101
+
102
+ for (const instance of ctx.instances) {
103
+ instance_to_ctx.set(instance, ctx);
104
+ }
105
+ }
106
+
107
+ // sort patches into relevant contexts
108
+ const geometry = render_context.geometry;
109
+ const patch_count = geometry.patch_count;
110
+ const patches = geometry.patches;
111
+
112
+ for (let i = 0; i < patch_count; i++) {
113
+ const i3 = i * 3;
114
+
115
+ const instance_id = patches[i3];
116
+ const geometry_id = patches[i3 + 1];
117
+ const patch_id = patches[i3 + 2];
118
+
119
+ const ctx = instance_to_ctx.get(instance_id);
120
+
121
+ const target_address = ctx.__patch_count * 3;
122
+ ctx.__patch_count++;
123
+
124
+ const ctx_patches = ctx.__patches;
125
+
126
+ ctx_patches[target_address] = instance_id;
127
+ ctx_patches[target_address + 1] = geometry_id;
128
+ ctx_patches[target_address + 2] = patch_id;
129
+ }
130
+
131
+ // build each context
132
+ for (let i = 0; i < context_count; i++) {
133
+ const ctx = contexts[i];
134
+
135
+ ctx.build(geometry);
136
+ }
137
+ }
138
+
139
+ }