@woosh/meep-engine 2.33.24 → 2.33.25

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 (74) hide show
  1. package/core/bvh2/binary/IndexedBinaryBVH.js +1 -1
  2. package/core/bvh2/traversal/ThreeClippingPlaneComputingBVHVisitor.js +5 -1
  3. package/core/bvh2/traversal/__detailed_box_volume_intersection.js +22 -5
  4. package/core/collection/array/binarySearchHighIndex.js +1 -1
  5. package/core/collection/array/copyArray.js +2 -2
  6. package/core/geom/3d/normal/hemioct/unit_hemioct.spec.js +1 -1
  7. package/core/geom/3d/shape/AbstractShape3D.js +9 -0
  8. package/core/geom/3d/shape/CompositeShape.js +188 -8
  9. package/core/geom/3d/shape/TransformedShape3D.js +58 -2
  10. package/core/geom/3d/shape/UnitCubeShape3D.js +11 -0
  11. package/core/geom/3d/shape/UnitSphereShape3D.js +8 -0
  12. package/core/geom/3d/shape/util/shape_to_visual_entity.js +159 -0
  13. package/core/geom/random/randomPointInSphere.js +3 -2
  14. package/core/json/resolvePathByArray.js +2 -2
  15. package/{engine/graphics/render/forward_plus/materials → core/primitives/strings}/insert_after.js +3 -0
  16. package/core/primitives/strings/insert_after_or_replace.js +27 -0
  17. package/editor/process/symbolic/makeHelperBoxGeometry.js +44 -0
  18. package/editor/view/ecs/EntityEditor.js +2 -2
  19. package/editor/view/ecs/components/particles/ParticleEmitterController.js +2 -2
  20. package/engine/EngineHarness.js +1 -0
  21. package/engine/animation/AnimationUtils.js +5 -5
  22. package/engine/ecs/EntityBuilder.js +25 -5
  23. package/engine/ecs/attachment/AttachmentBinding.js +8 -0
  24. package/engine/ecs/attachment/AttachmentSystem.js +4 -0
  25. package/engine/ecs/attachment/TransformAttachmentBinding.js +14 -44
  26. package/engine/ecs/components/Tag.js +27 -6
  27. package/engine/ecs/fow/FogOfWar.js +4 -0
  28. package/engine/ecs/fow/FogOfWarSystem.js +2 -0
  29. package/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +2 -0
  30. package/engine/ecs/system/AbstractContextSystem.js +1 -1
  31. package/engine/ecs/systems/TagSystem.js +17 -0
  32. package/engine/ecs/transform/Transform.js +19 -6
  33. package/engine/graphics/GraphicsEngine.js +11 -6
  34. package/engine/graphics/composit/CompositLayer.js +17 -4
  35. package/engine/graphics/composit/CompositingStages.js +8 -0
  36. package/engine/graphics/composit/LayerCompositer.js +35 -6
  37. package/engine/graphics/ecs/highlight/plugin/OutlineRenderPlugin.js +11 -7
  38. package/engine/graphics/ecs/light/Light.js +2 -0
  39. package/engine/graphics/ecs/light/binding/three/ThreeLightBinding.js +5 -1
  40. package/engine/graphics/ecs/mesh-v2/DrawMode.js +5 -0
  41. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +32 -18
  42. package/engine/graphics/particles/ParticleEmitterLibrary.js +3 -0
  43. package/engine/graphics/particles/ecs/{ParticleEmitterSystem2.js → ParticleEmitterSystem.js} +17 -9
  44. package/engine/graphics/particles/particular/engine/ParticularEngine.js +8 -2
  45. package/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +14 -25
  46. package/engine/graphics/particles/particular/engine/emitter/ParticleEmitterFlag.js +5 -0
  47. package/engine/graphics/particles/particular/engine/emitter/ParticlePool.js +90 -2
  48. package/engine/graphics/particles/particular/engine/emitter/ParticlePool.spec.js +7 -7
  49. package/engine/graphics/particles/particular/engine/renderers/billboard/BILLBOARD_PARTICLE_SPECIFICATION.js +15 -12
  50. package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +262 -51
  51. package/engine/graphics/particles/particular/engine/shader/ShaderManager.js +80 -46
  52. package/engine/graphics/particles/particular/engine/shader/debugAtlas.js +14 -0
  53. package/engine/graphics/particles/particular/engine/utils/volume/AttributeValue.js +141 -0
  54. package/engine/graphics/particles/particular/engine/utils/volume/ParticleVolume.js +148 -54
  55. package/engine/graphics/particles/particular/engine/utils/volume/lut_to_sampler.js +27 -0
  56. package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +542 -165
  57. package/engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js +12 -6
  58. package/engine/graphics/render/forward_plus/materials/FP_INJECTION_POINT_ACCUMULATION.js +1 -0
  59. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_ACCUMULATION.js +32 -0
  60. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_DECODE_PARS.js +51 -0
  61. package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_PREAMBLE.js +25 -0
  62. package/engine/graphics/render/forward_plus/materials/fp_build_fragment_shader.js +31 -120
  63. package/engine/graphics/render/forward_plus/materials/fp_build_vertex_lighting_shared.js +35 -0
  64. package/engine/graphics/render/forward_plus/materials/fp_build_vertex_shader.js +4 -5
  65. package/engine/graphics/render/forward_plus/plugin/MaterialTransformer.js +10 -3
  66. package/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +588 -53
  67. package/engine/graphics/render/forward_plus/prototypeLightManager.js +29 -4
  68. package/engine/graphics/shaders/TerrainShader.js +4 -5
  69. package/engine/graphics/util/composeMatrix4.js +33 -23
  70. package/engine/graphics/util/decompose_matrix_4_array.js +61 -0
  71. package/engine/intelligence/behavior/ecs/BehaviorComponent.js +30 -14
  72. package/engine/knowledge/database/StaticKnowledgeDataTable.js +6 -1
  73. package/engine/navigation/ecs/components/Path.js +0 -5
  74. package/package.json +1 -1
@@ -2,47 +2,29 @@ import { EngineHarness } from "../../../../../../EngineHarness.js";
2
2
  import { EngineConfiguration } from "../../../../../../EngineConfiguration.js";
3
3
  import GUIElementSystem from "../../../../../../ecs/gui/GUIElementSystem.js";
