@woosh/meep-engine 2.34.49 → 2.35.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 (51) hide show
  1. package/core/bvh2/BinaryNode.js +19 -35
  2. package/core/bvh2/aabb3/aabb3_intersects_frustum_array.js +5 -5
  3. package/core/bvh2/aabb3_combined_surface_area.js +21 -0
  4. package/core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js +24 -12
  5. package/core/cache/Cache.d.ts +2 -0
  6. package/core/cache/Cache.js +27 -23
  7. package/core/geom/3d/frustum/frustum_from_projection_matrix_array.js +2 -0
  8. package/core/math/max2.js +2 -6
  9. package/core/math/min2.js +2 -6
  10. package/engine/asset/loaders/geometry/geometry/computeGeometryEquality.js +1 -1
  11. package/engine/asset/loaders/geometry/geometry/computeGeometryHash.js +9 -1
  12. package/engine/ecs/EntityComponentDataset.js +7 -2
  13. package/engine/ecs/foliage/ViewState.js +13 -3
  14. package/engine/ecs/parent/EntityNode.js +23 -11
  15. package/engine/ecs/transform/Transform.js +15 -13
  16. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +63 -26
  17. package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +63 -3
  18. package/engine/graphics/ecs/mesh-v2/render/AbstractRenderAdapter.js +67 -0
  19. package/engine/graphics/ecs/mesh-v2/render/GenericRendererAdapter.js +48 -0
  20. package/engine/graphics/ecs/mesh-v2/render/InstancedRendererAdapter.js +110 -0
  21. package/engine/graphics/ecs/mesh-v2/render/ShadedGeometryRendererContext.js +98 -0
  22. package/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +5 -0
  23. package/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +23 -5
  24. package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +8 -3
  25. package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +23 -85
  26. package/engine/graphics/geometry/instancing/rewriteMaterial.js +9 -45
  27. package/engine/graphics/material/optimization/BUFFER_GEOMETRY_UVS.js +10 -0
  28. package/engine/graphics/material/optimization/MaterialDescriptor.js +46 -0
  29. package/engine/graphics/material/optimization/MaterialOptimizationContext.js +470 -201
  30. package/engine/graphics/material/optimization/UvContext.js +18 -0
  31. package/engine/graphics/material/optimization/is_compliant_mesh.js +71 -0
  32. package/engine/graphics/material/optimization/prepare_atlas_texture.js +23 -0
  33. package/engine/graphics/material/optimization/prototypeMaterialOptimizer.js +127 -0
  34. package/engine/graphics/micron/format/MicronGeometryPatch.js +1 -1
  35. package/engine/graphics/micron/format/VirtualGeometry.js +47 -11
  36. package/engine/graphics/micron/format/serialization/MicronGeometryBinarySerializationAdapter.js +16 -0
  37. package/engine/graphics/micron/prototypeVirtualGeometry.js +3 -2
  38. package/engine/graphics/micron/render/VirtualGeometryBuilder.js +5 -7
  39. package/engine/graphics/micron/render/instanced/AttributeDataTexture.js +1 -45
  40. package/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +18 -7
  41. package/engine/graphics/micron/render/refinement/RefinementSpec.js +0 -1
  42. package/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +17 -24
  43. package/engine/graphics/micron/render/v1/MaterialContext.js +3 -2
  44. package/engine/graphics/micron/render/v1/VGThreeRenderer.js +19 -4
  45. package/engine/graphics/render/utils/ThreeBypassRenderer.js +3 -2
  46. package/engine/graphics/texture/normalized_internal_format.js +48 -0
  47. package/engine/graphics/texture/sampler/Sampler2D.js +6 -0
  48. package/engine/graphics/texture/sampler/sampler2d_copy_channel_data.js +25 -0
  49. package/engine/graphics/texture/sampler/scaleSampler2D.js +3 -0
  50. package/engine/graphics/texture/sampler/util/drawSamplerHTML.js +14 -1
  51. package/package.json +1 -1
