@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
|
@@ -85,6 +85,14 @@ export class BinaryBuffer {
|
|
|
85
85
|
this.__growFactor = 1.1;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Access raw underlying bytes attached to the buffer
|
|
90
|
+
* @return {Uint8Array}
|
|
91
|
+
*/
|
|
92
|
+
get raw_bytes() {
|
|
93
|
+
return this.__data_uint8;
|
|
94
|
+
}
|
|
95
|
+
|
|
88
96
|
/**
|
|
89
97
|
* @param {ArrayBuffer} arrayBuffer
|
|
90
98
|
*/
|
package/core/bvh2/aabb3/AABB3.js
CHANGED
|
@@ -551,139 +551,6 @@ export class AABB3 {
|
|
|
551
551
|
return aabb3_intersects_line_segment(this.x0, this.y0, this.z0, this.x1, this.y1, this.z1, startX, startY, startZ, endX, endY, endZ);
|
|
552
552
|
}
|
|
553
553
|
|
|
554
|
-
/**
|
|
555
|
-
* @source http://stackoverflow.com/questions/3106666/intersection-of-line-segment-with-axis-aligned-box-in-c-sharp
|
|
556
|
-
* @param {number} startX
|
|
557
|
-
* @param {number} startY
|
|
558
|
-
* @param {number} startZ
|
|
559
|
-
* @param {number} endX
|
|
560
|
-
* @param {number} endY
|
|
561
|
-
* @param {number} endZ
|
|
562
|
-
* @returns {boolean}
|
|
563
|
-
*/
|
|
564
|
-
intersectSegment2(startX, startY, startZ, endX, endY, endZ) {
|
|
565
|
-
//var beginToEnd = segmentEnd - segmentBegin;
|
|
566
|
-
const deltaX = endX - startX,
|
|
567
|
-
deltaY = endY - startY,
|
|
568
|
-
deltaZ = endZ - startZ;
|
|
569
|
-
//var minToMax = new Vector3D(boxSize.X, boxSize.Y, boxSize.Z);
|
|
570
|
-
|
|
571
|
-
//var min = boxCenter - minToMax / 2;
|
|
572
|
-
//var max = boxCenter + minToMax / 2;
|
|
573
|
-
//var beginToMin = min - segmentBegin;
|
|
574
|
-
//var beginToMax = max - segmentBegin;
|
|
575
|
-
//var tNear = double.MinValue;
|
|
576
|
-
let tNear = Number.NEGATIVE_INFINITY;
|
|
577
|
-
//var tFar = double.MaxValue;
|
|
578
|
-
let tFar = Number.POSITIVE_INFINITY;
|
|
579
|
-
let t1, t2, tMin, tMax;
|
|
580
|
-
//var intersections = new List<Point3D>();
|
|
581
|
-
//var intersections = [];
|
|
582
|
-
let beginToMin = this.x0 - startX;
|
|
583
|
-
let beginToMax = this.x1 - startX;
|
|
584
|
-
if (deltaX === 0) {//parallel
|
|
585
|
-
if (beginToMin > 0 || beginToMax < 0) {
|
|
586
|
-
return false; //segment is not between planes
|
|
587
|
-
}
|
|
588
|
-
} else {
|
|
589
|
-
t1 = beginToMin / deltaX;
|
|
590
|
-
t2 = beginToMax / deltaX;
|
|
591
|
-
tMin = Math.min(t1, t2);
|
|
592
|
-
tMax = Math.max(t1, t2);
|
|
593
|
-
if (tMin > tNear) {
|
|
594
|
-
tNear = tMin;
|
|
595
|
-
}
|
|
596
|
-
if (tMax < tFar) {
|
|
597
|
-
tFar = tMax;
|
|
598
|
-
}
|
|
599
|
-
if (tNear > tFar || tFar < 0) {
|
|
600
|
-
return false;
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
beginToMin = this.y0 - startY;
|
|
604
|
-
beginToMax = this.y1 - startY;
|
|
605
|
-
if (deltaY === 0) {//parallel
|
|
606
|
-
if (beginToMin > 0 || beginToMax < 0) {
|
|
607
|
-
return false; //segment is not between planes
|
|
608
|
-
}
|
|
609
|
-
} else {
|
|
610
|
-
t1 = beginToMin / deltaY;
|
|
611
|
-
t2 = beginToMax / deltaY;
|
|
612
|
-
tMin = Math.min(t1, t2);
|
|
613
|
-
tMax = Math.max(t1, t2);
|
|
614
|
-
if (tMin > tNear) {
|
|
615
|
-
tNear = tMin;
|
|
616
|
-
}
|
|
617
|
-
if (tMax < tFar) {
|
|
618
|
-
tFar = tMax;
|
|
619
|
-
}
|
|
620
|
-
if (tNear > tFar || tFar < 0) {
|
|
621
|
-
return false;
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
beginToMin = this.z0 - startZ;
|
|
625
|
-
beginToMax = this.z1 - startZ;
|
|
626
|
-
if (deltaZ === 0) {//parallel
|
|
627
|
-
if (beginToMin > 0 || beginToMax < 0) {
|
|
628
|
-
return false; //segment is not between planes
|
|
629
|
-
}
|
|
630
|
-
} else {
|
|
631
|
-
t1 = beginToMin / deltaZ;
|
|
632
|
-
t2 = beginToMax / deltaZ;
|
|
633
|
-
tMin = Math.min(t1, t2);
|
|
634
|
-
tMax = Math.max(t1, t2);
|
|
635
|
-
if (tMin > tNear) {
|
|
636
|
-
tNear = tMin;
|
|
637
|
-
}
|
|
638
|
-
if (tMax < tFar) {
|
|
639
|
-
tFar = tMax;
|
|
640
|
-
}
|
|
641
|
-
if (tNear > tFar || tFar < 0) {
|
|
642
|
-
return false;
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
//
|
|
646
|
-
if (tNear >= 0 && tNear <= 1) {
|
|
647
|
-
//intersections.push({
|
|
648
|
-
// x: startX + deltaX * tNear,
|
|
649
|
-
// y: startY + deltaY * tNear,
|
|
650
|
-
// z: startZ + deltaZ * tNear
|
|
651
|
-
//});
|
|
652
|
-
return true;
|
|
653
|
-
}
|
|
654
|
-
if (tFar >= 0 && tFar <= 1) {
|
|
655
|
-
//intersections.push({
|
|
656
|
-
// x: startX + deltaX * tFar,
|
|
657
|
-
// y: startY + deltaY * tFar,
|
|
658
|
-
// z: startZ + deltaZ * tFar
|
|
659
|
-
//});
|
|
660
|
-
return true;
|
|
661
|
-
}
|
|
662
|
-
return false;
|
|
663
|
-
//foreach (Axis axis in Enum.GetValues(typeof(Axis)))
|
|
664
|
-
//{
|
|
665
|
-
// if (beginToEnd.GetCoordinate(axis) == 0) // parallel
|
|
666
|
-
// {
|
|
667
|
-
// if (beginToMin.GetCoordinate(axis) > 0 || beginToMax.GetCoordinate(axis) < 0)
|
|
668
|
-
// return intersections; // segment is not between planes
|
|
669
|
-
// }
|
|
670
|
-
// else
|
|
671
|
-
// {
|
|
672
|
-
// var t1 = beginToMin.GetCoordinate(axis) / beginToEnd.GetCoordinate(axis);
|
|
673
|
-
// var t2 = beginToMax.GetCoordinate(axis) / beginToEnd.GetCoordinate(axis);
|
|
674
|
-
// var tMin = Math.Min(t1, t2);
|
|
675
|
-
// var tMax = Math.Max(t1, t2);
|
|
676
|
-
// if (tMin > tNear) tNear = tMin;
|
|
677
|
-
// if (tMax < tFar) tFar = tMax;
|
|
678
|
-
// if (tNear > tFar || tFar < 0) return intersections;
|
|
679
|
-
//
|
|
680
|
-
// }
|
|
681
|
-
//}
|
|
682
|
-
//if (tNear >= 0 && tNear <= 1) intersections.Add(segmentBegin + beginToEnd * tNear);
|
|
683
|
-
//if (tFar >= 0 && tFar <= 1) intersections.Add(segmentBegin + beginToEnd * tFar);
|
|
684
|
-
//return intersections;
|
|
685
|
-
}
|
|
686
|
-
|
|
687
554
|
/**
|
|
688
555
|
*
|
|
689
556
|
* @param {THREE.Box} box
|
|
@@ -28,10 +28,11 @@ import SelectionClearAction from "../actions/concrete/SelectionClearAction.js";
|
|
|
28
28
|
import EntityCreateAction from "../actions/concrete/EntityCreateAction.js";
|
|
29
29
|
import ComponentAddAction from "../actions/concrete/ComponentAddAction.js";
|
|
30
30
|
import SelectionAddAction from "../actions/concrete/SelectionAddAction.js";
|
|
31
|
-
import {
|
|
31
|
+
import { passThrough } from "../../core/function/Functions.js";
|
|
32
32
|
import { ProcessState } from "../../core/process/ProcessState.js";
|
|
33
33
|
import { MeshEvents } from "../../engine/graphics/ecs/mesh/MeshEvents.js";
|
|
34
34
|
import { obtainTerrain } from "../../engine/ecs/terrain/util/obtainTerrain.js";
|
|
35
|
+
import { SurfacePoint3 } from "../../core/geom/3d/SurfacePoint3.js";
|
|
35
36
|
|
|
36
37
|
class ViewManager extends View {
|
|
37
38
|
constructor() {
|
|
@@ -204,35 +205,37 @@ function prepareMeshLibrary(editor) {
|
|
|
204
205
|
const entityCreateAction = new EntityCreateAction();
|
|
205
206
|
actions.do(entityCreateAction);
|
|
206
207
|
|
|
207
|
-
|
|
208
|
-
function handleMeshSetEvent() {
|
|
209
|
-
const bb = mesh.boundingBox;
|
|
208
|
+
const sp3 = new SurfacePoint3();
|
|
210
209
|
|
|
211
|
-
|
|
212
|
-
const c1 = new Vector3(bb.x1, bb.y1, bb.z1);
|
|
210
|
+
const hit_found = terrain.raycastFirstSync(sp3, source.x, source.y, source.z, direction.x, direction.y, direction.z);
|
|
213
211
|
|
|
214
|
-
|
|
212
|
+
function handleMeshSetEvent() {
|
|
213
|
+
const bb = mesh.boundingBox;
|
|
215
214
|
|
|
216
|
-
|
|
215
|
+
const c0 = new Vector3(bb.x0, bb.y0, bb.z0);
|
|
216
|
+
const c1 = new Vector3(bb.x1, bb.y1, bb.z1);
|
|
217
217
|
|
|
218
|
-
|
|
218
|
+
const diagonal = c0.distanceTo(c1);
|
|
219
219
|
|
|
220
|
-
|
|
221
|
-
ecd.removeEntityEventListener(entityCreateAction.entity, MeshEvents.DataSet, handleMeshSetEvent);
|
|
222
|
-
}
|
|
220
|
+
const offset = direction.clone().multiplyScalar(diagonal);
|
|
223
221
|
|
|
224
|
-
|
|
225
|
-
//got a terrain ray hit, set world placement position to that point
|
|
226
|
-
worldPosition.copy(hit);
|
|
227
|
-
} else {
|
|
228
|
-
//set position to the source of the ray pick if there's nothing else available
|
|
229
|
-
worldPosition.copy(source);
|
|
222
|
+
transform.position.add(offset);
|
|
230
223
|
|
|
224
|
+
//remove listener
|
|
225
|
+
ecd.removeEntityEventListener(entityCreateAction.entity, MeshEvents.DataSet, handleMeshSetEvent);
|
|
226
|
+
}
|
|
231
227
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
}
|
|
228
|
+
if (hit_found) {
|
|
229
|
+
//got a terrain ray hit, set world placement position to that point
|
|
230
|
+
worldPosition.copy(sp3.position);
|
|
231
|
+
} else {
|
|
232
|
+
//set position to the source of the ray pick if there's nothing else available
|
|
233
|
+
worldPosition.copy(source);
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
//wait for mesh to load
|
|
237
|
+
ecd.addEntityEventListener(entityCreateAction.entity, MeshEvents.DataSet, handleMeshSetEvent);
|
|
238
|
+
}
|
|
236
239
|
|
|
237
240
|
transform.position.copy(worldPosition);
|
|
238
241
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import View from "../../../../../view/View.js";
|
|
2
2
|
import Vector1 from "../../../../../core/geom/Vector1.js";
|
|
3
3
|
|
|
4
|
+
const DEFAULT_VALUE = 0;
|
|
5
|
+
|
|
4
6
|
export class NumberController extends View {
|
|
5
7
|
/**
|
|
6
8
|
*
|
|
@@ -32,6 +34,22 @@ export class NumberController extends View {
|
|
|
32
34
|
|
|
33
35
|
let lockForward = false;
|
|
34
36
|
|
|
37
|
+
/**
|
|
38
|
+
*
|
|
39
|
+
* @param {number} num_value
|
|
40
|
+
* @return {string}
|
|
41
|
+
*/
|
|
42
|
+
function format_value_string(num_value) {
|
|
43
|
+
|
|
44
|
+
let str = String(num_value);
|
|
45
|
+
|
|
46
|
+
if (Math.abs(num_value) > 0 && Math.abs(num_value % 1).toString().length > (figures + 2)) {
|
|
47
|
+
str = num_value.toFixed(figures);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return str;
|
|
51
|
+
}
|
|
52
|
+
|
|
35
53
|
function data2view() {
|
|
36
54
|
|
|
37
55
|
if (lockForward) {
|
|
@@ -40,26 +58,37 @@ export class NumberController extends View {
|
|
|
40
58
|
|
|
41
59
|
const num_value = _value.getValue();
|
|
42
60
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (Math.abs(num_value) > 0 && Math.abs(num_value % 1).toString().length > (figures + 2)) {
|
|
46
|
-
str = num_value.toFixed(figures);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
el.value = str;
|
|
61
|
+
el.value = format_value_string(num_value);
|
|
50
62
|
|
|
51
63
|
}
|
|
52
64
|
|
|
53
65
|
function view2data() {
|
|
54
66
|
lockForward = true;
|
|
55
67
|
|
|
56
|
-
|
|
68
|
+
const value = parseFloat(el.value);
|
|
69
|
+
|
|
70
|
+
if (Number.isNaN(value)) {
|
|
71
|
+
_value.set(DEFAULT_VALUE);
|
|
72
|
+
} else {
|
|
73
|
+
_value.set(value);
|
|
74
|
+
}
|
|
57
75
|
|
|
58
76
|
lockForward = false;
|
|
59
77
|
}
|
|
60
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Input field stops being edited
|
|
81
|
+
*/
|
|
82
|
+
function handle_blur() {
|
|
83
|
+
if (Number.isNaN(parseFloat(el.value))) {
|
|
84
|
+
// input in the field is invalid, replace with the value held in the data container
|
|
85
|
+
el.value = format_value_string(_value.getValue());
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
61
89
|
_value.process(data2view);
|
|
62
90
|
|
|
63
91
|
el.addEventListener('input', view2data);
|
|
92
|
+
el.addEventListener('blur', handle_blur);
|
|
64
93
|
}
|
|
65
94
|
}
|
package/engine/EngineHarness.js
CHANGED
|
@@ -9,7 +9,6 @@ import Vector3 from "../core/geom/Vector3.js";
|
|
|
9
9
|
import Terrain from "./ecs/terrain/ecs/Terrain.js";
|
|
10
10
|
import Vector2 from "../core/geom/Vector2.js";
|
|
11
11
|
import Water from "./graphics/ecs/water/Water.js";
|
|
12
|
-
import { loadGameClassRegistry } from "../../model/game/GameClassRegistry.js";
|
|
13
12
|
import { WebEnginePlatform } from "./platform/WebEnginePlatform.js";
|
|
14
13
|
import Tag from "./ecs/components/Tag.js";
|
|
15
14
|
import { SerializationMetadata } from "./ecs/components/SerializationMetadata.js";
|
|
@@ -116,8 +115,6 @@ export class EngineHarness {
|
|
|
116
115
|
|
|
117
116
|
await setLocale(engine);
|
|
118
117
|
|
|
119
|
-
loadGameClassRegistry(engine.classRegistry);
|
|
120
|
-
|
|
121
118
|
engine.sceneManager.create("test");
|
|
122
119
|
engine.sceneManager.set("test");
|
|
123
120
|
|
|
@@ -7,7 +7,14 @@ import { PNG } from './PNG.js';
|
|
|
7
7
|
import { BinaryBuffer } from "../../../../../core/binary/BinaryBuffer.js";
|
|
8
8
|
import { isArrayEqualStrict } from "../../../../../core/collection/array/isArrayEqualStrict.js";
|
|
9
9
|
import { PNG_HEADER_BYTES } from "./PNG_HEADER_BYTES.js";
|
|
10
|
+
import { crc } from "./crc.js";
|
|
10
11
|
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @param {Uint8Array} buffer
|
|
15
|
+
* @param {number} offset
|
|
16
|
+
* @return {number}
|
|
17
|
+
*/
|
|
11
18
|
function readUInt32(buffer, offset) {
|
|
12
19
|
return (buffer[offset] << 24) +
|
|
13
20
|
(buffer[offset + 1] << 16) +
|
|
@@ -16,6 +23,12 @@ function readUInt32(buffer, offset) {
|
|
|
16
23
|
}
|
|
17
24
|
|
|
18
25
|
|
|
26
|
+
/**
|
|
27
|
+
*
|
|
28
|
+
* @param {Uint8Array} buffer
|
|
29
|
+
* @param {number} offset
|
|
30
|
+
* @return {number}
|
|
31
|
+
*/
|
|
19
32
|
function readUInt8(buffer, offset) {
|
|
20
33
|
return buffer[offset];
|
|
21
34
|
}
|
|
@@ -37,8 +50,19 @@ export function PNGReader(bytes) {
|
|
|
37
50
|
|
|
38
51
|
this.buffer = new BinaryBuffer();
|
|
39
52
|
this.buffer.fromArrayBuffer(bytes);
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Whether CRC should be performed or not
|
|
56
|
+
* @type {boolean}
|
|
57
|
+
*/
|
|
58
|
+
this.crc_enabled = false;
|
|
40
59
|
}
|
|
41
60
|
|
|
61
|
+
/**
|
|
62
|
+
*
|
|
63
|
+
* @param {number} length
|
|
64
|
+
* @return {Uint8Array}
|
|
65
|
+
*/
|
|
42
66
|
PNGReader.prototype.readBytes = function (length) {
|
|
43
67
|
const result = new Uint8Array(length);
|
|
44
68
|
|
|
@@ -91,16 +115,31 @@ PNGReader.prototype.decodeChunk = function () {
|
|
|
91
115
|
throw new Error('Bad chunk length ' + (0xFFFFFFFF & length));
|
|
92
116
|
}
|
|
93
117
|
|
|
118
|
+
|
|
119
|
+
const chunk_address = buffer.position;
|
|
120
|
+
|
|
94
121
|
const type = buffer.readASCIICharacters(4);
|
|
95
122
|
|
|
96
123
|
/**
|
|
97
124
|
*
|
|
98
125
|
* @type {Uint8Array}
|
|
99
126
|
*/
|
|
100
|
-
|
|
127
|
+
const chunk = this.readBytes(length);
|
|
101
128
|
|
|
102
129
|
// checksum
|
|
103
|
-
|
|
130
|
+
const crc_expected = buffer.readUint32();
|
|
131
|
+
|
|
132
|
+
if (this.crc_enabled) {
|
|
133
|
+
|
|
134
|
+
// NOTE: CRC includes the "type" tag, not just the chunk bytes
|
|
135
|
+
const crc_actual = crc(buffer.raw_bytes, chunk_address, length + 4);
|
|
136
|
+
|
|
137
|
+
if (crc_actual !== crc_expected) {
|
|
138
|
+
console.warn(`CRC (Cyclic Redundancy Check) error at block '${type}' at address ${chunk_address}`);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
}
|
|
142
|
+
|
|
104
143
|
|
|
105
144
|
switch (type) {
|
|
106
145
|
case 'IHDR':
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Ported from C source at https://www.w3.org/TR/PNG-CRCAppendix.html
|
|
3
|
+
* See also ISO 3309 [ISO-3309] or ITU-T V.42 [ITU-V42] for a formal specification
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @type {Uint32Array}
|
|
9
|
+
*/
|
|
10
|
+
const crc_table = new Uint32Array(256);
|
|
11
|
+
|
|
12
|
+
// Precompute checksum table
|
|
13
|
+
for (let n = 0; n < 256; n++) {
|
|
14
|
+
let c = n;
|
|
15
|
+
for (let k = 0; k < 8; k++) {
|
|
16
|
+
if (c & 1) {
|
|
17
|
+
c = 0xedb88320 ^ (c >>> 1);
|
|
18
|
+
} else {
|
|
19
|
+
c = c >>> 1;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
crc_table[n] = c;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const INITIAL = 0xffffffff;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Update a running CRC with the bytes buf[0..len-1]--the CRC
|
|
29
|
+
* should be initialized to all 1's, and the transmitted value
|
|
30
|
+
* is the 1's complement of the final running CRC (see the
|
|
31
|
+
* crc() routine below)).
|
|
32
|
+
* @param {number} crc
|
|
33
|
+
* @param {Uint8Array} buf
|
|
34
|
+
* @param {number} offset
|
|
35
|
+
* @param {number} len
|
|
36
|
+
* @return {number}
|
|
37
|
+
*/
|
|
38
|
+
function update_crc(
|
|
39
|
+
crc,
|
|
40
|
+
buf,
|
|
41
|
+
offset,
|
|
42
|
+
len,
|
|
43
|
+
) {
|
|
44
|
+
let c = crc;
|
|
45
|
+
|
|
46
|
+
const end = offset + len;
|
|
47
|
+
|
|
48
|
+
for (let n = offset; n < end; n++) {
|
|
49
|
+
const lookup_index = (c ^ buf[n]) & 0xff;
|
|
50
|
+
|
|
51
|
+
c = crc_table[lookup_index] ^ (c >>> 8);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return c;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Returns CRC of the bytes buf[0..len-1]
|
|
59
|
+
* @param {Uint8Array} buf byte buffer
|
|
60
|
+
* @param {number} offset
|
|
61
|
+
* @param {number} len how many bytes to include in checksum calculation
|
|
62
|
+
* @return {number}
|
|
63
|
+
*/
|
|
64
|
+
export function crc(buf, offset, len) {
|
|
65
|
+
return (update_crc(INITIAL, buf, offset, len) ^ INITIAL) >>> 0;
|
|
66
|
+
}
|
|
@@ -429,7 +429,7 @@ export class VoiceSystem extends AbstractContextSystem {
|
|
|
429
429
|
const bb = ecd.getComponent(entity, Blackboard);
|
|
430
430
|
|
|
431
431
|
if (bb !== undefined) {
|
|
432
|
-
bb.
|
|
432
|
+
bb.incrementNumber(`voice.line_spoken.${line_id}.count`);
|
|
433
433
|
}
|
|
434
434
|
|
|
435
435
|
}
|
|
@@ -37,6 +37,8 @@ import { buildLightTexture } from "./BuildLightTexture.js";
|
|
|
37
37
|
import { promiseSamplerHeight } from "./PromiseSamplerHeight.js";
|
|
38
38
|
import { loadLegacyTerrainSplats } from "./splat/loadLegacyTerrainSplats.js";
|
|
39
39
|
import { WHITE_PIXEL_DATA_URL } from "../../../graphics/WHITE_PIXEL_DATA_URL.js";
|
|
40
|
+
import { mat4 } from "gl-matrix";
|
|
41
|
+
import { SurfacePoint3 } from "../../../../core/geom/3d/SurfacePoint3.js";
|
|
40
42
|
|
|
41
43
|
let idCounter = 0;
|
|
42
44
|
|
|
@@ -157,6 +159,13 @@ class Terrain {
|
|
|
157
159
|
*/
|
|
158
160
|
this.frustumCulled = true;
|
|
159
161
|
|
|
162
|
+
/**
|
|
163
|
+
* 4x4 transform matrix
|
|
164
|
+
* @private
|
|
165
|
+
* @type {Float32Array}
|
|
166
|
+
*/
|
|
167
|
+
this.__transform_matrix = mat4.create();
|
|
168
|
+
|
|
160
169
|
|
|
161
170
|
/**
|
|
162
171
|
*
|
|
@@ -176,6 +185,11 @@ class Terrain {
|
|
|
176
185
|
*/
|
|
177
186
|
this.__buildWorker = makeTerrainWorkerProxy();
|
|
178
187
|
|
|
188
|
+
/**
|
|
189
|
+
*
|
|
190
|
+
* @type {TerrainTileManager}
|
|
191
|
+
* @private
|
|
192
|
+
*/
|
|
179
193
|
this.__tiles = new TerrainTileManager({
|
|
180
194
|
material: this.material,
|
|
181
195
|
buildWorker: this.__buildWorker
|
|
@@ -393,26 +407,17 @@ class Terrain {
|
|
|
393
407
|
* @param {function} errorCallback
|
|
394
408
|
*/
|
|
395
409
|
sampleHeight(x, y, callback, missCallback, errorCallback) {
|
|
396
|
-
assert.
|
|
397
|
-
assert.
|
|
398
|
-
assert.
|
|
410
|
+
assert.isFunction(callback, 'callback');
|
|
411
|
+
assert.isFunction(missCallback, 'missCallback');
|
|
412
|
+
assert.isFunction(errorCallback, 'errorCallback');
|
|
399
413
|
|
|
400
|
-
|
|
414
|
+
const hit = new SurfacePoint3();
|
|
401
415
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
* @param geometry
|
|
407
|
-
*/
|
|
408
|
-
function processHit(hit, face, geometry) {
|
|
409
|
-
if (!processed) {
|
|
410
|
-
processed = true;
|
|
411
|
-
callback(hit.y);
|
|
412
|
-
}
|
|
416
|
+
if (this.raycastVerticalFirstSync(hit, x, y)) {
|
|
417
|
+
callback(hit.position.y);
|
|
418
|
+
} else {
|
|
419
|
+
missCallback();
|
|
413
420
|
}
|
|
414
|
-
|
|
415
|
-
this.raycastVertical(x, y, processHit, missCallback, errorCallback);
|
|
416
421
|
}
|
|
417
422
|
|
|
418
423
|
/**
|
|
@@ -426,27 +431,27 @@ class Terrain {
|
|
|
426
431
|
* @param {number} directionZ
|
|
427
432
|
* @returns {boolean}
|
|
428
433
|
*/
|
|
429
|
-
raycastFirstSync(
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
+
raycastFirstSync(
|
|
435
|
+
result,
|
|
436
|
+
originX, originY, originZ,
|
|
437
|
+
directionX, directionY, directionZ
|
|
438
|
+
) {
|
|
434
439
|
return this.__tiles.raycastFirstSync(result, originX, originY, originZ, directionX, directionY, directionZ);
|
|
435
440
|
}
|
|
436
441
|
|
|
437
442
|
/**
|
|
438
|
-
*
|
|
443
|
+
* @deprecated
|
|
439
444
|
* @param {Vector3} origin
|
|
440
445
|
* @param {Vector3} direction
|
|
441
446
|
* @param {function(hit:Vector3, normal:Vector3, geometry:BufferGeometry)} callback
|
|
442
447
|
* @param {function} missCallback
|
|
443
448
|
*/
|
|
444
449
|
raycast(origin, direction, callback, missCallback) {
|
|
445
|
-
|
|
450
|
+
throw new Error('Deprecated, use raycastFirstSync instead');
|
|
446
451
|
}
|
|
447
452
|
|
|
448
453
|
/**
|
|
449
|
-
*
|
|
454
|
+
* @deprecated
|
|
450
455
|
* @param {number} x
|
|
451
456
|
* @param {number} y
|
|
452
457
|
* @param {function} callback
|
|
@@ -454,11 +459,7 @@ class Terrain {
|
|
|
454
459
|
* @param {function} errorCallback
|
|
455
460
|
*/
|
|
456
461
|
raycastVertical(x, y, callback, missCallback, errorCallback) {
|
|
457
|
-
|
|
458
|
-
assert.typeOf(missCallback, 'function', 'missCallback');
|
|
459
|
-
assert.typeOf(errorCallback, 'function', 'errorCallback');
|
|
460
|
-
|
|
461
|
-
this.__tiles.raycastVertical(x, y, callback, missCallback);
|
|
462
|
+
throw new Error('Deprecated, use raycastVerticalFirstSync instead');
|
|
462
463
|
}
|
|
463
464
|
|
|
464
465
|
/**
|
|
@@ -469,12 +470,7 @@ class Terrain {
|
|
|
469
470
|
* @return {boolean}
|
|
470
471
|
*/
|
|
471
472
|
raycastVerticalFirstSync(contact, x, y) {
|
|
472
|
-
|
|
473
|
-
//tiles don't exist
|
|
474
|
-
return false;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
return this.__tiles.raycastVerticalFirstSync(contact, x, y);
|
|
473
|
+
return this.__tiles.raycastVerticalFirstSync(contact, x, y);
|
|
478
474
|
}
|
|
479
475
|
|
|
480
476
|
/**
|
|
@@ -649,6 +645,24 @@ class Terrain {
|
|
|
649
645
|
m.uniformsNeedUpdate = true;
|
|
650
646
|
}
|
|
651
647
|
|
|
648
|
+
/**
|
|
649
|
+
*
|
|
650
|
+
* @param {mat4|Float32Array|number[]} m4
|
|
651
|
+
*/
|
|
652
|
+
set transform(m4) {
|
|
653
|
+
mat4.copy(this.__transform_matrix, m4);
|
|
654
|
+
|
|
655
|
+
this.__tiles.transform = m4;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
*
|
|
660
|
+
* @return {Float32Array}
|
|
661
|
+
*/
|
|
662
|
+
get transform() {
|
|
663
|
+
return this.__transform_matrix;
|
|
664
|
+
}
|
|
665
|
+
|
|
652
666
|
/**
|
|
653
667
|
*
|
|
654
668
|
* @param {TerrainLayer} layer
|
|
@@ -846,6 +860,14 @@ class Terrain {
|
|
|
846
860
|
this.setFlag(TerrainFlags.Built);
|
|
847
861
|
}
|
|
848
862
|
|
|
863
|
+
/**
|
|
864
|
+
* Note: For advanced users only. You can seriously mess up how things look and function with respect to terrain here
|
|
865
|
+
* @return {TerrainTileManager}
|
|
866
|
+
*/
|
|
867
|
+
get tiles() {
|
|
868
|
+
return this.__tiles;
|
|
869
|
+
}
|
|
870
|
+
|
|
849
871
|
/**
|
|
850
872
|
*
|
|
851
873
|
* @returns {Texture|null}
|