@woosh/meep-engine 2.33.59 → 2.33.60
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.
- package/core/bvh2/aabb3/AABB3.js +4 -1
- package/core/bvh2/traversal/traverseBinaryNodeUsingVisitor.js +6 -6
- package/core/cache/Cache.js +7 -0
- package/core/collection/array/fastArrayEquals.js +17 -0
- package/core/collection/array/typed/is_typed_array_equals.js +58 -0
- package/core/collection/map/AbstractAsyncMap.js +30 -0
- package/core/collection/map/AsyncMapWrapper.js +16 -0
- package/core/collection/map/AsyncRemoteHashMap.js +358 -0
- package/core/collection/map/CachedAsyncMap.js +34 -0
- package/core/geom/Vector4.js +5 -5
- package/engine/animation/removeEntityGenericEffect.js +22 -31
- package/engine/asset/Asset.js +0 -45
- package/engine/asset/AssetDescription.js +51 -0
- package/engine/asset/AssetManager.d.ts +7 -0
- package/engine/asset/AssetManager.js +98 -2
- package/engine/asset/AssetTransformer.d.ts +5 -0
- package/engine/asset/AssetTransformer.js +15 -0
- package/engine/asset/loaders/GLTFAssetLoader.js +27 -25
- package/engine/asset/loaders/material/computeImageBitmapEquality.js +2 -2
- package/engine/asset/loaders/material/computeTextureEquality.js +2 -2
- package/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +60 -45
- package/engine/ecs/storage/binary/BinaryClassUpgrader.js +1 -0
- package/engine/ecs/util/removeComponentsExcept.js +3 -3
- package/engine/graphics/GraphicsEngine.js +3 -3
- package/engine/graphics/ecs/mesh/Mesh.js +5 -5
- package/engine/graphics/ecs/mesh/MeshSystem.js +12 -20
- package/engine/graphics/ecs/trail2d/Trail2D.js +35 -1
- package/engine/graphics/ecs/trail2d/Trail2DSystem.js +26 -19
- package/engine/graphics/ecs/trail2d/makeGradientTrail.js +68 -0
- package/engine/graphics/micron/convert_three_object_to_micron.js +24 -7
- package/engine/graphics/micron/plugin/MicronRenderPlugin.js +107 -4
- package/engine/graphics/micron/plugin/serialization/BufferGeometrySerializationAdapter.js +176 -0
- package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +1 -2
- package/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +3 -1
- package/engine/graphics/shadows/ShadowMapRenderer.js +10 -4
- package/engine/graphics/texture/sampler/Sampler2D.js +24 -45
- package/engine/intelligence/behavior/ecs/WaitForEventBehavior.js +3 -0
- package/engine/save/storage/IndexedDBStorage.js +8 -1
- package/package.json +1 -1
|
@@ -18,7 +18,6 @@ import Mesh, { MeshFlags } from "./Mesh.js";
|
|
|
18
18
|
import { applyComponentPropertiesToThreeObject, setMesh } from "./setMesh.js";
|
|
19
19
|
import { GLTFAssetLoader } from "../../../asset/loaders/GLTFAssetLoader.js";
|
|
20
20
|
import { MeshEvents } from "./MeshEvents.js";
|
|
21
|
-
import { MicronRenderPlugin } from "../../micron/plugin/MicronRenderPlugin.js";
|
|
22
21
|
import { assert } from "../../../../core/assert.js";
|
|
23
22
|
|
|
24
23
|
const placeholderGeometry = new BoxBufferGeometry(1, 1, 1);
|
|
@@ -86,13 +85,6 @@ export class MeshSystem extends System {
|
|
|
86
85
|
* @type {BinaryNode}
|
|
87
86
|
*/
|
|
88
87
|
this.bvh = null;
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
*
|
|
92
|
-
* @type {boolean}
|
|
93
|
-
* @private
|
|
94
|
-
*/
|
|
95
|
-
this.__use_micron = false;
|
|
96
88
|
}
|
|
97
89
|
|
|
98
90
|
/**
|
|
@@ -126,11 +118,11 @@ export class MeshSystem extends System {
|
|
|
126
118
|
|
|
127
119
|
component.setFlag(MeshFlags.Loaded);
|
|
128
120
|
|
|
129
|
-
//
|
|
130
|
-
if (asset.
|
|
131
|
-
component.
|
|
121
|
+
// override
|
|
122
|
+
if (asset.override_mesh !== undefined ) {
|
|
123
|
+
component.override_mesh = asset.override_mesh.clone();
|
|
132
124
|
|
|
133
|
-
applyComponentPropertiesToThreeObject(component, component.
|
|
125
|
+
applyComponentPropertiesToThreeObject(component, component.override_mesh, entity);
|
|
134
126
|
}
|
|
135
127
|
|
|
136
128
|
setMesh(dataset, entity, component, mesh);
|
|
@@ -141,11 +133,6 @@ export class MeshSystem extends System {
|
|
|
141
133
|
}
|
|
142
134
|
|
|
143
135
|
async startup(entityManager, readyCallback, errorCallback) {
|
|
144
|
-
const engine = this.__engine;
|
|
145
|
-
|
|
146
|
-
// is micron supported here?
|
|
147
|
-
this.__use_micron = engine.plugins.getPlugin(MicronRenderPlugin) !== undefined;
|
|
148
|
-
|
|
149
136
|
const am = this.assetManager;
|
|
150
137
|
|
|
151
138
|
this.entityManager = entityManager;
|
|
@@ -158,10 +145,15 @@ export class MeshSystem extends System {
|
|
|
158
145
|
const graphics = this.graphics;
|
|
159
146
|
this.renderLayer = graphics.layers.create("mesh-system");
|
|
160
147
|
|
|
148
|
+
/**
|
|
149
|
+
*
|
|
150
|
+
* @param {Mesh} component
|
|
151
|
+
* @return {Object3D}
|
|
152
|
+
*/
|
|
161
153
|
const extractRenderable = (component) => {
|
|
162
|
-
if (
|
|
163
|
-
// use
|
|
164
|
-
return component.
|
|
154
|
+
if (component.override_mesh !== null) {
|
|
155
|
+
// use override mesh
|
|
156
|
+
return component.override_mesh;
|
|
165
157
|
} else {
|
|
166
158
|
// use standard mesh
|
|
167
159
|
return component.mesh;
|
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
import Vector3 from "../../../../core/geom/Vector3.js";
|
|
7
7
|
import Vector4 from "../../../../core/geom/Vector4.js";
|
|
8
8
|
import { RibbonXMaterialSpec } from "../../trail/x/RibbonXMaterialSpec.js";
|
|
9
|
+
import { LeafNode } from "../../../../core/bvh2/LeafNode.js";
|
|
10
|
+
import { makeGradientTrail } from "./makeGradientTrail.js";
|
|
11
|
+
import { RibbonX } from "../../trail/x/RibbonX.js";
|
|
12
|
+
import ThreeFactory from "../../three/ThreeFactory.js";
|
|
9
13
|
|
|
10
14
|
/**
|
|
11
15
|
* @readonly
|
|
@@ -14,6 +18,7 @@ import { RibbonXMaterialSpec } from "../../trail/x/RibbonXMaterialSpec.js";
|
|
|
14
18
|
export const Trail2DFlags = {
|
|
15
19
|
Spawning: 1,
|
|
16
20
|
Aging: 2,
|
|
21
|
+
Built: 4,
|
|
17
22
|
};
|
|
18
23
|
|
|
19
24
|
class Trail2D {
|
|
@@ -37,6 +42,12 @@ class Trail2D {
|
|
|
37
42
|
*/
|
|
38
43
|
this.time = 0;
|
|
39
44
|
|
|
45
|
+
/**
|
|
46
|
+
*
|
|
47
|
+
* @type {number}
|
|
48
|
+
*/
|
|
49
|
+
this.trailingIndex = 0;
|
|
50
|
+
|
|
40
51
|
/**
|
|
41
52
|
* Time elapsed since last update
|
|
42
53
|
* @type {number}
|
|
@@ -72,7 +83,11 @@ class Trail2D {
|
|
|
72
83
|
* transient
|
|
73
84
|
* @type {LeafNode|null}
|
|
74
85
|
*/
|
|
75
|
-
this.bvhLeaf =
|
|
86
|
+
this.bvhLeaf = new LeafNode(
|
|
87
|
+
this,
|
|
88
|
+
0, 0, 0,
|
|
89
|
+
0, 0, 0
|
|
90
|
+
);
|
|
76
91
|
|
|
77
92
|
/**
|
|
78
93
|
* @private
|
|
@@ -165,6 +180,21 @@ class Trail2D {
|
|
|
165
180
|
}
|
|
166
181
|
}
|
|
167
182
|
|
|
183
|
+
build(segment_count) {
|
|
184
|
+
|
|
185
|
+
const ribbon = new RibbonX();
|
|
186
|
+
|
|
187
|
+
ribbon.buildGeometry();
|
|
188
|
+
ribbon.setCount(segment_count);
|
|
189
|
+
|
|
190
|
+
const geometry = ribbon.getGeometry();
|
|
191
|
+
|
|
192
|
+
const mesh = ThreeFactory.createMesh(geometry, null);
|
|
193
|
+
|
|
194
|
+
this.ribbon = ribbon;
|
|
195
|
+
this.mesh = mesh;
|
|
196
|
+
}
|
|
197
|
+
|
|
168
198
|
toJSON() {
|
|
169
199
|
return {
|
|
170
200
|
maxAge: this.maxAge,
|
|
@@ -187,10 +217,14 @@ class Trail2D {
|
|
|
187
217
|
&& this.offset.equals(other.offset)
|
|
188
218
|
;
|
|
189
219
|
}
|
|
220
|
+
|
|
221
|
+
|
|
190
222
|
}
|
|
191
223
|
|
|
192
224
|
Trail2D.typeName = "Trail2D";
|
|
193
225
|
|
|
194
226
|
Trail2D.serializable = false;
|
|
195
227
|
|
|
228
|
+
Trail2D.makeGradientTrail = makeGradientTrail;
|
|
229
|
+
|
|
196
230
|
export default Trail2D;
|
|
@@ -10,9 +10,6 @@ import { Transform } from '../../../ecs/transform/Transform.js';
|
|
|
10
10
|
import Vector3 from '../../../../core/geom/Vector3.js';
|
|
11
11
|
|
|
12
12
|
import Trail2D, { Trail2DFlags } from './Trail2D.js';
|
|
13
|
-
|
|
14
|
-
import { LeafNode } from '../../../../core/bvh2/LeafNode.js';
|
|
15
|
-
import ThreeFactory from '../../three/ThreeFactory.js';
|
|
16
13
|
import { GraphicsEngine } from "../../GraphicsEngine.js";
|
|
17
14
|
import { RibbonXFixedPhysicsSimulator } from "../../trail/x/simulator/RibbonXFixedPhysicsSimulator.js";
|
|
18
15
|
import { RibbonX } from "../../trail/x/RibbonX.js";
|
|
@@ -118,11 +115,11 @@ class Trail2DSystem extends System {
|
|
|
118
115
|
|
|
119
116
|
/**
|
|
120
117
|
*
|
|
121
|
-
* @param {Transform} transform
|
|
122
118
|
* @param {Trail2D} trail
|
|
123
|
-
* @param {
|
|
119
|
+
* @param {Transform} transform
|
|
120
|
+
* @private
|
|
124
121
|
*/
|
|
125
|
-
|
|
122
|
+
__build_trail(trail, transform) {
|
|
126
123
|
const segmentsPerSecond = 60;
|
|
127
124
|
const maxSegments = 1000;
|
|
128
125
|
//instantiation
|
|
@@ -130,24 +127,19 @@ class Trail2DSystem extends System {
|
|
|
130
127
|
//make a mesh
|
|
131
128
|
const segment_count = Math.ceil(clamp(trail.maxAge * segmentsPerSecond, 2, maxSegments));
|
|
132
129
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
ribbon.buildGeometry();
|
|
136
|
-
ribbon.setCount(segment_count);
|
|
130
|
+
trail.build(segment_count);
|
|
137
131
|
|
|
138
|
-
|
|
139
|
-
const geometry = ribbon.getGeometry();
|
|
132
|
+
const ribbon = trail.ribbon;
|
|
140
133
|
|
|
141
134
|
const ribbons = this.__ribbon_plugin.getValue();
|
|
142
135
|
|
|
143
136
|
const material = ribbons.obtain_material_x(trail.material);
|
|
144
137
|
|
|
145
|
-
|
|
138
|
+
trail.mesh.material = material;
|
|
146
139
|
|
|
147
140
|
trail.time = 0;
|
|
148
141
|
trail.trailingIndex = 0;
|
|
149
142
|
trail.ribbon = ribbon;
|
|
150
|
-
trail.mesh = mesh;
|
|
151
143
|
trail.timeSinceLastUpdate = 0;
|
|
152
144
|
|
|
153
145
|
|
|
@@ -173,16 +165,31 @@ class Trail2DSystem extends System {
|
|
|
173
165
|
|
|
174
166
|
}
|
|
175
167
|
|
|
176
|
-
|
|
177
|
-
trail,
|
|
178
|
-
|
|
168
|
+
trail.bvhLeaf.resize(
|
|
179
169
|
position_x, position_y, position_z,
|
|
180
170
|
position_x, position_y, position_z
|
|
181
171
|
);
|
|
182
172
|
|
|
183
|
-
trail.
|
|
173
|
+
trail.setFlag(Trail2DFlags.Built);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
*
|
|
178
|
+
* @param {Transform} transform
|
|
179
|
+
* @param {Trail2D} trail
|
|
180
|
+
* @param {number} entityId
|
|
181
|
+
*/
|
|
182
|
+
link(trail, transform, entityId) {
|
|
183
|
+
if (!trail.getFlag(Trail2DFlags.Built)) {
|
|
184
|
+
this.__build_trail(trail, transform);
|
|
185
|
+
} else {
|
|
186
|
+
|
|
187
|
+
const material = this.__ribbon_plugin.getValue().obtain_material_x(trail.material);
|
|
188
|
+
trail.mesh.material = material;
|
|
189
|
+
}
|
|
190
|
+
|
|
184
191
|
|
|
185
|
-
this.bvh.insertNode(
|
|
192
|
+
this.bvh.insertNode(trail.bvhLeaf);
|
|
186
193
|
}
|
|
187
194
|
|
|
188
195
|
/**
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import Trail2D, { Trail2DFlags } from "./Trail2D.js";
|
|
2
|
+
import {
|
|
3
|
+
RIBBON_ATTRIBUTE_ADDRESS_AGE,
|
|
4
|
+
RIBBON_ATTRIBUTE_ADDRESS_COLOR,
|
|
5
|
+
RIBBON_ATTRIBUTE_ADDRESS_THICKNESS,
|
|
6
|
+
RIBBON_ATTRIBUTE_ADDRESS_UV_OFFSET
|
|
7
|
+
} from "../../trail/x/ribbon_attributes_spec.js";
|
|
8
|
+
import { assert } from "../../../../core/assert.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param {number[]} color
|
|
13
|
+
* @param {number[]} thickness
|
|
14
|
+
* @param {number} [duration]
|
|
15
|
+
* @param {number} [scale]
|
|
16
|
+
* @param {number[]} position
|
|
17
|
+
* @param {number[]} ages
|
|
18
|
+
* @param {string} texture
|
|
19
|
+
* @returns {Trail2D}
|
|
20
|
+
*/
|
|
21
|
+
export function makeGradientTrail({
|
|
22
|
+
color,
|
|
23
|
+
thickness,
|
|
24
|
+
position,
|
|
25
|
+
duration = 1,
|
|
26
|
+
scale = 1,
|
|
27
|
+
ages,
|
|
28
|
+
texture
|
|
29
|
+
}) {
|
|
30
|
+
|
|
31
|
+
const trail2D = new Trail2D();
|
|
32
|
+
trail2D.maxAge = duration;
|
|
33
|
+
trail2D.width = 1;
|
|
34
|
+
trail2D.textureURL = texture;
|
|
35
|
+
|
|
36
|
+
const point_count = thickness.length;
|
|
37
|
+
|
|
38
|
+
trail2D.build(point_count);
|
|
39
|
+
|
|
40
|
+
const ribbon = trail2D.ribbon;
|
|
41
|
+
|
|
42
|
+
for (let i = 0; i < point_count; i++) {
|
|
43
|
+
|
|
44
|
+
const f = i / (point_count - 1);
|
|
45
|
+
const i3 = i * 3;
|
|
46
|
+
|
|
47
|
+
ribbon.setPointAlpha(i, 0);
|
|
48
|
+
ribbon.setPointPosition(i, position[i3], position[i3 + 1], position[i3 + 2]);
|
|
49
|
+
|
|
50
|
+
ribbon.setPointAttribute_Scalar(i, RIBBON_ATTRIBUTE_ADDRESS_AGE, ages[i] * duration);
|
|
51
|
+
ribbon.setPointAttribute_Scalar(i, RIBBON_ATTRIBUTE_ADDRESS_UV_OFFSET, f);
|
|
52
|
+
ribbon.setPointAttribute_Scalar(i, RIBBON_ATTRIBUTE_ADDRESS_THICKNESS, thickness[i]);
|
|
53
|
+
|
|
54
|
+
const c_0 = color[i];
|
|
55
|
+
|
|
56
|
+
assert.isNumber(c_0, `color[i]`);
|
|
57
|
+
|
|
58
|
+
ribbon.setPointAttribute_Vector3(i, RIBBON_ATTRIBUTE_ADDRESS_COLOR, c_0 >> 16, c_0 >> 8, c_0);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// don't spawn more trail segments
|
|
62
|
+
trail2D.clearFlag(Trail2DFlags.Spawning);
|
|
63
|
+
trail2D.setFlag(Trail2DFlags.Built);
|
|
64
|
+
|
|
65
|
+
ribbon.computeBoundingBox(trail2D.bvhLeaf);
|
|
66
|
+
|
|
67
|
+
return trail2D;
|
|
68
|
+
}
|
|
@@ -3,12 +3,18 @@ import { computeGeometryHash } from "../../asset/loaders/geometry/geometry/compu
|
|
|
3
3
|
import { computeGeometryEquality } from "../../asset/loaders/geometry/geometry/computeGeometryEquality.js";
|
|
4
4
|
import { buildMicronGeometryFromBufferGeometry } from "./build/buildMicronGeometryFromBufferGeometry.js";
|
|
5
5
|
import { ThreeMicronMesh } from "./format/ThreeMicronMesh.js";
|
|
6
|
+
import { AsyncMapWrapper } from "../../../core/collection/map/AsyncMapWrapper.js";
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
*
|
|
9
10
|
* @type {HashMap<THREE.BufferGeometry, MicronGeometry>}
|
|
10
11
|
*/
|
|
11
|
-
const
|
|
12
|
+
const default_micron_cache = new AsyncMapWrapper(new HashMap({
|
|
13
|
+
keyHashFunction: computeGeometryHash,
|
|
14
|
+
keyEqualityFunction: computeGeometryEquality
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
const pending_cache = new HashMap({
|
|
12
18
|
keyHashFunction: computeGeometryHash,
|
|
13
19
|
keyEqualityFunction: computeGeometryEquality
|
|
14
20
|
});
|
|
@@ -17,9 +23,10 @@ const micron_cache = new HashMap({
|
|
|
17
23
|
/**
|
|
18
24
|
*
|
|
19
25
|
* @param {THREE.Object3D} object
|
|
26
|
+
* @param {AbstractAsyncMap<THREE.BufferGeometry, MicronGeometry>} micron_cache
|
|
20
27
|
* @returns {THREE.Object3D}
|
|
21
28
|
*/
|
|
22
|
-
export async function convert_three_object_to_micron(object) {
|
|
29
|
+
export async function convert_three_object_to_micron(object, micron_cache = default_micron_cache) {
|
|
23
30
|
|
|
24
31
|
const promises = [];
|
|
25
32
|
|
|
@@ -29,19 +36,29 @@ export async function convert_three_object_to_micron(object) {
|
|
|
29
36
|
* @returns {MicronGeometry}
|
|
30
37
|
*/
|
|
31
38
|
async function obtain_geometry(g) {
|
|
32
|
-
const existing = micron_cache.get(g);
|
|
39
|
+
const existing = await micron_cache.get(g);
|
|
40
|
+
|
|
41
|
+
if (existing !== undefined && existing !== null) {
|
|
42
|
+
return existing;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const pending = pending_cache.get(g);
|
|
33
46
|
|
|
34
|
-
if (
|
|
35
|
-
return await
|
|
47
|
+
if (pending !== undefined) {
|
|
48
|
+
return await pending;
|
|
36
49
|
}
|
|
37
50
|
|
|
38
51
|
const micron_geometry_promise = buildMicronGeometryFromBufferGeometry(g);
|
|
39
52
|
|
|
40
|
-
|
|
53
|
+
pending_cache.set(g, micron_geometry_promise);
|
|
41
54
|
|
|
42
55
|
promises.push(micron_geometry_promise);
|
|
43
56
|
|
|
44
|
-
|
|
57
|
+
const micron_geometry = await micron_geometry_promise;
|
|
58
|
+
|
|
59
|
+
await micron_cache.set(g, micron_geometry);
|
|
60
|
+
|
|
61
|
+
return micron_geometry;
|
|
45
62
|
}
|
|
46
63
|
|
|
47
64
|
|
|
@@ -3,6 +3,57 @@ import { VGThreeRenderer } from "../render/v1/VGThreeRenderer.js";
|
|
|
3
3
|
import { RenderLayer } from "../../render/layers/RenderLayer.js";
|
|
4
4
|
import { RenderPassType } from "../../render/RenderPassType.js";
|
|
5
5
|
import { SOURCE_RENDER_LAYER_PROPERTY } from "../../render/visibility/VisibilityComputer.js";
|
|
6
|
+
import { AssetTransformer } from "../../../asset/AssetTransformer.js";
|
|
7
|
+
import { convert_three_object_to_micron } from "../convert_three_object_to_micron.js";
|
|
8
|
+
import { Cache } from "../../../../core/cache/Cache.js";
|
|
9
|
+
import { computeGeometryHash } from "../../../asset/loaders/geometry/geometry/computeGeometryHash.js";
|
|
10
|
+
import { computeGeometryEquality } from "../../../asset/loaders/geometry/geometry/computeGeometryEquality.js";
|
|
11
|
+
import { CachedAsyncMap } from "../../../../core/collection/map/CachedAsyncMap.js";
|
|
12
|
+
import { AsyncRemoteHashMap } from "../../../../core/collection/map/AsyncRemoteHashMap.js";
|
|
13
|
+
import { BufferGeometrySerializationAdapter } from "./serialization/BufferGeometrySerializationAdapter.js";
|
|
14
|
+
import { MicronGeometryBinarySerializationAdapter } from "../format/serialization/MicronGeometryBinarySerializationAdapter.js";
|
|
15
|
+
import { AsyncMapWrapper } from "../../../../core/collection/map/AsyncMapWrapper.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
*
|
|
19
|
+
* @type {string}
|
|
20
|
+
*/
|
|
21
|
+
const STORAGE_KEY = '@plugin/virtual-geometry-micron/geometry-cache';
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class GLTFAssetTransformer extends AssetTransformer {
|
|
25
|
+
/**
|
|
26
|
+
*
|
|
27
|
+
* @param {AbstractAsyncMap<THREE.BufferGeometry, MicronGeometry>} cache
|
|
28
|
+
*/
|
|
29
|
+
constructor(cache) {
|
|
30
|
+
super();
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @type {AbstractAsyncMap<THREE.BufferGeometry, MicronGeometry>}
|
|
35
|
+
* @private
|
|
36
|
+
*/
|
|
37
|
+
this.__cache = cache;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async transform(source) {
|
|
41
|
+
const animationClips = source.animations;
|
|
42
|
+
if (animationClips !== undefined && animationClips.length > 0) {
|
|
43
|
+
// not suitable
|
|
44
|
+
return source;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const root = source.create();
|
|
48
|
+
|
|
49
|
+
const micron_root = await convert_three_object_to_micron(root.clone(), this.__cache);
|
|
50
|
+
micron_root.boundingSphere = root.boundingSphere;
|
|
51
|
+
|
|
52
|
+
source.override_mesh = micron_root;
|
|
53
|
+
|
|
54
|
+
return source;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
6
57
|
|
|
7
58
|
export class MicronRenderPlugin extends EnginePlugin {
|
|
8
59
|
constructor() {
|
|
@@ -37,6 +88,40 @@ export class MicronRenderPlugin extends EnginePlugin {
|
|
|
37
88
|
});
|
|
38
89
|
|
|
39
90
|
this.__view_observers = new Map();
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
*
|
|
94
|
+
* @type {AsyncRemoteHashMap}
|
|
95
|
+
* @private
|
|
96
|
+
*/
|
|
97
|
+
this.__persisted_geometry = new AsyncRemoteHashMap({
|
|
98
|
+
keyHashFunction: computeGeometryHash,
|
|
99
|
+
keyEqualityFunction: computeGeometryEquality,
|
|
100
|
+
keySerializationAdapter: new BufferGeometrySerializationAdapter(),
|
|
101
|
+
valueSerializationAdapter: new MicronGeometryBinarySerializationAdapter(),
|
|
102
|
+
storageKeyPrefix: STORAGE_KEY,
|
|
103
|
+
|
|
104
|
+
});
|
|
105
|
+
/**
|
|
106
|
+
*
|
|
107
|
+
* @type {AbstractAsyncMap<THREE.BufferGeometry, MicronGeometry>}
|
|
108
|
+
* @private
|
|
109
|
+
*/
|
|
110
|
+
this.__cache = new CachedAsyncMap(
|
|
111
|
+
new AsyncMapWrapper(new Cache({
|
|
112
|
+
keyHashFunction: computeGeometryHash,
|
|
113
|
+
keyEqualityFunction: computeGeometryEquality
|
|
114
|
+
})),
|
|
115
|
+
this.__persisted_geometry
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
*
|
|
120
|
+
* @type {AssetTransformer}
|
|
121
|
+
* @private
|
|
122
|
+
*/
|
|
123
|
+
this.__asset_transformer = new GLTFAssetTransformer(this.__cache);
|
|
124
|
+
|
|
40
125
|
}
|
|
41
126
|
|
|
42
127
|
/**
|
|
@@ -87,13 +172,22 @@ export class MicronRenderPlugin extends EnginePlugin {
|
|
|
87
172
|
view.on.preRender.remove(observer);
|
|
88
173
|
}
|
|
89
174
|
|
|
175
|
+
__ingest_cache() {
|
|
176
|
+
this.engine.storage.lo
|
|
177
|
+
}
|
|
178
|
+
|
|
90
179
|
async startup() {
|
|
91
180
|
|
|
181
|
+
const engine = this.engine;
|
|
182
|
+
|
|
183
|
+
engine.assetManager.registerTransformer("model/gltf", this.__asset_transformer);
|
|
184
|
+
engine.assetManager.registerTransformer("model/gltf+json", this.__asset_transformer);
|
|
185
|
+
|
|
92
186
|
/**
|
|
93
187
|
*
|
|
94
188
|
* @type {GraphicsEngine}
|
|
95
189
|
*/
|
|
96
|
-
const ge =
|
|
190
|
+
const ge = engine.graphics;
|
|
97
191
|
|
|
98
192
|
ge.layers.add(this.__micron_render_layer);
|
|
99
193
|
|
|
@@ -101,13 +195,22 @@ export class MicronRenderPlugin extends EnginePlugin {
|
|
|
101
195
|
ge.views.elements.on.removed.add(this.__handle_view_removed, this);
|
|
102
196
|
|
|
103
197
|
// link all views
|
|
104
|
-
ge.views.elements.forEach(this.__handle_view_added,this);
|
|
198
|
+
ge.views.elements.forEach(this.__handle_view_added, this);
|
|
199
|
+
|
|
200
|
+
this.__persisted_geometry.attach_storage(engine.storage);
|
|
105
201
|
|
|
106
202
|
await super.startup();
|
|
107
203
|
}
|
|
108
204
|
|
|
109
205
|
async shutdown() {
|
|
110
|
-
const
|
|
206
|
+
const engine = this.engine;
|
|
207
|
+
|
|
208
|
+
this.__persisted_geometry.detach_storage();
|
|
209
|
+
|
|
210
|
+
engine.assetManager.unregisterTransformer("model/gltf", this.__asset_transformer);
|
|
211
|
+
engine.assetManager.unregisterTransformer("model/gltf+json", this.__asset_transformer);
|
|
212
|
+
|
|
213
|
+
const ge = engine.graphics;
|
|
111
214
|
|
|
112
215
|
ge.layers.remove(this.__micron_render_layer);
|
|
113
216
|
|
|
@@ -115,7 +218,7 @@ export class MicronRenderPlugin extends EnginePlugin {
|
|
|
115
218
|
ge.views.elements.on.removed.remove(this.__handle_view_removed, this);
|
|
116
219
|
|
|
117
220
|
// clear all observer
|
|
118
|
-
ge.views.elements.forEach(this.__handle_view_removed,this);
|
|
221
|
+
ge.views.elements.forEach(this.__handle_view_removed, this);
|
|
119
222
|
|
|
120
223
|
await super.shutdown();
|
|
121
224
|
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { BinaryClassSerializationAdapter } from "../../../../ecs/storage/binary/BinaryClassSerializationAdapter.js";
|
|
2
|
+
import { BufferAttribute, BufferGeometry } from "three";
|
|
3
|
+
|
|
4
|
+
function typed_array_to_enum(array) {
|
|
5
|
+
if (array instanceof Uint8Array) {
|
|
6
|
+
return 0;
|
|
7
|
+
} else if (array instanceof Uint16Array) {
|
|
8
|
+
return 1;
|
|
9
|
+
} else if (array instanceof Uint32Array) {
|
|
10
|
+
return 2;
|
|
11
|
+
} else if (array instanceof Uint8Array) {
|
|
12
|
+
return 3;
|
|
13
|
+
} else if (array instanceof Uint16Array) {
|
|
14
|
+
return 4;
|
|
15
|
+
} else if (array instanceof Uint32Array) {
|
|
16
|
+
return 5;
|
|
17
|
+
} else if (array instanceof Float32Array) {
|
|
18
|
+
return 6;
|
|
19
|
+
} else if (array instanceof Float64Array) {
|
|
20
|
+
return 7;
|
|
21
|
+
} else {
|
|
22
|
+
throw new Error('Unsupported array type');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function marker_to_typed_array_constructor(marker) {
|
|
27
|
+
switch (marker) {
|
|
28
|
+
case 0:
|
|
29
|
+
return Uint8Array;
|
|
30
|
+
case 1:
|
|
31
|
+
return Uint16Array;
|
|
32
|
+
case 2:
|
|
33
|
+
return Uint32Array;
|
|
34
|
+
case 3:
|
|
35
|
+
return Int8Array;
|
|
36
|
+
case 4:
|
|
37
|
+
return Int16Array;
|
|
38
|
+
case 5:
|
|
39
|
+
return Int32Array;
|
|
40
|
+
case 6:
|
|
41
|
+
return Float32Array;
|
|
42
|
+
case 7:
|
|
43
|
+
return Float64Array;
|
|
44
|
+
default:
|
|
45
|
+
throw new Error('Unsupported marker');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
*
|
|
51
|
+
* @param {BinaryBuffer} buffer
|
|
52
|
+
* @param {Uint8Array|Float32Array|ArrayLike<number>} value
|
|
53
|
+
*/
|
|
54
|
+
function write_typed_array(buffer, value) {
|
|
55
|
+
|
|
56
|
+
buffer.writeUint8(typed_array_to_enum(value));
|
|
57
|
+
buffer.writeUintVar(value.byteLength);
|
|
58
|
+
|
|
59
|
+
const data = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
|
|
60
|
+
buffer.writeBytes(data, 0, value.byteLength);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function read_typed_array(buffer) {
|
|
64
|
+
const type_marker = buffer.readUint8();
|
|
65
|
+
const byte_length = buffer.readUintVar();
|
|
66
|
+
|
|
67
|
+
const array = new Uint8Array(byte_length);
|
|
68
|
+
|
|
69
|
+
buffer.readBytes(array, 0, byte_length);
|
|
70
|
+
|
|
71
|
+
// re-interpret bytes
|
|
72
|
+
const TypedArray = marker_to_typed_array_constructor(type_marker);
|
|
73
|
+
|
|
74
|
+
return new TypedArray(array.buffer, 0);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
*
|
|
79
|
+
* @param {BinaryBuffer} buffer
|
|
80
|
+
* @param {BufferAttribute} value
|
|
81
|
+
*/
|
|
82
|
+
function write_attribute(buffer, value) {
|
|
83
|
+
buffer.writeUTF8String(value.name);
|
|
84
|
+
buffer.writeUintVar(value.itemSize);
|
|
85
|
+
buffer.writeUint8(value.normalized ? 1 : 0);
|
|
86
|
+
buffer.writeUint32(value.usage);
|
|
87
|
+
|
|
88
|
+
write_typed_array(buffer, value.array);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
*
|
|
93
|
+
* @param {BinaryBuffer} buffer
|
|
94
|
+
* @returns {BufferAttribute}
|
|
95
|
+
*/
|
|
96
|
+
function read_attribute(buffer) {
|
|
97
|
+
const name = buffer.readUTF8String();
|
|
98
|
+
const itemSize = buffer.readUintVar();
|
|
99
|
+
const normalized = buffer.readUint8() !== 0;
|
|
100
|
+
const usage = buffer.readUint32();
|
|
101
|
+
|
|
102
|
+
const array = read_typed_array(buffer);
|
|
103
|
+
|
|
104
|
+
const attribute = new BufferAttribute(array, itemSize, normalized);
|
|
105
|
+
|
|
106
|
+
attribute.usage = usage;
|
|
107
|
+
attribute.name = name;
|
|
108
|
+
|
|
109
|
+
return attribute;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export class BufferGeometrySerializationAdapter extends BinaryClassSerializationAdapter {
|
|
113
|
+
constructor() {
|
|
114
|
+
super();
|
|
115
|
+
|
|
116
|
+
this.klass = BufferGeometry;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
*
|
|
121
|
+
* @param {BinaryBuffer} buffer
|
|
122
|
+
* @param {BufferGeometry} value
|
|
123
|
+
*/
|
|
124
|
+
serialize(buffer, value) {
|
|
125
|
+
// write index if one exists
|
|
126
|
+
const index = value.getIndex();
|
|
127
|
+
if (index === null) {
|
|
128
|
+
buffer.writeUint8(0);
|
|
129
|
+
} else {
|
|
130
|
+
buffer.writeUint8(1);
|
|
131
|
+
|
|
132
|
+
write_attribute(buffer, index);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const attributes = value.attributes;
|
|
136
|
+
const attribute_keys = Object.keys(attributes);
|
|
137
|
+
|
|
138
|
+
const attribute_count = attribute_keys.length;
|
|
139
|
+
buffer.writeUintVar(attribute_count);
|
|
140
|
+
|
|
141
|
+
for (let i = 0; i < attribute_count; i++) {
|
|
142
|
+
const attribute_key = attribute_keys[i];
|
|
143
|
+
|
|
144
|
+
buffer.writeUTF8String(attribute_key);
|
|
145
|
+
|
|
146
|
+
const attribute = attributes[attribute_key];
|
|
147
|
+
|
|
148
|
+
write_attribute(buffer, attribute);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
*
|
|
154
|
+
* @param {BinaryBuffer} buffer
|
|
155
|
+
* @param {BufferGeometry} value
|
|
156
|
+
*/
|
|
157
|
+
deserialize(buffer, value) {
|
|
158
|
+
const index_flag = buffer.readUint8();
|
|
159
|
+
|
|
160
|
+
if (index_flag !== 0) {
|
|
161
|
+
value.setIndex(read_attribute(buffer));
|
|
162
|
+
} else {
|
|
163
|
+
value.setIndex(null);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const attribute_count = buffer.readUintVar();
|
|
167
|
+
|
|
168
|
+
for (let i = 0; i < attribute_count; i++) {
|
|
169
|
+
const attribute_key = buffer.readUTF8String();
|
|
170
|
+
|
|
171
|
+
const attribute = read_attribute(buffer);
|
|
172
|
+
|
|
173
|
+
value.setAttribute(attribute_key, attribute);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|