4
4
  import HeadsUpDisplaySystem from "../../../../../../ecs/gui/hud/HeadsUpDisplaySystem.js";
5
- import ScriptSystem from "../../../../../../ecs/systems/ScriptSystem.js";
6
- import FacingDirectionSystem from "../../../../../../../../model/game/ecs/system/FacingDirectionSystem.js";
7
- import PathFollowingSystem from "../../../../../../navigation/ecs/path_following/PathFollowingSystem.js";
8
- import SteeringSystem from "../../../../../../ecs/systems/SteeringSystem.js";
9
- import MotionSystem from "../../../../../../ecs/systems/MotionSystem.js";
10
5
  import TagSystem from "../../../../../../ecs/systems/TagSystem.js";
11
6
  import { AttachmentSocketsSystem } from "../../../../../../ecs/sockets/AttachmentSocketsSystem.js";
12
7
  import { AttachmentSystem } from "../../../../../../ecs/attachment/AttachmentSystem.js";
13
8
  import { SoundEmitterSystem } from "../../../../../../sound/ecs/emitter/SoundEmitterSystem.js";
14
9
  import SoundControllerSystem from "../../../../../../sound/ecs/SoundControllerSystem.js";
15
10
  import SoundListenerSystem from "../../../../../../sound/ecs/SoundListenerSystem.js";
16
- import TimerSystem from "../../../../../../ecs/systems/TimerSystem.js";
17
11
  import AnimationSystem from "../../../../../../ecs/systems/AnimationSystem.js";
18
12
  import TopDownCameraControllerSystem from "../../../../../ecs/camera/topdown/TopDownCameraControllerSystem.js";
19
- import { TopDownCameraLanderSystem } from "../../../../../ecs/camera/topdown/TopDownCameraLanderSystem.js";
20
13
  import { CameraSystem } from "../../../../../ecs/camera/CameraSystem.js";
21
14
  import { MeshSystem } from "../../../../../ecs/mesh/MeshSystem.js";
22
15
  import ClingToTerrainSystem from "../../../../../../ecs/terrain/ecs/ClingToTerrainSystem.js";
23
16
  import TerrainSystem from "../../../../../../ecs/terrain/ecs/TerrainSystem.js";
24
- import WaterSystem from "../../../../../ecs/water/WaterSystem.js";
25
17
  import Trail2DSystem from "../../../../../ecs/trail2d/Trail2DSystem.js";
26
18
  import { Foliage2System } from "../../../../../../ecs/foliage/ecs/Foliage2System.js";
27
19
  import ViewportPositionSystem from "../../../../../../ecs/gui/position/ViewportPositionSystem.js";
28
- import { GridPosition2TransformSystem } from "../../../../../../grid/systems/GridPosition2TransformSystem.js";
29
- import { Transform2GridPositionSystem } from "../../../../../../grid/transform2grid/Transform2GridPositionSystem.js";
30
20
  import SynchronizePositionSystem from "../../../../../../ecs/systems/SynchronizePositionSystem.js";
31
- import GridObstacleSystem from "../../../../../../grid/systems/GridObstacleSystem.js";
32
- import GridPositionSystem from "../../../../../../grid/systems/GridPositionSystem.js";
33
21
  import InputControllerSystem from "../../../../../../input/ecs/systems/InputControllerSystem.js";
34
22
  import { InputSystem } from "../../../../../../input/ecs/systems/InputSystem.js";
35
23
  import MeshHighlightSystem from "../../../../../ecs/highlight/system/MeshHighlightSystem.js";
36
24
  import LightSystem from "../../../../../ecs/light/LightSystem.js";
37
- import AnimationControllerSystem from "../../../../../ecs/animation/AnimationControllerSystem.js";
38
- import { AnimationGraphSystem } from "../../../../../ecs/animation/animator/AnimationGraphSystem.js";
39
- import { FogOfWarSystem } from "../../../../../../ecs/fow/FogOfWarSystem.js";
40
- import { FogOfWarRevealerSystem } from "../../../../../../ecs/fow/FogOfWarRevealerSystem.js";
41
25
  import { BehaviorSystem } from "../../../../../../intelligence/behavior/ecs/BehaviorSystem.js";
42
26
  import { SerializationMetadataSystem } from "../../../../../../ecs/systems/SerializationMetadataSystem.js";
43
- import { InverseKinematicsSystem } from "../../../../../../ecs/animation/InverseKinematicsSystem.js";
44
27
  import { PathDisplaySystem } from "../../../../../ecs/path/PathDisplaySystem.js";
45
- import { MicronRenderPlugin } from "../../../../../micron/plugin/MicronRenderPlugin.js";
46
28
  import RenderSystem from "../../../../../../ecs/systems/RenderSystem.js";
47
29
  import { makeEngineOptionsModel } from "../../../../../../../../model/game/options/makeEngineOptionsModel.js";
48
30
  import { enableEditor } from "../../../../../../../editor/enableEditor.js";
@@ -55,7 +37,7 @@ import { Transform } from "../../../../../../ecs/transform/Transform.js";
55
37
  import Mesh from "../../../../../ecs/mesh/Mesh.js";
56
38
  import { AABB3 } from "../../../../../../../core/bvh2/aabb3/AABB3.js";
57
39
  import { ParticleVolume } from "./ParticleVolume.js";
58
- import { ParticleEmitterSystem2 } from "../../../../ecs/ParticleEmitterSystem2.js";
40
+ import { ParticleEmitterSystem } from "../../../../ecs/ParticleEmitterSystem.js";
59
41
  import { BehaviorComponent } from "../../../../../../intelligence/behavior/ecs/BehaviorComponent.js";
60
42
  import { RepeatBehavior } from "../../../../../../intelligence/behavior/decorator/RepeatBehavior.js";
61
43
  import { ActionBehavior } from "../../../../../../intelligence/behavior/primitive/ActionBehavior.js";
@@ -67,11 +49,34 @@ import GUIElement from "../../../../../../ecs/gui/GUIElement.js";
67
49
  import EmptyView from "../../../../../../../view/elements/EmptyView.js";
68
50
  import HeadsUpDisplay from "../../../../../../ecs/gui/hud/HeadsUpDisplay.js";
