@woosh/meep-engine 2.44.7 → 2.45.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/cache/Cache.js +1 -1
- package/core/collection/HashMap.d.ts +1 -1
- package/core/collection/HashMap.js +2 -1
- package/core/localization/LanguageMetadata.js +48 -0
- package/core/localization/LocaleDataset.js +37 -0
- package/core/localization/Localization.js +253 -0
- package/core/model/node-graph/DataType.js +1 -1
- package/core/model/node-graph/node/Port.js +4 -0
- package/core/process/task/Task.js +22 -5
- package/core/process/task/util/iteratorTask.js +29 -0
- package/editor/view/ecs/components/items/ItemContainerController.stories.js +1 -1
- package/engine/Engine.js +1 -1
- package/engine/asset/AssetManager.js +4 -0
- package/engine/ecs/foliage/ViewState.js +7 -1
- package/engine/ecs/speaker/VoiceSystem.js +1 -1
- package/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +17 -11
- package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +37 -0
- package/engine/graphics/ecs/mesh-v2/render/ShadedGeometryRendererContext.js +19 -0
- package/engine/graphics/ecs/mesh-v2/render/adapters/AbstractRenderAdapter.js +11 -2
- package/engine/graphics/render/forward_plus/LightManager.js +33 -123
- package/engine/graphics/render/forward_plus/SPECIFICATION.md +155 -0
- package/engine/graphics/render/forward_plus/assign_cluster.js +125 -0
- package/engine/graphics/render/forward_plus/model/Decal.js +6 -2
- package/engine/graphics/render/forward_plus/plugin/ForwardPlusRenderingPlugin.d.ts +5 -0
- package/engine/graphics/render/forward_plus/plugin/ForwardPlusRenderingPlugin.js +11 -4
- package/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +3 -3
- package/engine/graphics/render/forward_plus/query/query_bvh_frustum_from_texture.js +2 -2
- package/engine/graphics/render/forward_plus/sort_decal_data.js +102 -0
- package/engine/graphics/sh3/path_tracer/prototypePathTracer.js +1 -1
- package/engine/input/devices/InputDeviceButton.d.ts +7 -0
- package/engine/input/devices/InputDeviceButton.js +22 -0
- package/engine/input/devices/KeyboardDevice.d.ts +11 -0
- package/engine/input/devices/KeyboardDevice.js +17 -7
- package/package.json +1 -1
- package/core/Localization.js +0 -199
package/core/cache/Cache.js
CHANGED
|
@@ -29,7 +29,7 @@ export class HashMap<K, V> implements Iterable<[V, K]> {
|
|
|
29
29
|
|
|
30
30
|
forEach(callback: (value: V, key: K, map: this) => any, thisArg?: any): void
|
|
31
31
|
|
|
32
|
-
[Symbol.iterator](): IterableIterator<[
|
|
32
|
+
[Symbol.iterator](): IterableIterator<[K, V]>
|
|
33
33
|
|
|
34
34
|
values(): IterableIterator<V>
|
|
35
35
|
|
|
@@ -40,6 +40,7 @@ const DEFAULT_LOAD_FACTOR = 0.75;
|
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
42
|
* Implements part of {@link Map} interface
|
|
43
|
+
* @copyright Alex Goldring (c) 2023
|
|
43
44
|
* @template K,V
|
|
44
45
|
* @extends Map<K,V>
|
|
45
46
|
*/
|
|
@@ -519,7 +520,7 @@ export class HashMap {
|
|
|
519
520
|
*/
|
|
520
521
|
const entry = bucket[i];
|
|
521
522
|
|
|
522
|
-
yield [entry.
|
|
523
|
+
yield [entry.key, entry.value];
|
|
523
524
|
}
|
|
524
525
|
}
|
|
525
526
|
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { assert } from "../assert.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents information about a language
|
|
5
|
+
*/
|
|
6
|
+
export class LanguageMetadata {
|
|
7
|
+
/**
|
|
8
|
+
* Measured in characters per second
|
|
9
|
+
* @type {number}
|
|
10
|
+
*/
|
|
11
|
+
reading_speed = 10
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Ordered list of fallback languages, if no value is found for a key in this language, other languages will be attempted in order
|
|
15
|
+
* Identified by localization key
|
|
16
|
+
* @see {@link #locale}
|
|
17
|
+
* @type {string[]}
|
|
18
|
+
*/
|
|
19
|
+
fallback_languages = []
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Localization key,
|
|
23
|
+
* @see ISO 639
|
|
24
|
+
* @type {string}
|
|
25
|
+
*/
|
|
26
|
+
locale = "";
|
|
27
|
+
|
|
28
|
+
fromJSON({
|
|
29
|
+
reading_speed = 10,
|
|
30
|
+
fallback_languages = []
|
|
31
|
+
}) {
|
|
32
|
+
|
|
33
|
+
assert.isNumber(reading_speed, 'reading_speed');
|
|
34
|
+
assert.greaterThan(reading_speed, 0, 'reading_speed');
|
|
35
|
+
|
|
36
|
+
this.reading_speed = reading_speed;
|
|
37
|
+
|
|
38
|
+
this.fallback_languages = fallback_languages;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static fromJSON(j) {
|
|
42
|
+
const r = new LanguageMetadata();
|
|
43
|
+
|
|
44
|
+
r.fromJSON(j);
|
|
45
|
+
|
|
46
|
+
return r;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { assert } from "../assert.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Represents data for a single localization
|
|
7
|
+
*/
|
|
8
|
+
export class LocaleDataset {
|
|
9
|
+
/**
|
|
10
|
+
* Localized strings, identified by localization key
|
|
11
|
+
* @type {Object<string>}
|
|
12
|
+
* @private
|
|
13
|
+
*/
|
|
14
|
+
__strings = {}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
* Does a given key exist?
|
|
19
|
+
* @param {string} key
|
|
20
|
+
* @return {boolean}
|
|
21
|
+
*/
|
|
22
|
+
hasString(key) {
|
|
23
|
+
assert.isString(key, 'key');
|
|
24
|
+
|
|
25
|
+
return this.__strings[key] !== undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
*
|
|
30
|
+
* @param {string} key
|
|
31
|
+
* @returns {string|undefined}
|
|
32
|
+
*/
|
|
33
|
+
getString(key) {
|
|
34
|
+
return this.__strings[key];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import levenshtein from "fast-levenshtein";
|
|
2
|
+
import { parseTooltipString } from "../../view/tooltip/gml/parser/parseTooltipString.js";
|
|
3
|
+
import { assert } from "../assert.js";
|
|
4
|
+
import ObservedString from "../model/ObservedString.js";
|
|
5
|
+
import { seedVariablesIntoTemplateString } from "../parser/seedVariablesIntoTemplateString.js";
|
|
6
|
+
import { STRING_TEMPLATE_VARIABLE_REGEX } from "../parser/STRING_TEMPLATE_VARIABLE_REGEX.js";
|
|
7
|
+
import { Cache } from "../cache/Cache.js";
|
|
8
|
+
import { computeStringHash } from "../primitives/strings/computeStringHash.js";
|
|
9
|
+
import { computeHashArray } from "../collection/array/computeHashArray.js";
|
|
10
|
+
import { LanguageMetadata } from "./LanguageMetadata.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Validation utility method
|
|
14
|
+
* @param {string} template
|
|
15
|
+
* @return {string}
|
|
16
|
+
*/
|
|
17
|
+
function validationMockSeed(template) {
|
|
18
|
+
|
|
19
|
+
const result = template.replace(STRING_TEMPLATE_VARIABLE_REGEX, function (match, varName) {
|
|
20
|
+
return "0";
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const EMPTY_SEED = Object.freeze({});
|
|
27
|
+
|
|
28
|
+
const DEFAULT_LANGUAGE_METADATA = Object.freeze(new LanguageMetadata());
|
|
29
|
+
|
|
30
|
+
export class Localization {
|
|
31
|
+
constructor() {
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @type {AssetManager|null}
|
|
35
|
+
*/
|
|
36
|
+
this.assetManager = null;
|
|
37
|
+
|
|
38
|
+
this.json = {};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @protected
|
|
42
|
+
* @type {LanguageMetadata}
|
|
43
|
+
*/
|
|
44
|
+
this.language_metadata = DEFAULT_LANGUAGE_METADATA;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
*
|
|
48
|
+
* @type {ObservedString}
|
|
49
|
+
*/
|
|
50
|
+
this.locale = new ObservedString('');
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* In debug mode error messages are a lot more verbose and helpful
|
|
54
|
+
* @type {boolean}
|
|
55
|
+
*/
|
|
56
|
+
this.debug = true;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @type {Cache<string[], string>}
|
|
60
|
+
* @private
|
|
61
|
+
*/
|
|
62
|
+
this.__failure_cache = new Cache({
|
|
63
|
+
maxWeight: 1024,
|
|
64
|
+
keyHashFunction: (key) => computeHashArray(key, computeStringHash)
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Measured in characters per second
|
|
70
|
+
* @deprecated use 'language_metadata' directly instead
|
|
71
|
+
* @return {number}
|
|
72
|
+
*/
|
|
73
|
+
get reading_speed() {
|
|
74
|
+
return this.language_metadata.reading_speed;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Time required to read a piece of text, in seconds
|
|
79
|
+
* @param {string} text
|
|
80
|
+
* @returns {number} time in seconds
|
|
81
|
+
*/
|
|
82
|
+
estimateReadingTime(text) {
|
|
83
|
+
assert.isString(text, 'text');
|
|
84
|
+
|
|
85
|
+
return text.length / this.reading_speed;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
*
|
|
90
|
+
* @param {AssetManager} am
|
|
91
|
+
*/
|
|
92
|
+
setAssetManager(am) {
|
|
93
|
+
this.assetManager = am;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* @returns {boolean}
|
|
98
|
+
* @param {function(key:string, error:*, original: string)} errorConsumer
|
|
99
|
+
*/
|
|
100
|
+
validate(errorConsumer) {
|
|
101
|
+
let result = true;
|
|
102
|
+
|
|
103
|
+
for (let key in this.json) {
|
|
104
|
+
const value = this.json[key];
|
|
105
|
+
|
|
106
|
+
const seededValue = validationMockSeed(value);
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
parseTooltipString(seededValue);
|
|
110
|
+
} catch (e) {
|
|
111
|
+
result = false;
|
|
112
|
+
errorConsumer(key, e, value);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Request locale switch
|
|
121
|
+
* Assumes a specific folder structure, each different locale is stored with its locale code as name, and there's also "languages.json" file expected to be in the folder
|
|
122
|
+
* @param {string} locale
|
|
123
|
+
* @param {string} path where to look for localization data
|
|
124
|
+
* @returns {Promise}
|
|
125
|
+
*/
|
|
126
|
+
loadLocale(locale, path = 'data/database/text') {
|
|
127
|
+
assert.isString(locale, 'locale');
|
|
128
|
+
assert.isString(path, 'path');
|
|
129
|
+
|
|
130
|
+
const am = this.assetManager;
|
|
131
|
+
|
|
132
|
+
if (am === null) {
|
|
133
|
+
throw new Error('AssetManager is not set');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
let _path = path.trim();
|
|
137
|
+
|
|
138
|
+
while (_path.endsWith('/') || _path.endsWith('\\')) {
|
|
139
|
+
// remove trailing slash if present
|
|
140
|
+
_path.slice(0, _path.length - 1);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const pLoadData = am.promise(`${_path}/${locale}.json`, "json")
|
|
144
|
+
.then(asset => {
|
|
145
|
+
const json = asset.create();
|
|
146
|
+
|
|
147
|
+
this.json = json;
|
|
148
|
+
|
|
149
|
+
this.locale.set(locale);
|
|
150
|
+
}, reason => {
|
|
151
|
+
|
|
152
|
+
console.error(`Failed to load locale data for locale '${locale}' : ${reason}`);
|
|
153
|
+
|
|
154
|
+
// reset data
|
|
155
|
+
this.json = {};
|
|
156
|
+
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const pLoadMetadata = am.promise(`${_path}/languages.json`, "json")
|
|
160
|
+
.then(asset => {
|
|
161
|
+
const languages_metadata = asset.create();
|
|
162
|
+
|
|
163
|
+
this.language_metadata = LanguageMetadata.fromJSON(languages_metadata[locale]);
|
|
164
|
+
}, reason => {
|
|
165
|
+
console.error(`Failed to load language metadata: ${reason}`);
|
|
166
|
+
|
|
167
|
+
this.language_metadata = DEFAULT_LANGUAGE_METADATA;
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
return Promise.all([pLoadData, pLoadMetadata]);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
*
|
|
176
|
+
* @param {number} value
|
|
177
|
+
*/
|
|
178
|
+
formatIntegerByThousands(value) {
|
|
179
|
+
const formatter = new Intl.NumberFormat(this.locale.getValue(), { useGrouping: true });
|
|
180
|
+
|
|
181
|
+
return formatter.format(value);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
*
|
|
186
|
+
* @param {string} id
|
|
187
|
+
* @param {Object} seed
|
|
188
|
+
* @private
|
|
189
|
+
*/
|
|
190
|
+
__debugMissingKey(id, seed) {
|
|
191
|
+
const locale = this.locale.getValue();
|
|
192
|
+
|
|
193
|
+
const seed_string = JSON.stringify(seed);
|
|
194
|
+
|
|
195
|
+
const message = this.__failure_cache.getOrCompute([locale, id, seed_string], () => {
|
|
196
|
+
|
|
197
|
+
//try to find similar keys
|
|
198
|
+
const similarities = Object.keys(this.json).map(function (key) {
|
|
199
|
+
const distance = levenshtein.get(key, id);
|
|
200
|
+
return {
|
|
201
|
+
key,
|
|
202
|
+
distance
|
|
203
|
+
};
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
similarities.sort(function (a, b) {
|
|
207
|
+
return a.distance - b.distance;
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
const suggestions = similarities.slice(0, 3).map(p => p.key);
|
|
211
|
+
|
|
212
|
+
return `No localization value for id='${id}', seed=${seed_string}, approximate matches: ${suggestions.join(', ')}`;
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
console.warn(message);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Get a localized string by a key
|
|
220
|
+
* @param {string} key
|
|
221
|
+
* @param {object} [seed]
|
|
222
|
+
*
|
|
223
|
+
* @returns {string}
|
|
224
|
+
*/
|
|
225
|
+
getString(key, seed = EMPTY_SEED) {
|
|
226
|
+
assert.isString(key, 'id');
|
|
227
|
+
|
|
228
|
+
const value = this.json[key];
|
|
229
|
+
|
|
230
|
+
if (value === undefined) {
|
|
231
|
+
|
|
232
|
+
if (this.debug) {
|
|
233
|
+
this.__debugMissingKey(key, seed)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
//no value, provide substitute
|
|
237
|
+
return `@${key}`;
|
|
238
|
+
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
//value needs to be seeded
|
|
242
|
+
return seedVariablesIntoTemplateString(value, seed);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Does a given key exist?
|
|
247
|
+
* @param {string} key
|
|
248
|
+
* @return {boolean}
|
|
249
|
+
*/
|
|
250
|
+
hasString(key) {
|
|
251
|
+
return this.json[key] !== undefined;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { assert } from "../../assert.js";
|
|
7
7
|
import Signal from "../../events/signal/Signal.js";
|
|
8
|
-
import { noop
|
|
8
|
+
import { noop } from "../../function/Functions.js";
|
|
9
9
|
import ObservedInteger from "../../model/ObservedInteger.js";
|
|
10
10
|
import { TaskSignal } from "./TaskSignal.js";
|
|
11
11
|
import TaskState from "./TaskState.js";
|
|
@@ -27,14 +27,14 @@ class Task {
|
|
|
27
27
|
name,
|
|
28
28
|
initializer = noop,
|
|
29
29
|
cycleFunction,
|
|
30
|
-
computeProgress
|
|
30
|
+
computeProgress,
|
|
31
31
|
dependencies = [],
|
|
32
32
|
estimatedDuration = 1
|
|
33
33
|
}
|
|
34
34
|
) {
|
|
35
35
|
|
|
36
|
-
assert.
|
|
37
|
-
assert.
|
|
36
|
+
assert.isFunction(cycleFunction, 'cycleFunction');
|
|
37
|
+
assert.isNumber(estimatedDuration, 'estimatedDuration');
|
|
38
38
|
|
|
39
39
|
|
|
40
40
|
this.dependencies = dependencies;
|
|
@@ -59,7 +59,12 @@ class Task {
|
|
|
59
59
|
*/
|
|
60
60
|
this.initialize = initializer;
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
if (computeProgress !== undefined) {
|
|
63
|
+
|
|
64
|
+
// override progress function
|
|
65
|
+
this.computeProgress = computeProgress;
|
|
66
|
+
|
|
67
|
+
}
|
|
63
68
|
|
|
64
69
|
this.on = {
|
|
65
70
|
started: new Signal(),
|
|
@@ -87,6 +92,18 @@ class Task {
|
|
|
87
92
|
this.__executedCycleCount = 0;
|
|
88
93
|
}
|
|
89
94
|
|
|
95
|
+
computeProgress() {
|
|
96
|
+
|
|
97
|
+
const cycles = this.__executedCycleCount;
|
|
98
|
+
|
|
99
|
+
if (cycles === 0) {
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// inverse logarithmic progression, never reaches 1
|
|
104
|
+
return 1 - (1 / cycles);
|
|
105
|
+
}
|
|
106
|
+
|
|
90
107
|
/**
|
|
91
108
|
* Time in milliseconds that the task has been executing for, suspended time does not count
|
|
92
109
|
* @returns {number}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import Task from "../Task.js";
|
|
2
|
+
import { TaskSignal } from "../TaskSignal.js";
|
|
3
|
+
import { assert } from "../../../assert.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {string} name
|
|
8
|
+
* @param {Iterator} iterator
|
|
9
|
+
* @param {TaskSignal.Continue|TaskSignal.Yield} [cycle_signal] what to signal at the end of each iteration, Continue will provide better throughput, whereas Yield will produce very low load on the CPU
|
|
10
|
+
* @returns {Task}
|
|
11
|
+
*/
|
|
12
|
+
export function iteratorTask(name, iterator, cycle_signal = TaskSignal.Continue) {
|
|
13
|
+
assert.defined(iterator, 'iterator');
|
|
14
|
+
assert.notNull(iterator, 'iterator');
|
|
15
|
+
assert.isFunction(iterator.next, 'iterator.next');
|
|
16
|
+
|
|
17
|
+
return new Task({
|
|
18
|
+
name,
|
|
19
|
+
cycleFunction() {
|
|
20
|
+
const next = iterator.next();
|
|
21
|
+
|
|
22
|
+
if (next.done) {
|
|
23
|
+
return TaskSignal.EndSuccess
|
|
24
|
+
} else {
|
|
25
|
+
return cycle_signal;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { storiesOf } from "@storybook/html/dist/client/preview";
|
|
2
|
-
import { Localization } from "../../../../../core/Localization.js";
|
|
2
|
+
import { Localization } from "../../../../../core/localization/Localization.js";
|
|
3
3
|
import { ItemContainerController } from "./ItemContainerController.js";
|
|
4
4
|
import ItemContainer from "../../../../../../model/game/ecs/component/item_container/ItemContainer.js";
|
|
5
5
|
import Item from "../../../../../../model/game/ecs/component/Item.js";
|
package/engine/Engine.js
CHANGED
|
@@ -23,7 +23,7 @@ import EmptyView from "../view/elements/EmptyView.js";
|
|
|
23
23
|
import { assert } from "../core/assert.js";
|
|
24
24
|
import { StaticKnowledgeDatabase } from "./knowledge/database/StaticKnowledgeDatabase.js";
|
|
25
25
|
import Ticker from "./simulation/Ticker.js";
|
|
26
|
-
import { Localization } from "../core/Localization.js";
|
|
26
|
+
import { Localization } from "../core/localization/Localization.js";
|
|
27
27
|
import { ModuleRegistry } from "../core/model/ModuleRegistry.js";
|
|
28
28
|
import { BinarySerializationRegistry } from "./ecs/storage/binary/BinarySerializationRegistry.js";
|
|
29
29
|
import { EnginePluginManager } from "./plugin/EnginePluginManager.js";
|
|
@@ -326,6 +326,10 @@ export class AssetManager {
|
|
|
326
326
|
throw new Error("Path must be string. Path = " + JSON.stringify(path));
|
|
327
327
|
}
|
|
328
328
|
|
|
329
|
+
if(typeof type !== "string"){
|
|
330
|
+
throw new TypeError(`type must be a string, instead was '${typeof type}'`);
|
|
331
|
+
}
|
|
332
|
+
|
|
329
333
|
const assetDescription = new AssetDescription(path, type);
|
|
330
334
|
|
|
331
335
|
const asset = this.assets.get(assetDescription);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { BitSet } from "../../../core/binary/BitSet.js";
|
|
2
2
|
import { InstancedMeshGroup } from "../../graphics/geometry/instancing/InstancedMeshGroup.js";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
queryBinaryNode_FrustumIntersections_Data
|
|
5
|
+
} from "../../../core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js";
|
|
4
6
|
import Quaternion from "../../../core/geom/Quaternion.js";
|
|
5
7
|
import Vector3 from "../../../core/geom/Vector3.js";
|
|
6
8
|
import { compose_matrix4_array } from "../../../core/geom/3d/compose_matrix4_array.js";
|
|
@@ -30,6 +32,10 @@ export class ViewState {
|
|
|
30
32
|
* @type {InstancedMeshGroup}
|
|
31
33
|
*/
|
|
32
34
|
this.instances = new InstancedMeshGroup();
|
|
35
|
+
|
|
36
|
+
// make shrinking unlikely to prevent thrashing
|
|
37
|
+
this.instances.shrinkFactor = 0.4;
|
|
38
|
+
this.instances.shrinkConstant = 1024;
|
|
33
39
|
|
|
34
40
|
/**
|
|
35
41
|
*
|
|
@@ -373,7 +373,7 @@ export class VoiceSystem extends AbstractContextSystem {
|
|
|
373
373
|
// localized line may contain reference tags, the user will not see/read those, so we also compile line as pure text for estimating reading time
|
|
374
374
|
const line_pure_text = gml.compileAsText(localized_line);
|
|
375
375
|
|
|
376
|
-
const display_time_raw = localiation.
|
|
376
|
+
const display_time_raw = localiation.estimateReadingTime(line_pure_text);
|
|
377
377
|
|
|
378
378
|
const display_time = max2(TIMING_MINIMUM_READ_TIME, display_time_raw * line.displayDuration) + TIMING_NOTICE_DELAY;
|
|
379
379
|
|
|
@@ -15,7 +15,7 @@ import { GameAssetType } from "../../../../asset/GameAssetType.js";
|
|
|
15
15
|
import { GLTFAssetLoader } from "../../../../asset/loaders/GLTFAssetLoader.js";
|
|
16
16
|
import '../../../../../../../../css/game.scss';
|
|
17
17
|
import { countTask } from "../../../../../core/process/task/util/countTask.js";
|
|
18
|
-
import Vector2 from "../../../../../core/geom/Vector2.js";
|
|
18
|
+
import Vector2, { v2_distance } from "../../../../../core/geom/Vector2.js";
|
|
19
19
|
import { RotationBehavior } from "../../../../intelligence/behavior/util/RotationBehavior.js";
|
|
20
20
|
import { BehaviorComponent } from "../../../../intelligence/behavior/ecs/BehaviorComponent.js";
|
|
21
21
|
import Vector3 from "../../../../../core/geom/Vector3.js";
|
|
@@ -270,14 +270,17 @@ function grid(ecd, offset_x, offset_y, x, y, size_x, size_y, spacing, textures)
|
|
|
270
270
|
function makeNormalTestGridDecal(ecd, root_transform = new Transform()) {
|
|
271
271
|
const uv = new OctahedralUvEncoder();
|
|
272
272
|
|
|
273
|
-
const GRID_SIZE =
|
|
273
|
+
const GRID_SIZE = 16;
|
|
274
274
|
|
|
275
275
|
const CELL_SIZE = 1;
|
|
276
276
|
|
|
277
|
-
const SPACING = CELL_SIZE*1.2;
|
|
277
|
+
const SPACING = CELL_SIZE * 1.2;
|
|
278
|
+
// const SPACING = CELL_SIZE * 0.6;
|
|
278
279
|
|
|
279
280
|
const DEBUG_BOX = makeHelperBoxGeometry();
|
|
280
281
|
|
|
282
|
+
const random = seededRandom(7);
|
|
283
|
+
|
|
281
284
|
for (let i = 0; i < GRID_SIZE; i++) {
|
|
282
285
|
for (let j = 0; j < GRID_SIZE; j++) {
|
|
283
286
|
|
|
@@ -290,7 +293,7 @@ function makeNormalTestGridDecal(ecd, root_transform = new Transform()) {
|
|
|
290
293
|
const decal = new Decal();
|
|
291
294
|
|
|
292
295
|
// decal.uri = decal_urls[1];
|
|
293
|
-
decal.uri ='moicon/ISO 7010 - Safety Signs (3)/ISO 7010 - Safety Signs/Emergency/400px/E001 – Emergency exit (left hand).png';
|
|
296
|
+
decal.uri = 'moicon/ISO 7010 - Safety Signs (3)/ISO 7010 - Safety Signs/Emergency/400px/E001 – Emergency exit (left hand).png';
|
|
294
297
|
|
|
295
298
|
const entity = new EntityBuilder();
|
|
296
299
|
|
|
@@ -303,7 +306,7 @@ function makeNormalTestGridDecal(ecd, root_transform = new Transform()) {
|
|
|
303
306
|
0,
|
|
304
307
|
);
|
|
305
308
|
transform.scale.setScalar(CELL_SIZE);
|
|
306
|
-
transform.rotation._lookRotation(direction[0],direction[2], direction[1]
|
|
309
|
+
transform.rotation._lookRotation(direction[0], direction[2], direction[1], 0, 1, 0);
|
|
307
310
|
|
|
308
311
|
transform.multiplyTransforms(root_transform, transform);
|
|
309
312
|
|
|
@@ -314,9 +317,12 @@ function makeNormalTestGridDecal(ecd, root_transform = new Transform()) {
|
|
|
314
317
|
.add(decal)
|
|
315
318
|
.build(ecd);
|
|
316
319
|
|
|
317
|
-
setInterval(()=>{
|
|
318
|
-
|
|
319
|
-
},7000);
|
|
320
|
+
// setInterval(()=>{
|
|
321
|
+
// decal.priority = Math.random();
|
|
322
|
+
// },7000);
|
|
323
|
+
|
|
324
|
+
// decal.priority = randomIntegerBetween(random,0,4096);
|
|
325
|
+
decal.priority = v2_distance(i, j, GRID_SIZE * 0.5, GRID_SIZE * 0.5);
|
|
320
326
|
|
|
321
327
|
|
|
322
328
|
// make an arrow helper
|
|
@@ -330,7 +336,7 @@ function makeNormalTestGridDecal(ecd, root_transform = new Transform()) {
|
|
|
330
336
|
side: DoubleSide
|
|
331
337
|
}), DrawMode.Triangles))
|
|
332
338
|
.add(arrow_transform)
|
|
333
|
-
|
|
339
|
+
.build(ecd);
|
|
334
340
|
}
|
|
335
341
|
}
|
|
336
342
|
}
|
|
@@ -448,9 +454,9 @@ async function main(engine) {
|
|
|
448
454
|
new EntityBuilder()
|
|
449
455
|
.add(SGMesh.fromURL('data/models/snaps/cube_white.gltf'))
|
|
450
456
|
.add(Transform.fromJSON({
|
|
451
|
-
|
|
457
|
+
position: new Vector3(14, 1, 4.8),
|
|
452
458
|
rotation: t_forward_grid.rotation,
|
|
453
|
-
scale: new Vector3(25,25,0.1)
|
|
459
|
+
scale: new Vector3(25, 25, 0.1)
|
|
454
460
|
}))
|
|
455
461
|
.build(ecd);
|
|
456
462
|
|