@woosh/meep-engine 2.33.62 → 2.33.67

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 (48) hide show
  1. package/core/FilePath.js +28 -2
  2. package/core/binary/BinaryBuffer.js +13 -0
  3. package/core/geom/2d/quad-tree/QuadTreeNode.js +3 -2
  4. package/ecs/grid/pick.js +44 -0
  5. package/editor/tools/GridPaintTool.js +1 -1
  6. package/editor/tools/paint/TerrainPaintTool.js +1 -1
  7. package/editor/view/GridPickCoordinateView.js +1 -1
  8. package/engine/asset/AssetManager.js +1 -1
  9. package/engine/asset/AssetTransformer.js +2 -1
  10. package/engine/asset/loaders/GLTFAssetLoader.js +5 -21
  11. package/engine/asset/loaders/async_traverse_three_object.js +24 -0
  12. package/engine/ecs/attachment/AttachmentSystem.js +3 -51
  13. package/engine/ecs/fow/FogOfWarRevealerSystem.js +1 -1
  14. package/engine/ecs/fow/shader/screenSpaceFogOfWarShader.js +2 -10
  15. package/engine/ecs/grid/NormalMap2AOMap.js +10 -13
  16. package/engine/ecs/team/Team.js +82 -0
  17. package/engine/ecs/terrain/ecs/BuildLightTexture.js +106 -0
  18. package/engine/ecs/terrain/ecs/PromiseSamplerHeight.js +59 -0
  19. package/engine/ecs/terrain/ecs/Terrain.js +14 -153
  20. package/engine/ecs/tooltip/TooltipComponentSystem.js +1 -1
  21. package/engine/graphics/FULL_SCREEN_QUAD_VERTEX_SHADER.js +10 -0
  22. package/engine/graphics/filter/ImageFilter.js +6 -2
  23. package/engine/graphics/geometry/AttributeSpec.d.ts +8 -0
  24. package/engine/graphics/geometry/VertexDataSpec.d.ts +15 -0
  25. package/engine/graphics/geometry/buffered/deinterleaveBufferAttribute.js +39 -0
  26. package/engine/graphics/geometry/buffered/deinterleaveBufferGeometry.js +50 -0
  27. package/engine/graphics/micron/MICRON_GEOMETRY_FIELD.js +1 -0
  28. package/engine/graphics/micron/MICRON_URI_FIELD.js +1 -0
  29. package/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +10 -7
  30. package/engine/graphics/micron/convert_three_object_to_micron.js +31 -5
  31. package/engine/graphics/micron/format/MicronGeometry.d.ts +4 -0
  32. package/engine/graphics/micron/format/MicronGeometry.js +6 -0
  33. package/engine/graphics/micron/plugin/MicronRenderPlugin.js +110 -6
  34. package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +4 -2
  35. package/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +1 -1
  36. package/engine/graphics/render/webgpu/sample/MeshInstance.js +21 -0
  37. package/engine/graphics/render/webgpu/sample/main.js +2 -2
  38. package/engine/graphics/shaders/AmbientOcclusionShader.js +57 -77
  39. package/engine/graphics/shaders/DenoiseShader.js +119 -0
  40. package/engine/graphics/texture/noise_octaves.js +33 -0
  41. package/engine/graphics/texture/sampler/Sampler2D2Texture.js +7 -18
  42. package/engine/graphics/texture/sampler/debug/paintSamplerOnHTML.js +8 -5
  43. package/engine/graphics/texture/sampler/sampler2DToFloat32Texture.js +10 -3
  44. package/engine/graphics/util/modelHitTest.js +63 -0
  45. package/generation/example/filters/SampleGroundMoistureFilter.js +2 -1
  46. package/generation/filtering/numeric/complex/CellFilterGaussianBlur.js +29 -13
  47. package/generation/grid/GridData.js +17 -2
  48. package/package.json +1 -1