69
51
  import ViewportPosition from "../../../../../../ecs/gui/position/ViewportPosition.js";
70
- import { Sampler2D } from "../../../../../texture/sampler/Sampler2D.js";
71
52
  import { CanvasView } from "../../../../../../../view/elements/CanvasView.js";
72
53
  import convertSampler2D2Canvas from "../../../../../texture/sampler/Sampler2D2Canvas.js";
73
54
  import Vector1 from "../../../../../../../core/geom/Vector1.js";
74
55
  import { clamp } from "../../../../../../../core/math/clamp.js";
56
+ import { UnitCubeShape3D } from "../../../../../../../core/geom/3d/shape/UnitCubeShape3D.js";
57
+ import { ShadedGeometrySystem } from "../../../../../ecs/mesh-v2/ShadedGeometrySystem.js";
58
+ import { lut_to_sampler } from "./lut_to_sampler.js";
59
+ import {
60
+ shape_to_visual_entity,
61
+ SHAPE_VISUAL_ENTITY_TAG
62
+ } from "../../../../../../../core/geom/3d/shape/util/shape_to_visual_entity.js";
63
+ import { seededRandom } from "../../../../../../../core/math/random/seededRandom.js";
64
+ import { TransformedShape3D } from "../../../../../../../core/geom/3d/shape/TransformedShape3D.js";
65
+ import { mat4 } from "gl-matrix";
66
+ import { CompositeShape3D } from "../../../../../../../core/geom/3d/shape/CompositeShape.js";
67
+ import { ShadedGeometry } from "../../../../../ecs/mesh-v2/ShadedGeometry.js";
68
+ import { DrawMode } from "../../../../../ecs/mesh-v2/DrawMode.js";
69
+ import { makeHelperBoxGeometry } from "../../../../../../../editor/process/symbolic/makeHelperBoxGeometry.js";
70
+ import { LineBasicMaterial } from "three";
71
+ import Renderable from "../../../../../../ecs/components/Renderable.js";
72
+ import { TransformControls } from "three/examples/jsm/controls/TransformControls.js";
73
+ import { threeUpdateTransform } from "../../../../../util/threeUpdateTransform.js";
74
+ import InputController from "../../../../../../input/ecs/components/InputController.js";
75
+ import { computeStatisticalMean } from "../../../../../../../core/math/statistics/computeStatisticalMean.js";
76
+ import ButtonView from "../../../../../../../view/elements/button/ButtonView.js";
77
+ import { UnitSphereShape3D } from "../../../../../../../core/geom/3d/shape/UnitSphereShape3D.js";
78
+ import TopDownCameraController from "../../../../../ecs/camera/topdown/TopDownCameraController.js";
79
+ import { randomFloatBetween } from "../../../../../../../core/math/random/randomFloatBetween.js";
75
80
 
76
81
  const engineHarness = new EngineHarness();
77
82
 