@@ -12,6 +12,42 @@ const DEFAULT_FLAGS = ShadedGeometryFlags.CastShadow
12
12
  | ShadedGeometryFlags.ReceiveShadow
13
13
  ;
14
14
 
15
+ /**
16
+ *
17
+ * @param {ShadedGeometry} sg
18
+ * @returns {THREE.Object3D}
19
+ */
20
+ export function build_three_object(sg) {
21
+
22
+ /**
23
+ * @type {THREE.Object3D}
24
+ */
25
+ let object;
26
+
27
+ const mode = sg.mode;
28
+ const shader = sg.material;
29
+ const geo = sg.geometry;
30
+
31
+ if (mode === DrawMode.Triangles) {
32
+ object = new Mesh(geo, shader);
33
+ } else if (mode === DrawMode.Lines) {
34
+ object = new Line(geo, shader);
35
+ } else if (mode === DrawMode.LineSegments) {
36
+ object = new LineSegments(geo, shader);
37
+ } else {
38
+ throw new Error(`Unsupported draw mode '${mode}'`);
39
+ }
40
+
41
+ object.matrixAutoUpdate = false;
42
+ object.frustumCulled = false;
43
+ object.matrixWorldNeedsUpdate = false;
44
+
45
+ object.castShadow = sg.getFlag(ShadedGeometryFlags.CastShadow);
46
+ object.receiveShadow = sg.getFlag(ShadedGeometryFlags.ReceiveShadow);
47
+
48
+ return object;
49
+ }
50
+
15
51
  export class ShadedGeometry {
16
52
  constructor() {
17
53
  /**
@@ -51,6 +87,7 @@ export class ShadedGeometry {
51
87
  * @private
52
88
  */
53
89
  this.__entity = -1;
90
+
54
91
  /**
55
92
  * Transform matrix
56
93
  * Transient, assigned in the system
@@ -59,6 +96,12 @@ export class ShadedGeometry {
59
96
  */
60
97
  this.__transform = null;
61
98
 
99
+ /**
100
+ * Transient property signifying how to render object
101
+ * @type {number}
102
+ */
103
+ this.draw_method = 0;
104
+
62
105
  /**
63
106
  *
64
107
  * @type {number}
@@ -106,6 +149,25 @@ export class ShadedGeometry {
106
149
  return (this.flags & flag) === flag;
107
150
  }
108
151
 
152
+ /**
153
+ *
154
+ * @return {number}
155
+ */
156
+ hash() {
157
+ return this.geometry.id ^ this.material.id;
158
+ }
159
+
160
+ /**
161
+ *
162
+ * @param {ShadedGeometry} other
163
+ * @returns {boolean}
164
+ */
165
+ equals(other) {
166
+ return this.geometry.id === other.geometry.id
167
+ && this.material.id === other.material.id
168
+ ;
169
+ }
170
+
109
171
  /**
110
172
  * Current cached entity that this component is attached to
111
173
  * @return {number}
@@ -130,32 +192,7 @@ export class ShadedGeometry {
130
192
  }
131
193
 
132
194
  __build_object() {
133
- /**
134
- * @type {THREE.Object3D}
135
- */
136
- let object;
137
-
138
- const mode = this.mode;
139
- const shader = this.material;
140
- const geo = this.geometry;
141
-
142
- if (mode === DrawMode.Triangles) {
143
- object = new Mesh(geo, shader);
144
- } else if (mode === DrawMode.Lines) {
145
- object = new Line(geo, shader);
146
- } else if (mode === DrawMode.LineSegments) {
147
- object = new LineSegments(geo, shader);
148
- } else {
149
- throw new Error(`Unsupported draw mode '${mode}'`);
150
- }
151
-
152
- object.matrixAutoUpdate = false;
153
- object.frustumCulled = false;
154
-
155
- object.castShadow = this.getFlag(ShadedGeometryFlags.CastShadow);
156
- object.receiveShadow = this.getFlag(ShadedGeometryFlags.ReceiveShadow);
157
-
158
- this.__cached_object = object;
195
+ this.__cached_object = build_three_object(this);
159
196
  }
160
197
 
161
198
  get bvh() {
@@ -7,6 +7,8 @@ import { v3_distance_sqr } from "../../../../core/geom/v3_distance_sqr.js";
7
7
  import { mat4 } from "gl-matrix";
8
8
  import { returnTrue } from "../../../../core/function/Functions.js";
9
9
  import { aabb3_intersects_ray } from "../../../../core/bvh2/aabb3/aabb3_intersects_ray.js";
10
+ import { ShadedGeometryRendererContext } from "./render/ShadedGeometryRendererContext.js";
11
+ import { BinaryNode } from "../../../../core/bvh2/BinaryNode.js";
10
12
 
11
13
  /**
12
14
  *
@@ -54,14 +56,72 @@ export class ShadedGeometrySystem extends System {
54
56
  * @private
55
57
  */
56
58
  this.__render_layer = null;
59
+
60
+ /**
61
+ *
62
+ * @type {Map<CameraView, ShadedGeometryRendererContext>}
63
+ * @private
64
+ */
65
+ this.__view_contexts = new Map();
66
+
67
+ this.__bvh = new BinaryNode();
68
+ this.__bvh.setNegativelyInfiniteBounds();
69
+ }
70
+
71
+ /**
72
+ *
73
+ * @param {CameraView} view
74
+ * @private
75
+ */
76
+ __handle_view_added(view) {
77
+ this.__view_contexts.set(view, new ShadedGeometryRendererContext());
78
+ }
79
+
80
+ /**
81
+ *
82
+ * @param {CameraView} view
83
+ * @private
84
+ */
85
+ __handle_view_removed(view) {
86
+ const ctx = this.__view_contexts.get(view);
87
+
88
+ this.__view_contexts.delete(view);
89
+
90
+ ctx.dispose();
57
91
  }
58
92
 
59
93
  async startup(entityManager, readyCallback, errorCallback) {
60
94
 
61
95
  const engine = this.__engine;
96
+ const graphics = engine.graphics;
97
+
98
+ const view_list = graphics.views.elements;
99
+
100
+ view_list.forEach(this.__handle_view_added, this);
101
+ view_list.on.added.add(this.__handle_view_added, this);
102
+ view_list.on.removed.add(this.__handle_view_removed, this);
103
+
104
+ this.__render_layer = graphics.layers.create('shaded-geometry');
105
+
106
+ this.__render_layer.buildVisibleSet = ((destination, destination_offset, view) => {
107
+ const ctx = this.__view_contexts.get(view);
108
+
109
+ return ctx.collect(destination, destination_offset, view, this.__bvh);
110
+ });
111
+
112
+ readyCallback();
113
+ }
114
+
115
+ async shutdown(entityManager, readyCallback, errorCallback) {
116
+
117
+ const engine = this.__engine;
118
+ const graphics = engine.graphics;
119
+
120
+ const view_list = graphics.views.elements;
62
121
 
63
- this.__render_layer = engine.graphics.layers.create('shaded-geometry');
64
- this.__render_layer.extractRenderable = (sg) => sg.__cached_object;
122
+ view_list.forEach(this.__handle_view_removed, this);
123
+ view_list.on.added.remove(this.__handle_view_added, this);
124
+ view_list.on.removed.remove(this.__handle_view_removed, this);
65
125
 
66
126
  readyCallback();
67
127
  }
@@ -87,7 +147,7 @@ export class ShadedGeometrySystem extends System {
87
147
  // remember entity for lookups
88
148
  sg.__entity = entity;
89
149
 
90
- this.__render_layer.bvh.insertNode(leaf_node);
150
+ this.__bvh.insertNode(leaf_node);
91
151
  }
92
152
 
93
153
  /**
@@ -0,0 +1,67 @@
1
+ export class AbstractRenderAdapter {
2
+ constructor() {
3
+
4
+ /**
5
+ *
6
+ * @type {number}
7
+ * @protected
8
+ */
9
+ this.__object_count = 0;
10
+
11
+ /**
12
+ *
13
+ * @type {THREE.Object3D[]}
14
+ * @protected
15
+ */
16
+ this.__objects = [];
17
+ }
18
+
19
+ /**
20
+ *
21
+ * @param {THREE.BufferGeometry} geometry
22
+ * @param {THREE.Material} material
23
+ * @returns {number}
24
+ */
25
+ score(geometry, material) {
26
+ return 0;
27
+ }
28
+
29
+ /**
30
+ *
31
+ * @param {ShadedGeometry} sg
32
+ * @returns {void}
33
+ */
34
+ add(sg) {
35
+ throw new Error('Not Implemented');
36
+ }
37
+
38
+ build_start() {
39
+
40
+ }
41
+
42
+ build_end() {
43
+
44
+ }
45
+
46
+ clear() {
47
+ this.__object_count = 0;
48
+ }
49
+
50
+ /**
51
+ * @returns {THREE.Object3D[]}
52
+ */
53
+ get objects() {
54
+ return this.__objects;
55
+ }
56
+
57
+ /**
58
+ * @returns {number}
59
+ */
60
+ get object_count() {
61
+ return this.__object_count;
62
+ }
63
+
64
+ dispose() {
65
+
66
+ }
67
+ }
@@ -0,0 +1,48 @@
1
+ import { AbstractRenderAdapter } from "./AbstractRenderAdapter.js";
2
+ import { build_three_object } from "../ShadedGeometry.js";
3
+ import { array_copy } from "../../../../../core/collection/array/copyArray.js";
4
+
5
+ export class GenericRendererAdapter extends AbstractRenderAdapter {
6
+ constructor() {
7
+ super();
8
+
9
+ /**
10
+ *
11
+ * @type {Cache<ShadedGeometry, THREE.Object3D>}
12
+ * @private
13
+ */
14
+ this.__cache = new WeakMap();
15
+ }
16
+
17
+
18
+ score(geometry, material) {
19
+ return 0;
20
+ }
21
+
22
+ build_start() {
23
+ this.clear();
24
+ }
25
+
26
+ add(sg) {
27
+ const cache = this.__cache;
28
+
29
+ /**
30
+ *
31
+ * @type {THREE.Object3D}
32
+ */
33
+ let object = cache.get(sg);
34
+
35
+ if (object === undefined) {
36
+
37
+ object = build_three_object(sg);
38
+
39
+ cache.set(sg, object);
40
+
41
+ }
42
+
43
+ array_copy(sg.__transform, 0, object.matrixWorld.elements, 0, 16);
44
+
45
+ this.__objects[this.__object_count++] = object;
46
+ }
47
+
48
+ }
@@ -0,0 +1,110 @@
1
+ import { AbstractRenderAdapter } from "./AbstractRenderAdapter.js";
2
+ import { HashMap } from "../../../../../core/collection/HashMap.js";
3
+ import { InstancedMeshGroup } from "../../../geometry/instancing/InstancedMeshGroup.js";
4
+ import { ShadedGeometryFlags } from "../ShadedGeometryFlags.js";
5
+
6
+ const INSTANCED_EQUALITY_FLAGS = ShadedGeometryFlags.CastShadow
7
+ | ShadedGeometryFlags.ReceiveShadow
8
+ ;
9
+
10
+ export class InstancedRendererAdapter extends AbstractRenderAdapter {
11
+ constructor() {
12
+ super();
13
+
14
+ /**
15
+ *
16
+ * @type {HashMap<ShadedGeometry, InstancedMeshGroup>}
17
+ * @private
18
+ */
19
+ this.__instanced_meshes = new HashMap({
20
+ keyHashFunction(sg) {
21
+ return sg.geometry.id ^ sg.material.id;
22
+ },
23
+ keyEqualityFunction(a, b) {
24
+ return a.material.id === b.material.id
25
+ && a.geometry.id === b.geometry.id
26
+ && (a.flags & INSTANCED_EQUALITY_FLAGS) === (b.flags & INSTANCED_EQUALITY_FLAGS)
27
+ ;
28
+ }
29
+ });
30
+
31
+ /**
32
+ *
33
+ * @type {Set<InstancedMeshGroup>}
34
+ * @private
35
+ */
36
+ this.__active_meshes = new Set();
37
+ }
38
+
39
+ /**
40
+ *
41
+ * @param {ShadedGeometry} sg
42
+ * @returns {InstancedMeshGroup}
43
+ * @private
44
+ */
45
+ __get_instanced_mesh(sg) {
46
+ let im = this.__instanced_meshes.get(sg);
47
+
48
+ if (im === undefined) {
49
+ im = new InstancedMeshGroup();
50
+ im.shrinkFactor = 0; // prevent shrinking as we're essentially rebuilding this geometry frame
51
+
52
+ im.setMaterial(sg.material);
53
+ im.setGeometry(sg.geometry);
54
+
55
+ im.mesh.castShadow = sg.getFlag(ShadedGeometryFlags.CastShadow);
56
+ im.mesh.receiveShadow = sg.getFlag(ShadedGeometryFlags.ReceiveShadow);
57
+
58
+ this.__instanced_meshes.set(sg, im);
59
+ }
60
+
61
+ return im;
62
+ }
63
+
64
+ add(sg) {
65
+ const mesh = this.__get_instanced_mesh(sg);
66
+
67
+ const index = mesh.count;
68
+
69
+ mesh.ensureCapacity(index + 1);
70
+
71
+ mesh.setTransformAt(index, sg.transform);
72
+
73
+ mesh.count++;
74
+
75
+ this.__active_meshes.add(mesh);
76
+ }
77
+
78
+ build_start() {
79
+ this.clear();
80
+ }
81
+
82
+ build_end() {
83
+
84
+ for (const activeMesh of this.__active_meshes) {
85
+ // force underlying geometry to update
86
+ activeMesh.setCount(activeMesh.getCount());
87
+ activeMesh.requestAttributeUpdate();
88
+
89
+ this.__objects[this.__object_count++] = activeMesh.mesh;
90
+ }
91
+
92
+ }
93
+
94
+ clear() {
95
+ super.clear();
96
+
97
+ for (const activeMesh of this.__active_meshes) {
98
+ activeMesh.setCount(0);
99
+ }
100
+
101
+ this.__active_meshes.clear();
102
+ }
103
+
104
+ dispose() {
105
+ // release GPU memory
106
+ this.__instanced_meshes.forEach((value, key) => {
107
+ value.dispose();
108
+ });
109
+ }
110
+ }
@@ -0,0 +1,98 @@
1
+ import { queryBinaryNode_FrustumIntersections_Data } from "../../../../../core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js";
2
+ import { AbstractRenderAdapter } from "./AbstractRenderAdapter.js";
3
+ import { InstancedRendererAdapter } from "./InstancedRendererAdapter.js";
4
+ import { GenericRendererAdapter } from "./GenericRendererAdapter.js";
5
+
6
+ /**
7
+ * 1 - collect visible meshes
8
+ * 2 - figure out how to render a given mesh
9
+ */
10
+ export class ShadedGeometryRendererContext {
11
+ constructor() {
12
+ /**
13
+ * @readonly
14
+ * @type {AbstractRenderAdapter[]}
15
+ */
16
+ this.adapters = [
17
+ new GenericRendererAdapter(),
18
+ new InstancedRendererAdapter()
19
+ ];
20
+ }
21
+
22
+ setAdapter(index, adapter) {
23
+ const existing = this.adapters[index];
24
+ if (existing !== undefined) {
25
+ // dispose of existing adapter
26
+ existing.dispose();
27
+ }
28
+
29
+ this.adapters[index] = adapter;
30
+ }
31
+
32
+ /**
33
+ *
34
+ * @param {THREE.Object3D[]} destination
35
+ * @param {number} destination_offset
36
+ * @param {CameraView} view
37
+ * @param {BinaryNode<ShadedGeometry>} bvh
38
+ */
39
+ collect(destination, destination_offset, view, bvh) {
40
+ const adapters = this.adapters;
41
+ const adapter_count = adapters.length;
42
+
43
+ let i = 0, j = 0;
44
+ for (; i < adapter_count; i++) {
45
+ const adapter = adapters[i];
46
+
47
+ adapter.build_start();
48
+ }
49
+
50
+
51
+ // get all meshes
52
+
53
+ const data = [];
54
+
55
+ const intersection_count = queryBinaryNode_FrustumIntersections_Data(data, 0, bvh, view.frustum);
56
+
57
+ for (i = 0; i < intersection_count; i++) {
58
+ /**
59
+ *
60
+ * @type {ShadedGeometry}
61
+ */
62
+ const sg = data[i];
63
+
64
+ const adapter = adapters[sg.draw_method];
65
+
66
+ adapter.add(sg);
67
+ }
68
+
69
+ let additions = 0;
70
+
71
+ for (i = 0; i < adapter_count; i++) {
72
+ const adapter = adapters[i];
73
+
74
+ adapter.build_end();
75
+
76
+ const adapter_object_count = adapter.object_count;
77
+
78
+ for (j = 0; j < adapter_object_count; j++) {
79
+ const object3D = adapter.objects[j];
80
+
81
+ destination[destination_offset + additions] = object3D;
82
+
83
+ additions++;
84
+ }
85
+
86
+ }
87
+
88
+ return additions;
89
+ }
90
+
91
+ dispose() {
92
+ for (const adapter of this.adapters) {
93
+ if (adapter !== undefined) {
94
+ adapter.dispose();
95
+ }
96
+ }
97
+ }
98
+ }
@@ -6,6 +6,7 @@ import { GLTFAssetLoader } from "../../../../asset/loaders/GLTFAssetLoader.js";
6
6
  import { three_object_to_entity_composition } from "../three_object_to_entity_composition.js";