@@ -0,0 +1,59 @@
1
+ import { BinaryBuffer } from "../../../../core/binary/BinaryBuffer.js";
2
+ import { deserializeTexture } from "../../../graphics/texture/sampler/TextureBinaryBufferSerializer.js";
3
+ import { Sampler2D } from "../../../graphics/texture/sampler/Sampler2D.js";
4
+ import { GameAssetType } from "../../../asset/GameAssetType.js";
5
+ import rgbaData2valueSampler2D from "../../../graphics/texture/sampler/rgbaData2valueSampler2D.js";
6
+
7
+ /**
8
+ *
9
+ * @param zRange
10
+ * @param heightMapURL
11
+ * @param {AssetManager} assetManager
12
+ * @returns {Promise<any>}
13
+ */
14
+ export function promiseSamplerHeight(zRange, heightMapURL, assetManager) {
15
+ return new Promise(function (fulfill, reject) {
16
+
17
+ function assetObtained(asset) {
18
+ const array = asset.create();
19
+
20
+ const binaryBuffer = new BinaryBuffer();
21
+ //
22
+ // binaryBuffer.writeUint32(2560);
23
+ // binaryBuffer.writeUint32(2560);
24
+ //
25
+ // binaryBuffer.writeUint8(1);
26
+ //
27
+ // binaryBuffer.writeUint8(6);
28
+
29
+ binaryBuffer.writeBytes(new Uint8Array(array), 0, array.length);
30
+
31
+ binaryBuffer.position = 0;
32
+
33
+ const sampler2D = deserializeTexture(binaryBuffer);
34
+ fulfill(sampler2D);
35
+ }
36
+
37
+
38
+ if (heightMapURL === undefined) {
39
+ console.warn('Height map is not specified');
40
+ const defaultSampler = new Sampler2D(new Uint8Array(1), 1, 1, 1);
41
+ fulfill(defaultSampler);
42
+ } else if (heightMapURL.endsWith('.bin')) {
43
+ //load texture from a binary file
44
+ assetManager.get(heightMapURL, GameAssetType.ArrayBuffer, assetObtained, reject);
45
+ } else {
46
+ assetManager.get(heightMapURL, GameAssetType.Image, function (asset) {
47
+ const image = asset.create();
48
+
49
+ // plane
50
+ const imgWidth = image.width;
51
+ const imgHeight = image.height;
52
+
53
+ const samplerHeight = rgbaData2valueSampler2D(image.data, imgWidth, imgHeight, zRange, -zRange / 2);
54
+
55
+ fulfill(samplerHeight);
56
+ }, reject);
57
+ }
58
+ });
59
+ }
@@ -14,9 +14,6 @@ import {
14
14
  } from 'three';
15
15
  import { clamp } from "../../../../core/math/clamp.js";
16
16
  import { Sampler2D } from '../../../graphics/texture/sampler/Sampler2D.js';
17
- import heightMap2NormalMap from '../../grid/HeightMap2NormalMap.js';
18
- import normalMap2AOMap from '../../grid/NormalMap2AOMap.js';
19
- import rgbaData2valueSampler2D from '../../../graphics/texture/sampler/rgbaData2valueSampler2D.js';
20
17
  import { BinaryNode } from '../../../../core/bvh2/BinaryNode.js';
21
18
  import Vector2 from '../../../../core/geom/Vector2.js';
22
19
  import { TerrainOverlay } from '../overlay/TerrainOverlay.js';
@@ -24,13 +21,9 @@ import { TerrainOverlay } from '../overlay/TerrainOverlay.js';
24
21
  import Clouds from '../TerrainClouds.js';
25
22
 
26
23
  import TerrainTileManager from '../tiles/TerrainTileManager.js';
27
- import { WebGLRendererPool } from "../../../graphics/render/RendererPool.js";
28
- import { deserializeTexture } from "../../../graphics/texture/sampler/TextureBinaryBufferSerializer.js";
29
- import { BinaryBuffer } from "../../../../core/binary/BinaryBuffer.js";
30
24
  import { TerrainPreview } from "../TerrainPreview.js";
31
25
  import { assert } from "../../../../core/assert.js";
32
26
  import { GameAssetType } from "../../../asset/GameAssetType.js";
33
- import { writeSample2DDataToDataTexture } from "../../../graphics/texture/sampler/writeSampler2DDataToDataTexture.js";
34
27
  import { TerrainLayers } from "./layers/TerrainLayers.js";
35
28
  import { SplatMaterial } from "../../../graphics/material/SplatMaterial.js";
36
29
  import { loadLegacyTerrainSplats, SplatMapping } from "./splat/SplatMapping.js";