@@ -92,55 +97,40 @@ function makeConfig(engine) {
92
97
  const headsUpDisplaySystem = new HeadsUpDisplaySystem(graphics);
93
98
 
94
99
  config.systems.push(
95
- new ScriptSystem(),
96
- new FacingDirectionSystem(),
97
- new PathFollowingSystem(),
98
- new SteeringSystem(),
99
- new MotionSystem(),
100
100
  new TagSystem(),
101
101
  new AttachmentSocketsSystem(),
102
102
  new AttachmentSystem(),
103
103
  new SoundEmitterSystem(assetManager, sound.destination, sound.context),
104
104
  new SoundControllerSystem(),
105
105
  new SoundListenerSystem(sound.context),
106
- new TimerSystem(),
107
106
  guiSystem,
108
107
  new AnimationSystem(graphics.viewport.size),
109
108
  new TopDownCameraControllerSystem(graphics),
110
- new TopDownCameraLanderSystem(),
111
109
  new CameraSystem(graphics.scene, graphics),
112
110
  new MeshSystem(engine),
113
111
  new ClingToTerrainSystem(),
114
112
  new TerrainSystem(graphics, assetManager),
115
- new WaterSystem(graphics),
116
113
  new Trail2DSystem(engine),
117
114
  new Foliage2System(assetManager, graphics),
118
115
  new ViewportPositionSystem(graphics.viewport.size),
119
- new GridPosition2TransformSystem(),
120
- new Transform2GridPositionSystem(),
121
116
  new SynchronizePositionSystem(),
122
- new GridObstacleSystem(),
123
- new GridPositionSystem(),
124
117
  new InputControllerSystem(devices),
125
118
  new InputSystem(devices),
126
119
  new MeshHighlightSystem(engine),
127
120
  new LightSystem(engine, {
128
121
  shadowResolution: 2048
129
122
  }),
130
- new AnimationControllerSystem(),
131
- new AnimationGraphSystem(graphics.viewport.size),
132
123
  headsUpDisplaySystem,
133
- new FogOfWarSystem(graphics),
134
- new FogOfWarRevealerSystem(0),
135
124
  new BehaviorSystem(engine),
136
125
  new SerializationMetadataSystem(),
137
- new InverseKinematicsSystem(),
138
126
  new PathDisplaySystem(engine),
127
+ new ParticleEmitterSystem(engine),
128
+ new ShadedGeometrySystem(engine)
139
129
  );
140
130
 
141
131
 
142
132
  // Plugins
143
- config.addPlugin(MicronRenderPlugin);
133
+ // config.addPlugin(MicronRenderPlugin);
144
134
 
145
135
 
146
136
  // Knowledge
@@ -186,19 +176,19 @@ heatmap_lut_0.write([
186
176
  ]);
187
177
  heatmap_lut_0.computeUniformPositions();
188
178
 
189
- const heatmap_lut_1 = new ParameterLookupTable(4);
190
- heatmap_lut_1.write([
179
+ const heatmap_lut_orange_to_red = new ParameterLookupTable(4);
180
+ heatmap_lut_orange_to_red.write([
191
181
  255, 127, 0, 100,
192
182
  206, 2, 86, 100
193
183
  ]);
194
- heatmap_lut_1.computeUniformPositions();
184
+ heatmap_lut_orange_to_red.computeUniformPositions();
195
185
 
196
- const heatmap_lut_2 = new ParameterLookupTable(4);
197
- heatmap_lut_2.write([
186
+ const heatmap_lut_pink_to_blue = new ParameterLookupTable(4);
187
+ heatmap_lut_pink_to_blue.write([
198
188
  255, 151, 213, 50,
199
189
  2, 243, 255, 50
200
190
  ]);
201
- heatmap_lut_2.computeUniformPositions();
191
+ heatmap_lut_pink_to_blue.computeUniformPositions();
202
192
 
203
193
  const heatmap_lut_3 = new ParameterLookupTable(4);
204
194
  heatmap_lut_3.write(
@@ -220,75 +210,113 @@ heatmap_lut_3.write(
220
210
  ]
221
211
  );
222
212
 
213
+
223
214
  /**
224
215
  *
225
216
  * @param {Engine} engine
226
217
  */
227
- async function main(engine) {
228
- EngineHarness.buildBasics({
229
- engine,
230
- enableWater: false,
231
- // enableTerrain: false,
232
- enableTerrain: true,
233
- terrainSize: new Vector2(100, 100),
234
- focus: new Vector3(102, 0, 61),
235
- // pitch: -0.5,
236
- // yaw: 2.2,
237
- // distance: 3
238
- pitch: 0.9,
239
- yaw: 3.1,
240
- distance: 20
241
- });
218
+ function make_shape_vis_toggle(engine) {
219
+ const ecd = engine.entityManager.dataset;
220
+ const entities = TagSystem.find_entities_with_tag(SHAPE_VISUAL_ENTITY_TAG, ecd);
242
221
 
243
222
 
244
- engine.graphics.renderer.setClearColor('rgba(99,99,99,1)');
223
+ const builders = entities.map(e => EntityBuilder.readFromDataset(e, ecd));
245
224
 
225
+ function toggle() {
226
+ if (builders.length <= 1) {
227
+ return;
228
+ }
246
229
 
247
- const ecd = engine.entityManager.dataset;
230
+ if (builders[0].isBuilt) {
231
+ builders.forEach(b => b.destroy());
232
+ } else {
233
+ builders.forEach(b => b.build(ecd));
234
+ }
235
+ }
236
+
237
+ const buttonView = new ButtonView({
238
+ action: toggle,
239
+ name: 'Toggle Shapes',
240
+ css: {
241
+ position: 'absolute',
242
+ bottom: '10px',
243
+ right: '10px',
244
+ background: 'rgba(255,255,255,0.8)',
245
+ border: '1px solid rgba(0,0,0,1)',
246
+ padding: '2px'
247
+ }
248
+ });
248
249
 
249
250
  new EntityBuilder()
250
- .add(Transform.fromJSON({
251
- position: {
252
- x: 20,
253
- y: -5.8,
254
- z: 100
255
- },
256
- scale: {
257
- x: 1,
258
- y: 1,
259
- z: 1
260
- }
261
- }))
262
- .add(Mesh.fromJSON({
263
- url: 'data/models/moicon/05-ground-floor/model.gltf',
264
- castShadow: true,
265
- receiveShadow: true
266
- }))
267
- // .build(ecd);
268
- new EntityBuilder()
269
- .add(Transform.fromJSON({
270
- position: {
271
- x: 20,
272
- y: -5.8,
273
- z: 100
274
- },
275
- scale: {
276
- x: 1,
277
- y: 1,
278
- z: 1
279
- }
280
- }))
251
+ .add(GUIElement.fromView(buttonView))
252
+ .build(ecd);
253
+
254
+ return {
255
+ toggle
256
+ };
257
+ }
258
+
259
+ function mat_from_aabb3(aabb3) {
260
+ const m4 = mat4.create();
261
+
262
+ mat4.fromRotationTranslationScale(m4, [0, 0, 0, 1], [(aabb3.x0 + aabb3.x1) / 2, (aabb3.y0 + aabb3.y1) / 2, (aabb3.z0 + aabb3.z1) / 2], [aabb3.getExtentsX(), aabb3.getExtentsY(), aabb3.getExtentsZ()]);
263
+
264
+ return m4;
265
+ }
266
+
267
+ /**
268
+ *
269
+ * @param {string} url
270
+ * @param {EntityComponentDataset} ecd
271
+ * @returns {EntityBuilder}
272
+ */
273
+ function load_model(url, ecd) {
274
+
275
+ const b = new EntityBuilder();
276
+ b
277
+ .add(new Transform())
281
278
  .add(Mesh.fromJSON({
282
- url: 'data/models/moicon/08-clickable-assets/model.gltf',
279
+ url: url,
283
280
  castShadow: true,
284
281
  receiveShadow: true
285
282
  }))
286
- // .build(ecd);
283
+ .build(ecd);
284
+
285
+ return b;
286
+ }
287
+
288
+ /**
289
+ *
290
+ * @param {Engine} engine
291
+ * @returns {Promise<void>}
292
+ */
293
+ async function sample_scene_0(engine) {
294
+ const ecd = engine.entityManager.dataset;
295
+
296
+ function load_model_s(url, y_offset = 0) {
297
+ const b = load_model(url, ecd);
298
+ b.getComponent(Transform).position.set(
299
+ 20,
300
+ -5.8 + y_offset,
301
+ 100
302
+ );
303
+
304
+ return b;
305
+ }
306
+
307
+ // load_model('moicon/06_04_hapro/00-environment/model.gltf', -0.1);
308
+ load_model_s('moicon/06_04_hapro/05-ground-floor/model.gltf');
309
+ // load_model('moicon/06_04_hapro/02-bearers/model.gltf');
310
+ // load_model('moicon/06_04_hapro/04-1st-floor/model.gltf');
311
+
287
312
 
288
313
  await make_demo_volume({
289
314
  ecd: ecd,
290
315
  lut: heatmap_lut_0,
291
- bounds: new AABB3(67.73, 0, 89, 115.84, 3, 118.34),
316
+ shape: CompositeShape3D.from([
317
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), mat_from_aabb3(new AABB3(67.73, 0, 89, 115.84, 3, 118.34))),
318
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), mat_from_aabb3(new AABB3(98, 0, 76.5, 109.5, 3, 89)))
319
+ ]),
292
320
  particle_size: 4,
293
321
  density: 4,
294
322
  period: 10
@@ -297,7 +325,11 @@ async function main(engine) {
297
325
  await make_demo_volume({
298
326
  ecd: ecd,
299
327
  lut: heatmap_lut_0,
300
- bounds: new AABB3(43.8, 0, 89, 67.40, 3, 131),
328
+ shape: CompositeShape3D.from([
329
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [14.980091485108495, 0, 0, 0, 0, 2.812495250139616, 0, 0, 0, 0, 7.469446746375293, 0, 54.83080514238756, 1.568241402881399, 92.51937192481576, 1]),
330
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [6.644515553810907, 0, 0, 0, 0, 2.812495250139616, 0, 0, 0, 0, 5.507507223409315, 0, 46.95032009188344, 1.568241402881399, 95.54148649329517, 1]),
331
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [23.762890107594952, 0, 0, 0, 0, 2.812495250139616, 0, 0, 0, 0, 34.57956316503163, 0, 55.436098243647756, 1.568241402881399, 113.46988143189215, 1])
332
+ ]),
301
333
  particle_size: 2,
302
334
  density: 1,
303
335
  period: 10,
@@ -306,8 +338,8 @@ async function main(engine) {
306
338
 
307
339
  await make_demo_volume({
308
340
  ecd: ecd,
309
- lut: heatmap_lut_1,
310
- bounds: new AABB3(97.68, 0, 67.71, 115.76, 3, 76.14),
341
+ lut: heatmap_lut_orange_to_red,
342
+ shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), mat_from_aabb3(new AABB3(97.68, 0, 67.71, 115.76, 3, 76.14))),
311
343
  particle_size: 1,
312
344
  density: 1.2,
313
345
  period: 7,
@@ -316,121 +348,436 @@ async function main(engine) {
316
348
 
317
349
  await make_demo_volume({
318
350
  ecd: ecd,
319
- lut: heatmap_lut_2,
320
- bounds: new AABB3(79.0, 0, 67.71, 97.35, 3, 76.14),
351
+ lut: heatmap_lut_pink_to_blue,
352
+ shape: CompositeShape3D.from([
353
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [15.218520811592711, 0, 0, 0, 0, 3.058639690434693, 0, 0, 0, 0, 5.828701399328644, 0, 89.53848861962253, 2.0721850959505907, 73.05504876489894, 1]),
354
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [18.10977091153633, 0, 0, 0, 0, 3.058639690434693, 0, 0, 0, 0, 2.5862076050328002, 0, 88.03260126722904, 2.0721850959505907, 69.0797462656922, 1])
355
+ ]),
321
356
  particle_size: 4,
322
357
  density: 4,
323
358
  period: 7,
324
359
  period_offset: 2,
325
360
  });
326
361
 
362
+ // large open room, dense particles
327
363
  await make_demo_volume({
328
364
  ecd: ecd,
329
365
  lut: heatmap_lut_3,
330
- bounds: new AABB3(67.85, 0, 31.1, 109.8, 3, 67.02),
331
- particle_size: 0.1,
366
+ shape: CompositeShape3D.from([
367
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [20.977896627021547, 0, 0, 0, 0, 2.956899734575006, 0, 0, 0, 0, 36.201589869571954, 0, 99.2120028317975, 1.5919924971428276, 49.21655402009093, 1]),
368
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [24.455615450514458, 0, 0, 0, 0, 2.956899734575006, 0, 0, 0, 0, 28.081536987027807, 0, 80.11618755300161, 1.5919924971428276, 45.13808745329574, 1]),
369
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [5.562874425497998, 0, 0, 0, 0, 2.956899734575006, 0, 0, 0, 0, 2.654155224548708, 0, 70.80986716000054, 1.5919924971428276, 59.679876796143446, 1])
370
+ ]),
371
+ particle_size: 0.15,
332
372
  density: 5,
333
373
  period: 7,
334
374
  period_offset: 2,
335
375
  });
336
376
 
377
+ // popsicle
378
+ await make_demo_volume({
379
+ ecd: ecd,
380
+ lut: heatmap_lut_orange_to_red,
381
+ shape: CompositeShape3D.from([
382
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [-3.8971594611231577, -1.9562533614625899, -0.5725042419276598, 0, -8.346390838999248, 16.986127440019352, -1.226109479938015, 0, 0.12112312197093604, 0, -0.8245111322851176, 0, 55.83305788880312, 9.579537179233043, 83.59013920067233, 1]),
383
+ TransformedShape3D.from_m4(new UnitSphereShape3D(), [10.237283879346698, 0, 0, 0, 0, 10.237283879346698, 0, 0, 0, 0, 10.237283879346698, 0, 51.783732965076716, 18.028888481196716, 82.91084586075068, 1])
384
+ ]),
385
+ particle_size: 0.7,
386
+ density: 5,
387
+ period: 3,
388
+ period_offset: 2,
389
+ sort: true
390
+ });
391
+
337
392
  engine.devices.pointer.on.down.add((p) => {
338
393
  pick(p.x, p.y, engine.graphics, obtainTerrain(ecd), (grid_position, position, normal) => {
339
394
  console.log(position.toJSON());
340
395
  });
341
396
  });
397
+
398
+ make_shape_vis_toggle(engine).toggle(); // turn off shape vis initially
399
+
400
+ // editing box
401
+ make_box_editor(engine, Transform.fromJSON({
402
+ position: {
403
+ x: 20,
404
+ y: 5,
405
+ z: 100
406
+ },
407
+ scale: {
408
+ x: 1,
409
+ y: 1,
410
+ z: 1
411
+ }
412
+ }));
342
413
  }
