@woosh/meep-engine 2.41.0 → 2.42.1
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/assert.js +2 -2
- package/core/collection/array/array_swap.js +3 -3
- package/core/collection/map/AsyncLoadingCache.js +47 -0
- package/core/geom/3d/aabb/aabb3_compute_distance_above_plane_max.js +1 -1
- package/core/geom/3d/apply_mat4_transform_to_v3_array.js +2 -4
- package/core/geom/3d/sphere/sphere_radius_sqr_from_v3_array_transformed.js +28 -0
- package/core/geom/Quaternion.js +14 -0
- package/core/math/statistics/computeSampleSize_Cochran.js +3 -3
- package/editor/ecs/component/editors/geom/QuaternionEditor.js +12 -5
- package/engine/Engine.js +6 -1
- package/engine/EngineBootstrapper.js +2 -1
- package/engine/EngineHarness.js +13 -3
- package/engine/asset/AssetManager.js +97 -7
- package/engine/development/performance/AbstractMetric.js +1 -0
- package/engine/development/performance/RingBufferMetric.js +25 -4
- package/engine/ecs/EntityBuilder.js +29 -4
- package/engine/ecs/transform/Transform.js +23 -3
- package/engine/graphics/ecs/camera/topdown/TopDownCameraControllerSystem.js +17 -1
- package/engine/graphics/ecs/decal/v2/Decal.d.ts +11 -0
- package/engine/graphics/ecs/decal/v2/Decal.js +50 -0
- package/engine/graphics/ecs/decal/v2/FPDecalSystem.d.ts +8 -0
- package/engine/graphics/ecs/decal/v2/FPDecalSystem.js +201 -0
- package/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +278 -0
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +8 -1
- package/engine/graphics/ecs/mesh-v2/allocate_v3.js +37 -0
- package/engine/graphics/ecs/mesh-v2/build_three_object.js +4 -0
- package/engine/graphics/geometry/MikkT/AddTriToGroup.js +10 -0
- package/engine/graphics/geometry/MikkT/AssignRecur.js +84 -0
- package/engine/graphics/geometry/MikkT/AvgTSpace.js +38 -0
- package/engine/graphics/geometry/MikkT/Build4RuleGroups.js +96 -0
- package/engine/graphics/geometry/MikkT/BuildNeighborsFast.js +137 -0
- package/engine/graphics/geometry/MikkT/CalcTexArea.js +31 -0
- package/engine/graphics/geometry/MikkT/CompareSubGroups.js +26 -0
- package/engine/graphics/geometry/MikkT/DegenEpilogue.js +220 -0
- package/engine/graphics/geometry/MikkT/DegenPrologue.js +115 -0
- package/engine/graphics/geometry/MikkT/EvalTspace.js +128 -0
- package/engine/graphics/geometry/MikkT/GenerateInitialVerticesIndexList.js +48 -0
- package/engine/graphics/geometry/MikkT/GenerateSharedVerticesIndexList.js +184 -0
- package/engine/graphics/geometry/MikkT/GenerateTSpaces.js +226 -0
- package/engine/graphics/geometry/MikkT/GetEdge.js +45 -0
- package/engine/graphics/geometry/MikkT/GetNormal.js +16 -0
- package/engine/graphics/geometry/MikkT/GetPosition.js +25 -0
- package/engine/graphics/geometry/MikkT/GetTexCoord.js +18 -0
- package/engine/graphics/geometry/MikkT/InitTriInfo.js +180 -0
- package/engine/graphics/geometry/MikkT/Length.js +10 -0
- package/engine/graphics/geometry/MikkT/MakeIndex.js +18 -0
- package/engine/graphics/geometry/MikkT/MikkTSpace.js +197 -2068
- package/engine/graphics/geometry/MikkT/NormalizeSafe.js +21 -0
- package/engine/graphics/geometry/MikkT/NotZero.js +10 -0
- package/engine/graphics/geometry/MikkT/QuickSort.js +54 -0
- package/engine/graphics/geometry/MikkT/QuickSortEdges.js +71 -0
- package/engine/graphics/geometry/MikkT/SSubGroup.js +15 -0
- package/engine/graphics/geometry/MikkT/STSpace.js +36 -0
- package/engine/graphics/geometry/MikkT/constants/GROUP_WITH_ANY.js +1 -0
- package/engine/graphics/geometry/MikkT/constants/INTERNAL_RND_SORT_SEED.js +1 -0
- package/engine/graphics/geometry/MikkT/constants/MARK_DEGENERATE.js +1 -0
- package/engine/graphics/geometry/MikkT/constants/ORIENT_PRESERVING.js +1 -0
- package/engine/graphics/geometry/MikkT/constants/QUAD_ONE_DEGEN_TRI.js +1 -0
- package/engine/graphics/geometry/MikkT/m_getNormal.js +16 -0
- package/engine/graphics/geometry/MikkT/m_getNumFaces.js +8 -0
- package/engine/graphics/geometry/MikkT/m_getNumVerticesOfFace.js +11 -0
- package/engine/graphics/geometry/MikkT/m_getPosition.js +20 -0
- package/engine/graphics/geometry/MikkT/m_getTexCoord.js +16 -0
- package/engine/graphics/geometry/MikkT/m_setTSpace.js +35 -0
- package/engine/graphics/geometry/MikkT/m_setTSpaceBasic.js +22 -0
- package/engine/graphics/geometry/MikkT/malloc.js +16 -0
- package/engine/graphics/geometry/MikkT/v3_scale_dot_sub_normalize.js +52 -0
- package/engine/graphics/geometry/buffered/computeGeometryEquality.js +1 -1
- package/engine/graphics/geometry/buffered/computeGeometryHash.js +1 -1
- package/engine/graphics/impostors/octahedral/ImpostorBaker.js +28 -14
- package/engine/graphics/impostors/octahedral/ImpostorDescription.js +6 -0
- package/engine/graphics/impostors/octahedral/README.md +1 -0
- package/engine/graphics/impostors/octahedral/bake/compute_bounding_sphere.js +25 -22
- package/engine/graphics/impostors/octahedral/bake/compute_bounding_sphere_radius_only.js +37 -0
- package/engine/graphics/impostors/octahedral/bake/prepare_bake_material.js +30 -1
- package/engine/graphics/impostors/octahedral/grid/HemiOctahedralUvEncoder.js +1 -1
- package/engine/graphics/impostors/octahedral/prototypeBaker.js +121 -22
- package/engine/graphics/impostors/octahedral/shader/BakeShaderStandard.js +46 -7
- package/engine/graphics/impostors/octahedral/shader/ImpostorShaderV0.js +349 -0
- package/engine/graphics/impostors/octahedral/shader/ImpostorShaderV1.js +74 -0
- package/engine/graphics/impostors/octahedral/shader/glsl/v1/common.glsl +209 -0
- package/engine/graphics/impostors/octahedral/shader/glsl/v1/flagment.glsl +80 -0
- package/engine/graphics/impostors/octahedral/shader/glsl/v1/vertex.glsl +350 -0
- package/engine/graphics/micron/render/v1/getTransformedPositionsCached.js +1 -1
- package/engine/graphics/render/forward_plus/LightManager.js +17 -7
- package/engine/graphics/render/forward_plus/data/TextureBackedMemoryRegion.js +7 -1
- package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_ACCUMULATION.js +13 -5
- package/engine/graphics/render/forward_plus/materials/FP_SHADER_CHUNK_PREAMBLE.js +3 -1
- package/engine/graphics/render/forward_plus/model/Decal.js +19 -2
- package/engine/graphics/render/forward_plus/plugin/MaterialTransformer.js +14 -2
- package/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +2 -2
- package/engine/graphics/texture/sampler/Sampler2D.js +10 -10
- package/engine/graphics/texture/sampler/prototypeSamplerFiltering.js +117 -11
- package/engine/graphics/texture/sampler/resize/sampler2d_downsample_mipmap.js +66 -0
- package/engine/graphics/texture/sampler/sampler2_d_scale_down_lanczos.js +2 -2
- package/engine/intelligence/behavior/util/RotationBehavior.js +69 -0
- package/generation/example/filters/SampleGroundMoistureFilter.js +5 -5
- package/package.json +1 -1
package/core/assert.js
CHANGED
|
@@ -167,8 +167,8 @@ function arrayHasNo(haystack, needle, message = 'Array contains the item') {
|
|
|
167
167
|
|
|
168
168
|
/**
|
|
169
169
|
* @template T
|
|
170
|
-
* @param {T[]|ArrayLike<T>|Float32Array} a
|
|
171
|
-
* @param {T[]|ArrayLike<T>|Float32Array} b
|
|
170
|
+
* @param {T[]|ArrayLike<T>|Float32Array|Int32Array} a
|
|
171
|
+
* @param {T[]|ArrayLike<T>|Float32Array|Int32Array} b
|
|
172
172
|
* @param {string} [message]
|
|
173
173
|
*/
|
|
174
174
|
function arrayEqual(a, b, message = 'Arrays are not equal') {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @param {T[]|ArrayLike<T>|TypedArray|Uint8ClampedArray|Uint8Array} a
|
|
2
|
+
* @template T
|
|
3
|
+
* @param {T[]|ArrayLike<T>|TypedArray|Uint8ClampedArray|Uint8Array|Float32Array} a
|
|
4
4
|
* @param {number} a_offset
|
|
5
|
-
* @param {T[]|ArrayLike<T>|TypedArray|Uint8ClampedArray|Uint8Array} b
|
|
5
|
+
* @param {T[]|ArrayLike<T>|TypedArray|Uint8ClampedArray|Uint8Array|Float32Array} b
|
|
6
6
|
* @param {number} b_offset
|
|
7
7
|
* @param {number} length How many elements should be moved
|
|
8
8
|
*/
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { AbstractAsyncMap } from "./AbstractAsyncMap.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Cache wrapper that loads data when it's not found in the cache
|
|
5
|
+
*/
|
|
6
|
+
export class AsyncLoadingCache extends AbstractAsyncMap {
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param {Map} cache
|
|
10
|
+
* @param {function(K):Promise<T>} loader
|
|
11
|
+
*/
|
|
12
|
+
constructor(cache, loader) {
|
|
13
|
+
super();
|
|
14
|
+
|
|
15
|
+
this.__cache = cache;
|
|
16
|
+
this.__loader = loader;
|
|
17
|
+
this.__pending = new Map();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async get(key) {
|
|
21
|
+
|
|
22
|
+
const cached = this.__cache.get(key);
|
|
23
|
+
|
|
24
|
+
if (cached !== undefined) {
|
|
25
|
+
return cached;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let promise = this.__pending.get(key);
|
|
29
|
+
let original_loader = false;
|
|
30
|
+
|
|
31
|
+
if (promise === undefined) {
|
|
32
|
+
promise = this.__loader(key);
|
|
33
|
+
|
|
34
|
+
this.__pending.set(key, promise);
|
|
35
|
+
|
|
36
|
+
original_loader = true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const value = await promise;
|
|
40
|
+
|
|
41
|
+
if (original_loader) {
|
|
42
|
+
this.__cache.get(key, value);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -18,7 +18,7 @@ export function aabb3_computeDistanceAbovePlane_max(
|
|
|
18
18
|
_x1, _y1, _z1
|
|
19
19
|
) {
|
|
20
20
|
|
|
21
|
-
// pick a corner point
|
|
21
|
+
// pick a corner point that is the closest along the plane normal
|
|
22
22
|
const px = plane_normal_x > 0 ? _x1 : _x0;
|
|
23
23
|
const py = plane_normal_y > 0 ? _y1 : _y0;
|
|
24
24
|
const pz = plane_normal_z > 0 ? _z1 : _z0;
|
|
@@ -6,11 +6,9 @@
|
|
|
6
6
|
* @param {number[]|Float32Array|Float64Array} destination
|
|
7
7
|
* @param {number} destination_offset
|
|
8
8
|
* @param {number} count
|
|
9
|
-
* @param {
|
|
9
|
+
* @param {mat4|number[]|Float32Array} mat4
|
|
10
10
|
*/
|
|
11
|
-
export function apply_mat4_transform_to_v3_array(source, source_offset, destination, destination_offset, count,
|
|
12
|
-
|
|
13
|
-
const mat4 = matrix.elements;
|
|
11
|
+
export function apply_mat4_transform_to_v3_array(source, source_offset, destination, destination_offset, count, mat4) {
|
|
14
12
|
|
|
15
13
|
const a0 = mat4[0];
|
|
16
14
|
const a1 = mat4[1];
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {number[]|ArrayLike<number>} input
|
|
4
|
+
* @param {number} input_length
|
|
5
|
+
* @param {ArrayLike<number>|number[]|Float32Array} e 4x4 transformation matrix
|
|
6
|
+
* @returns {number}
|
|
7
|
+
*/
|
|
8
|
+
export function sphere_radius_sqr_from_v3_array_transformed(input, input_length, e) {
|
|
9
|
+
let result = 0;
|
|
10
|
+
|
|
11
|
+
for (let i = 0; i < input_length; i += 3) {
|
|
12
|
+
const x = input[i];
|
|
13
|
+
const y = input[i + 1];
|
|
14
|
+
const z = input[i + 2];
|
|
15
|
+
|
|
16
|
+
const _x = e[0] * x + e[4] * y + e[8] * z + e[12];
|
|
17
|
+
const _y = e[1] * x + e[5] * y + e[9] * z + e[13];
|
|
18
|
+
const _z = e[2] * x + e[6] * y + e[10] * z + e[14];
|
|
19
|
+
|
|
20
|
+
const l2 = _x * _x + _y * _y + _z * _z;
|
|
21
|
+
|
|
22
|
+
if (l2 > result) {
|
|
23
|
+
result = l2;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return result;
|
|
28
|
+
}
|
package/core/geom/Quaternion.js
CHANGED
|
@@ -1705,6 +1705,20 @@ class Quaternion {
|
|
|
1705
1705
|
return result;
|
|
1706
1706
|
}
|
|
1707
1707
|
|
|
1708
|
+
/**
|
|
1709
|
+
*
|
|
1710
|
+
* @param {number} x
|
|
1711
|
+
* @param {number} y
|
|
1712
|
+
* @param {number} z
|
|
1713
|
+
* @returns {Quaternion}
|
|
1714
|
+
*/
|
|
1715
|
+
static fromEulerAngles(x, y, z) {
|
|
1716
|
+
const r = new Quaternion();
|
|
1717
|
+
|
|
1718
|
+
r.fromEulerAnglesXYZ(x, y, z);
|
|
1719
|
+
|
|
1720
|
+
return r;
|
|
1721
|
+
}
|
|
1708
1722
|
|
|
1709
1723
|
/**
|
|
1710
1724
|
* Behaves similarly to Unity's Quaternion `RotateToward` method
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
* 99% | 2.57583
|
|
13
13
|
* 99.9% | 3.29053
|
|
14
14
|
*
|
|
15
|
-
* @param z Standard distribution value. # of standard deviations. See statistical tables
|
|
16
|
-
* @param p Fraction of the population with attribute in question. For example if we want to estimate what time people have breakfast and we know that only 30% of people have have breakfast overall, p would be 0.3
|
|
17
|
-
* @param e Error tolerance, 0.05 represents 5% error tolerance
|
|
15
|
+
* @param {number} z Standard distribution value. # of standard deviations. See statistical tables
|
|
16
|
+
* @param {number} p Fraction of the population with attribute in question. For example if we want to estimate what time people have breakfast and we know that only 30% of people have have breakfast overall, p would be 0.3
|
|
17
|
+
* @param {number} e Error tolerance, 0.05 represents 5% error tolerance
|
|
18
18
|
* @returns {number} Sample size
|
|
19
19
|
*/
|
|
20
20
|
export function computeSampleSize_Cochran(z, p, e) {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { TypeEditor } from "../../TypeEditor.js";
|
|
2
2
|
import Vector3 from "../../../../../core/geom/Vector3.js";
|
|
3
|
-
import { DEG2RAD, RAD2DEG } from "three/src/math/MathUtils.js";
|
|
4
3
|
import { makeV3_editor } from "../common/makeV3_editor.js";
|
|
4
|
+
import { DEG_TO_RAD } from "../../../../../core/math/DEG_TO_RAD.js";
|
|
5
|
+
import { RAD_TO_DEG } from "../../../../../core/math/RAD_TO_DEG.js";
|
|
5
6
|
|
|
6
7
|
export class QuaternionEditor extends TypeEditor {
|
|
7
8
|
build(parent, field, registry) {
|
|
@@ -20,7 +21,13 @@ export class QuaternionEditor extends TypeEditor {
|
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
lock = true;
|
|
23
|
-
|
|
24
|
+
|
|
25
|
+
q.__setFromEuler(
|
|
26
|
+
euler.x * DEG_TO_RAD,
|
|
27
|
+
euler.y * DEG_TO_RAD,
|
|
28
|
+
euler.z * DEG_TO_RAD
|
|
29
|
+
);
|
|
30
|
+
|
|
24
31
|
lock = false;
|
|
25
32
|
};
|
|
26
33
|
|
|
@@ -36,9 +43,9 @@ export class QuaternionEditor extends TypeEditor {
|
|
|
36
43
|
q.toEulerAnglesXYZ(t);
|
|
37
44
|
|
|
38
45
|
euler.set(
|
|
39
|
-
t.x *
|
|
40
|
-
t.y *
|
|
41
|
-
t.z *
|
|
46
|
+
t.x * RAD_TO_DEG,
|
|
47
|
+
t.y * RAD_TO_DEG,
|
|
48
|
+
t.z * RAD_TO_DEG,
|
|
42
49
|
);
|
|
43
50
|
|
|
44
51
|
lock = false;
|
package/engine/Engine.js
CHANGED
|
@@ -84,7 +84,7 @@ class Engine {
|
|
|
84
84
|
*
|
|
85
85
|
* @type {ConcurrentExecutor}
|
|
86
86
|
*/
|
|
87
|
-
this.executor = new ConcurrentExecutor(
|
|
87
|
+
this.executor = new ConcurrentExecutor(1, 10);
|
|
88
88
|
|
|
89
89
|
this.__using_external_entity_manager = entityManager !== undefined;
|
|
90
90
|
|
|
@@ -412,6 +412,9 @@ class Engine {
|
|
|
412
412
|
start() {
|
|
413
413
|
const self = this;
|
|
414
414
|
|
|
415
|
+
|
|
416
|
+
this.assetManager.startup();
|
|
417
|
+
|
|
415
418
|
function promiseEntityManager() {
|
|
416
419
|
return new Promise(function (resolve, reject) {
|
|
417
420
|
//initialize entity manager
|
|
@@ -488,6 +491,8 @@ class Engine {
|
|
|
488
491
|
|
|
489
492
|
|
|
490
493
|
// TODO shutdown executor
|
|
494
|
+
|
|
495
|
+
await this.assetManager.shutdown();
|
|
491
496
|
}
|
|
492
497
|
|
|
493
498
|
exit() {
|
|
@@ -30,7 +30,8 @@ export class EngineBootstrapper {
|
|
|
30
30
|
|
|
31
31
|
this.rootNode.appendChild(v.el);
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
// NOTE: the engine used to be started here, this was moved out
|
|
34
|
+
const started = Promise.resolve();
|
|
34
35
|
|
|
35
36
|
const vExecutionEngineState = new LabelView('');
|
|
36
37
|
const vAssetManagerState = new LabelView('');
|
package/engine/EngineHarness.js
CHANGED
|
@@ -153,6 +153,7 @@ export class EngineHarness {
|
|
|
153
153
|
* @param {boolean} [autoClip]
|
|
154
154
|
* @param {number} [distanceMin]
|
|
155
155
|
* @param {number} [distanceMax]
|
|
156
|
+
* @param {number} [fieldOfView] in degrees
|
|
156
157
|
* @returns {EntityBuilder}
|
|
157
158
|
*/
|
|
158
159
|
static buildCamera(
|
|
@@ -163,9 +164,10 @@ export class EngineHarness {
|
|
|
163
164
|
distance = 10,
|
|
164
165
|
pitch = 1.4,
|
|
165
166
|
yaw = 0,
|
|
166
|
-
autoClip =
|
|
167
|
+
autoClip = false,
|
|
167
168
|
distanceMin = 0,
|
|
168
|
-
distanceMax = 1000
|
|
169
|
+
distanceMax = 1000,
|
|
170
|
+
fieldOfView = 45
|
|
169
171
|
}
|
|
170
172
|
) {
|
|
171
173
|
const em = engine.entityManager;
|
|
@@ -199,6 +201,8 @@ export class EngineHarness {
|
|
|
199
201
|
|
|
200
202
|
camera.active.set(true);
|
|
201
203
|
camera.autoClip = autoClip;
|
|
204
|
+
camera.clip_far = distanceMax;
|
|
205
|
+
camera.fov.set(fieldOfView);
|
|
202
206
|
|
|
203
207
|
const entityBuilder = new EntityBuilder();
|
|
204
208
|
|
|
@@ -229,6 +233,8 @@ export class EngineHarness {
|
|
|
229
233
|
* @param {boolean} [enableWater]
|
|
230
234
|
* @param {boolean} [enableTerrain]
|
|
231
235
|
* @param {boolean} [enableLights=true]
|
|
236
|
+
* @param {number} [cameraFieldOfView]
|
|
237
|
+
* @param {number} [cameraFarDistance]
|
|
232
238
|
* @param {boolean} [cameraController=true]
|
|
233
239
|
*/
|
|
234
240
|
static async buildBasics({
|
|
@@ -244,6 +250,8 @@ export class EngineHarness {
|
|
|
244
250
|
enableWater = true,
|
|
245
251
|
enableTerrain = true,
|
|
246
252
|
enableLights = true,
|
|
253
|
+
cameraFieldOfView,
|
|
254
|
+
cameraFarDistance,
|
|
247
255
|
cameraController = true
|
|
248
256
|
}) {
|
|
249
257
|
|
|
@@ -256,7 +264,9 @@ export class EngineHarness {
|
|
|
256
264
|
target: focus,
|
|
257
265
|
pitch,
|
|
258
266
|
yaw,
|
|
259
|
-
distance
|
|
267
|
+
distance,
|
|
268
|
+
fieldOfView: cameraFieldOfView,
|
|
269
|
+
distanceMax: cameraFarDistance
|
|
260
270
|
});
|
|
261
271
|
|
|
262
272
|
const cameraEntity = camera.entity;
|
|
@@ -13,6 +13,9 @@ import { CrossOriginConfig } from "./CORS/CrossOriginConfig.js";
|
|
|
13
13
|
import { array_remove_element } from "../../core/collection/array/array_remove_element.js";
|
|
14
14
|
import { AssetDescription } from "./AssetDescription.js";
|
|
15
15
|
import { noop } from "../../core/function/Functions.js";
|
|
16
|
+
import { Deque } from "../../core/collection/queue/Deque.js";
|
|
17
|
+
import Task from "../../core/process/task/Task.js";
|
|
18
|
+
import { TaskSignal } from "../../core/process/task/TaskSignal.js";
|
|
16
19
|
|
|
17
20
|
class AssetRequest {
|
|
18
21
|
/**
|
|
@@ -68,6 +71,18 @@ class PendingAsset {
|
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
73
|
|
|
74
|
+
class Response {
|
|
75
|
+
/**
|
|
76
|
+
*
|
|
77
|
+
* @param {Asset} asset
|
|
78
|
+
* @param {AssetRequest} request
|
|
79
|
+
*/
|
|
80
|
+
constructor(asset, request) {
|
|
81
|
+
this.asset = asset;
|
|
82
|
+
this.request = request;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
71
86
|
|
|
72
87
|
/**
|
|
73
88
|
* @class
|
|
@@ -139,6 +154,60 @@ export class AssetManager {
|
|
|
139
154
|
* @type {boolean}
|
|
140
155
|
*/
|
|
141
156
|
this.isAssetManager = true;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
*
|
|
160
|
+
* @type {Deque<Response>}
|
|
161
|
+
* @private
|
|
162
|
+
*/
|
|
163
|
+
this.__response_queue = new Deque();
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
*
|
|
167
|
+
* @type {Task}
|
|
168
|
+
* @private
|
|
169
|
+
*/
|
|
170
|
+
this.__response_processor = new Task({
|
|
171
|
+
name: "Asset Manager Response processor",
|
|
172
|
+
cycleFunction: () => {
|
|
173
|
+
if (this.__response_queue.isEmpty()) {
|
|
174
|
+
return TaskSignal.Yield;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const response = this.__response_queue.removeFirst();
|
|
178
|
+
|
|
179
|
+
this.__process_response(response);
|
|
180
|
+
|
|
181
|
+
return TaskSignal.Continue;
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
this.__is_running = false;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
startup() {
|
|
189
|
+
if (this.__is_running) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
this.__engine.executor.run(this.__response_processor);
|
|
194
|
+
|
|
195
|
+
this.__is_running = true;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async shutdown(immediate = false) {
|
|
199
|
+
if (!this.__is_running) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (!immediate) {
|
|
204
|
+
// wait until all responses have been processed
|
|
205
|
+
await Promise.allSettled([Task.promise(this.__response_processor)]);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
this.__engine.executor.removeTask(this.__response_processor);
|
|
209
|
+
|
|
210
|
+
this.__is_running = false;
|
|
142
211
|
}
|
|
143
212
|
|
|
144
213
|
/**
|
|
@@ -215,6 +284,30 @@ export class AssetManager {
|
|
|
215
284
|
this.assets.set(assetDescription, asset);
|
|
216
285
|
}
|
|
217
286
|
|
|
287
|
+
/**
|
|
288
|
+
*
|
|
289
|
+
* @param {Response} response
|
|
290
|
+
* @private
|
|
291
|
+
*/
|
|
292
|
+
__process_response(response) {
|
|
293
|
+
|
|
294
|
+
try {
|
|
295
|
+
response.request.successCallback(response.asset);
|
|
296
|
+
} catch (e) {
|
|
297
|
+
console.error("Failed to execute asset success callback", e);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
*
|
|
303
|
+
* @param {Asset} asset
|
|
304
|
+
* @param {AssetRequest} request
|
|
305
|
+
* @private
|
|
306
|
+
*/
|
|
307
|
+
__schedule_response(asset, request) {
|
|
308
|
+
this.__response_queue.add(new Response(asset, request));
|
|
309
|
+
}
|
|
310
|
+
|
|
218
311
|
/**
|
|
219
312
|
*
|
|
220
313
|
* @param {string} path
|
|
@@ -299,18 +392,15 @@ export class AssetManager {
|
|
|
299
392
|
//register asset
|
|
300
393
|
assets.set(assetDescription, asset);
|
|
301
394
|
|
|
395
|
+
//clear callbacks
|
|
396
|
+
requestMap.delete(assetDescription);
|
|
397
|
+
|
|
302
398
|
// process callbacks
|
|
303
399
|
for (let i = 0; i < requests.length; i++) {
|
|
304
400
|
const request = requests[i];
|
|
305
|
-
|
|
306
|
-
request.successCallback(asset);
|
|
307
|
-
} catch (e) {
|
|
308
|
-
console.error("Failed to execute asset success callback", e);
|
|
309
|
-
}
|
|
401
|
+
this.__schedule_response(asset, request);
|
|
310
402
|
}
|
|
311
403
|
|
|
312
|
-
//clear callbacks
|
|
313
|
-
requestMap.delete(assetDescription);
|
|
314
404
|
}
|
|
315
405
|
|
|
316
406
|
function failure(error) {
|
|
@@ -20,16 +20,37 @@ export class RingBufferMetric extends AbstractMetric {
|
|
|
20
20
|
this.__data.push(value);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
*
|
|
25
|
+
* @param {MetricStatistics} result
|
|
26
|
+
* @returns {boolean}
|
|
27
|
+
*/
|
|
23
28
|
computeStats(result) {
|
|
24
29
|
|
|
25
30
|
const buffer = this.__data;
|
|
26
31
|
const array = buffer.data;
|
|
27
32
|
const data_count = buffer.count;
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
34
|
+
if (data_count === 0) {
|
|
35
|
+
|
|
36
|
+
// no data
|
|
37
|
+
result.mean = 0;
|
|
38
|
+
result.meadian = 0;
|
|
39
|
+
result.min = 0;
|
|
40
|
+
result.max = 0;
|
|
41
|
+
|
|
42
|
+
return false;
|
|
43
|
+
|
|
44
|
+
} else {
|
|
45
|
+
|
|
46
|
+
result.mean = computeStatisticalMean(array, 0, data_count);
|
|
47
|
+
result.meadian = computeStatisticalPartialMedian(array, 0, data_count);
|
|
48
|
+
result.max = computeArrayMax(array, 0, data_count);
|
|
49
|
+
result.min = computeArrayMin(array, 0, data_count);
|
|
50
|
+
|
|
51
|
+
return true;
|
|
52
|
+
|
|
53
|
+
}
|
|
33
54
|
}
|
|
34
55
|
|
|
35
56
|
clear() {
|
|
@@ -8,11 +8,30 @@ import { isDefined } from "../../core/process/matcher/Matchers.js";
|
|
|
8
8
|
* @enum
|
|
9
9
|
*/
|
|
10
10
|
export const EntityBuilderFlags = {
|
|
11
|
+
/**
|
|
12
|
+
* Whether the entity is built, set internally
|
|
13
|
+
*/
|
|
11
14
|
Built: 1,
|
|
12
|
-
|
|
15
|
+
/**
|
|
16
|
+
* If component type is not registered on the {@link EntityComponentDataset} when calling {@link #build} - will register the component first
|
|
17
|
+
*/
|
|
18
|
+
RegisterComponents: 2,
|
|
19
|
+
/**
|
|
20
|
+
* Entity builder will watch destruction of the entity (subscribe to event), this will make the EntityBuilder automatically
|
|
21
|
+
* recognize when the corresponding entity is destroyed outside the EntityBuilder API
|
|
22
|
+
* NOTE: useful to turn off to save a bit of memory, as those event listeners take up a bit of space. Feel free to turn this flag off when you don't care to keep the reference to the EntityBuilder
|
|
23
|
+
*/
|
|
24
|
+
WatchDestruction: 4
|
|
13
25
|
};
|
|
14
26
|
|
|
15
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Set of default flags
|
|
29
|
+
* @type {number}
|
|
30
|
+
*/
|
|
31
|
+
const DEFAULT_FLAGS =
|
|
32
|
+
EntityBuilderFlags.RegisterComponents
|
|
33
|
+
| EntityBuilderFlags.WatchDestruction
|
|
34
|
+
;
|
|
16
35
|
|
|
17
36
|
/**
|
|
18
37
|
* Representation of an entity, helps build entities and keep track of them without having to access {@link EntityComponentDataset} directly
|
|
@@ -53,6 +72,10 @@ class EntityBuilder {
|
|
|
53
72
|
*/
|
|
54
73
|
this.dataset = null;
|
|
55
74
|
|
|
75
|
+
/**
|
|
76
|
+
*
|
|
77
|
+
* @type {EntityBuilderFlags|number}
|
|
78
|
+
*/
|
|
56
79
|
this.flags = DEFAULT_FLAGS;
|
|
57
80
|
|
|
58
81
|
/**
|
|
@@ -132,7 +155,7 @@ class EntityBuilder {
|
|
|
132
155
|
throw new Error("Can not add " + componentInstance + " to EntityBuilder");
|
|
133
156
|
}
|
|
134
157
|
|
|
135
|
-
assert.notOk(this.hasComponent(Object.getPrototypeOf(componentInstance).constructor)
|
|
158
|
+
assert.notOk(this.hasComponent(Object.getPrototypeOf(componentInstance).constructor), 'Component of this type already exists');
|
|
136
159
|
|
|
137
160
|
this.element.push(componentInstance);
|
|
138
161
|
|
|
@@ -378,7 +401,9 @@ class EntityBuilder {
|
|
|
378
401
|
|
|
379
402
|
this.setFlag(EntityBuilderFlags.Built);
|
|
380
403
|
|
|
381
|
-
|
|
404
|
+
if (this.getFlag(EntityBuilderFlags.WatchDestruction)) {
|
|
405
|
+
dataset.addEntityEventListener(entity, EventType.EntityRemoved, this.__handleEntityDestroyed, this);
|
|
406
|
+
}
|
|
382
407
|
|
|
383
408
|
this.on.built.send2(entity, dataset);
|
|
384
409
|
return entity;
|
|
@@ -63,9 +63,29 @@ export class Transform {
|
|
|
63
63
|
this.flags = FLAGS_DEFAULT;
|
|
64
64
|
|
|
65
65
|
// watch changes
|
|
66
|
-
this.
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
this.subscribeAllChanges(this.__handle_component_change, this);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
*
|
|
71
|
+
* @param {function} handler
|
|
72
|
+
* @param {*} [thisArg]
|
|
73
|
+
*/
|
|
74
|
+
subscribeAllChanges(handler, thisArg) {
|
|
75
|
+
this.position.onChanged.add(handler, thisArg);
|
|
76
|
+
this.rotation.onChanged.add(handler, thisArg);
|
|
77
|
+
this.scale.onChanged.add(handler, thisArg);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
*
|
|
82
|
+
* @param {function} handler
|
|
83
|
+
* @param {*} [thisArg]
|
|
84
|
+
*/
|
|
85
|
+
unsubscribeAllChanges(handler, thisArg) {
|
|
86
|
+
this.position.onChanged.remove(handler, thisArg);
|
|
87
|
+
this.rotation.onChanged.remove(handler, thisArg);
|
|
88
|
+
this.scale.onChanged.scale(handler, thisArg);
|
|
69
89
|
}
|
|
70
90
|
|
|
71
91
|
/**
|
|
@@ -24,6 +24,22 @@ class TopDownCameraControllerSystem extends System {
|
|
|
24
24
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
*
|
|
29
|
+
* @param {TopDownCameraController} ctrl
|
|
30
|
+
* @param {number} entity
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
33
|
+
__visit_camera_entity(ctrl, entity){
|
|
34
|
+
const transform = this.entityManager.dataset.getComponent(entity,Transform);
|
|
35
|
+
|
|
36
|
+
if(transform === undefined){
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
computeTopDownTransform(ctrl,transform);
|
|
41
|
+
}
|
|
42
|
+
|
|
27
43
|
update(timeDelta) {
|
|
28
44
|
const em = this.entityManager;
|
|
29
45
|
|
|
@@ -34,7 +50,7 @@ class TopDownCameraControllerSystem extends System {
|
|
|
34
50
|
const dataset = em.dataset;
|
|
35
51
|
|
|
36
52
|
if (this.enabled.get() && dataset !== null) {
|
|
37
|
-
dataset.
|
|
53
|
+
dataset.traverseComponents(TopDownCameraController, this.__visit_camera_entity, this);
|
|
38
54
|
}
|
|
39
55
|
|
|
40
56
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export class Decal {
|
|
2
|
+
constructor() {
|
|
3
|
+
/**
|
|
4
|
+
* Asset URL
|
|
5
|
+
* @type {string}
|
|
6
|
+
*/
|
|
7
|
+
this.uri = "";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Controls draw order
|
|
11
|
+
* @type {number}
|
|
12
|
+
*/
|
|
13
|
+
this.priority = 0;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Internal transient reference to loaded asset
|
|
17
|
+
* @type {Sampler2D|null}
|
|
18
|
+
* @private
|
|
19
|
+
*/
|
|
20
|
+
this.__cached_sampler = null;
|
|
21
|
+
/**
|
|
22
|
+
*
|
|
23
|
+
* @type {String|null}
|
|
24
|
+
* @private
|
|
25
|
+
*/
|
|
26
|
+
this.__cached_uri = null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
toJSON() {
|
|
30
|
+
return {
|
|
31
|
+
uri: this.uri,
|
|
32
|
+
priority: this.priority
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
fromJSON({
|
|
37
|
+
uri, priority = 0
|
|
38
|
+
}) {
|
|
39
|
+
this.uri = uri;
|
|
40
|
+
this.priority = priority;
|
|
41
|
+
|
|
42
|
+
if (uri !== this.__cached_uri) {
|
|
43
|
+
// reset sampler
|
|
44
|
+
this.__cached_sampler = null;
|
|
45
|
+
this.__cached_uri = null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
Decal.typeName = 'Decal';
|