@@ -41,147 +34,8 @@ import { MeepSettings } from "../../../MeepSettings.js";
41
34
  import { loadLegacyTerrainLayers } from "./layers/loadLegacyTerrainLayers.js";
42
35
  import { TerrainFlags } from "./TerrainFlags.js";
43
36
  import { IllegalStateException } from "../../../../core/fsm/exceptions/IllegalStateException.js";
44
-
45
- /**
46
- *
47
- * @param zRange
48
- * @param heightMapURL
49
- * @param {AssetManager} assetManager
50
- * @returns {Promise<any>}
51
- */
52
- function promiseSamplerHeight(zRange, heightMapURL, assetManager) {
53
- return new Promise(function (fulfill, reject) {
54
-
55
- function assetObtained(asset) {
56
- const array = asset.create();
57
-
58
- const binaryBuffer = new BinaryBuffer();
59
- //
60
- // binaryBuffer.writeUint32(2560);
61
- // binaryBuffer.writeUint32(2560);
62
- //
63
- // binaryBuffer.writeUint8(1);
64
- //
65
- // binaryBuffer.writeUint8(6);
66
-
67
- binaryBuffer.writeBytes(new Uint8Array(array), 0, array.length);
68
-
69
- binaryBuffer.position = 0;
70
-
71
- const sampler2D = deserializeTexture(binaryBuffer);
72
- fulfill(sampler2D);
73
- }
74
-
75
-
76
- if (heightMapURL === undefined) {
77
- console.warn('Height map is not specified');
78
- const defaultSampler = new Sampler2D(new Uint8Array(1), 1, 1, 1);
79
- fulfill(defaultSampler);
80
- } else if (heightMapURL.endsWith('.bin')) {
81
- //load texture from a binary file
82
- assetManager.get(heightMapURL, GameAssetType.ArrayBuffer, assetObtained, reject);
83
- } else {
84
- assetManager.get(heightMapURL, GameAssetType.Image, function (asset) {
85
- const image = asset.create();
86
-
87
- // plane
88
- const imgWidth = image.width;
89
- const imgHeight = image.height;
90
-
91
- const samplerHeight = rgbaData2valueSampler2D(image.data, imgWidth, imgHeight, zRange, -zRange / 2);
92
-
93
- fulfill(samplerHeight);
94
- }, reject);
95
- }
96
- });
97
- }
98
-
99
- /**
100
- *
101
- * @param {WebGLRenderer} renderer
102
- * @param {Sampler2D} sampler
103
- * @returns {Promise<Sampler2D>}
104
- */
105
- function promiseSamplerNormal(renderer, sampler) {
106
-
107
- console.time("generating normal map");
108
- const normalSampler = heightMap2NormalMap(renderer, sampler);
109
- console.timeEnd("generating normal map");
110
-
111
-
112
- return Promise.resolve(normalSampler);
113
- }
114
-
115
- /**
116
- *
117
- * @param {WebGLRenderer} renderer
118
- * @param {Promise<Sampler2D>} pSamplerNormal
119
- * @param {Sampler2D} samplerHeight
120
- * @param {Vector2} resolution
121
- * @param {number} rayLength
122
- * @returns {Promise<unknown>}
123
- */
124
- function promiseSamplerAO(
125
- renderer,
126
- pSamplerNormal,
127
- samplerHeight,
128
- resolution,
129
- rayLength
130
- ) {
131
- return new Promise(function (resolve, reject) {
132
- Promise.all([pSamplerNormal]).then(function (values) {
133
- const samplerNormal = values[0];
134
- console.time("generating AO map");
135
- const occlusionSampler = normalMap2AOMap(
136
- renderer,
137
- samplerHeight,
138
- samplerNormal,
139
- resolution,
140
- rayLength
141
- );
142
- console.timeEnd("generating AO map");
143
- //console.info(occlusionSampler);
144
- //
145
- // paintSamplerOnHTML(samplerHeight, 0, 0, 40, 3);
146
- // paintSamplerOnHTML(samplerNormal, 1, 0, 128, 1);
147
- // paintSamplerOnHTML(occlusionSampler, 2, 0, 1, 0);
148
- //
149
- //
150
- resolve(occlusionSampler);
151
- }, reject);
152
- });
153
- }
154
-
155
- /**
156
- *
157
- * @param {DataTexture} texture
158
- * @param {Vector2} resolution
159
- * @param {Sampler2D} heightSampler
160
- * @param {number} heightRange
161
- * @param {number} [rayLength]
162
- * @returns {Promise}
163
- */
164
- function buildLightTexture({ texture, heightSampler, resolution, rayLength = 17 }) {
165
-
166
- const renderer = WebGLRendererPool.global.get();
167
-
168
- if (resolution === undefined) {
169
- resolution = new Vector2(texture.image.width, texture.image.height);
170
- }
171
-
172
- const normal = promiseSamplerNormal(renderer, heightSampler);
173
- const ao = promiseSamplerAO(renderer, normal, heightSampler, resolution, rayLength);
174
-
175
- const promise = ao.then(sampler => {
176
- writeSample2DDataToDataTexture(sampler, texture);
177
- });
178
-
179
- Promise.all([normal, ao]).finally(() => {
180
- WebGLRendererPool.global.release(renderer);
181
- });
182
-
183
- return promise;
184
- }
37
+ import { buildLightTexture } from "./BuildLightTexture.js";
38
+ import { promiseSamplerHeight } from "./PromiseSamplerHeight.js";
185
39
 
