@woosh/meep-engine 2.35.10 → 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.
@@ -3,6 +3,7 @@
3
3
  * @enum {boolean}
4
4
  */
5
5
  import { assert } from "../assert.js";
6
+ import { array_copy } from "../collection/array/copyArray.js";
6
7
 
7
8
  /**
8
9
  *
@@ -30,17 +31,50 @@ function BinaryBuffer() {
30
31
  */
31
32
  this.endianness = EndianType.BigEndian;
32
33
 
34
+ /**
35
+ *
36
+ * @type {number}
37
+ */
33
38
  this.position = 0;
39
+
40
+ /**
41
+ *
42
+ * @type {number}
43
+ */
34
44
  this.length = 0;
45
+
46
+ /**
47
+ *
48
+ * @type {number}
49
+ */
35
50
  this.capacity = 0;
36
51
 
37
52
  /**
38
53
  *
39
54
  * @type {ArrayBuffer}
55
+ * @private
40
56
  */
41
57
  this.data = new ArrayBuffer(0);
58
+
59
+ /**
60
+ *
61
+ * @type {DataView}
62
+ * @private
63
+ */
42
64
  this.dataView = new DataView(this.data);
43
65
 
66
+ /**
67
+ *
68
+ * @type {Uint8Array}
69
+ * @private
70
+ */
71
+ this.__data_uint8 = new Uint8Array(0);
72
+
73
+ /**
74
+ *
75
+ * @type {number}
76
+ * @private
77
+ */
44
78
  this.__growFactor = 1.1;
45
79
  }
46
80
 
