@woosh/meep-engine 2.39.44 → 2.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/binary/BinaryBuffer.js +8 -0
- package/core/bvh2/aabb3/AABB3.js +0 -133
- package/core/bvh2/aabb3/aabb3_intersects_line_segment.js +1 -1
- package/core/geom/3d/matrix/MATRIX_4_IDENTITY.js +9 -0
- package/core/parser/simple/DataType.js +2 -2
- package/editor/view/EditorView.js +25 -22
- package/editor/view/ecs/components/common/NumberController.js +37 -8
- package/engine/EngineHarness.js +0 -3
- package/engine/asset/loaders/image/png/PNGReader.js +41 -2
- package/engine/asset/loaders/image/png/crc.js +66 -0
- package/engine/ecs/speaker/VoiceSystem.js +1 -1
- package/engine/ecs/terrain/ecs/Terrain.js +58 -36
- package/engine/ecs/terrain/ecs/TerrainSystem.js +22 -4
- package/engine/ecs/terrain/tiles/TerrainTile.js +107 -131
- package/engine/ecs/terrain/tiles/TerrainTileManager.js +100 -121
- package/engine/graphics/ecs/camera/Camera.js +1 -1
- package/engine/graphics/ecs/light/binding/fp/FPLightBinding.js +4 -4
- package/engine/graphics/geometry/bvh/buffered/BVHGeometryRaycaster.js +0 -78
- package/engine/graphics/geometry/optimization/merge/merge_geometry_hierarchy.js +0 -9
- package/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +2 -2
- package/engine/intelligence/behavior/util/LogMessageBehavior.js +29 -0
- package/package.json +1 -1
|
@@ -5,6 +5,8 @@ import { assert } from "../../../../core/assert.js";
|
|
|
5
5
|
import { noop } from "../../../../core/function/Functions.js";
|
|
6
6
|
import { TerrainFlags } from "./TerrainFlags.js";
|
|
7
7
|
import { ImageRGBADataLoader } from "../../../asset/loaders/image/ImageRGBADataLoader.js";
|
|
8
|
+
import { Transform } from "../../transform/Transform.js";
|
|
9
|
+
import { MATRIX_4_IDENTITY } from "../../../../core/geom/3d/matrix/MATRIX_4_IDENTITY.js";
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
*
|
|
@@ -157,9 +159,12 @@ class TerrainSystem extends System {
|
|
|
157
159
|
this.__time_delta = timeDelta;
|
|
158
160
|
|
|
159
161
|
|
|
160
|
-
if (dataset
|
|
161
|
-
|
|
162
|
+
if (dataset === null) {
|
|
163
|
+
return;
|
|
162
164
|
}
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
dataset.traverseComponents(Terrain, this.__visitTerrainComponent, this);
|
|
163
168
|
}
|
|
164
169
|
|
|
165
170
|
/**
|
|
@@ -171,13 +176,26 @@ class TerrainSystem extends System {
|
|
|
171
176
|
__visitTerrainComponent(terrain, entity) {
|
|
172
177
|
const em = this.entityManager;
|
|
173
178
|
|
|
174
|
-
const
|
|
179
|
+
const ecd = em.dataset;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
*
|
|
183
|
+
* @type {Transform|undefined}
|
|
184
|
+
*/
|
|
185
|
+
const transform = ecd.getComponent(entity, Transform);
|
|
186
|
+
|
|
187
|
+
if (transform !== undefined) {
|
|
188
|
+
// terrain has a transform
|
|
189
|
+
terrain.transform = transform.matrix;
|
|
190
|
+
}else{
|
|
191
|
+
terrain.transform = MATRIX_4_IDENTITY;
|
|
192
|
+
}
|
|
175
193
|
|
|
176
194
|
terrain.update(this.__time_delta);
|
|
177
195
|
|
|
178
196
|
//do frustum culling
|
|
179
197
|
if (terrain.frustumCulled) {
|
|
180
|
-
TerrainSystem.traverseVisibleTiles(
|
|
198
|
+
TerrainSystem.traverseVisibleTiles(ecd, terrain, ensureTileBuilt);
|
|
181
199
|
}
|
|
182
200
|
}
|
|
183
201
|
|
|
@@ -18,13 +18,14 @@ import ThreeFactory from '../../../graphics/three/ThreeFactory.js';
|
|
|
18
18
|
|
|
19
19
|
import { LeafNode } from '../../../../core/bvh2/LeafNode.js';
|
|
20
20
|
|
|
21
|
-
import BVHFromBufferGeometry from '../../../graphics/geometry/bvh/buffered/BVHFromBufferGeometry.js';
|
|
22
|
-
|
|
23
21
|
import IndexedBinaryBVH from '../../../../core/bvh2/binary/IndexedBinaryBVH.js';
|
|
24
22
|
import { BVHGeometryRaycaster } from "../../../graphics/geometry/bvh/buffered/BVHGeometryRaycaster.js";
|
|
25
23
|
import ObservedInteger from "../../../../core/model/ObservedInteger.js";
|
|
26
24
|
import { SurfacePoint3 } from "../../../../core/geom/3d/SurfacePoint3.js";
|
|
27
25
|
import Signal from "../../../../core/events/signal/Signal.js";
|
|
26
|
+
import { mat4 } from "gl-matrix";
|
|
27
|
+
import { AABB3 } from "../../../../core/bvh2/aabb3/AABB3.js";
|
|
28
|
+
import { NumericInterval } from "../../../../core/math/interval/NumericInterval.js";
|
|
28
29
|
|
|
29
30
|
function extractFaceIndexFromLeaf(leaf) {
|
|
30
31
|
return leaf;
|
|
@@ -92,11 +93,17 @@ class TerrainTile {
|
|
|
92
93
|
this.isBuildInProgress = false;
|
|
93
94
|
this.referenceCount = 0;
|
|
94
95
|
|
|
96
|
+
/**
|
|
97
|
+
*
|
|
98
|
+
* @type {Signal<TerrainTile>}
|
|
99
|
+
*/
|
|
95
100
|
this.onBuilt = new Signal();
|
|
96
101
|
this.onDestroyed = new Signal();
|
|
97
102
|
|
|
98
|
-
|
|
99
|
-
|
|
103
|
+
/**
|
|
104
|
+
* @private
|
|
105
|
+
* @type {{bottomLeft: boolean, top: boolean, left: boolean, bottom: boolean, bottomRight: boolean, topLeft: boolean, topRight: boolean, right: boolean}}
|
|
106
|
+
*/
|
|
100
107
|
this.stitching = {
|
|
101
108
|
top: false,
|
|
102
109
|
bottom: false,
|
|
@@ -110,27 +117,34 @@ class TerrainTile {
|
|
|
110
117
|
bottomRight: false
|
|
111
118
|
};
|
|
112
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Initial estimate of height bounds for this tile
|
|
122
|
+
* Untransformed by transform matrix
|
|
123
|
+
* @type {NumericInterval}
|
|
124
|
+
* @private
|
|
125
|
+
*/
|
|
126
|
+
this.__initial_height_range = new NumericInterval(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY);
|
|
127
|
+
|
|
113
128
|
this.raycaster = new BVHGeometryRaycaster();
|
|
114
129
|
//Binary BVH form doesn't have distinct leaf objects and stores face indices directly, this requires a special face index extractor that treats leaves as indices directly.
|
|
115
130
|
this.raycaster.extractFaceIndexFromLeaf = extractFaceIndexFromLeaf;
|
|
116
131
|
}
|
|
117
132
|
|
|
118
133
|
/**
|
|
119
|
-
*
|
|
134
|
+
*
|
|
135
|
+
* @return {number[]}
|
|
120
136
|
*/
|
|
121
|
-
|
|
122
|
-
|
|
137
|
+
get transform() {
|
|
138
|
+
return this.mesh.matrixWorld.elements;
|
|
123
139
|
}
|
|
124
140
|
|
|
125
141
|
/**
|
|
126
142
|
*
|
|
127
|
-
* @param {number}
|
|
128
|
-
* @param {number} y
|
|
129
|
-
* @param {function} callback
|
|
130
|
-
* @param {function} missCallback
|
|
143
|
+
* @param {number[]|Float32Array|mat4} m4
|
|
131
144
|
*/
|
|
132
|
-
|
|
133
|
-
|
|
145
|
+
set transform(m4) {
|
|
146
|
+
mat4.copy(this.mesh.matrixWorld.elements, m4);
|
|
147
|
+
this.computeBoundingBox();
|
|
134
148
|
}
|
|
135
149
|
|
|
136
150
|
/**
|
|
@@ -188,7 +202,7 @@ class TerrainTile {
|
|
|
188
202
|
}
|
|
189
203
|
|
|
190
204
|
/**
|
|
191
|
-
*
|
|
205
|
+
* Stitch vertex normals along the edges of the tile set
|
|
192
206
|
* @param {TerrainTile|undefined} top
|
|
193
207
|
* @param {TerrainTile|undefined} bottom
|
|
194
208
|
* @param {TerrainTile|undefined} left
|
|
@@ -254,7 +268,9 @@ class TerrainTile {
|
|
|
254
268
|
bottom.getVertexNormal(i, v0);
|
|
255
269
|
top.getVertexNormal(otherOffset + i, v1);
|
|
256
270
|
|
|
257
|
-
v0.add(v1)
|
|
271
|
+
v0.add(v1);
|
|
272
|
+
v0.normalize();
|
|
273
|
+
|
|
258
274
|
bottom.setVertexNormal(i, v0);
|
|
259
275
|
top.setVertexNormal(otherOffset + i, v0);
|
|
260
276
|
}
|
|
@@ -316,7 +332,9 @@ class TerrainTile {
|
|
|
316
332
|
right.getVertexNormal(index0, v0);
|
|
317
333
|
left.getVertexNormal(index1, v1);
|
|
318
334
|
|
|
319
|
-
v0.add(v1)
|
|
335
|
+
v0.add(v1);
|
|
336
|
+
v0.normalize();
|
|
337
|
+
|
|
320
338
|
right.setVertexNormal(index0, v0);
|
|
321
339
|
left.setVertexNormal(index1, v0);
|
|
322
340
|
}
|
|
@@ -361,7 +379,11 @@ class TerrainTile {
|
|
|
361
379
|
topRight.getVertexNormal(tCornerIndex, v2);
|
|
362
380
|
bottomLeft.getVertexNormal(lCornerIndex, v3);
|
|
363
381
|
|
|
364
|
-
v0.add(v1)
|
|
382
|
+
v0.add(v1);
|
|
383
|
+
v0.add(v2);
|
|
384
|
+
v0.add(v3);
|
|
385
|
+
v0.normalize();
|
|
386
|
+
|
|
365
387
|
topLeft.setVertexNormal(tlCornerIndex, v0);
|
|
366
388
|
bottomRight.setVertexNormal(cornerIndex, v0);
|
|
367
389
|
topRight.setVertexNormal(tCornerIndex, v0);
|
|
@@ -404,118 +426,76 @@ class TerrainTile {
|
|
|
404
426
|
stitchSides();
|
|
405
427
|
}
|
|
406
428
|
|
|
407
|
-
stitchNormals(top, left, topLeft) {
|
|
408
|
-
const v0 = new Vector3(),
|
|
409
|
-
v1 = new Vector3();
|
|
410
|
-
if (top !== null && left !== null && topLeft !== null) {
|
|
411
|
-
|
|
412
|
-
const v2 = new Vector3();
|
|
413
|
-
const v3 = new Vector3();
|
|
414
|
-
//fix corner
|
|
415
|
-
const tlCornerIndex = (topLeft.size.x * topLeft.resolution.getValue()) * (topLeft.size.y * topLeft.resolution.getValue()) - 1;
|
|
416
|
-
const cornerIndex = 0;
|
|
417
|
-
const tCornerIndex = top.size.x * top.resolution.getValue() * (top.size.y * top.resolution.getValue() - 1);
|
|
418
|
-
const lCornerIndex = left.size.x * left.resolution.getValue() - 1;
|
|
419
|
-
|
|
420
|
-
topLeft.getVertexNormal(tlCornerIndex, v0);
|
|
421
|
-
this.getVertexNormal(cornerIndex, v1);
|
|
422
|
-
top.getVertexNormal(tCornerIndex, v2);
|
|
423
|
-
left.getVertexNormal(lCornerIndex, v3);
|
|
424
|
-
|
|
425
|
-
v0.add(v1).add(v2).add(v3).normalize();
|
|
426
|
-
topLeft.setVertexNormal(tlCornerIndex, v0);
|
|
427
|
-
this.setVertexNormal(cornerIndex, v0);
|
|
428
|
-
top.setVertexNormal(tCornerIndex, v0);
|
|
429
|
-
left.setVertexNormal(lCornerIndex, v0);
|
|
430
|
-
}
|
|
431
|
-
let i, l;
|
|
432
|
-
let otherOffset;
|
|
433
|
-
let otherResolution;
|
|
434
|
-
const thisResolution = this.resolution.getValue();
|
|
435
|
-
if (top !== null) {
|
|
436
|
-
otherResolution = top.resolution.getValue();
|
|
437
|
-
otherOffset = top.size.x * otherResolution * (top.size.y * otherResolution - 1);
|
|
438
|
-
for (i = 0, l = this.size.x * thisResolution; i < l; i++) {
|
|
439
|
-
this.getVertexNormal(i, v0);
|
|
440
|
-
top.getVertexNormal(otherOffset + i, v1);
|
|
441
|
-
|
|
442
|
-
v0.add(v1).normalize();
|
|
443
|
-
this.setVertexNormal(i, v0);
|
|
444
|
-
top.setVertexNormal(otherOffset + i, v0);
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
if (left !== null) {
|
|
448
|
-
otherResolution = left.resolution.getValue();
|
|
449
|
-
otherOffset = left.size.x * otherResolution - 1;
|
|
450
|
-
const otherMultiplier = left.size.x * otherResolution;
|
|
451
|
-
const thisMultiplier = this.size.x * thisResolution;
|
|
452
|
-
for (i = 0, l = this.size.y * thisResolution; i < l; i++) {
|
|
453
|
-
|
|
454
|
-
const index0 = i * thisMultiplier;
|
|
455
|
-
const index1 = otherOffset + i * otherMultiplier;
|
|
456
|
-
|
|
457
|
-
this.getVertexNormal(index0, v0);
|
|
458
|
-
left.getVertexNormal(index1, v1);
|
|
459
|
-
|
|
460
|
-
v0.add(v1).normalize();
|
|
461
|
-
this.setVertexNormal(index0, v0);
|
|
462
|
-
left.setVertexNormal(index1, v0);
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
|
|
467
429
|
computeBoundingBox() {
|
|
430
|
+
/**
|
|
431
|
+
* @type {ThreeBox3}
|
|
432
|
+
*/
|
|
433
|
+
let bb;
|
|
434
|
+
|
|
468
435
|
const geometry = this.geometry;
|
|
469
|
-
//check for bvh
|
|
470
|
-
const bvh = this.bvh;
|
|
471
|
-
if (bvh !== null) {
|
|
472
|
-
geometry.boundingBox = new ThreeBox3(new ThreeVector3(bvh.x0, bvh.y0, bvh.z0), new ThreeVector3(bvh.x1, bvh.y1, bvh.z1));
|
|
473
436
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
const dZ = bvh.z1 - bvh.z0;
|
|
437
|
+
if (geometry === null) {
|
|
438
|
+
// no geometry present yet
|
|
477
439
|
|
|
478
|
-
const
|
|
440
|
+
const position = this.position;
|
|
441
|
+
const scale = this.scale;
|
|
442
|
+
const size = this.size;
|
|
479
443
|
|
|
480
|
-
const
|
|
444
|
+
const initial_height_range = this.__initial_height_range;
|
|
481
445
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
//pull bounding box from geometry
|
|
485
|
-
let bb = geometry.boundingBox;
|
|
486
|
-
if (bb === null) {
|
|
487
|
-
geometry.computeBoundingBox();
|
|
488
|
-
bb = geometry.boundingBox;
|
|
489
|
-
}
|
|
490
|
-
this.boundingBox.setBounds(bb.min.x, bb.min.y, bb.min.z, bb.max.x, bb.max.y, bb.max.z);
|
|
491
|
-
}
|
|
446
|
+
const min = new ThreeVector3(position.x * scale.x, initial_height_range.min, position.y * scale.y);
|
|
447
|
+
const max = new ThreeVector3(min.x + size.x * scale.x, initial_height_range.max, min.z + size.y * scale.y);
|
|
492
448
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
// console.profileEnd('build bvh');
|
|
498
|
-
}
|
|
449
|
+
bb = new ThreeBox3(
|
|
450
|
+
min,
|
|
451
|
+
max
|
|
452
|
+
);
|
|
499
453
|
|
|
500
|
-
|
|
501
|
-
this.isBuilt = false;
|
|
454
|
+
} else {
|
|
502
455
|
|
|
503
|
-
|
|
504
|
-
|
|
456
|
+
//check for bvh
|
|
457
|
+
const bvh = this.bvh;
|
|
458
|
+
if (bvh !== null) {
|
|
459
|
+
geometry.boundingBox = new ThreeBox3(new ThreeVector3(bvh.x0, bvh.y0, bvh.z0), new ThreeVector3(bvh.x1, bvh.y1, bvh.z1));
|
|
460
|
+
|
|
461
|
+
const dX = bvh.x1 - bvh.x0;
|
|
462
|
+
const dY = bvh.y1 - bvh.y0;
|
|
463
|
+
const dZ = bvh.z1 - bvh.z0;
|
|
464
|
+
|
|
465
|
+
const radius = Math.sqrt(dX * dX + dY * dY + dZ * dZ) / 2;
|
|
466
|
+
|
|
467
|
+
const center = new ThreeVector3(bvh.x0 + dX / 2, bvh.y0 + dY / 2, bvh.z0 + dZ / 2);
|
|
468
|
+
|
|
469
|
+
geometry.boundingSphere = new ThreeSphere(center, radius);
|
|
470
|
+
}
|
|
471
|
+
//pull bounding box from geometry
|
|
505
472
|
|
|
506
|
-
|
|
473
|
+
bb = geometry.boundingBox;
|
|
474
|
+
if (bb === null) {
|
|
475
|
+
geometry.computeBoundingBox();
|
|
476
|
+
bb = geometry.boundingBox;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
507
479
|
|
|
508
|
-
|
|
509
|
-
|
|
480
|
+
const x0 = bb.min.x;
|
|
481
|
+
const y0 = bb.min.y;
|
|
482
|
+
const z0 = bb.min.z;
|
|
510
483
|
|
|
511
|
-
|
|
512
|
-
|
|
484
|
+
const x1 = bb.max.x;
|
|
485
|
+
const y1 = bb.max.y;
|
|
486
|
+
const z1 = bb.max.z;
|
|
487
|
+
|
|
488
|
+
const geometry_bb = new AABB3(
|
|
489
|
+
x0, y0, z0,
|
|
490
|
+
x1, y1, z1
|
|
491
|
+
);
|
|
513
492
|
|
|
514
|
-
|
|
515
|
-
stitching.topRight = false;
|
|
493
|
+
geometry_bb.applyMatrix4(this.transform);
|
|
516
494
|
|
|
517
|
-
|
|
518
|
-
|
|
495
|
+
this.boundingBox.setBounds(
|
|
496
|
+
geometry_bb.x0, geometry_bb.y0, geometry_bb.z0,
|
|
497
|
+
geometry_bb.x1, geometry_bb.y1, geometry_bb.z1
|
|
498
|
+
);
|
|
519
499
|
}
|
|
520
500
|
|
|
521
501
|
/**
|
|
@@ -523,23 +503,17 @@ class TerrainTile {
|
|
|
523
503
|
* @param {number} min_height
|
|
524
504
|
* @param {number} max_height
|
|
525
505
|
*/
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
const size = this.size.clone().multiply(this.scale);
|
|
530
|
-
|
|
531
|
-
const max = offset.clone().add(size);
|
|
532
|
-
|
|
533
|
-
this.boundingBox.setBounds(
|
|
534
|
-
offset.x, min_height, offset.y,
|
|
535
|
-
max.x, max_height, max.y
|
|
536
|
-
);
|
|
506
|
+
setInitialHeightBounds(min_height, max_height) {
|
|
507
|
+
this.__initial_height_range.set(min_height, max_height);
|
|
537
508
|
}
|
|
538
509
|
|
|
539
510
|
dispose() {
|
|
540
511
|
if (this.geometry !== null) {
|
|
541
512
|
this.geometry.dispose();
|
|
513
|
+
this.geometry = null;
|
|
542
514
|
}
|
|
515
|
+
|
|
516
|
+
this.isBuilt = false;
|
|
543
517
|
}
|
|
544
518
|
|
|
545
519
|
build(tileData) {
|
|
@@ -549,7 +523,9 @@ class TerrainTile {
|
|
|
549
523
|
const tileDataGeometry = tileData.geometry;
|
|
550
524
|
|
|
551
525
|
const g = new ThreeBufferGeometry();
|
|
526
|
+
|
|
552
527
|
g.setIndex(new ThreeBufferAttribute(tileDataGeometry.indices, 1));
|
|
528
|
+
|
|
553
529
|
g.setAttribute('position', new ThreeBufferAttribute(tileDataGeometry.vertices, 3));
|
|
554
530
|
g.setAttribute('normal', new ThreeBufferAttribute(tileDataGeometry.normals, 3));
|
|
555
531
|
g.setAttribute('uv', new ThreeBufferAttribute(tileDataGeometry.uvs, 2));
|
|
@@ -571,11 +547,6 @@ class TerrainTile {
|
|
|
571
547
|
}
|
|
572
548
|
|
|
573
549
|
|
|
574
|
-
//set bounding box
|
|
575
|
-
// console.time('bb');
|
|
576
|
-
this.computeBoundingBox();
|
|
577
|
-
// console.timeEnd('bb');
|
|
578
|
-
|
|
579
550
|
const mesh = this.mesh;
|
|
580
551
|
|
|
581
552
|
mesh.geometry = g;
|
|
@@ -583,6 +554,11 @@ class TerrainTile {
|
|
|
583
554
|
mesh.receiveShadow = true;
|
|
584
555
|
mesh.castShadow = true;
|
|
585
556
|
|
|
557
|
+
//set bounding box
|
|
558
|
+
// console.time('bb');
|
|
559
|
+
this.computeBoundingBox();
|
|
560
|
+
// console.timeEnd('bb');
|
|
561
|
+
|
|
586
562
|
// console.timeEnd('total');
|
|
587
563
|
// console.groupEnd();
|
|
588
564
|
|