186
40
  let idCounter = 0;
187
41
 
@@ -903,13 +757,13 @@ class Terrain {
903
757
  this.updateWorkerHeights();
904
758
  }
905
759
 
906
- updateWorkerHeights() {
760
+ async updateWorkerHeights() {
907
761
  const s = this.samplerHeight;
908
762
  const worker = this.buildWorker;
909
763
 
910
- worker.setHeightSampler(s.data, s.itemSize, s.width, s.height);
764
+ await worker.setHeightSampler(s.data, s.itemSize, s.width, s.height);
911
765
 
912
- return worker.computeHeightRange()
766
+ return await worker.computeHeightRange()
913
767
  .then(({ min, max }) => {
914
768
  this.tiles.setHeightRange(min, max);
915
769
  });
@@ -1012,7 +866,12 @@ class Terrain {
1012
866
  this.setFlag(TerrainFlags.Built);
1013
867
  }
1014
868
 
1015
- buildLightMap() {
869
+ /**
870
+ *
871
+ * @param {number} quality resolution in texels per grid cell (4 = 4x4 light map texels per single grid cell)
872
+ * @return {Promise<DataTexture>}
873
+ */
874
+ buildLightMap(quality = 4) {
1016
875
 
1017
876
 
1018
877
  const size_x = this.size.x;
@@ -1035,7 +894,9 @@ class Terrain {
1035
894
 
1036
895
  const promise = buildLightTexture({
1037
896
  texture,
1038
- heightSampler: this.samplerHeight
897
+ heightSampler: this.samplerHeight,
898
+ worldSize: new Vector2(size_x * this.gridScale, size_y * this.gridScale),
899
+ resolution: new Vector2(size_x * quality, size_y *quality)
1039
900
  });
1040
901
 
1041
902
 
@@ -2,10 +2,10 @@ import { System } from "../System.js";
2
2
  import { TooltipComponent } from "./TooltipComponent.js";
3
3
  import Vector3 from "../../../core/geom/Vector3.js";
4
4
  import { MeshSystem } from "../../graphics/ecs/mesh/MeshSystem.js";
5
- import { modelHitTest } from "../../../../model/game/util/ScreenGridPicker.js";
6
5
  import { SurfacePoint3 } from "../../../core/geom/3d/SurfacePoint3.js";
7
6
  import { VisualTip } from "../../../view/tooltip/VisualTip.js";
8
7
  import Rectangle from "../../../core/geom/Rectangle.js";
8
+ import { modelHitTest } from "../../graphics/util/modelHitTest.js";
9
9
 
10
10
  const ray_source = new Vector3();
11
11
  const ray_direction = new Vector3();
@@ -0,0 +1,10 @@
1
+ export const FULL_SCREEN_QUAD_VERTEX_SHADER = `
2
+ varying vec2 vUv;
3
+
4
+ void main() {
5
+
6
+ vUv = uv;
7
+
8
+ gl_Position = vec4( (uv - 0.5)*2.0, 0.0, 1.0 );
9
+
10
+ }`;
@@ -5,13 +5,14 @@
5
5
 
6
6
  import { LinearFilter, Mesh, OrthographicCamera, Scene, ShaderMaterial, WebGLRenderTarget } from 'three';
7
7
  import { FULL_SCREEN_TRIANGLE_GEOMETRY } from "../geometry/FULL_SCREEN_TRIANGLE_GEOMETRY.js";
8
+ import { FULL_SCREEN_QUAD_VERTEX_SHADER } from "../FULL_SCREEN_QUAD_VERTEX_SHADER.js";
8
9
 
9
10
  /**
10
11
  *
11
12
  * @param {WebGLRenderer} renderer
12
13
  * @param {number} width
13
14
  * @param {number} height
14
- * @param {{vertexShader:string,fragmentShader:string, uniforms?:Object, defines?:Object}} processShader
15
+ * @param {{vertexShader?:string,fragmentShader:string, uniforms?:Object, defines?:Object}} processShader
15
16
  * @param {Uint8Array} [destination]
16
17
  * @return {{array: Uint8Array, renderer: WebGLRenderer}}
17
18
  */
@@ -34,9 +35,12 @@ function processTexture(
34
35
  scene.add(camera);
35
36
 
36
37
  //make a quad to render
37
- const material = new ShaderMaterial(processShader);
38
+ const material = new ShaderMaterial(Object.assign({ vertexShader: FULL_SCREEN_QUAD_VERTEX_SHADER }, processShader));
39
+
38
40
  material.lights = false;
39
41
  material.fog = false;
42
+ material.uniformsNeedUpdate = true;
43
+ material.needsUpdate = true;
40
44
 
41
45
  const quad = new Mesh(FULL_SCREEN_TRIANGLE_GEOMETRY, material);
42
46
 
@@ -0,0 +1,8 @@
1
+ import {DataType} from "../../../core/parser/simple/DataType";
2
+
3
+ export class AttributeSpec {
4
+ readonly name: string
5
+ readonly type: DataType
6
+ readonly itemSize: number
7
+ readonly normalized: boolean
8
+ }
@@ -0,0 +1,15 @@
1
+ import {AttributeSpec} from "./AttributeSpec";
2
+
3
+ export class VertexDataSpec {
4
+ readonly attributes: AttributeSpec[]
5
+
6
+ getAttributeByName(name: string): AttributeSpec | undefined
7
+
8
+ add(attribute: AttributeSpec): this
9
+
10
+ setAttributes(attributes: AttributeSpec[]): void
11
+
12
+ equals(other: VertexDataSpec): boolean
13
+
14
+ hash(): number
15
+ }
@@ -0,0 +1,39 @@
1
+ import { BufferAttribute } from "three";
2
+
3
+
4
+ /**
5
+ *
6
+ * @param {THREE.InterleavedBufferAttribute|THREE.BufferAttribute} source_attribute
7
+ * @returns {THREE.BufferAttribute}
8
+ */
9
+ export function deinterleaveBufferAttribute(source_attribute) {
10
+ if (source_attribute.isInterleavedBufferAttribute !== true && source_attribute.isBufferAttribute) {
11
+ return source_attribute;
12
+ }
13
+
14
+ const source_data = source_attribute.data;
15
+ const source_data_array = source_data.array;
16
+ const stride = source_data.stride;
17
+
18
+ const item_count = source_attribute.count;
19
+ const itemSize = source_attribute.itemSize;
20
+ const array_size = item_count * itemSize;
21
+
22
+ const offset = source_attribute.offset;
23
+
24
+ const destination_array = new source_data_array.constructor(array_size);
25
+
26
+ const attribute = new BufferAttribute(destination_array, itemSize);
27
+
28
+ attribute.normalized = source_attribute.normalized;
29
+ attribute.name = source_attribute.name;
30
+
31
+ // copy data
32
+ for (let i = 0; i < item_count; i++) {
33
+ for (let j = 0; j < itemSize; j++) {
34
+ destination_array[i * itemSize + j] = source_data_array[i * stride + offset + j];
35
+ }
36
+ }
37
+
38
+ return attribute;
39
+ }
@@ -0,0 +1,50 @@
1
+ import { BufferGeometry } from "three";
2
+ import { deinterleaveBufferAttribute } from "./deinterleaveBufferAttribute.js";
3
+
4
+ /**
5
+ *
6
+ * @param {THREE.BufferGeometry} geometry
7
+ * @returns {THREE.BufferGeometry}
8
+ */
9
+ export function deinterleaveBufferGeometry(geometry) {
10
+ const result = new BufferGeometry();
11
+
12
+ if (geometry.getIndex() !== null) {
13
+ result.setIndex(deinterleaveBufferAttribute(geometry.getIndex()));
14
+ }
15
+
16
+ for (const attribute_key in geometry.attributes) {
17
+ const source_attribute = geometry.attributes[attribute_key];
18
+
19
+ result.setAttribute(attribute_key, deinterleaveBufferAttribute(source_attribute));
20
+ }
21
+
22
+ // copy other bits
23
+ result.name = geometry.name;
24
+
25
+ result.morphTargetsRelative = geometry.morphTargetsRelative;
26
+
27
+ for (const attribute_key in geometry.morphAttributes) {
28
+ const source_attributes = geometry.morphAttributes[attribute_key];
29
+
30
+ const result_attributes = [];
31
+
32
+ result.morphAttributes[attribute_key] = result_attributes;
33
+
34
+ for (let i = 0; i < source_attributes.length; i++) {
35
+ const source_attribute = source_attributes[i];
36
+ result_attributes[i] = deinterleaveBufferAttribute(source_attribute);
37
+ }
38
+ }
39
+
40
+ result.groups = geometry.groups.slice();
41
+
42
+
43
+ result.boundingBox = geometry.boundingBox !== null ? geometry.boundingBox.clone() : null;
44
+ result.boundingSphere = geometry.boundingSphere !== null ? geometry.boundingSphere.clone() : null;
45
+ result.drawRange.start = geometry.drawRange.start;
46
+ result.drawRange.count = geometry.drawRange.count;
47
+ result.userData = JSON.parse(JSON.stringify(geometry.userData));
48
+
49
+ return result;
50
+ }
@@ -0,0 +1 @@
1
+ export const MICRON_GEOMETRY_FIELD = '@micron_geometry';
@@ -0,0 +1 @@
1
+ export const MICRON_URI_FIELD = '@micron_path';
@@ -12,6 +12,7 @@ import { expandConnectivityByLocality } from "../../../../core/geom/3d/topology/
12
12
  import { build_geometry_info } from "./build_geometry_info.js";
13
13
  import { build_leaf_patches_metis } from "./clustering/build_leaf_patches_metis.js";
14
14
  import { compute_buffer_geometry_byte_size } from "../../geometry/buffered/compute_buffer_geometry_byte_size.js";
15
+ import { deinterleaveBufferGeometry } from "../../geometry/buffered/deinterleaveBufferGeometry.js";
15
16
 
16
17
  /**
17
18
  * Returns current time in milliseconds
@@ -105,11 +106,13 @@ const PRINT_VERBOSE_STATS = false;
105
106
  * @returns {MicronGeometry}
106
107
  */
107
108
  export async function buildMicronGeometryFromBufferGeometry(input) {
109
+ const source_geometry = deinterleaveBufferGeometry(input);
110
+
108
111
  // build topology representation
109
112
  const topoMesh = new TopoMesh();
110
113
 
111
- const position_attribute = input.getAttribute("position");
112
- const index_attribute = input.index;
114
+ const position_attribute = source_geometry.getAttribute("position");
115
+ const index_attribute = source_geometry.index;
113
116
 
114
117
  const face_index_array = index_attribute.array;
115
118
  const vertex_position_array = position_attribute.array;
@@ -183,18 +186,18 @@ export async function buildMicronGeometryFromBufferGeometry(input) {
183
186
 
184
187
  const r = new MicronGeometry();
185
188
 
186
- r.proxy = input; // TODO use r.buildProxy(1) instead
189
+ r.proxy = source_geometry; // TODO use r.buildProxy(1) instead
187
190
 
188
191
  r.source_triangle_count = index_attribute.count / 3;
189
- r.source_vertex_count = input.getAttribute('position').count;
190
- r.source_byte_size = compute_buffer_geometry_byte_size(input);
192
+ r.source_vertex_count = source_geometry.getAttribute('position').count;
193
+ r.source_byte_size = compute_buffer_geometry_byte_size(source_geometry);
191
194
 
192
195
  // console.time('build geometry');
193
196
 
194
- const vertex_attributes = attributes_from_buffer_geometry(input);
197
+ const vertex_attributes = attributes_from_buffer_geometry(source_geometry);
195
198
 
196
199
  r.vertex_spec.setAttributes(vertex_attributes);
197
- r.root = compilePatchGraph(root, input, r.vertex_spec);
200
+ r.root = compilePatchGraph(root, source_geometry, r.vertex_spec);
198
201
 
199
202
  r.initialize();
200
203
 
@@ -4,6 +4,7 @@ import { computeGeometryEquality } from "../../asset/loaders/geometry/geometry/c
4
4
  import { buildMicronGeometryFromBufferGeometry } from "./build/buildMicronGeometryFromBufferGeometry.js";
5
5
  import { ThreeMicronMesh } from "./format/ThreeMicronMesh.js";
6
6
  import { AsyncMapWrapper } from "../../../core/collection/map/AsyncMapWrapper.js";
7
+ import { MICRON_GEOMETRY_FIELD } from "./MICRON_GEOMETRY_FIELD.js";
7
8
 
8
9
  /**
9
10
  *
@@ -19,7 +20,6 @@ const pending_cache = new HashMap({
19
20
  keyEqualityFunction: computeGeometryEquality
20
21
  });
21
22
 
22
-
23
23
  /**
24
24
  *
25
25
  * @param {THREE.Object3D} object
@@ -36,10 +36,22 @@ export async function convert_three_object_to_micron(object, micron_cache = defa
36
36
  * @returns {MicronGeometry}
37
37
  */
38
38
  async function obtain_geometry(g) {
39
- const existing = await micron_cache.get(g);
39
+ const attached_micron = g[MICRON_GEOMETRY_FIELD];
40
40
 
41
- if (existing !== undefined && existing !== null) {
42
- return existing;
41
+ if (attached_micron !== undefined && attached_micron.isMicronGeometry) {
42
+ // micron geometry is already attached, use it
43
+ return attached_micron;
44
+ }
45
+
46
+ const cached_micron = await micron_cache.get(g);
47
+
48
+
49
+ if (cached_micron !== undefined && cached_micron !== null) {
50
+
51
+ // set proxy
52
+ cached_micron.proxy = g;
53
+
54
+ return cached_micron;
43
55
  }
44
56
 
45
57
  const pending = pending_cache.get(g);
@@ -54,8 +66,14 @@ export async function convert_three_object_to_micron(object, micron_cache = defa
54
66
 
55
67
  promises.push(micron_geometry_promise);
56
68
 
69
+ /**
70
+ *
71
+ * @type {MicronGeometry}
72
+ */
57
73
  const micron_geometry = await micron_geometry_promise;
58
74
 
75
+ micron_geometry.proxy = g;
76
+
59
77
  await micron_cache.set(g, micron_geometry);
60
78
 
61
79
  return micron_geometry;
@@ -90,7 +108,15 @@ export async function convert_three_object_to_micron(object, micron_cache = defa
90
108
  && !mesh.isSkinnedMesh // skinned meshes not supported
91
109
  ) {
92
110
 
93
- const micronGeometry = await obtain_geometry(mesh.geometry);
111
+ let micronGeometry;
112
+ try {
113
+ micronGeometry = await obtain_geometry(mesh.geometry);
114
+ } catch (e) {
115
+ console.error(`Failed to convert geometry to micron, skipping : ${e}`);
116
+
117
+ // return original
118
+ return mesh;
119
+ }
94
120
 
95
121
  const micron_mesh = new ThreeMicronMesh(micronGeometry, mesh.material);
96
122
 
@@ -1,5 +1,9 @@
1
1
  import {BufferGeometry} from "three";
2
+ import {VertexDataSpec} from "../../geometry/VertexDataSpec";
2
3
 
3
4
  export class MicronGeometry {
5
+ vertex_spec: VertexDataSpec
4
6
  public proxy: BufferGeometry
7
+
8
+ initialize(): void
5
9
  }
@@ -117,3 +117,9 @@ export class MicronGeometry {
117
117
  return this.__patches[id];
118
118
  }
119
119
  }
120
+
121
+ /**
122
+ * @readonly
123
+ * @type {boolean}
124
+ */
125
+ MicronGeometry.prototype.isMicronGeometry = true;