@@ -50,6 +84,7 @@ function BinaryBuffer() {
50
84
  BinaryBuffer.prototype.fromArrayBuffer = function (arrayBuffer) {
51
85
  this.data = arrayBuffer;
52
86
  this.dataView = new DataView(arrayBuffer);
87
+ this.__data_uint8 = new Uint8Array(arrayBuffer);
53
88
 
54
89
  this.capacity = arrayBuffer.byteLength;
55
90
  //assume that all the data is useful
@@ -85,7 +120,7 @@ BinaryBuffer.prototype.trim = function () {
85
120
  * @param {number} capacity
86
121
  */
87
122
  BinaryBuffer.prototype.setCapacity = function (capacity) {
88
- const oldData = new Uint8Array(this.data);
123
+ const oldData = this.__data_uint8;
89
124
  const newData = new Uint8Array(capacity);
90
125
 
91
126
  //copy old data
@@ -93,7 +128,7 @@ BinaryBuffer.prototype.setCapacity = function (capacity) {
93
128
  newData.set(oldData.subarray(0, copyLength), 0);
94
129
 
95
130
  this.data = newData.buffer;
96
-
131
+ this.__data_uint8 = newData;
97
132
  this.dataView = new DataView(this.data);
98
133
 
99
134
  this.capacity = capacity;
@@ -680,11 +715,11 @@ BinaryBuffer.prototype.writeUint32LE = function (value) {
680
715
  /**
681
716
  *
682
717
  * @param {Uint8Array|Uint8ClampedArray} array
683
- * @param {number} sourceOffset
718
+ * @param {number} source_offset
684
719
  * @param {number} length
685
720
  */
686
- BinaryBuffer.prototype.writeBytes = function (array, sourceOffset, length) {
687
- const source_end = sourceOffset + length;
721
+ BinaryBuffer.prototype.writeBytes = function (array, source_offset, length) {
722
+ const source_end = source_offset + length;
688
723
  assert.greaterThanOrEqual(array.length, source_end, 'source array underflow');
689
724
 
690
725
  const targetAddress = this.position;
@@ -693,18 +728,21 @@ BinaryBuffer.prototype.writeBytes = function (array, sourceOffset, length) {
693
728
 
694
729
  this.ensureCapacity(end);
695
730
 
696
- const destination = new Uint8Array(this.data, targetAddress, length);
731
+ if (source_offset === 0 && array.length === length) {
732
+ // copying entire source array
697
733
 
698
- if (typeof array.subarray === "function") {
734
+ this.__data_uint8.set(array, targetAddress);
735
+
736
+ } else if (typeof array.subarray === "function") {
699
737
  // typed array, use "subarray" method
700
738
 
701
- destination.set(array.subarray(sourceOffset, source_end));
739
+ this.__data_uint8.set(array.subarray(source_offset, source_end), targetAddress);
702
740
 
703
741
  } else {
704
742
  // not a typed array, copy byte by byte manually
705
743
 
706
744
  for (let i = 0; i < length; i++) {
707
- destination[i] = array[sourceOffset + i];
745
+ this.__data_uint8[targetAddress + i] = array[source_offset + i];
708
746
  }
709
747
 
710
748
  }
@@ -714,14 +752,23 @@ BinaryBuffer.prototype.writeBytes = function (array, sourceOffset, length) {
714
752
 
715
753
  /**
716
754
  *
717
- * @param {Uint8Array} target
718
- * @param {number} targetOffset
755
+ * @param {Uint8Array} destination
756
+ * @param {number} destination_offset
719
757
  * @param {number} length
720
758
  */
721
- BinaryBuffer.prototype.readBytes = function (target, targetOffset, length) {
722
- const end = this.position + length;
723
- const uint8Array = new Uint8Array(this.data);
724
- target.set(uint8Array.subarray(this.position, end), targetOffset);
759
+ BinaryBuffer.prototype.readBytes = function (destination, destination_offset, length) {
760
+ const source_position = this.position;
761
+
762
+ const end = source_position + length;
763
+
764
+ const uint8 = this.__data_uint8;
765
+
766
+ if (length < 128) {
767
+ // small copy
768
+ array_copy(uint8, source_position, destination, destination_offset, length);
769
+ } else {
770
+ destination.set(uint8.subarray(source_position, end), destination_offset);
771
+ }
725
772
 
726
773
  this.position = end;
727
774
  };
@@ -764,7 +811,7 @@ BinaryBuffer.prototype.writeUTF8String = function (string) {
764
811
 
765
812
  this.ensureCapacity(tlen + at);
766
813
 
767
- let target = new Uint8Array(this.data); // ... but at 8 byte offset
814
+ let target = this.__data_uint8; // ... but at 8 byte offset
768
815
 
769
816
 
770
817
  while (pos < len) {
@@ -791,7 +838,7 @@ BinaryBuffer.prototype.writeUTF8String = function (string) {
791
838
 
792
839
  this.ensureCapacity(tlen + startPosition);
793
840
 
794
- target = new Uint8Array(this.data);
841
+ target = this.__data_uint8;
795
842
  }
796
843
 
797
844
  if ((value & 0xffffff80) === 0) { // 1-byte
@@ -851,7 +898,7 @@ BinaryBuffer.prototype.readUTF8String = function () {
851
898
  return undefined;
852
899
  }
853
900
 
854
- const bytes = new Uint8Array(this.data);
901
+ const bytes = this.__data_uint8;
855
902
 
856
903
 
857
904
  let result = "";
@@ -62,7 +62,7 @@ export class Camera {
62
62
  * @type {number}
63
63
  * @private
64
64
  */
65
- this.__clip_far = 0;
65
+ this.__clip_far = 100;
66
66
 
67
67
  /**
68
68
  * Far clipping plane
@@ -297,7 +297,7 @@ export class CameraSystem extends System {
297
297
  * @param {Camera} c
298
298
  */
299
299
  function visitCameraEntity(c) {
300
- if (c.object !== null) {
300
+ if (c.object === null) {
301
301
  return;
302
302
  }
303
303
 
@@ -305,7 +305,7 @@ export class CameraSystem extends System {
305
305
  return;
306
306
  }
307
307
 
308
- if (c.autoClip) {
308
+ if (c.autoClip === true) {
309
309
  autoSetClippingPlanes(c, layers);
310
310
  } else {
311
311
  c.object.far = c.clip_far;
@@ -313,13 +313,19 @@ export class ShadedGeometrySystem extends System {
313
313
  const local_direction_x = scratch_m4[0] * direction_x + scratch_m4[4] * direction_y + scratch_m4[8] * direction_z;
314
314
  const local_direction_y = scratch_m4[1] * direction_x + scratch_m4[5] * direction_y + scratch_m4[9] * direction_z;
315
315
  const local_direction_z = scratch_m4[2] * direction_x + scratch_m4[6] * direction_y + scratch_m4[10] * direction_z;
316
- // NOTE: direction is not normalized
316
+
317
+ const local_direction_magnitude = Math.hypot(local_direction_x, local_direction_y, local_direction_z);
318
+ const local_direction_magnitude_inverse = 1 / local_direction_magnitude;
319
+
320
+ const local_direction_normalized_x = local_direction_x * local_direction_magnitude_inverse;
321
+ const local_direction_normalized_y = local_direction_y * local_direction_magnitude_inverse;
322
+ const local_direction_normalized_z = local_direction_z * local_direction_magnitude_inverse;
317
323
 
318
324
  const geometry_hit_found = GeometrySpatialQueryAccelerator.INSTANCE.queryRaycastNearest_primitive(
319
325
  scratch_point,
320
326
  sg.geometry,
321
327
  local_origin_x, local_origin_y, local_origin_z,
322
- local_direction_x, local_direction_y, local_direction_z
328
+ local_direction_normalized_x, local_direction_normalized_y, local_direction_normalized_z
323
329
  );
324
330
 
325
331
  if (!geometry_hit_found) {
@@ -20,6 +20,9 @@ import { randomFromArray } from "../../../../../core/math/random/randomFromArray
20
20
  import { BehaviorComponent } from "../../../../intelligence/behavior/ecs/BehaviorComponent.js";
21
21
  import { OrbitingBehavior } from "../../../../../../model/game/util/behavior/OrbitingBehavior.js";
22
22
  import { BehaviorSystem } from "../../../../intelligence/behavior/ecs/BehaviorSystem.js";
23
+ import { MicronShadedGeometryRenderAdapter } from "../../../micron/plugin/shaded_geometry/MicronShadedGeometryRenderAdapter.js";
24
+ import { MicronRenderContext } from "../../../micron/render/v1/MicronRenderContext.js";
25
+ import { randomIntegerBetween } from "../../../../../core/math/random/randomIntegerBetween.js";
23
26
 
24
27
  const eh = new EngineHarness();
25
28
 
@@ -50,7 +53,17 @@ async function main(engine) {
50
53
 
51
54
  const em = engine.entityManager;
52
55
 
53
- await em.addSystem(new ShadedGeometrySystem(engine));
56
+ const sgs = new ShadedGeometrySystem(engine);
57
+
58
+ const mrc = new MicronRenderContext();
59
+ sgs.register_render_adapter(2, () => {
60
+ const adapter = new MicronShadedGeometryRenderAdapter();
61
+ adapter.ctx = mrc;
62
+
63
+ return adapter;
64
+ });
65
+
66
+ await em.addSystem(sgs);
54
67
  await em.addSystem(new BehaviorSystem(engine));
55
68
 
56
69
  EngineHarness.buildBasics({
@@ -74,7 +87,7 @@ async function main(engine) {
74
87
 
75
88
  const random = seededRandom(0);
76
89
 
77
- const INSTANCE_COUNT = 0;
90
+ const INSTANCE_COUNT = 10000;
78
91
 
79
92
  const geometries = [];
80
93
 
@@ -87,7 +100,9 @@ async function main(engine) {
87
100
  const sg = ShadedGeometry.from(geometry, material);
88
101
 
89
102
  // sg.draw_method = DRAW_METHOD_PLAIN;
90
- sg.draw_method = DRAW_METHOD_INSTANCED;
103
+ // sg.draw_method = DRAW_METHOD_INSTANCED;
104
+ // sg.draw_method = 2;
105
+ sg.draw_method = randomIntegerBetween(random, 0, 2);
91
106
  // sg.draw_method = random() > 0.01 ? DRAW_METHOD_INSTANCED : DRAW_METHOD_PLAIN;
92
107
  sg.clearFlag(ShadedGeometryFlags.CastShadow | ShadedGeometryFlags.ReceiveShadow);
93
108
 
@@ -105,7 +120,7 @@ async function main(engine) {
105
120
  .build(ecd);
106
121
  }
107
122
 
108
- makeMovingShadedGeometry().build(ecd);
123
+ // makeMovingShadedGeometry().build(ecd);
109
124
 
110
125
  debug_button(engine, () => {
111
126
  const dot = convert_bvh_to_dot_format_string(engine.graphics.layers.getLayerByName('shaded-geometry').bvh);
@@ -121,7 +121,7 @@ const PRINT_VERBOSE_STATS = false;
121
121
  /**
122
122
  *
123
123
  * @param {THREE.BufferGeometry} input
124
- * @returns {MicronGeometry}
124
+ * @returns {Promise<MicronGeometry>}
125
125
  */
126
126
  export async function buildMicronGeometryFromBufferGeometry(input) {
127
127
  const source_geometry = deinterleaveBufferGeometry(input);
@@ -1,5 +1,14 @@
1
1
  import { AbstractRenderAdapter } from "../../../ecs/mesh-v2/render/adapters/AbstractRenderAdapter.js";
2
2
  import Vector2 from "../../../../../core/geom/Vector2.js";
3
+ import { buildMicronGeometryFromBufferGeometry } from "../../build/buildMicronGeometryFromBufferGeometry.js";
4
+ import { ShadedGeometryFlags } from "../../../ecs/mesh-v2/ShadedGeometryFlags.js";
5
+ import { MaterialVertexSpec, MaterialVertexSpecFlags } from "../../render/v1/MaterialVertexSpec.js";
6
+
7
+ /**
8
+ *
9
+ * @type {MaterialVertexSpec}
10
+ */
11
+ const scratch_mvc = new MaterialVertexSpec();
3
12
 
4
13
  export class MicronShadedGeometryRenderAdapter extends AbstractRenderAdapter {
5
14
 
@@ -21,19 +30,42 @@ export class MicronShadedGeometryRenderAdapter extends AbstractRenderAdapter {
21
30
 
22
31
  /**
23
32
  *
24
- * @type {Set<MaterialContext>}
33
+ * @type {Map<number, Promise>}
25
34
  * @private
26
35
  */
27
- this.__active_contexts = new Set();
36
+ this.__geometry_building_promises = new Map();
28
37
  }
29
38
 
30
39
  add(sg) {
31
40
 
32
- const micron_geometry = this.__geometry_map.get(sg.geometry.id);
41
+ const geometry_id = sg.geometry.id;
42
+
43
+ const micron_geometry = this.__geometry_map.get(geometry_id);
44
+
45
+ if (micron_geometry === undefined) {
46
+ // no micron geometry
47
+ if (!this.__geometry_building_promises.has(geometry_id)) {
48
+ const p = buildMicronGeometryFromBufferGeometry(sg.geometry);
49
+
50
+ this.__geometry_building_promises.set(geometry_id, p);
51
+
52
+ p.then(mg => this.__geometry_map.set(geometry_id, mg));
53
+ }
54
+ return;
55
+ }
33
56
 
34
57
  // populate virtual geometry for this instance
35
58
  this.ctx.builder.buildForMesh(sg.entity, micron_geometry, sg.transform);
36
59
 
60
+ scratch_mvc.material = sg.material;
61
+ scratch_mvc.spec = micron_geometry.vertex_spec;
62
+ scratch_mvc.writeFlag(MaterialVertexSpecFlags.CastShadow, sg.getFlag(ShadedGeometryFlags.CastShadow));
63
+ scratch_mvc.writeFlag(MaterialVertexSpecFlags.ReceiveShadow, sg.getFlag(ShadedGeometryFlags.ReceiveShadow));
64
+
65
+ const material_context = this.ctx.obtain_material(scratch_mvc);
66
+
67
+ material_context.instances.add(sg.entity);
68
+
37
69
  }
38
70
 
39
71
  /**
@@ -69,6 +101,16 @@ export class MicronShadedGeometryRenderAdapter extends AbstractRenderAdapter {
69
101
 
70
102
  build_end() {
71
103
  this.ctx.render();
104
+
105
+ const material_contexts = this.ctx.contexts_array;
106
+ const contexts_count = material_contexts.length;
107
+ for (let i = 0; i < contexts_count; i++) {
108
+ const mc = material_contexts[i];
109
+
110
+ if (mc.instances.size > 0) {
111
+ this.__objects[this.__object_count++] = mc.mesh;
112
+ }
113
+ }
72
114
  }
73
115
 
74
116
  dispose() {
@@ -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
  }
@@ -3,7 +3,7 @@ import { VirtualGeometryBuilder } from "../VirtualGeometryBuilder.js";
3
3
  import { HashMap } from "../../../../../core/collection/HashMap.js";
4
4
  import Signal from "../../../../../core/events/signal/Signal.js";
5
5
  import { MaterialContext } from "./MaterialContext.js";
6
- import { MaterialVertexSpec } from "./MaterialVertexSpec.js";
6
+ import { MaterialVertexSpec, MaterialVertexSpecFlags } from "./MaterialVertexSpec.js";
7
7
 
8
8
  /**
9
9
  *
@@ -39,6 +39,14 @@ export class MicronRenderContext {
39
39
  };
40
40
  }
41
41
 
42
+ /**
43
+ *
44
+ * @returns {MaterialContext[]}
45
+ */
46
+ get contexts_array() {
47
+ return this.__contexts_array;
48
+ }
49
+
42
50
  /**
43
51
  * Enable/disable wireframe rendering
44
52
  * @param {boolean} x
@@ -55,27 +63,27 @@ export class MicronRenderContext {
55
63
 
56
64
  /**
57
65
  *
58
- * @param {VertexDataSpec} spec
59
- * @param {Material} m
66
+ * @param {MaterialVertexSpec} descriptor
60
67
  * @returns {MaterialContext}
61
68
  */
62
- obtain_material(spec, m) {
63
- scratch_mvc.material = m;
64
- scratch_mvc.spec = spec;
69
+ obtain_material(descriptor) {
65
70
 
66
- const existing = this.material_contexts.get(scratch_mvc);
71
+ const existing = this.material_contexts.get(descriptor);
67
72
 
68
73
  if (existing !== undefined) {
69
74
  return existing;
70
75
  }
71
76
 
72
77
  // create a separate instance to be stored alongside the context
73
- const key = scratch_mvc.clone();
78
+ const key = descriptor.clone();
74
79
 
75
- const ctx = new MaterialContext(spec, m);
80
+ const ctx = new MaterialContext(descriptor.spec, descriptor.material);
76
81
 
77
82
  ctx.init();
78
83
 
84
+ ctx.mesh.castShadow = descriptor.getFlag(MaterialVertexSpecFlags.CastShadow);
85
+ ctx.mesh.receiveShadow = descriptor.getFlag(MaterialVertexSpecFlags.ReceiveShadow);
86
+
79
87
  this.material_contexts.set(key, ctx);
80
88
  this.__contexts_array.push(ctx);
81
89
 
@@ -95,7 +103,9 @@ export class MicronRenderContext {
95
103
  */
96
104
  const instance_to_ctx = new Map();
97
105
 
98
- for (let i = 0; i < context_count; i++) {
106
+ let i = 0;
107
+
108
+ for (i = 0; i < context_count; i++) {
99
109
  const ctx = contexts[i];
100
110
  ctx.__patch_count = 0;
101
111
 
@@ -109,7 +119,7 @@ export class MicronRenderContext {
109
119
  const patch_count = geometry.patch_count;
110
120
  const patches = geometry.patches;
111
121
 
112
- for (let i = 0; i < patch_count; i++) {
122
+ for (i = 0; i < patch_count; i++) {
113
123
  const i3 = i * 3;
114
124
 
115
125
  const instance_id = patches[i3];
@@ -118,7 +128,9 @@ export class MicronRenderContext {
118
128
 
119
129
  const ctx = instance_to_ctx.get(instance_id);
120
130
 
121
- const target_address = ctx.__patch_count * 3;
131
+ const target_index = ctx.__patch_count;
132
+ const target_address = target_index * 3;
133
+
122
134
  ctx.__patch_count++;
123
135
 
124
136
  const ctx_patches = ctx.__patches;
@@ -129,7 +141,7 @@ export class MicronRenderContext {
129
141
  }
130
142
 
131
143
  // build each context
132
- for (let i = 0; i < context_count; i++) {
144
+ for (i = 0; i < context_count; i++) {
133
145
  const ctx = contexts[i];
134
146
 
135
147
  ctx.build(geometry);
@@ -2,6 +2,13 @@ import Vector2 from "../../../../../core/geom/Vector2.js";
2
2
  import { MaterialContext } from "./MaterialContext.js";
3
3
  import { array_copy } from "../../../../../core/collection/array/copyArray.js";
4
4
  import { MicronRenderContext } from "./MicronRenderContext.js";
5
+ import { MaterialVertexSpec, MaterialVertexSpecFlags } from "./MaterialVertexSpec.js";
6
+
7
+ /**
8
+ *
9
+ * @type {MaterialVertexSpec}
10
+ */
11
+ const scratch_mvc = new MaterialVertexSpec();
5
12
 
6
13
  export class VGThreeRenderer {
7
14
  constructor() {
@@ -73,7 +80,12 @@ export class VGThreeRenderer {
73
80
  */
74
81
  const m = o;
75
82
 
76
- const ctx = render_context.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);
77
89
 
78
90
  ctx.instances.add(o.instance_id);
79
91
  }
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.10",
8
+ "version": "2.35.12",
9
9
  "dependencies": {
10
10
  "gl-matrix": "3.4.3",
11
11
  "fast-levenshtein": "2.0.6",