@woosh/meep-engine 2.39.3 → 2.39.6
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 +1 -0
- package/core/geom/3d/topology/bounds/{computeTraingleClusterNormalBoundingCone.js → computeTriangleClusterNormalBoundingCone.js} +8 -1
- package/core/geom/Vector3.d.ts +8 -0
- package/core/math/FLT_EPSILON_32.js +7 -0
- package/core/math/random/seededRandom_Mulberry32.js +1 -1
- package/core/model/stat/LinearModifier.js +7 -0
- package/core/process/task/RemainingTimeEstimator.js +49 -0
- package/core/process/task/Task.js +3 -1
- package/engine/Engine.js +3 -69
- package/engine/asset/AssetManager.d.ts +3 -0
- package/engine/asset/AssetManager.js +5 -4
- package/engine/ecs/terrain/ecs/Terrain.js +33 -0
- package/engine/ecs/terrain/ecs/layers/TerrainLayer.js +13 -0
- package/engine/ecs/terrain/ecs/layers/TerrainLayers.js +44 -2
- package/engine/ecs/terrain/ecs/splat/SplatMapping.js +12 -4
- package/engine/graphics/ecs/path/testPathDisplaySystem.js +58 -53
- package/engine/graphics/ecs/path/tube/PathNormalType.d.ts +4 -0
- package/engine/graphics/ecs/path/tube/PathNormalType.js +11 -0
- package/engine/graphics/ecs/path/tube/TubePathStyle.d.ts +4 -0
- package/engine/graphics/ecs/path/tube/TubePathStyle.js +21 -3
- package/engine/graphics/ecs/path/tube/build/build_geometry_catmullrom.js +4 -1
- package/engine/graphics/ecs/path/tube/build/build_geometry_linear.js +4 -1
- package/engine/graphics/ecs/path/tube/build/computeFrenetFrames.js +41 -24
- package/engine/graphics/geometry/VertexDataSpec.js +24 -0
- package/engine/graphics/micron/build/PatchRepresentation.js +3 -3
- package/engine/graphics/shaders/TerrainShader.js +3 -7
- package/engine/knowledge/database/StaticKnowledgeDataTable.js +66 -28
- package/engine/navigation/ecs/components/Path.js +58 -232
- package/engine/notify/Notification.js +3 -0
- package/engine/ui/notification/AnimatedObjectEmitter.js +3 -2
- package/engine/ui/notification/ViewEmitter.js +8 -0
- package/engine/ui/scene/initializeNotifications.js +3 -0
- package/generation/{GridGenerator.js → GridTaskGroup.js} +21 -5
- package/generation/example/SampleGenerator0.js +2 -2
- package/generation/filtering/core/CellFilterUnaryOperation.js +5 -8
- package/generation/filtering/numeric/util/CellFilterDisplaced.js +7 -7
- package/generation/grid/generation/GridTaskSequence.js +5 -3
- package/generation/markers/actions/MarkerNodeActionImaginary.js +86 -0
- package/generation/markers/actions/terrain/MarkerNodeActionPaintTerrain.js +265 -0
- package/generation/theme/TerrainLayerDescription.js +11 -0
- package/generation/theme/ThemeEngine.js +5 -6
- package/package.json +1 -1
- package/view/common/ListView.js +7 -1
- package/view/elements/windrose/WindRoseDiagram.js +13 -0
- package/view/task/TaskLoadingScreen.js +163 -0
- package/view/{common → task}/TaskProgressView.js +4 -36
- package/view/tooltip/gml/GMLEngine.js +13 -0
- package/generation/markers/actions/MarkerNodeActionSelectRandom.js +0 -65
|
@@ -5,6 +5,8 @@ import { MatcapMaterialDefinition } from "./MatcapMaterialDefinition.js";
|
|
|
5
5
|
import { CapType } from "./CapType.js";
|
|
6
6
|
import { StandardMaterialDefinition } from "./StandardMaterialDefinition.js";
|
|
7
7
|
import { BasicMaterialDefinition } from "./BasicMaterialDefinition.js";
|
|
8
|
+
import { PathNormalType } from "./PathNormalType.js";
|
|
9
|
+
import Vector3 from "../../../../../core/geom/Vector3.js";
|
|
8
10
|
|
|
9
11
|
const DEFAULT_COLOR = Object.freeze({ r: 1, g: 1, b: 1 });
|
|
10
12
|
|
|
@@ -51,8 +53,6 @@ export class TubePathStyle {
|
|
|
51
53
|
*/
|
|
52
54
|
this.shape_normals = null;
|
|
53
55
|
|
|
54
|
-
// TODO expose shading style "flat/smooth"
|
|
55
|
-
|
|
56
56
|
/**
|
|
57
57
|
*
|
|
58
58
|
* @type {number}
|
|
@@ -71,6 +71,17 @@ export class TubePathStyle {
|
|
|
71
71
|
*/
|
|
72
72
|
this.receive_shadow = false;
|
|
73
73
|
|
|
74
|
+
/**
|
|
75
|
+
* @type {PathNormalType}
|
|
76
|
+
*/
|
|
77
|
+
this.path_normal_type = PathNormalType.Automatic;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
*
|
|
81
|
+
* @type {Vector3}
|
|
82
|
+
*/
|
|
83
|
+
this.path_normal = Vector3.up;
|
|
84
|
+
|
|
74
85
|
/**
|
|
75
86
|
* Which parts of the path to visualise, in normalized offsets
|
|
76
87
|
* @example [ 0, 1 ] = whole path
|
|
@@ -120,7 +131,9 @@ export class TubePathStyle {
|
|
|
120
131
|
receive_shadow = false,
|
|
121
132
|
path_mask = [0, 1],
|
|
122
133
|
cap_type = CapType.None,
|
|
123
|
-
shape
|
|
134
|
+
shape,
|
|
135
|
+
path_normal = Vector3.up,
|
|
136
|
+
path_normal_type = PathNormalType.Automatic
|
|
124
137
|
}) {
|
|
125
138
|
assert.enum(material_type, TubeMaterialType, 'material_type');
|
|
126
139
|
assert.isNumber(opacity, 'opacity');
|
|
@@ -135,6 +148,7 @@ export class TubePathStyle {
|
|
|
135
148
|
assert.greaterThanOrEqual(path_mask.length, 2, 'path_mask length bust be at least 2');
|
|
136
149
|
assert.ok(path_mask.length % 2 === 0, 'path_mask length bust be multiple of 2');
|
|
137
150
|
assert.enum(cap_type, CapType, 'cap_type');
|
|
151
|
+
assert.enum(path_normal_type, 'path_normal_type');
|
|
138
152
|
|
|
139
153
|
if (shape === undefined) {
|
|
140
154
|
// legacy API, using circle
|
|
@@ -177,6 +191,10 @@ export class TubePathStyle {
|
|
|
177
191
|
}
|
|
178
192
|
|
|
179
193
|
this.material.fromJSON(material);
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
this.path_normal.fromJSON(path_normal);
|
|
197
|
+
this.path_normal_type = path_normal_type;
|
|
180
198
|
}
|
|
181
199
|
}
|
|
182
200
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { computeFrenetFrames } from "./computeFrenetFrames.js";
|
|
2
2
|
import { makeTubeGeometry } from "./makeTubeGeometry.js";
|
|
3
3
|
import Vector3 from "../../../../../../core/geom/Vector3.js";
|
|
4
|
+
import { PathNormalType } from "../PathNormalType.js";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
*
|
|
@@ -63,7 +64,9 @@ export function build_geometry_catmullrom(
|
|
|
63
64
|
added_points++;
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
const
|
|
67
|
+
const normal_hint = style.path_normal_type === PathNormalType.FixedStart ? style.path_normal : undefined;
|
|
68
|
+
|
|
69
|
+
const frames = computeFrenetFrames(points_f32, false, normal_hint);
|
|
67
70
|
|
|
68
71
|
return makeTubeGeometry(
|
|
69
72
|
points_f32, frames.normals, frames.binormals, frames.tangents,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { computeFrenetFrames } from "./computeFrenetFrames.js";
|
|
2
2
|
import { makeTubeGeometry } from "./makeTubeGeometry.js";
|
|
3
3
|
import Vector3 from "../../../../../../core/geom/Vector3.js";
|
|
4
|
+
import { PathNormalType } from "../PathNormalType.js";
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
const scratch_array_0 = [];
|
|
@@ -57,7 +58,9 @@ export function build_geometry_linear(
|
|
|
57
58
|
points_added++;
|
|
58
59
|
}
|
|
59
60
|
|
|
60
|
-
const
|
|
61
|
+
const normal_hint = style.path_normal_type === PathNormalType.FixedStart ? style.path_normal : undefined;
|
|
62
|
+
|
|
63
|
+
const frames = computeFrenetFrames(points, false, normal_hint);
|
|
61
64
|
|
|
62
65
|
return makeTubeGeometry(
|
|
63
66
|
points, frames.normals, frames.binormals, frames.tangents,
|
|
@@ -5,13 +5,49 @@ import { clamp } from "../../../../../../core/math/clamp.js";
|
|
|
5
5
|
import { vec3 } from "gl-matrix";
|
|
6
6
|
import { array_copy } from "../../../../../../core/collection/array/copyArray.js";
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Compute a normal vector for Frenet frame based on a tangent (direction in which vertex points)
|
|
10
|
+
* @param {Vector3} result
|
|
11
|
+
* @param {Vector3} tangent
|
|
12
|
+
*/
|
|
13
|
+
function computeNormalHintFromTangent(result, tangent) {
|
|
14
|
+
let min = Number.MAX_VALUE;
|
|
15
|
+
|
|
16
|
+
const tx = Math.abs(tangent.x);
|
|
17
|
+
const ty = Math.abs(tangent.y);
|
|
18
|
+
const tz = Math.abs(tangent.z);
|
|
19
|
+
|
|
20
|
+
if (ty <= min) {
|
|
21
|
+
|
|
22
|
+
min = ty;
|
|
23
|
+
result.set(0, 1, 0);
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (tz < min) {
|
|
28
|
+
|
|
29
|
+
min = tz;
|
|
30
|
+
result.set(0, 0, 1);
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (tx < min) {
|
|
35
|
+
|
|
36
|
+
min = tx;
|
|
37
|
+
result.set(1, 0, 0);
|
|
38
|
+
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
8
43
|
/**
|
|
9
44
|
* @see https://github.com/mrdoob/three.js/blob/c12c9a166a1369cdd58622fff2aff7e3a84305d7/src/extras/core/Curve.js#L260
|
|
10
45
|
* @param {Float32Array|number[]} points
|
|
11
46
|
* @param {boolean} [closed]
|
|
47
|
+
* @param {Vector3} [normal_hint]
|
|
12
48
|
* @returns {{normals:Vector3[], binormals:Vector3[], tangents:Vector3[]}}
|
|
13
49
|
*/
|
|
14
|
-
export function computeFrenetFrames(points, closed = false) {
|
|
50
|
+
export function computeFrenetFrames(points, closed = false, normal_hint) {
|
|
15
51
|
// see http://www.cs.indiana.edu/pub/techreports/TR425.pdf
|
|
16
52
|
|
|
17
53
|
const normal = new Vector3();
|
|
@@ -82,30 +118,11 @@ export function computeFrenetFrames(points, closed = false) {
|
|
|
82
118
|
|
|
83
119
|
normals[0] = new Vector3();
|
|
84
120
|
binormals[0] = new Vector3();
|
|
85
|
-
let min = Number.MAX_VALUE;
|
|
86
|
-
const tx = Math.abs(tangents[0].x);
|
|
87
|
-
const ty = Math.abs(tangents[0].y);
|
|
88
|
-
const tz = Math.abs(tangents[0].z);
|
|
89
|
-
|
|
90
|
-
if (ty <= min) {
|
|
91
|
-
|
|
92
|
-
min = ty;
|
|
93
|
-
normal.set(0, 1, 0);
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
if (tz < min) {
|
|
98
|
-
min = tz;
|
|
99
|
-
|
|
100
|
-
normal.set(0, 0, 1);
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (tx < min) {
|
|
105
|
-
|
|
106
|
-
min = tx;
|
|
107
|
-
normal.set(1, 0, 0);
|
|
108
121
|
|
|
122
|
+
if (normal_hint !== undefined) {
|
|
123
|
+
normal.copy(normal_hint);
|
|
124
|
+
} else {
|
|
125
|
+
computeNormalHintFromTangent(normal, tangents[0]);
|
|
109
126
|
}
|
|
110
127
|
|
|
111
128
|
vec.crossVectors(tangents[0], normal).normalize();
|
|
@@ -20,6 +20,19 @@ export class VertexDataSpec {
|
|
|
20
20
|
this.__hash = DEFAULT_HASH;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
*
|
|
25
|
+
* @param {AttributeSpec} attributes
|
|
26
|
+
* @returns {VertexDataSpec}
|
|
27
|
+
*/
|
|
28
|
+
static from(...attributes) {
|
|
29
|
+
const r = new VertexDataSpec();
|
|
30
|
+
|
|
31
|
+
r.addMany(attributes);
|
|
32
|
+
|
|
33
|
+
return r;
|
|
34
|
+
}
|
|
35
|
+
|
|
23
36
|
/**
|
|
24
37
|
*
|
|
25
38
|
* @param {string} name
|
|
@@ -61,6 +74,17 @@ export class VertexDataSpec {
|
|
|
61
74
|
return undefined;
|
|
62
75
|
}
|
|
63
76
|
|
|
77
|
+
/**
|
|
78
|
+
*
|
|
79
|
+
* @param {AttributeSpec[]} attributes
|
|
80
|
+
*/
|
|
81
|
+
addMany(attributes) {
|
|
82
|
+
const n = attributes.length;
|
|
83
|
+
for (let i = 0; i < n; i++) {
|
|
84
|
+
this.add(attributes[i]);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
64
88
|
/**
|
|
65
89
|
*
|
|
66
90
|
* @param {AttributeSpec} attribute
|
|
@@ -4,8 +4,8 @@ import { fill_patch_geometry_data } from "./fill_patch_geometry_data.js";
|
|
|
4
4
|
import { AABB3 } from "../../../../core/bvh2/aabb3/AABB3.js";
|
|
5
5
|
import { assert } from "../../../../core/assert.js";
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
} from "../../../../core/geom/3d/topology/bounds/
|
|
7
|
+
computeTriangleClusterNormalBoundingCone
|
|
8
|
+
} from "../../../../core/geom/3d/topology/bounds/computeTriangleClusterNormalBoundingCone.js";
|
|
9
9
|
import { noop } from "../../../../core/function/Functions.js";
|
|
10
10
|
import { ConicRay } from "../../../../core/geom/ConicRay.js";
|
|
11
11
|
import { vec4 } from "gl-matrix";
|
|
@@ -379,7 +379,7 @@ export class PatchRepresentation {
|
|
|
379
379
|
}
|
|
380
380
|
|
|
381
381
|
computeNormalBoundingCone() {
|
|
382
|
-
|
|
382
|
+
computeTriangleClusterNormalBoundingCone(this.normal_cone, this.topology_snapshot.getFaces());
|
|
383
383
|
}
|
|
384
384
|
|
|
385
385
|
/**
|
|
@@ -99,7 +99,7 @@ function fragment() {
|
|
|
99
99
|
precision highp sampler2DArray;
|
|
100
100
|
|
|
101
101
|
uniform sampler2DArray splatWeightMap;
|
|
102
|
-
uniform
|
|
102
|
+
uniform int splatLayerCount;
|
|
103
103
|
|
|
104
104
|
uniform vec2 splatResolution;
|
|
105
105
|
|
|
@@ -280,13 +280,9 @@ function fragment() {
|
|
|
280
280
|
float weightSum = 0.0;
|
|
281
281
|
vec4 colorSum = vec4(0.0);
|
|
282
282
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
for( float i = 0.0; i < splatLayerCount; i++){
|
|
286
|
-
|
|
287
|
-
float nI = i * m;
|
|
283
|
+
for( int i = 0; i < splatLayerCount; i++){
|
|
288
284
|
|
|
289
|
-
vec2 scale =
|
|
285
|
+
vec2 scale = texelFetch(materialScalesMap, ivec2(i, 0), 0 ).xy;
|
|
290
286
|
|
|
291
287
|
vec2 layerUv = vUv * scale;
|
|
292
288
|
|
|
@@ -4,6 +4,33 @@ import Task from "../../../core/process/task/Task.js";
|
|
|
4
4
|
import { assert } from "../../../core/assert.js";
|
|
5
5
|
import TaskSignal from "../../../core/process/task/TaskSignal.js";
|
|
6
6
|
|
|
7
|
+
let id_seed = 0;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @param {{contains:function(string):boolean}} database
|
|
12
|
+
* @returns {string}
|
|
13
|
+
*/
|
|
14
|
+
function generate_id(database) {
|
|
15
|
+
let retries_left = 10000;
|
|
16
|
+
let id;
|
|
17
|
+
|
|
18
|
+
do {
|
|
19
|
+
id = id_seed.toString(16);
|
|
20
|
+
|
|
21
|
+
id_seed++;
|
|
22
|
+
|
|
23
|
+
retries_left--;
|
|
24
|
+
|
|
25
|
+
if (retries_left <= 0) {
|
|
26
|
+
throw new Error(`Couldn't find a unique ID after maximum number of attempts`);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
} while (database.contains(id))
|
|
30
|
+
|
|
31
|
+
return id;
|
|
32
|
+
}
|
|
33
|
+
|
|
7
34
|
/**
|
|
8
35
|
* Base class for managing various kinds of static game data
|
|
9
36
|
* @template T
|
|
@@ -11,31 +38,31 @@ import TaskSignal from "../../../core/process/task/TaskSignal.js";
|
|
|
11
38
|
export class StaticKnowledgeDataTable {
|
|
12
39
|
|
|
13
40
|
/**
|
|
14
|
-
*
|
|
15
|
-
* @
|
|
41
|
+
* Elements mapped by their string ID
|
|
42
|
+
* @type {Object<T>}
|
|
16
43
|
*/
|
|
17
|
-
|
|
44
|
+
elements = {};
|
|
18
45
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
46
|
+
/**
|
|
47
|
+
*
|
|
48
|
+
* @type {Map<string, object>}
|
|
49
|
+
* @protected
|
|
50
|
+
*/
|
|
51
|
+
__json = new Map();
|
|
24
52
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
53
|
+
/**
|
|
54
|
+
* Array representation of elements, useful for fast traversal
|
|
55
|
+
* @type {T[]}
|
|
56
|
+
* @protected
|
|
57
|
+
*/
|
|
58
|
+
__array = [];
|
|
31
59
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
60
|
+
/**
|
|
61
|
+
* Allow automatic ID generation when ID is not present
|
|
62
|
+
* @type {boolean}
|
|
63
|
+
* @protected
|
|
64
|
+
*/
|
|
65
|
+
__automatic_ids = false;
|
|
39
66
|
|
|
40
67
|
reset() {
|
|
41
68
|
Object.keys(this.elements).forEach(id => {
|
|
@@ -208,11 +235,17 @@ export class StaticKnowledgeDataTable {
|
|
|
208
235
|
const task = countTask(0, n, i => {
|
|
209
236
|
const datum = data[i];
|
|
210
237
|
|
|
211
|
-
|
|
238
|
+
let id = datum.id;
|
|
212
239
|
|
|
213
240
|
if (typeof id !== "string") {
|
|
214
|
-
|
|
215
|
-
|
|
241
|
+
|
|
242
|
+
if (this.__automatic_ids) {
|
|
243
|
+
id = generate_id(this);
|
|
244
|
+
} else {
|
|
245
|
+
console.error(`datum.id must be a string, instead was '${typeof id}' (= ${id})`);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
|
|
216
249
|
}
|
|
217
250
|
|
|
218
251
|
let element;
|
|
@@ -221,15 +254,15 @@ export class StaticKnowledgeDataTable {
|
|
|
221
254
|
element = this.parse(datum);
|
|
222
255
|
} catch (e) {
|
|
223
256
|
|
|
224
|
-
let
|
|
257
|
+
let _id;
|
|
225
258
|
//attempt to extract item ID
|
|
226
259
|
try {
|
|
227
|
-
|
|
260
|
+
_id = datum.id;
|
|
228
261
|
} catch (e) {
|
|
229
|
-
|
|
262
|
+
_id = 'ERROR';
|
|
230
263
|
}
|
|
231
264
|
|
|
232
|
-
console.error(`Failed to parse element (id=${
|
|
265
|
+
console.error(`Failed to parse element (id=${_id})`, e, datum);
|
|
233
266
|
return;
|
|
234
267
|
}
|
|
235
268
|
|
|
@@ -250,6 +283,11 @@ export class StaticKnowledgeDataTable {
|
|
|
250
283
|
|
|
251
284
|
this.__json.set(id, datum);
|
|
252
285
|
|
|
286
|
+
if (datum.id !== id) {
|
|
287
|
+
// ID was generated, write it back into the element
|
|
288
|
+
element.id = id;
|
|
289
|
+
}
|
|
290
|
+
|
|
253
291
|
const added = this.add(element);
|
|
254
292
|
|
|
255
293
|
if (!added) {
|