@woosh/meep-engine 2.33.36 → 2.33.40
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/binary/2/BinaryUint32BVH.js +3 -3
- package/core/collection/HashMap.js +19 -12
- package/core/collection/array/typed/typed_array_copy.js +2 -2
- package/core/collection/table/RowFirstTable.js +13 -8
- package/core/collection/table/RowFirstTableSpec.js +6 -0
- package/core/color/Color.js +5 -9
- package/core/color/ColorUtils.js +4 -150
- package/core/color/YCbCr_to_rgb_uint24.js +20 -0
- package/core/color/hsv2rgb.js +54 -0
- package/core/color/int2rgb.js +12 -0
- package/core/color/parseHex.js +18 -0
- package/core/color/rgb2hex.js +16 -0
- package/core/color/rgb2hsv.js +47 -0
- package/core/color/rgb2uint24.js +17 -0
- package/core/color/rgb_to_YCbCr_uint24.js +18 -0
- package/core/geom/3d/aabb/aabb3_matrix4_project_by_corners.js +1 -1
- package/core/geom/3d/aabb/compute_aabb_from_points.js +28 -0
- package/core/geom/3d/morton/mortonEncode_magicbits.js +7 -6
- package/core/geom/3d/morton/v3_morton_encode_transformed.js +15 -11
- package/core/geom/3d/plane/orient3d_fast.js +51 -0
- package/core/geom/3d/plane/plane_computeConvex3PlaneIntersection.js +5 -0
- package/core/geom/3d/tetrahedra/GetDepthForTetrahedronProbe.glsl +43 -0
- package/core/geom/3d/tetrahedra/compute_bounding_simplex_3d.js +177 -0
- package/core/geom/3d/tetrahedra/compute_bounding_simplex_3d.spec.js +66 -0
- package/core/geom/3d/tetrahedra/compute_circumsphere.js +271 -0
- package/core/geom/3d/tetrahedra/compute_delaunay_tetrahedral_mesh.js +50 -0
- package/core/geom/3d/tetrahedra/compute_delaunay_tetrahedral_mesh.spec.js +14 -0
- package/core/geom/3d/tetrahedra/point_in_tetrahedron_circumsphere.js +77 -0
- package/core/geom/3d/tetrahedra/tetrahedra_collection.js +454 -0
- package/core/geom/3d/tetrahedra/tetrahedron_contains_point.js +26 -0
- package/core/geom/Quaternion.js +4 -0
- package/core/math/hash/murmur3_32.js +39 -0
- package/core/process/undo/ActionProcessor.d.ts +2 -0
- package/core/process/undo/ActionProcessor.js +15 -4
- package/editor/tools/FoliagePaintTool.js +1 -1
- package/editor/tools/GridPaintTool.js +1 -1
- package/engine/asset/loaders/GLTFAssetLoader.js +4 -8
- package/engine/ecs/System.d.ts +24 -1
- package/engine/ecs/foliage/InstancedFoliage.js +45 -0
- package/engine/ecs/foliage/ecs/InstancedMeshLayer.js +4 -0
- package/engine/ecs/storage/BinaryBufferSerializer.js +48 -38
- package/engine/ecs/storage/binary/collection/BinaryCollectionSerializer.js +1 -1
- package/engine/ecs/terrain/ecs/splat/SplatMapOptimizerDebugger.js +1 -1
- package/engine/ecs/terrain/tiles/TerrainTile.js +1 -1
- package/engine/graphics/GraphicsEngine.js +7 -0
- package/engine/graphics/ecs/light/binding/fp/FPLightBinding.js +1 -1
- package/engine/graphics/ecs/mesh/Mesh.js +2 -2
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +13 -0
- package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +339 -314
- package/engine/graphics/micron/prototypeVirtualGeometry.js +4 -1
- package/engine/graphics/micron/render/v1/VGThreeRenderer.js +6 -2
- package/engine/graphics/particles/node-based/rendering/billboard/ParticleBillboardShader.js +1 -1
- package/engine/graphics/particles/particular/engine/parameter/ParameterLookupTable.js +20 -24
- package/engine/graphics/particles/particular/engine/renderers/billboard/ParticleBillboardMaterial.js +100 -55
- package/engine/graphics/particles/particular/engine/shader/ShaderManager.js +7 -2
- package/engine/graphics/particles/particular/engine/utils/volume/ParticleVolume.js +1 -0
- package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +2 -2
- package/engine/graphics/render/buffer/simple-fx/DepthLimitedBlur.js +9 -4
- package/engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js +7 -1
- package/engine/graphics/render/forward_plus/LightManager.js +295 -51
- package/engine/graphics/render/forward_plus/LightManager.spec.js +1 -1
- package/engine/graphics/render/forward_plus/PointLightData.js +9 -13
- package/engine/graphics/render/forward_plus/cluster/compute_light_data_hash_0.js +1 -1
- package/engine/graphics/render/forward_plus/data/TextureBackedMemoryRegion.js +10 -1
- package/engine/graphics/render/forward_plus/debug/LightClusterVolumeMaterial.js +1 -1
- package/engine/graphics/render/forward_plus/debug/buildLightClusterWidget.js +3 -1
- package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_ACCUMULATION.js +31 -18
- package/engine/graphics/render/forward_plus/materials/fp_build_fragment_shader.js +18 -4
- package/engine/graphics/render/forward_plus/model/AbstractLight.js +50 -0
- package/engine/graphics/render/forward_plus/model/Decal.js +68 -0
- package/engine/graphics/render/forward_plus/{PointLight.js → model/PointLight.js} +19 -11
- package/engine/graphics/render/forward_plus/{SpotLight.js → model/SpotLight.js} +20 -12
- package/engine/graphics/render/forward_plus/plugin/ForwardPlusRenderingPlugin.js +1 -1
- package/engine/graphics/render/forward_plus/plugin/ptototypeFPPlugin.js +6 -5
- package/engine/graphics/render/forward_plus/{prototypeLightManager.js → prototype/prototypeLightManager.js} +100 -25
- package/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +29 -20
- package/engine/graphics/render/visibility/IncrementalDeltaSet.d.ts +2 -0
- package/engine/graphics/render/visibility/IncrementalDeltaSet.js +1 -0
- package/engine/graphics/render/visibility/VisibilityComputer.js +8 -7
- package/engine/graphics/shaders/TerrainShader.js +5 -5
- package/engine/graphics/shadows/testShadowMapRendering.js +192 -0
- package/engine/graphics/texture/atlas/AbstractTextureAtlas.js +19 -0
- package/engine/graphics/texture/atlas/CachingTextureAtlas.js +99 -0
- package/engine/graphics/texture/atlas/ManagedTextureAtlas.js +19 -39
- package/engine/graphics/texture/atlas/ReferencedTextureAtlas.js +75 -0
- package/engine/graphics/texture/atlas/TextureAtlas.js +22 -2
- package/engine/reference/v2/Reference.d.ts +4 -0
- package/engine/reference/v2/Reference.js +3 -1
- package/package.json +2 -1
- package/view/elements/ColorPickerView.js +2 -1
|
@@ -11,390 +11,415 @@ import { composeCompile } from "../../material/composeCompile.js";
|
|
|
11
11
|
import { typed_array_copy } from "../../../../core/collection/array/typed/typed_array_copy.js";
|
|
12
12
|
import { rewriteMaterial } from "./rewriteMaterial.js";
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
*
|
|
16
|
-
* @constructor
|
|
17
|
-
*/
|
|
18
|
-
function InstancedMeshGroup() {
|
|
19
|
-
this.__threeGeometry = null;
|
|
20
|
-
this.__threeInstanceGeometry = null;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @private
|
|
24
|
-
* @type {number}
|
|
25
|
-
*/
|
|
26
|
-
this.count = 0;
|
|
27
|
-
this.capacity = 0;
|
|
28
|
-
|
|
29
|
-
this.growFactor = 1.1;
|
|
14
|
+
export class InstancedMeshGroup {
|
|
30
15
|
/**
|
|
31
|
-
*
|
|
32
|
-
* @
|
|
16
|
+
*
|
|
17
|
+
* @constructor
|
|
33
18
|
*/
|
|
34
|
-
|
|
19
|
+
constructor() {
|
|
20
|
+
/**
|
|
21
|
+
* Instanced geometry
|
|
22
|
+
* @type {THREE.InstancedBufferGeometry|null}
|
|
23
|
+
* @private
|
|
24
|
+
*/
|
|
25
|
+
this.__threeGeometry = null;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Geometry of a single instance
|
|
29
|
+
* @type {THREE.BufferGeometry|null}
|
|
30
|
+
* @private
|
|
31
|
+
*/
|
|
32
|
+
this.__threeInstanceGeometry = null;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @private
|
|
36
|
+
* @type {number}
|
|
37
|
+
*/
|
|
38
|
+
this.count = 0;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
*
|
|
42
|
+
* @type {number}
|
|
43
|
+
*/
|
|
44
|
+
this.capacity = 0;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
*
|
|
48
|
+
* @type {number}
|
|
49
|
+
*/
|
|
50
|
+
this.growFactor = 1.1;
|
|
51
|
+
/**
|
|
52
|
+
* Minimum spare capacity increase during growing
|
|
53
|
+
* @type {number}
|
|
54
|
+
*/
|
|
55
|
+
this.growConstant = 4;
|
|
56
|
+
|
|
57
|
+
this.shrinkFactor = 0.5;
|
|
58
|
+
/**
|
|
59
|
+
* Minimum capacity reduction for shrinkage to occur
|
|
60
|
+
* @type {number}
|
|
61
|
+
*/
|
|
62
|
+
this.shrinkConstant = 64;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
*
|
|
66
|
+
* @type {InstancedBufferAttribute}
|
|
67
|
+
* @private
|
|
68
|
+
*/
|
|
69
|
+
this.__attributePosition = null;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
*
|
|
73
|
+
* @type {InstancedBufferAttribute}
|
|
74
|
+
* @private
|
|
75
|
+
*/
|
|
76
|
+
this.__attributeRotation = null;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
*
|
|
80
|
+
* @type {InstancedBufferAttribute}
|
|
81
|
+
* @private
|
|
82
|
+
*/
|
|
83
|
+
this.__attributeScale = null;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
*
|
|
87
|
+
* @type {Material}
|
|
88
|
+
* @private
|
|
89
|
+
*/
|
|
90
|
+
this.__material = null;
|
|
91
|
+
|
|
92
|
+
this.indices = [];
|
|
93
|
+
this.references = [];
|
|
94
|
+
|
|
95
|
+
this.mesh = ThreeFactory.createMesh();
|
|
96
|
+
}
|
|
35
97
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
this.shrinkConstant = 64;
|
|
98
|
+
dispose() {
|
|
99
|
+
if (this.__threeGeometry !== null) {
|
|
100
|
+
this.__threeGeometry.dispose();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
42
103
|
|
|
43
104
|
/**
|
|
44
105
|
*
|
|
45
|
-
* @
|
|
46
|
-
* @private
|
|
106
|
+
* @param {THREE.BufferGeometry} geometry
|
|
47
107
|
*/
|
|
48
|
-
|
|
108
|
+
setGeometry(geometry) {
|
|
109
|
+
if (geometry.isBufferGeometry !== true) {
|
|
110
|
+
throw new Error(`Expected THREE.BufferedGeometry, got something else instead.`);
|
|
111
|
+
}
|
|
49
112
|
|
|
50
|
-
|
|
51
|
-
*
|
|
52
|
-
* @type {InstancedBufferAttribute}
|
|
53
|
-
* @private
|
|
54
|
-
*/
|
|
55
|
-
this.__attributeRotation = null;
|
|
113
|
+
this.__threeInstanceGeometry = geometry;
|
|
56
114
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
* @type {InstancedBufferAttribute}
|
|
60
|
-
* @private
|
|
61
|
-
*/
|
|
62
|
-
this.__attributeScale = null;
|
|
115
|
+
this.build();
|
|
116
|
+
}
|
|
63
117
|
|
|
64
118
|
/**
|
|
65
119
|
*
|
|
66
|
-
* @
|
|
67
|
-
* @private
|
|
120
|
+
* @param {THREE.Material|THREE.ShaderMaterial} sourceMaterial
|
|
68
121
|
*/
|
|
69
|
-
|
|
122
|
+
setMaterial(sourceMaterial) {
|
|
123
|
+
const material = sourceMaterial.clone();
|
|
124
|
+
|
|
125
|
+
if (material.isShaderMaterial) {
|
|
126
|
+
// transfer source material uniforms
|
|
127
|
+
for (const uniformsKey in material.uniforms) {
|
|
128
|
+
material.uniforms[uniformsKey] = sourceMaterial.uniforms[uniformsKey];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
70
131
|
|
|
71
|
-
this.indices = [];
|
|
72
|
-
this.references = [];
|
|
73
132
|
|
|
74
|
-
|
|
75
|
-
}
|
|
133
|
+
material.onBeforeCompile = composeCompile(sourceMaterial.onBeforeCompile, rewriteMaterial);
|
|
76
134
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
135
|
+
//we need a custom depth material to ensure shadows will be drawn correctly
|
|
136
|
+
const depthMaterial = new MeshDepthMaterial({
|
|
137
|
+
depthPacking: RGBADepthPacking,
|
|
138
|
+
});
|
|
82
139
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (!(geometry instanceof BufferGeometry)) {
|
|
89
|
-
throw new Error(`Expected THREE.BufferedGeometry, got something else instead.`);
|
|
90
|
-
}
|
|
140
|
+
//if the source material uses alpha testing - enable it on the depth material
|
|
141
|
+
if (material.alphaTest !== 0) {
|
|
142
|
+
depthMaterial.alphaTest = material.alphaTest;
|
|
143
|
+
depthMaterial.map = material.map;
|
|
144
|
+
}
|
|
91
145
|
|
|
92
|
-
|
|
146
|
+
depthMaterial.onBeforeCompile = rewriteMaterial;
|
|
93
147
|
|
|
94
|
-
this.build();
|
|
95
|
-
};
|
|
96
148
|
|
|
149
|
+
const cachedMaterial = StaticMaterialCache.Global.acquire(material);
|
|
97
150
|
|
|
98
|
-
|
|
99
|
-
*
|
|
100
|
-
* @param {THREE.Material} sourceMaterial
|
|
101
|
-
*/
|
|
102
|
-
InstancedMeshGroup.prototype.setMaterial = function (sourceMaterial) {
|
|
103
|
-
const material = sourceMaterial.clone();
|
|
151
|
+
this.__material = cachedMaterial;
|
|
104
152
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
for (const uniformsKey in material.uniforms) {
|
|
108
|
-
material.uniforms[uniformsKey] = sourceMaterial.uniforms[uniformsKey];
|
|
109
|
-
}
|
|
153
|
+
this.mesh.material = cachedMaterial;
|
|
154
|
+
this.mesh.customDepthMaterial = StaticMaterialCache.Global.acquire(depthMaterial);
|
|
110
155
|
}
|
|
111
156
|
|
|
157
|
+
/**
|
|
158
|
+
*
|
|
159
|
+
* @param {number} size
|
|
160
|
+
*/
|
|
161
|
+
setCapacity(size) {
|
|
162
|
+
if (this.capacity === size) {
|
|
163
|
+
// no change
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
112
166
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
//we need a custom depth material to ensure shadows will be drawn correctly
|
|
116
|
-
const depthMaterial = new MeshDepthMaterial({
|
|
117
|
-
depthPacking: RGBADepthPacking,
|
|
118
|
-
});
|
|
167
|
+
this.capacity = size;
|
|
119
168
|
|
|
120
|
-
|
|
121
|
-
if (material.alphaTest !== 0) {
|
|
122
|
-
depthMaterial.alphaTest = material.alphaTest;
|
|
123
|
-
depthMaterial.map = material.map;
|
|
169
|
+
this.build();
|
|
124
170
|
}
|
|
125
171
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
172
|
+
/**
|
|
173
|
+
*
|
|
174
|
+
* @param {number} size
|
|
175
|
+
*/
|
|
176
|
+
ensureCapacity(size) {
|
|
130
177
|
|
|
131
|
-
|
|
178
|
+
const currentCapacity = this.capacity;
|
|
132
179
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
};
|
|
180
|
+
if (currentCapacity < size) {
|
|
181
|
+
// grow
|
|
136
182
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
*
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
this.capacity = size;
|
|
143
|
-
this.build();
|
|
144
|
-
};
|
|
183
|
+
const newCapacityRaw = Math.max(
|
|
184
|
+
size,
|
|
185
|
+
currentCapacity * this.growFactor,
|
|
186
|
+
currentCapacity + this.growConstant
|
|
187
|
+
);
|
|
145
188
|
|
|
146
|
-
|
|
147
|
-
*
|
|
148
|
-
* @param {number} size
|
|
149
|
-
*/
|
|
150
|
-
InstancedMeshGroup.prototype.ensureCapacity = function (size) {
|
|
189
|
+
const newCapacityInteger = Math.ceil(newCapacityRaw);
|
|
151
190
|
|
|
152
|
-
|
|
191
|
+
this.setCapacity(newCapacityInteger);
|
|
153
192
|
|
|
154
|
-
|
|
155
|
-
|
|
193
|
+
} else if (
|
|
194
|
+
currentCapacity * this.shrinkFactor > size
|
|
195
|
+
&& currentCapacity - this.shrinkConstant > size
|
|
196
|
+
) {
|
|
197
|
+
// shrink
|
|
198
|
+
this.setCapacity(size);
|
|
199
|
+
}
|
|
156
200
|
|
|
157
|
-
|
|
158
|
-
size,
|
|
159
|
-
currentCapacity * this.growFactor,
|
|
160
|
-
currentCapacity + this.growConstant
|
|
161
|
-
);
|
|
201
|
+
}
|
|
162
202
|
|
|
163
|
-
|
|
203
|
+
/**
|
|
204
|
+
*
|
|
205
|
+
* @param {number} index
|
|
206
|
+
* @param {number} x
|
|
207
|
+
* @param {number} y
|
|
208
|
+
* @param {number} z
|
|
209
|
+
*/
|
|
210
|
+
setPositionAt(index, x, y, z) {
|
|
211
|
+
this.__attributePosition.setXYZ(index, x, y, z);
|
|
212
|
+
this.__attributePosition.needsUpdate = true;
|
|
213
|
+
}
|
|
164
214
|
|
|
165
|
-
|
|
215
|
+
/**
|
|
216
|
+
*
|
|
217
|
+
* @param {number} index
|
|
218
|
+
* @param {number} x
|
|
219
|
+
* @param {number} y
|
|
220
|
+
* @param {number} z
|
|
221
|
+
* @param {number} w
|
|
222
|
+
*/
|
|
223
|
+
setRotationAt(index, x, y, z, w) {
|
|
224
|
+
this.__attributeRotation.setXYZW(index, x, y, z, w);
|
|
225
|
+
this.__attributeRotation.needsUpdate = true;
|
|
226
|
+
}
|
|
166
227
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
228
|
+
/**
|
|
229
|
+
*
|
|
230
|
+
* @param {number} index
|
|
231
|
+
* @param {number} x
|
|
232
|
+
* @param {number} y
|
|
233
|
+
* @param {number} z
|
|
234
|
+
*/
|
|
235
|
+
setScaleAt(index, x, y, z) {
|
|
236
|
+
this.__attributeScale.setXYZ(index, x, y, z);
|
|
237
|
+
this.__attributeScale.needsUpdate = true;
|
|
173
238
|
}
|
|
174
239
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
*/
|
|
184
|
-
InstancedMeshGroup.prototype.setPositionAt = function (index, x, y, z) {
|
|
185
|
-
this.__attributePosition.setXYZ(index, x, y, z);
|
|
186
|
-
this.__attributePosition.needsUpdate = true;
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
*
|
|
191
|
-
* @param {number} index
|
|
192
|
-
* @param {number} x
|
|
193
|
-
* @param {number} y
|
|
194
|
-
* @param {number} z
|
|
195
|
-
* @param {number} w
|
|
196
|
-
*/
|
|
197
|
-
InstancedMeshGroup.prototype.setRotationAt = function (index, x, y, z, w) {
|
|
198
|
-
this.__attributeRotation.setXYZW(index, x, y, z, w);
|
|
199
|
-
this.__attributeRotation.needsUpdate = true;
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
*
|
|
204
|
-
* @param {number} index
|
|
205
|
-
* @param {number} x
|
|
206
|
-
* @param {number} y
|
|
207
|
-
* @param {number} z
|
|
208
|
-
*/
|
|
209
|
-
InstancedMeshGroup.prototype.setScaleAt = function (index, x, y, z) {
|
|
210
|
-
this.__attributeScale.setXYZ(index, x, y, z);
|
|
211
|
-
this.__attributeScale.needsUpdate = true;
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Swap position in attribute arrays of two elements
|
|
216
|
-
* @param {int} indexA
|
|
217
|
-
* @param {int} indexB
|
|
218
|
-
*/
|
|
219
|
-
InstancedMeshGroup.prototype.swap = function (indexA, indexB) {
|
|
220
|
-
throw new Error('Not Implemented Yet');
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
*
|
|
225
|
-
* @param {int} size
|
|
226
|
-
*/
|
|
227
|
-
InstancedMeshGroup.prototype.setCount = function (size) {
|
|
228
|
-
this.ensureCapacity(size);
|
|
229
|
-
|
|
230
|
-
this.count = size;
|
|
231
|
-
this.__threeGeometry.instanceCount = size;
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
*
|
|
236
|
-
* @return {number|int}
|
|
237
|
-
*/
|
|
238
|
-
InstancedMeshGroup.prototype.getCount = function () {
|
|
239
|
-
return this.count;
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
*
|
|
244
|
-
* @param {int} reference
|
|
245
|
-
* @returns {int}
|
|
246
|
-
*/
|
|
247
|
-
InstancedMeshGroup.prototype.add = function (reference) {
|
|
248
|
-
//get index
|
|
249
|
-
const index = this.count;
|
|
250
|
-
//grow
|
|
251
|
-
this.setCount(this.count + 1);
|
|
252
|
-
|
|
253
|
-
this.indices[reference] = index;
|
|
254
|
-
this.references[index] = reference;
|
|
255
|
-
|
|
256
|
-
return index;
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
*
|
|
261
|
-
* @param {function(index:int,reference:int)} visitor
|
|
262
|
-
* @param {*} [thisArg]
|
|
263
|
-
*/
|
|
264
|
-
InstancedMeshGroup.prototype.traverseReferences = function (visitor, thisArg) {
|
|
265
|
-
const indices = this.indices;
|
|
266
|
-
const index_count = indices.length;
|
|
267
|
-
|
|
268
|
-
for (let i = 0; i < index_count; i++) {
|
|
269
|
-
const index = indices[i];
|
|
240
|
+
/**
|
|
241
|
+
* Swap position in attribute arrays of two elements
|
|
242
|
+
* @param {int} indexA
|
|
243
|
+
* @param {int} indexB
|
|
244
|
+
*/
|
|
245
|
+
swap(indexA, indexB) {
|
|
246
|
+
throw new Error('Not Implemented Yet');
|
|
247
|
+
}
|
|
270
248
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
249
|
+
/**
|
|
250
|
+
*
|
|
251
|
+
* @param {int} size
|
|
252
|
+
*/
|
|
253
|
+
setCount(size) {
|
|
254
|
+
this.ensureCapacity(size);
|
|
275
255
|
|
|
276
|
-
|
|
256
|
+
this.count = size;
|
|
257
|
+
this.__threeGeometry.instanceCount = size;
|
|
277
258
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
//dereference
|
|
286
|
-
const index = this.indices[reference];
|
|
287
|
-
|
|
288
|
-
if (index === undefined) {
|
|
289
|
-
//reference is not known
|
|
290
|
-
throw new Error(`Reference '${reference}' was not found`);
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
*
|
|
262
|
+
* @return {number|int}
|
|
263
|
+
*/
|
|
264
|
+
getCount() {
|
|
265
|
+
return this.count;
|
|
291
266
|
}
|
|
292
267
|
|
|
293
|
-
|
|
268
|
+
/**
|
|
269
|
+
*
|
|
270
|
+
* @param {int} reference
|
|
271
|
+
* @returns {int}
|
|
272
|
+
*/
|
|
273
|
+
add(reference) {
|
|
274
|
+
//get index
|
|
275
|
+
const index = this.count;
|
|
276
|
+
//grow
|
|
277
|
+
this.setCount(this.count + 1);
|
|
294
278
|
|
|
295
|
-
|
|
279
|
+
this.indices[reference] = index;
|
|
280
|
+
this.references[index] = reference;
|
|
296
281
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
delete this.references[index];
|
|
300
|
-
} else {
|
|
301
|
-
//not at the end, move end reference to this place
|
|
302
|
-
const index3 = index * 3;
|
|
303
|
-
const start3 = lastIndex * 3;
|
|
304
|
-
const end3 = start3 + 3;
|
|
282
|
+
return index;
|
|
283
|
+
}
|
|
305
284
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
285
|
+
/**
|
|
286
|
+
*
|
|
287
|
+
* @param {function(index:int,reference:int)} visitor
|
|
288
|
+
* @param {*} [thisArg]
|
|
289
|
+
*/
|
|
290
|
+
traverseReferences(visitor, thisArg) {
|
|
291
|
+
const indices = this.indices;
|
|
292
|
+
const index_count = indices.length;
|
|
309
293
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
this.__attributeScale.array.copyWithin(index3, start3, end3);
|
|
294
|
+
for (let i = 0; i < index_count; i++) {
|
|
295
|
+
const index = indices[i];
|
|
313
296
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
297
|
+
if (index === undefined) {
|
|
298
|
+
// unoccupied
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
317
301
|
|
|
318
|
-
|
|
319
|
-
|
|
302
|
+
visitor.call(thisArg, index, i);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
*
|
|
308
|
+
* @param {int} reference
|
|
309
|
+
*/
|
|
310
|
+
remove(reference) {
|
|
311
|
+
//dereference
|
|
312
|
+
const index = this.indices[reference];
|
|
320
313
|
|
|
321
|
-
if (
|
|
322
|
-
//
|
|
323
|
-
throw new Error(`
|
|
314
|
+
if (index === undefined) {
|
|
315
|
+
//reference is not known
|
|
316
|
+
throw new Error(`Reference '${reference}' was not found`);
|
|
324
317
|
}
|
|
325
318
|
|
|
326
|
-
delete this.
|
|
319
|
+
delete this.indices[reference];
|
|
327
320
|
|
|
328
|
-
|
|
329
|
-
this.references[index] = movedReference;
|
|
330
|
-
this.indices[movedReference] = index;
|
|
331
|
-
}
|
|
321
|
+
const lastIndex = this.count - 1;
|
|
332
322
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
323
|
+
if (index === lastIndex) {
|
|
324
|
+
//easy case, reference is placed at the end, no swap needed, we can just forget about it
|
|
325
|
+
delete this.references[index];
|
|
326
|
+
} else {
|
|
327
|
+
//not at the end, move end reference to this place
|
|
328
|
+
const index3 = index * 3;
|
|
329
|
+
const start3 = lastIndex * 3;
|
|
330
|
+
const end3 = start3 + 3;
|
|
336
331
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
this.__threeGeometry.dispose();
|
|
341
|
-
}
|
|
332
|
+
const index4 = index * 4;
|
|
333
|
+
const start4 = lastIndex * 4;
|
|
334
|
+
const end4 = start4 + 4;
|
|
342
335
|
|
|
343
|
-
|
|
336
|
+
this.__attributePosition.array.copyWithin(index3, start3, end3);
|
|
337
|
+
this.__attributeRotation.array.copyWithin(index4, start4, end4);
|
|
338
|
+
this.__attributeScale.array.copyWithin(index3, start3, end3);
|
|
344
339
|
|
|
345
|
-
|
|
346
|
-
|
|
340
|
+
this.__attributePosition.needsUpdate = true;
|
|
341
|
+
this.__attributeRotation.needsUpdate = true;
|
|
342
|
+
this.__attributeScale.needsUpdate = true;
|
|
347
343
|
|
|
348
|
-
|
|
349
|
-
|
|
344
|
+
//update moved reference index
|
|
345
|
+
const movedReference = this.references[lastIndex];
|
|
350
346
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
347
|
+
if (movedReference === undefined) {
|
|
348
|
+
//moved reference not found
|
|
349
|
+
throw new Error(`Moved reference was not found`);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
delete this.references[lastIndex];
|
|
353
|
+
|
|
354
|
+
//assume the place of removed reference
|
|
355
|
+
this.references[index] = movedReference;
|
|
356
|
+
this.indices[movedReference] = index;
|
|
356
357
|
}
|
|
357
358
|
|
|
358
|
-
|
|
359
|
+
//update size
|
|
360
|
+
this.setCount(this.count - 1);
|
|
359
361
|
}
|
|
360
362
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
363
|
+
build() {
|
|
364
|
+
if (this.__threeGeometry !== null) {
|
|
365
|
+
// dispose old geometry's GPU memory
|
|
366
|
+
this.__threeGeometry.dispose();
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
this.__threeGeometry = new InstancedBufferGeometry();
|
|
365
370
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
const oldPositionArray = this.__attributePosition.array;
|
|
369
|
-
typed_array_copy(oldPositionArray, newPositionArray);
|
|
370
|
-
}
|
|
371
|
-
if (this.__attributeRotation !== null) {
|
|
372
|
-
//copy old data
|
|
373
|
-
const oldRotationArray = this.__attributeRotation.array;
|
|
374
|
-
typed_array_copy(oldRotationArray, newRotationArray);
|
|
375
|
-
}
|
|
376
|
-
if (this.__attributeScale !== null) {
|
|
377
|
-
const oldScaleArray = this.__attributeScale.array;
|
|
378
|
-
typed_array_copy(oldScaleArray, newScaleArray);
|
|
371
|
+
const instance = this.__threeInstanceGeometry;
|
|
372
|
+
const geometry = this.__threeGeometry;
|
|
379
373
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
374
|
+
geometry.instanceCount = this.count;
|
|
375
|
+
geometry.dynamic = true;
|
|
376
|
+
|
|
377
|
+
//copy instance attributes
|
|
378
|
+
geometry.index = instance.index;
|
|
379
|
+
for (let attributeName in instance.attributes) {
|
|
380
|
+
if (!instance.attributes.hasOwnProperty(attributeName)) {
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
geometry.attributes[attributeName] = instance.attributes[attributeName];
|
|
383
385
|
}
|
|
384
|
-
}
|
|
385
386
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
387
|
+
//build instanced attributes
|
|
388
|
+
const newPositionArray = new Float32Array(this.capacity * 3);
|
|
389
|
+
const newRotationArray = new Float32Array(this.capacity * 4);
|
|
390
|
+
const newScaleArray = new Float32Array(this.capacity * 3);
|
|
390
391
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
392
|
+
if (this.__attributePosition !== null) {
|
|
393
|
+
//copy old data
|
|
394
|
+
const oldPositionArray = this.__attributePosition.array;
|
|
395
|
+
typed_array_copy(oldPositionArray, newPositionArray);
|
|
396
|
+
}
|
|
397
|
+
if (this.__attributeRotation !== null) {
|
|
398
|
+
//copy old data
|
|
399
|
+
const oldRotationArray = this.__attributeRotation.array;
|
|
400
|
+
typed_array_copy(oldRotationArray, newRotationArray);
|
|
401
|
+
}
|
|
402
|
+
if (this.__attributeScale !== null) {
|
|
403
|
+
const oldScaleArray = this.__attributeScale.array;
|
|
404
|
+
typed_array_copy(oldScaleArray, newScaleArray);
|
|
405
|
+
|
|
406
|
+
if (newScaleArray.length > oldScaleArray.length) {
|
|
407
|
+
//fill the rest of the array with scale factor of 1 as a default
|
|
408
|
+
newScaleArray.fill(1, oldScaleArray.length);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
395
411
|
|
|
412
|
+
//rewrite old attributes
|
|
413
|
+
this.__attributePosition = new InstancedBufferAttribute(newPositionArray, 3);
|
|
414
|
+
this.__attributeRotation = new InstancedBufferAttribute(newRotationArray, 4);
|
|
415
|
+
this.__attributeScale = new InstancedBufferAttribute(newScaleArray, 3);
|
|
396
416
|
|
|
397
|
-
|
|
398
|
-
|
|
417
|
+
//add attributes to newly created geometry
|
|
418
|
+
geometry.setAttribute("instancePosition", this.__attributePosition);
|
|
419
|
+
geometry.setAttribute("instanceRotation", this.__attributeRotation);
|
|
420
|
+
geometry.setAttribute("instanceScale", this.__attributeScale);
|
|
399
421
|
|
|
400
|
-
|
|
422
|
+
|
|
423
|
+
this.mesh.geometry = geometry;
|
|
424
|
+
}
|
|
425
|
+
}
|