343
414
 
415
+
344
416
  /**
345
417
  *
346
- * @param {ParameterLookupTable} lut
347
- * @param {number} width
348
- * @param {number} height
349
- * @returns {Sampler2D}
418
+ * @param {Engine} engine
419
+ * @returns {Promise<void>}
350
420
  */
351
- function lut_to_sampler(lut, width, height) {
352
- const sampler = Sampler2D.uint8(4, width, height);
421
+ async function sample_scene_nam(engine) {
422
+ const ecd = engine.entityManager.dataset;
353
423
 
354
- const s = [];
424
+ ecd.getAnyComponent(TopDownCameraController).component.fromJSON({
425
+ "target": {
426
+ "x": 21.09522080045099,
427
+ "y": -0.6327784109623013,
428
+ "z": 6.138907038731565
429
+ },
430
+ "pitch": 1.1099999999999923,
431
+ "yaw": -3.143185307179591,
432
+ "roll": 0,
433
+ "distance": 29,
434
+ "distanceMin": 0,
435
+ "distanceMax": 1000
436
+ });
355
437
 
356
- for (let i = 0; i < width; i++) {
438
+ load_model('moicon/20_Dec_2021_Nammo/with_assets(for_alex)/model.gltf', ecd)
357
439
 
358
- lut.sample(i / (width - 1), s);
359
- s[3] = 255;
440
+ const P_SIZE_SMALL = 0.15;
441
+ const P_SIZE_MEDIUM = 0.6;
442
+ const P_SIZE_LARGE = 2;
360
443
 
361
- for (let j = 0; j < height; j++) {
362
- sampler.set(i, j, s);
363
- }
444
+ const random = seededRandom(42);
364
445
 
365
- }
446
+ const PERIOD_LONG = 13;
447
+
448
+ await make_demo_volume({
449
+ ecd: ecd,
450
+ lut: heatmap_lut_pink_to_blue,
451
+ shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [5.267098043281134, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 6.606365126660234, 0, 2.8037239954452864, 1.4169994923726943, 11.460158766988037, 1]),
452
+ particle_size: P_SIZE_MEDIUM,
453
+ density: 3,
454
+ period: PERIOD_LONG,
455
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
456
+ sprite: 'data/textures/particle/UETools/Hexagon_01.png'
457
+ });
458
+ await make_demo_volume({
459
+ ecd: ecd,
460
+ lut: heatmap_lut_orange_to_red,
461
+ shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [4.7577406314060395, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 6.606365126660234, 0, 8.075207307031247, 1.4169994923726943, 11.460158766988037, 1]),
462
+ particle_size: P_SIZE_MEDIUM,
463
+ density: 3,
464
+ period: PERIOD_LONG,
465
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
466
+ sprite: 'data/textures/particle/UETools/Circle_04.png'
467
+ });
468
+
469
+ await make_demo_volume({
470
+ ecd: ecd,
471
+ lut: heatmap_lut_pink_to_blue,
472
+ shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [6.956797095914032, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 6.606365126660234, 0, 14.17733466985805, 1.4169994923726943, 11.460158766988037, 1]),
473
+ particle_size: P_SIZE_MEDIUM,
474
+ density: 3,
475
+ period: PERIOD_LONG,
476
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
477
+ sprite: 'data/textures/particle/travnik/plus_2.png'
478
+ });
479
+
480
+ await make_demo_volume({
481
+ ecd: ecd,
482
+ lut: heatmap_lut_pink_to_blue,
483
+ shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [4.733772190018377, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 6.606365126660234, 0, 20.284613387782148, 1.4169994923726943, 11.460158766988037, 1]),
484
+ particle_size: P_SIZE_MEDIUM,
485
+ density: 3,
486
+ period: PERIOD_LONG,
487
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
488
+ sprite: 'data/textures/particle/UETools/Circle_04.png'
489
+ });
366
490
 