7
7
  import { AttachmentSystem } from "../../../../ecs/attachment/AttachmentSystem.js";
8
8
  import { TransformAttachmentSystem } from "../../../../ecs/transform-attachment/TransformAttachmentSystem.js";
9
+ import { Camera } from "../../camera/Camera.js";
9
10
 
10
11
  const eh = new EngineHarness();
11
12
 
@@ -70,6 +71,10 @@ async function main(engine) {
70
71
  enableTerrain: false
71
72
  });
72
73
 
74
+ const camera = engine.entityManager.dataset.getAnyComponent(Camera);
75
+ camera.component.autoClip = false;
76
+ camera.component.object.far = 300;
77
+
73
78
  // a small delay to let background tasks finish, so we can get better performance reading later on
74
79
  timeout(20);
75
80
 
@@ -3,7 +3,7 @@ import { ShadedGeometrySystem } from "../ShadedGeometrySystem.js";
3
3
  import EntityBuilder from "../../../../ecs/EntityBuilder.js";
4
4
  import { Transform } from "../../../../ecs/transform/Transform.js";
5
5
  import { ShadedGeometry } from "../ShadedGeometry.js";
6
- import { BoxBufferGeometry, MeshBasicMaterial } from "three";
6
+ import { BoxBufferGeometry, MeshStandardMaterial } from "three";
7
7
  import { randomFloatBetween } from "../../../../../core/math/random/randomFloatBetween.js";