367
- return sampler;
491
+ await make_demo_volume({
492
+ ecd: ecd,
493
+ lut: heatmap_lut_pink_to_blue,
494
+ shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [5.924905976332568, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 6.606365126660234, 0, 31.662442543335885, 1.4169994923726943, 11.460158766988037, 1]),
495
+ particle_size: P_SIZE_MEDIUM,
496
+ density: 3,
497
+ period: PERIOD_LONG,
498
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
499
+ sprite: 'data/textures/particle/UETools/Circle_04.png'
500
+ });
501
+
502
+ await make_demo_volume({
503
+ ecd: ecd,
504
+ lut: heatmap_lut_0,
505
+ shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [5.7305058801925, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 6.606365126660234, 0, 37.70942297505848, 1.4169994923726943, 11.460158766988037, 1]),
506
+ particle_size: P_SIZE_MEDIUM,
507
+ density: 8,
508
+ period: PERIOD_LONG,
509
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
510
+ sprite: 'data/textures/particle/UETools/Circle_04.png'
511
+ });
512
+ await make_demo_volume({
513
+ ecd: ecd,
514
+ lut: heatmap_lut_0,
515
+ shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [6.575632395877399, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 4.51714948412602, 0, 37.272800538855826, 1.4169994923726943, 2.4066558057134095, 1]),
516
+ particle_size: P_SIZE_MEDIUM,
517
+ density: 8,
518
+ period: PERIOD_LONG,
519
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
520
+ sprite: 'data/textures/particle/UETools/Circle_04.png'
521
+ });
522
+
523
+ await make_demo_volume({
524
+ ecd: ecd,
525
+ lut: heatmap_lut_0,
526
+ shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [6.410614101275306, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 4.51714948412602, 0, 30.458756650580582, 1.4169994923726943, 2.4066558057134095, 1]),
527
+ particle_size: P_SIZE_MEDIUM,
528
+ density: 8,
529
+ period: PERIOD_LONG,
530
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
531
+ sprite: 'data/textures/particle/UETools/Circle_04.png'
532
+ });
533
+
534
+ await make_demo_volume({
535
+ ecd: ecd,
536
+ lut: heatmap_lut_3,
537
+ shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [4.260857135913424, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 4.51714948412602, 0, 24.82865688356064, 1.4169994923726943, 2.4066558057134095, 1]),
538
+ particle_size: P_SIZE_SMALL,
539
+ density: 3,
540
+ period: PERIOD_LONG,
541
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
542
+ sprite: 'data/textures/particle/UETools/Circle_01.png'
543
+ });
544
+
545
+ await make_demo_volume({
546
+ ecd: ecd,
547
+ lut: heatmap_lut_3,
548
+ shape: TransformedShape3D.from_m4(new UnitCubeShape3D(), [4.870266350649175, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 4.51714948412602, 0, 20.022408905267525, 1.4169994923726943, 2.4066558057134095, 1]),
549
+ particle_size: P_SIZE_SMALL,
550
+ density: 3,
551
+ period: PERIOD_LONG,
552
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
553
+ sprite: 'data/textures/particle/UETools/Cross_04.png'
554
+ });
555
+ await make_demo_volume({
556
+ ecd: ecd,
557
+ lut: heatmap_lut_pink_to_blue,
558
+ shape: CompositeShape3D.from([
559
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [5.985827128973811, 0, 0, 0, 0, 2.435269776236539, 0, 0, 0, 0, 4.669621139110231, 0, 11.08356834576874, 1.2643565739307023, 2.4360416869081885, 1]),
560
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [8.413758403821523, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 7.775469675813772, 0, 4.313201108449287, 1.4169994923726943, 4.011630095541064, 1]),
561
+ TransformedShape3D.from_m4(new UnitCubeShape3D(), [8.413758403821523, 0, 0, 0, 0, 2.3166487265965343, 0, 0, 0, 0, 2.925065210015915, 0, 12.417224289491141, 1.4169994923726943, 6.432483110925785, 1])
562
+ ]),
563
+ particle_size: P_SIZE_LARGE,
564
+ density: 4,
565
+ period: PERIOD_LONG,
566
+ period_offset: randomFloatBetween(random, 0, PERIOD_LONG),
567
+ sprite: 'data/textures/particle/UETools/Circle_04.png'
568
+ });
569
+
570
+ make_shape_vis_toggle(engine).toggle(); // turn off shape vis initially
571
+
572
+ // editing box
573
+ // make_box_editor(engine, Transform.fromJSON({
574
+ // position: {
575
+ // x: -2,
576
+ // y: 5,
577
+ // z: 0
578
+ // },
579
+ // scale: {
580
+ // x: 1,
581
+ // y: 1,
582
+ // z: 1
583
+ // }
584
+ // }));
585
+ }
586
+
587
+ /**
588
+ *
589
+ * @param {Engine} engine
590
+ */
591
+ async function main(engine) {
592
+ EngineHarness.buildBasics({
593
+ engine,
594
+ enableWater: false,
595
+ enableTerrain: false,
596
+ // enableTerrain: true,
597
+ terrainSize: new Vector2(100, 100),
598
+ focus: new Vector3(102, 0, 61),
599
+ // pitch: -0.5,
600
+ // yaw: 2.2,
601
+ // distance: 3
602
+ pitch: 0.9,
603
+ yaw: 3.1,
604
+ distance: 20
605
+ });
606
+
607
+
608
+ engine.graphics.renderer.setClearColor('rgba(99,99,99,1)');
609
+
610
+ await sample_scene_nam(engine);
368
611
  }