8
8
  import { seededRandom } from "../../../../../core/math/random/seededRandom.js";
9
9
  import ViewportPosition from "../../../../ecs/gui/position/ViewportPosition.js";
@@ -13,9 +13,15 @@ import { downloadAsFile } from "../../../../../core/binary/ByteArrayTools.js";
13
13
  import { convert_bvh_to_dot_format_string } from "../../../../../core/bvh2/visual/convert_bvh_to_dot_format_string.js";
14
14
  import ViewportPositionSystem from "../../../../ecs/gui/position/ViewportPositionSystem.js";
15
15
  import GUIElementSystem from "../../../../ecs/gui/GUIElementSystem.js";
16
+ import Vector3 from "../../../../../core/geom/Vector3.js";
17
+ import Quaternion from "../../../../../core/geom/Quaternion.js";
18
+ import { ShadedGeometryFlags } from "../ShadedGeometryFlags.js";
16
19
 
17
20
  const eh = new EngineHarness();
18
21
 
22
+ const DRAW_METHOD_PLAIN = 0;
23
+ const DRAW_METHOD_INSTANCED = 1;
24
+
19
25
  /**
20
26
  *
21
27
  * @param {Engine} engine
@@ -26,12 +32,18 @@ async function main(engine) {
26
32
 
27
33
  await em.addSystem(new ShadedGeometrySystem(engine));
28
34
 
29
- EngineHarness.buildBasics({ engine })
35
+ EngineHarness.buildBasics({
36
+ engine,
37
+ yaw: -0.8,
38
+ pitch: 1,
39
+ distance: 46,
40
+ focus: new Vector3(10, 0, 10)
41
+ });
30
42
 
31
43
 
32
44
  const ecd = em.dataset;
33
45
 
34
- const material = new MeshBasicMaterial({
46
+ const material = new MeshStandardMaterial({
35
47
  color: 0xFFFFFF
36
48
  });
37
49
 
@@ -45,6 +57,11 @@ async function main(engine) {
45
57
 
46
58
  for (let i = 0; i < 100000; i++) {
47
59
 
60
+ const sg = ShadedGeometry.from(geometry, material);
61
+
62
+ sg.draw_method = DRAW_METHOD_INSTANCED;
63
+ sg.clearFlag(ShadedGeometryFlags.CastShadow | ShadedGeometryFlags.ReceiveShadow);
64
+
48
65
  new EntityBuilder()
49
66
  .add(Transform.fromJSON({
50
67
  position: {
@@ -52,9 +69,10 @@ async function main(engine) {
52
69
  y: randomFloatBetween(random, 0, 10),
53
70
  z: randomFloatBetween(random, -50, 50)
54
71
  },
55
- scale: 0.01
72
+ rotation: Quaternion.random(random),
73
+ scale: 0.05
56
74
  }))
57
- .add(ShadedGeometry.from(geometry, material))
75
+ .add(sg)
58
76
  .build(ecd);
59
77
  }
60
78
 
@@ -12,24 +12,29 @@ export function three_object_to_entity_composition(root) {
12
12
 
13
13
  node.transform.fromMatrix4(root.matrix.elements);
14
14
 
15
- node.entity.add(new Transform());
15
+ const entity = node.entity;
16
+
17
+ entity.add(new Transform());
16
18
 
17
19
  if (root.isMesh) {
18
20
  if (root.isSkinnedMesh) {
19
21
  throw new Error(`Skinned meshes are not supported`);
20
22
  }
21
23
 
22
- node.entity.add(ShadedGeometry.from(root.geometry, root.material));
24
+ const sg = ShadedGeometry.from(root.geometry, root.material);
25
+ sg.draw_method = 1;
26
+
27
+ entity.add(sg);
23
28
  }
24
29
 
25
30
  const children = root.children;
26
31
  const child_count = children.length;
32
+
27
33
  for (let i = 0; i < child_count; i++) {
28
34
  const child = children[i];
29
35
 
30
36
  const child_node = three_object_to_entity_composition(child);
31
37
 
32
-
33
38
  node.addChild(child_node);
34
39
  }
35
40