369
612
 
370
- async function create_volume({
371
- bounds = new AABB3(0, 0, 0, 1, 1, 1),
372
- density = 10,
373
- particle_size = 1
374
- }) {
613
+ /**
614
+ *
615
+ * @param {Engine} engine
616
+ * @param {Transform} [transform]
617
+ */
618
+ function make_box_editor(engine, transform = new Transform()) {
619
+ const controls = new TransformControls(engine.graphics.camera, engine.graphics.domElement);
375
620
 
376
- const aabb_bounds = new AABB3();
377
- aabb_bounds.fromJSON(bounds);
621
+ const eb = new EntityBuilder();
622
+ const g_unit_cube = makeHelperBoxGeometry(1, 1, 1);
378
623
 
379
- const hs = particle_size / 4;
624
+ const ecd = engine.entityManager.dataset;
380
625
 
381
- aabb_bounds.x0 += hs;
382
- aabb_bounds.z0 += hs;
626
+ const lineMaterial = new LineBasicMaterial({
627
+ depthTest: true,
628
+ depthWrite: false,
629
+ transparent: true,
630
+ linewidth: 1,
631
+ fog: false,
632
+ color: '#4aff51',
633
+ opacity: 1
634
+ });
383
635
 
384
- aabb_bounds.x1 -= hs;
385
- aabb_bounds.z1 -= hs;
636
+ const box_transform = transform.clone();
637
+ eb.add(box_transform);
638
+ const sg = ShadedGeometry.from(g_unit_cube, lineMaterial, DrawMode.LineSegments);
639
+ eb.add(sg);
386
640
 
387
- const adjusted_density = density / particle_size;
641
+ eb.build(ecd);
388
642
 
389
- const v = new ParticleVolume();
643
+ const cachedObject = sg.__cached_object;
644
+ cachedObject.frustumCulled = false;
645
+ controls.attach(cachedObject);
390
646
 
391
- const dx = aabb_bounds.x1 - aabb_bounds.x0;
392
- const dy = aabb_bounds.y1 - aabb_bounds.y0;
393
- const dz = aabb_bounds.z1 - aabb_bounds.z0;
394
647
 
395
- v.transform.scale.set(
396
- dx,
397
- dy,
398
- dz
399
- );
648
+ controls.setSize(1);
649
+ const r_controls = new Renderable(controls);
650
+ r_controls.matrixAutoUpdate = true;
651
+ r_controls.boundingBoxNeedsUpdate = false;
652
+ r_controls.boundingBox.setBounds(0, 0, 0, 1, 1, 1);
400
653
 
401
- v.transform.position.set(
402
- aabb_bounds.x0 + dx / 2,
403
- aabb_bounds.y0 + dy / 2,
404
- aabb_bounds.z0 + dz / 2
405
- );
654
+ // make camera controller holder
655
+ const entity = TagSystem.find_entities_with_tag('CameraController', ecd)[0];
406
656
 
657
+ const camera_controls = EntityBuilder.readFromDataset(entity, ecd);
407
658
 
408
- const em = engine.entityManager;
409
659
 
410
- if (em.getSystem(ParticleEmitterSystem2) === null) {
411
- await em.addSystem(new ParticleEmitterSystem2(engine.assetManager, engine.graphics));
412
- }
660
+ new EntityBuilder()
661
+ .add(r_controls)
662
+ .add(new Transform())
663
+ .add(new InputController([
664
+ {
665
+ path: 'keyboard/keys/w/down',
666
+ listener() {
667
+ controls.setMode('translate');
668
+ }
669
+ },
670
+ {
671
+ path: 'keyboard/keys/e/down',
672
+ listener() {
673
+ controls.setMode('scale');
674
+ }
675
+ },
676
+ {
677
+ path: 'keyboard/keys/r/down',
678
+ listener() {
679
+ controls.setMode('rotate');
680
+ }
681
+ },
682
+ {
683
+ path: 'keyboard/keys/s/down',
684
+ listener() {
685
+ // output current box
686
+
687
+ const code_snippet = `TransformedShape3D.from_m4(new UnitCubeShape3D(), ${JSON.stringify(cachedObject.matrix.elements)})`;
688
+ console.warn(code_snippet);
689
+
690
+ navigator.clipboard.writeText(code_snippet);
691
+ }
692
+ },
693
+ {
694
+ path: 'keyboard/keys/space/down',
695
+ listener() {
696
+ // reset scale and rotation
697
+ box_transform.scale.setScalar(1);
698
+ box_transform.rotation.set(0, 0, 0, 1);
699
+ }
700
+ }
701
+ ]))
702
+ .add(BehaviorComponent.looping_function(() => {
703
+
704
+ threeUpdateTransform(controls);
705
+
706
+ if (controls.dragging) {
707
+ if (camera_controls.isBuilt) {
708
+ camera_controls.destroy();
709
+ }
710
+ } else {
711
+ if (!camera_controls.isBuilt) {
712
+ camera_controls.build(ecd);
713
+ }
714
+ }
715
+
716
+ cachedObject.updateMatrix();
717
+ const matrix = cachedObject.matrix;
718
+ const t = eb.getComponent(Transform);
719
+
720
+ t.position.onChanged.mute();
721
+ t.rotation.onChanged.mute();
722
+ t.scale.onChanged.mute();
723
+
724
+ t.fromMatrix4(matrix.elements);
725
+
726
+ t.position.onChanged.unmute();
727
+ t.rotation.onChanged.unmute();
728
+ t.scale.onChanged.unmute();
729
+
730
+ sg.updateTransform();
731
+
732
+ }))
733
+ .build(ecd);
734
+ }
735
+
736
+ /**
737
+ *
738
+ * @param {EntityComponentDataset} ecd
739
+ * @param {AbstractShape3D} shape
740
+ * @param {number} density
741
+ * @param {number} particle_size
742
+ * @param {boolean} sort
743
+ * @returns {ParticleVolume}
744
+ */
745
+ function create_volume({
746
+ ecd,
747
+ shape = new UnitCubeShape3D(),
748
+ density = 10,
749
+ particle_size = 1,
750
+ sort = false,
751
+ sprite
752
+ }) {
753
+
754
+ const adjusted_density = density / particle_size;
755
+
756
+ const v = new ParticleVolume();
413
757
 
414
758
  v.from({
415
759
  density: adjusted_density,
416
- particle_size
760
+ particle_size,
761
+ shape: shape,
762
+ sort,
763
+ sprite
417
764
  });
418
765
 
419
766
  v.build();
420
767
 
421
- v.entity.build(em.dataset);
768
+ v.entity.build(ecd);
422
769
 
423
770
  return v;
424
771
  }
425
772
 
426
773
  /**
427
774
  *
428
- * @param {AABB3} bounds
775
+ * @param {Vector3} position
429
776
  * @param {ParameterLookupTable} lut
430
777
  * @return {{position: Vector1}}
431
778
  */
432
779
  function make_symbol_view({
433
- bounds,
780
+ position,
434
781
  lut
435
782
  }) {
436
783
 
@@ -494,7 +841,7 @@ function make_symbol_view({
494
841
  symbol_view.addChild(view_cursor);
495
842
 
496
843
  const symbol_transform = new Transform();
497
- bounds.getCenter(symbol_transform.position);
844
+ symbol_transform.position.copy(position);
498
845
 
499
846
  const vp = new ViewportPosition();
500
847
  vp.anchor.set(0.5, 1);
@@ -512,29 +859,59 @@ function make_symbol_view({
512
859
 
513
860
  async function make_demo_volume({
514
861
  ecd,
515
- bounds = new AABB3(0, 0, 0, 20, 10, 20),
862
+ shape,
516
863
  lut,
517
864
  period = 5,
518
865
  period_offset = 0,
519
866
  density,
520
- particle_size
867
+ particle_size,
868
+ sort = false,
869
+ sprite
521
870
  }) {
522
871
 
523
- const v = await create_volume({
524
- bounds,
872
+ // estimate bounds
873
+ const bounds = new AABB3();
874
+ bounds.setNegativelyInfiniteBounds();
875
+
876
+ const sample = [];
877
+ const samples_x = [];
878
+ const samples_y = [];
879
+ const samples_z = [];
880
+
881
+ const random = seededRandom(0xBEEF);
882
+
883
+ for (let i = 0; i < 1024; i++) {
884
+ shape.sample_random_point_in_volume(sample, 0, random);
885
+
886
+ samples_x.push(sample[0]);
887
+ samples_y.push(sample[1]);
888
+ samples_z.push(sample[2]);
889
+ }
890
+
891
+ const v = create_volume({
892
+ ecd,
893
+ shape,
525
894
  density,
526
- particle_size
895
+ particle_size,
896
+ sort,
897
+ sprite
527
898
  });
528
899
 
529
900
  let time_total = 0;
530
901
 
531
902
  const symbol = make_symbol_view({
532
- bounds,
903
+ position: new Vector3(
904
+ computeStatisticalMean(samples_x),
905
+ computeStatisticalMean(samples_y),
906
+ computeStatisticalMean(samples_z),
907
+ ),
533
908
  lut
534
909
  });
535
910
 
536
911
  symbol.entity.build(ecd);
537
912
 
913
+ v.attributes.color.lookup = lut;
914
+
538
915
  new EntityBuilder()
539
916
  .add(BehaviorComponent.fromOne(RepeatBehavior.from(new ActionBehavior((time) => {
540
917
  time_total += time;
@@ -545,14 +922,14 @@ async function make_demo_volume({
545
922
 
546
923
  symbol.position.set(f);
547
924
 
548
- const s = [];
549
- lut.sample(f, s);
550
-
551
- // console.log(JSON.stringify(s));
552
-
553
- v.setColor(s[0] , s[1] , s[2] , s[3] );
925
+ v.attributes.color.write_lookup_value(f);
554
926
  }))))
555
927
  .build(ecd);
928
+
929
+ const shape_entity = shape_to_visual_entity(v.shape, ecd);
930
+ shape_entity
931
+ .getComponent(Transform)
932
+ .copy(v.transform);
556
933
  }
557
934
 
558
935
  init(engineHarness);