@woosh/meep-engine 2.159.0 → 2.160.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/package.json +1 -1
- package/src/engine/.fuse_hidden0000001500000001 +581 -0
- package/src/engine/Engine.d.ts.map +1 -1
- package/src/engine/Engine.js +4 -1
- package/src/engine/graphics/ecs/path/tube/build/compute_smooth_profile_normals.d.ts +8 -0
- package/src/engine/graphics/ecs/path/tube/build/compute_smooth_profile_normals.d.ts.map +1 -1
- package/src/engine/graphics/ecs/path/tube/build/compute_smooth_profile_normals.js +27 -20
- package/src/engine/graphics/ecs/path/tube/build/fix_shape_normal_order.d.ts +11 -5
- package/src/engine/graphics/ecs/path/tube/build/fix_shape_normal_order.d.ts.map +1 -1
- package/src/engine/graphics/ecs/path/tube/build/fix_shape_normal_order.js +25 -31
- package/src/engine/input/devices/GamepadDevice.d.ts +26 -0
- package/src/engine/input/devices/GamepadDevice.d.ts.map +1 -0
- package/src/engine/input/devices/GamepadDevice.js +280 -0
- package/src/engine/input/devices/events/GamepadEvents.d.ts +10 -0
- package/src/engine/input/devices/events/GamepadEvents.d.ts.map +1 -0
- package/src/engine/input/devices/events/GamepadEvents.js +10 -0
- package/src/engine/input/devices/gamepad/GamepadAxes.d.ts +14 -0
- package/src/engine/input/devices/gamepad/GamepadAxes.d.ts.map +1 -0
- package/src/engine/input/devices/gamepad/GamepadAxes.js +15 -0
- package/src/engine/input/devices/gamepad/GamepadButtons.d.ts +28 -0
- package/src/engine/input/devices/gamepad/GamepadButtons.d.ts.map +1 -0
- package/src/engine/input/devices/gamepad/GamepadButtons.js +29 -0
- package/src/engine/input/devices/gamepad/GamepadHandle.d.ts +29 -0
- package/src/engine/input/devices/gamepad/GamepadHandle.d.ts.map +1 -0
- package/src/engine/input/devices/gamepad/GamepadHandle.js +232 -0
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/engine/physics/fluid/ecs/FluidSystem.d.ts +3 -3
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"description": "Pure JavaScript game engine. Fully featured and production ready.",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"author": "Alexander Goldring",
|
|
9
|
-
"version": "2.
|
|
9
|
+
"version": "2.160.0",
|
|
10
10
|
"main": "build/meep.module.js",
|
|
11
11
|
"module": "build/meep.module.js",
|
|
12
12
|
"exports": {
|
|
@@ -0,0 +1,581 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { PerspectiveCamera as ThreePerspectiveCamera } from 'three';
|
|
6
|
+
import { assert } from "../core/assert.js";
|
|
7
|
+
import Vector1 from "../core/geom/Vector1.js";
|
|
8
|
+
import { Localization } from "../core/localization/Localization.js";
|
|
9
|
+
import { ModuleRegistry } from "../core/model/ModuleRegistry.js";
|
|
10
|
+
import ObservedBoolean from "../core/model/ObservedBoolean.js";
|
|
11
|
+
import ConcurrentExecutor from '../core/process/executor/ConcurrentExecutor.js';
|
|
12
|
+
import EmptyView from "../view/elements/EmptyView.js";
|
|
13
|
+
import { ViewStack } from "../view/elements/navigation/ViewStack.js";
|
|
14
|
+
|
|
15
|
+
import { AssetManager } from './asset/AssetManager.js';
|
|
16
|
+
import { AssetPreloader } from "./asset/preloader/AssetPreloader.js";
|
|
17
|
+
import { MetricCollection } from "./development/performance/MetricCollection.js";
|
|
18
|
+
import { MetricStatistics } from "./development/performance/MetricStatistics.js";
|
|
19
|
+
import { PeriodicConsolePrinter } from "./development/performance/monitor/PeriodicConsolePrinter.js";
|
|
20
|
+
import { EntityManager } from "./ecs/EntityManager.js";
|
|
21
|
+
import { BinarySerializationRegistry } from "./ecs/storage/binary/BinarySerializationRegistry.js";
|
|
22
|
+
import { GraphicsEngine } from './graphics/GraphicsEngine.js';
|
|
23
|
+
import { GamepadDevice } from "./input/devices/GamepadDevice.js";
|
|
24
|
+
import KeyboardDevice from "./input/devices/KeyboardDevice.js";
|
|
25
|
+
import { PointerDevice } from "./input/devices/PointerDevice.js";
|
|
26
|
+
import { StaticKnowledgeDatabase } from "./knowledge/database/StaticKnowledgeDatabase.js";
|
|
27
|
+
import { logger } from "./logging/GlobalLogger.js";
|
|
28
|
+
import { OptionGroup } from "./options/OptionGroup.js";
|
|
29
|
+
import { EnginePluginManager } from "./plugin/EnginePluginManager.js";
|
|
30
|
+
import SceneManager from "./scene/SceneManager.js";
|
|
31
|
+
import Ticker from "./simulation/Ticker.js";
|
|
32
|
+
import SoundEngine from './sound/SoundEngine.js';
|
|
33
|
+
|
|
34
|
+
import GUIEngine from './ui/GUIEngine.js';
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class EngineSettings {
|
|
38
|
+
graphics_control_viewport_size = new ObservedBoolean(true);
|
|
39
|
+
simulation_speed = new Vector1(1);
|
|
40
|
+
input_mouse_sensitivity = new Vector1(5);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const METRIC_ID_FRAME = 'frame_delay';
|
|
44
|
+
const METRIC_ID_RENDER = 'render_time';
|
|
45
|
+
const METRIC_ID_SIMULATION = 'simulation_time';
|
|
46
|
+
|
|
47
|
+
class Engine {
|
|
48
|
+
#last_frame_timestamp = 0;
|
|
49
|
+
|
|
50
|
+
viewStack = new ViewStack();
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
*
|
|
54
|
+
* Static database
|
|
55
|
+
* Can contain tables of structured data that the application often works with.
|
|
56
|
+
* Engine startup will load all tables ensuring that data is ready once startup finishes
|
|
57
|
+
* Use sparingly, this is not suitable for very large amounts of data as all the data will be in memory and deserialization will stall engine startup
|
|
58
|
+
* Example: inventory item table, monster table
|
|
59
|
+
* @readonly
|
|
60
|
+
* @type {StaticKnowledgeDatabase}
|
|
61
|
+
*/
|
|
62
|
+
staticKnowledge = new StaticKnowledgeDatabase();
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @readonly
|
|
66
|
+
* @type {EnginePluginManager}
|
|
67
|
+
*/
|
|
68
|
+
plugins = new EnginePluginManager();
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Main simulation ticker
|
|
72
|
+
* @readonly
|
|
73
|
+
* @type {Ticker}
|
|
74
|
+
*/
|
|
75
|
+
ticker = new Ticker();
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Default executor, enables time-sharing concurrency
|
|
79
|
+
* @readonly
|
|
80
|
+
* @type {ConcurrentExecutor}
|
|
81
|
+
*/
|
|
82
|
+
executor = new ConcurrentExecutor(1, 10);
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
*
|
|
86
|
+
* @param {EnginePlatform} platform
|
|
87
|
+
* @param {EntityManager} [entityManager]
|
|
88
|
+
* @param {boolean} [enableGraphics]
|
|
89
|
+
* @param {boolean} [enableAudio]
|
|
90
|
+
* @param {boolean} [debug]
|
|
91
|
+
* @constructor
|
|
92
|
+
*/
|
|
93
|
+
constructor(platform, {
|
|
94
|
+
entityManager,
|
|
95
|
+
enableGraphics = true,
|
|
96
|
+
enableAudio = true,
|
|
97
|
+
debug = true
|
|
98
|
+
} = {}) {
|
|
99
|
+
assert.defined(platform, 'platform');
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
*
|
|
103
|
+
* @type {EnginePlatform}
|
|
104
|
+
*/
|
|
105
|
+
this.platform = platform;
|
|
106
|
+
|
|
107
|
+
this.staticKnowledge.validation_enabled = debug;
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
*
|
|
112
|
+
* @type {MetricCollection}
|
|
113
|
+
*/
|
|
114
|
+
this.performance = new MetricCollection();
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
this.__using_external_entity_manager = entityManager !== undefined;
|
|
118
|
+
|
|
119
|
+
//setup entity component system
|
|
120
|
+
if (this.__using_external_entity_manager) {
|
|
121
|
+
// external entity manager provided
|
|
122
|
+
this.entityManager = entityManager;
|
|
123
|
+
} else {
|
|
124
|
+
this.entityManager = new EntityManager();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
*
|
|
130
|
+
* @type {AssetManager<Engine>}
|
|
131
|
+
*/
|
|
132
|
+
this.assetManager = new AssetManager({
|
|
133
|
+
context: this,
|
|
134
|
+
executor: this.executor
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
this.__performacne_monitor = new PeriodicConsolePrinter(15, () => {
|
|
138
|
+
const metrics = this.performance;
|
|
139
|
+
const stats = new MetricStatistics();
|
|
140
|
+
|
|
141
|
+
// RENDER
|
|
142
|
+
const m_render = metrics.get(METRIC_ID_RENDER);
|
|
143
|
+
|
|
144
|
+
m_render.computeStats(stats);
|
|
145
|
+
|
|
146
|
+
const v_render = (stats.mean * 1000).toFixed(2);
|
|
147
|
+
|
|
148
|
+
// SIMULATION
|
|
149
|
+
const m_sim = metrics.get(METRIC_ID_SIMULATION);
|
|
150
|
+
|
|
151
|
+
m_sim.computeStats(stats);
|
|
152
|
+
|
|
153
|
+
const v_sim = (stats.mean * 1000).toFixed(2);
|
|
154
|
+
|
|
155
|
+
// FPS
|
|
156
|
+
|
|
157
|
+
const m_frame = metrics.get(METRIC_ID_FRAME);
|
|
158
|
+
|
|
159
|
+
m_frame.computeStats(stats);
|
|
160
|
+
|
|
161
|
+
const v_fps = (1 / stats.mean).toFixed(2);
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
// clear stats
|
|
165
|
+
m_render.clear();
|
|
166
|
+
m_sim.clear();
|
|
167
|
+
m_frame.clear();
|
|
168
|
+
|
|
169
|
+
return `FPS: ${v_fps}, RENDER: ${v_render}ms, SIMULATION: ${v_sim}ms`;
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
if (!this.__using_external_entity_manager) {
|
|
174
|
+
// subscribe simulator to common ticker
|
|
175
|
+
this.ticker.onTick.add(timeDelta => {
|
|
176
|
+
const t0 = performance.now();
|
|
177
|
+
this.entityManager.simulate(timeDelta);
|
|
178
|
+
|
|
179
|
+
const t1 = performance.now();
|
|
180
|
+
const duration = (t1 - t0) / 1000;
|
|
181
|
+
|
|
182
|
+
// record frame time
|
|
183
|
+
this.performance.get(METRIC_ID_SIMULATION).record(duration);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// initialize performance metrics
|
|
188
|
+
this.performance.create({
|
|
189
|
+
name: METRIC_ID_RENDER
|
|
190
|
+
});
|
|
191
|
+
this.performance.create({
|
|
192
|
+
name: METRIC_ID_SIMULATION
|
|
193
|
+
});
|
|
194
|
+
this.performance.create({
|
|
195
|
+
name: METRIC_ID_FRAME
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
*
|
|
200
|
+
* @type {OptionGroup}
|
|
201
|
+
*/
|
|
202
|
+
this.options = new OptionGroup("options");
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
*
|
|
206
|
+
* @type {ModuleRegistry}
|
|
207
|
+
*/
|
|
208
|
+
this.moduleRegistry = new ModuleRegistry();
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* @readonly
|
|
212
|
+
* @type {BinarySerializationRegistry}
|
|
213
|
+
*/
|
|
214
|
+
this.binarySerializationRegistry = new BinarySerializationRegistry();
|
|
215
|
+
|
|
216
|
+
this.settings = new EngineSettings();
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* @deprecated use plugins instead
|
|
221
|
+
*/
|
|
222
|
+
this.services = {};
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
*
|
|
226
|
+
* @type {Storage}
|
|
227
|
+
*/
|
|
228
|
+
this.storage = this.platform.getStorage();
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
this.localization = new Localization();
|
|
232
|
+
this.localization.setAssetManager(this.assetManager);
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
const innerWidth = window.innerWidth / 3;
|
|
236
|
+
const innerHeight = window.innerHeight / 3;
|
|
237
|
+
|
|
238
|
+
this.camera = new ThreePerspectiveCamera(45, innerWidth / innerHeight, 1, 50);
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
if (enableGraphics !== false) {
|
|
242
|
+
|
|
243
|
+
const graphicsEngine = new GraphicsEngine({
|
|
244
|
+
camera: this.camera,
|
|
245
|
+
debug
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
*
|
|
250
|
+
* @type {GraphicsEngine}
|
|
251
|
+
*/
|
|
252
|
+
this.graphics = graphicsEngine;
|
|
253
|
+
|
|
254
|
+
try {
|
|
255
|
+
graphicsEngine.start();
|
|
256
|
+
} catch (e) {
|
|
257
|
+
logger.error(`Failed to start GraphicEngine: ${e}`);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
} else {
|
|
261
|
+
logger.info('enableGraphics option is not set, no graphics engine will be created');
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (enableAudio !== false) {
|
|
265
|
+
//sound engine
|
|
266
|
+
const soundEngine = new SoundEngine();
|
|
267
|
+
soundEngine.volume = 1;
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
*
|
|
271
|
+
* @type {SoundEngine}
|
|
272
|
+
*/
|
|
273
|
+
this.sound = soundEngine;
|
|
274
|
+
} else {
|
|
275
|
+
logger.info('enableAudio option is not set, no audio engine will be created');
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Graphical User Interface engine
|
|
280
|
+
* @type {GUIEngine}
|
|
281
|
+
*/
|
|
282
|
+
this.gui = new GUIEngine();
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* @readonly
|
|
286
|
+
* @type {SceneManager}
|
|
287
|
+
*/
|
|
288
|
+
this.sceneManager = new SceneManager(this.entityManager, this.ticker.clock);
|
|
289
|
+
|
|
290
|
+
this.initializeViews();
|
|
291
|
+
|
|
292
|
+
this.devices = {
|
|
293
|
+
pointer: new PointerDevice(this.viewStack.el),
|
|
294
|
+
keyboard: new KeyboardDevice(this.viewStack.el),
|
|
295
|
+
gamepad: new GamepadDevice()
|
|
296
|
+
};
|
|
297
|
+
|
|
298
|
+
//init level engine
|
|
299
|
+
|
|
300
|
+
this.devices.pointer.start();
|
|
301
|
+
this.devices.keyboard.start();
|
|
302
|
+
this.devices.gamepad.start();
|
|
303
|
+
|
|
304
|
+
//process settings
|
|
305
|
+
this.initializeSettings();
|
|
306
|
+
|
|
307
|
+
logger.info("engine initialized");
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Toggles GraphicsEngine rendering on and off
|
|
311
|
+
* @type {boolean}
|
|
312
|
+
*/
|
|
313
|
+
this.renderingEnabled = true;
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
this.plugins.initialize(this);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
#initialize_audio() {
|
|
320
|
+
const sound = this.sound;
|
|
321
|
+
if (sound === undefined || sound === null) {
|
|
322
|
+
// no sound engine
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// hook up context resumption to input
|
|
327
|
+
if (this.devices.pointer !== undefined) {
|
|
328
|
+
|
|
329
|
+
this.devices.pointer.on.down.addOne(sound.resumeContext, sound);
|
|
330
|
+
this.devices.keyboard.on.down.addOne(sound.resumeContext, sound);
|
|
331
|
+
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
initializeViews() {
|
|
336
|
+
|
|
337
|
+
const gameView = new EmptyView();
|
|
338
|
+
|
|
339
|
+
gameView.addClass('game-view');
|
|
340
|
+
|
|
341
|
+
gameView.css({
|
|
342
|
+
left: 0,
|
|
343
|
+
top: 0,
|
|
344
|
+
position: "absolute",
|
|
345
|
+
pointerEvents: "none"
|
|
346
|
+
});
|
|
347
|
+
this.gameView = gameView;
|
|
348
|
+
|
|
349
|
+
this.viewStack.push(gameView, 'game-view');
|
|
350
|
+
|
|
351
|
+
if (this.graphics !== undefined) {
|
|
352
|
+
|
|
353
|
+
const viewport = this.graphics.viewport;
|
|
354
|
+
|
|
355
|
+
viewport.css({
|
|
356
|
+
pointerEvents: "auto"
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
gameView.addChild(viewport);
|
|
360
|
+
//bind size of renderer viewport to game view
|
|
361
|
+
viewport.bindSignal(gameView.size.onChanged, viewport.size.set.bind(viewport.size));
|
|
362
|
+
gameView.on.linked.add(function () {
|
|
363
|
+
viewport.size.copy(gameView.size);
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
initializeSettings() {
|
|
370
|
+
logger.info('Initializing engine settings...');
|
|
371
|
+
|
|
372
|
+
const engine = this;
|
|
373
|
+
|
|
374
|
+
function setViewportToWindowSize() {
|
|
375
|
+
// get parent element
|
|
376
|
+
let parentElement = engine.viewStack.el.parentElement;
|
|
377
|
+
|
|
378
|
+
while (parentElement !== null && parentElement.innerWidth === undefined) {
|
|
379
|
+
// traverse up until we find an element with defined dimensions
|
|
380
|
+
parentElement = parentElement.parentElement;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (parentElement === null || parentElement === undefined) {
|
|
384
|
+
// no parent element, default to window
|
|
385
|
+
parentElement = window;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
engine.viewStack.size.set(parentElement.innerWidth, parentElement.innerHeight);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
this.settings.graphics_control_viewport_size.process(function (value) {
|
|
392
|
+
if (value) {
|
|
393
|
+
setViewportToWindowSize();
|
|
394
|
+
window.addEventListener("resize", setViewportToWindowSize, false);
|
|
395
|
+
} else {
|
|
396
|
+
window.removeEventListener("resize", setViewportToWindowSize);
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
logger.info('Engine settings initilized.');
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
benchmark() {
|
|
404
|
+
const duration = 2000;
|
|
405
|
+
let count = 0;
|
|
406
|
+
const t0 = Date.now();
|
|
407
|
+
let t1;
|
|
408
|
+
while (true) {
|
|
409
|
+
this.entityManager.simulate(0.0000000001);
|
|
410
|
+
t1 = Date.now();
|
|
411
|
+
if (t1 - t0 > duration) {
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
count++;
|
|
415
|
+
}
|
|
416
|
+
//normalize
|
|
417
|
+
const elapsed = (t1 - t0) / 1000;
|
|
418
|
+
const rate = (count / elapsed);
|
|
419
|
+
return rate;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Returns preloader object
|
|
424
|
+
* @param {String} listURL
|
|
425
|
+
*/
|
|
426
|
+
loadAssetList(listURL) {
|
|
427
|
+
const preloader = new AssetPreloader();
|
|
428
|
+
const assetManager = this.assetManager;
|
|
429
|
+
assetManager.get({
|
|
430
|
+
path: listURL, type: "json", callback: function (asset) {
|
|
431
|
+
preloader.addAll(asset.create());
|
|
432
|
+
preloader.load(assetManager);
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
return preloader;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
render() {
|
|
439
|
+
assert.isInstanceOf(this, Engine, 'this', 'Engine');
|
|
440
|
+
|
|
441
|
+
const graphics = this.graphics;
|
|
442
|
+
|
|
443
|
+
if (graphics.autoDraw) {
|
|
444
|
+
// request redraw
|
|
445
|
+
graphics.needDraw = true;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
if (graphics && this.renderingEnabled && graphics.needDraw) {
|
|
449
|
+
|
|
450
|
+
const metrics = this.performance;
|
|
451
|
+
|
|
452
|
+
const t0 = performance.now();
|
|
453
|
+
|
|
454
|
+
graphics.render();
|
|
455
|
+
|
|
456
|
+
const t1 = performance.now();
|
|
457
|
+
const frame_time = (t1 - t0) / 1000;
|
|
458
|
+
|
|
459
|
+
// record frame time
|
|
460
|
+
metrics.get(METRIC_ID_RENDER).record(frame_time);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Startup
|
|
466
|
+
* @returns {Promise}
|
|
467
|
+
*/
|
|
468
|
+
start() {
|
|
469
|
+
this.assetManager.startup();
|
|
470
|
+
|
|
471
|
+
this.#initialize_audio();
|
|
472
|
+
|
|
473
|
+
const promiseEntityManager = () => {
|
|
474
|
+
return new Promise((resolve, reject) => {
|
|
475
|
+
//initialize entity manager
|
|
476
|
+
this.entityManager.startup(resolve, reject);
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
this.__performacne_monitor.start();
|
|
481
|
+
|
|
482
|
+
return Promise.all([
|
|
483
|
+
this.sound.start()
|
|
484
|
+
.then(promiseEntityManager),
|
|
485
|
+
this.staticKnowledge.load(this.assetManager, this.executor),
|
|
486
|
+
this.gui.startup(this),
|
|
487
|
+
this.plugins.startup()
|
|
488
|
+
]).then(async () => {
|
|
489
|
+
|
|
490
|
+
this.#last_frame_timestamp = performance.now();
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Starting the engine
|
|
494
|
+
*/
|
|
495
|
+
requestAnimationFrame(this.#animation_frame);
|
|
496
|
+
|
|
497
|
+
//start simulation
|
|
498
|
+
this.ticker.start({ maxTimeout: 200 });
|
|
499
|
+
//self.uiController.init(self);
|
|
500
|
+
|
|
501
|
+
//load options
|
|
502
|
+
await this.options.attachToStorage('lazykitty.komrade.options', this.storage);
|
|
503
|
+
|
|
504
|
+
logger.info('engine started');
|
|
505
|
+
}, function (e) {
|
|
506
|
+
logger.error(`Engine Failed to start: ${e}`);
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Fired every animation frame via {@link requestAnimationFrame}
|
|
514
|
+
*/
|
|
515
|
+
#animation_frame = () => {
|
|
516
|
+
|
|
517
|
+
const t0 = this.#last_frame_timestamp;
|
|
518
|
+
const t1 = performance.now();
|
|
519
|
+
requestAnimationFrame(this.#animation_frame);
|
|
520
|
+
this.render();
|
|
521
|
+
|
|
522
|
+
const frame_delay = (t1 - t0) / 1000;
|
|
523
|
+
|
|
524
|
+
// swap variables
|
|
525
|
+
this.#last_frame_timestamp = t1;
|
|
526
|
+
|
|
527
|
+
// record metric
|
|
528
|
+
this.performance.get(METRIC_ID_FRAME).record(frame_delay);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Shutdown the engine, disposing all relevant resources
|
|
533
|
+
*/
|
|
534
|
+
async stop() {
|
|
535
|
+
this.__performacne_monitor.stop();
|
|
536
|
+
|
|
537
|
+
// stop the ticker
|
|
538
|
+
this.ticker.pause();
|
|
539
|
+
|
|
540
|
+
// shutdown entity manager
|
|
541
|
+
if (!this.__using_external_entity_manager) {
|
|
542
|
+
await new Promise((resolve, reject) => this.entityManager.shutdown(resolve, reject));
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// shutdown plugins
|
|
546
|
+
await this.plugins.shutdown();
|
|
547
|
+
|
|
548
|
+
// stop gui
|
|
549
|
+
await this.gui.shutdown();
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
// TODO shutdown executor
|
|
553
|
+
|
|
554
|
+
await this.assetManager.shutdown();
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
exit() {
|
|
558
|
+
window.close();
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* @returns {Promise}
|
|
563
|
+
*/
|
|
564
|
+
requestExit() {
|
|
565
|
+
return this.gui.confirmTextDialog({
|
|
566
|
+
title: this.localization.getString('system_confirm_exit_to_system.title'),
|
|
567
|
+
text: this.localization.getString('system_confirm_exit_to_system.text')
|
|
568
|
+
}).then(() => {
|
|
569
|
+
this.exit();
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* @readonly
|
|
577
|
+
* @type {boolean}
|
|
578
|
+
*/
|
|
579
|
+
Engine.prototype.isEngine = true;
|
|
580
|
+
|
|
581
|
+
export default Engine;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../../../src/engine/Engine.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../../../src/engine/Engine.js"],"names":[],"mappings":";AA8CA;IAqCI;;;;;;;;OAQG;IACH,8FANW,aAAa,EAsOvB;IA3QD,qBAA4B;IAE5B;;;;;;;;;OASG;IACH,0BAFU,uBAAuB,CAEe;IAEhD;;;OAGG;IACH,kBAFU,mBAAmB,CAEO;IAEpC;;;;OAIG;IACH,iBAFU,MAAM,CAEM;IAEtB;;;;OAIG;IACH,mBAFU,kBAAkB,CAEa;IAmBrC;;;OAGG;IACH,yBAAwB;IAKxB;;;OAGG;IACH,aAFU,gBAAgB,CAEe;IAGzC,yCAAkE;IAK9D,mBAAkC;IAMtC;;;OAGG;IACH,cAFU,aAAa,MAAM,CAAC,CAK5B;IAEF,8CAiCE;IA4BF;;;OAGG;IACH,SAFU,WAAW,CAEoB;IAEzC;;;OAGG;IACH,gBAFU,cAAc,CAEkB;IAE1C;;;OAGG;IACH,sCAFU,2BAA2B,CAE+B;IAEpE,yBAAoC;IAGpC;;OAEG;IACH,aAAkB;IAElB;;;OAGG;IACH,SAFU,OAAO,CAEwB;IAGzC,2BAAsC;IAOtC,+BAA6E;IAUzE;;;OAGG;IACH,UAFU,cAAc,CAEM;IAiB9B;;;OAGG;IACH,OAFU,WAAW,CAEG;IAK5B;;;OAGG;IACH,KAFU,SAAS,CAEO;IAE1B;;;OAGG;IACH,uBAFU,YAAY,CAEqD;IAI3E;;;;MAIC;IAaD;;;OAGG;IACH,kBAFU,OAAO,CAEW;IAsBhC,wBAgCC;IApBG,oBAAwB;IAsB5B,2BAgCC;IAED,oBAiBC;IAED;;;OAGG;IACH,+CAUC;IAED,eAwBC;IAED;;;OAGG;IACH,sBA0CC;IAqBD;;OAEG;IACH,sBAqBC;IAED,aAEC;IAED;;OAEG;IACH,4BAOC;IAIL;;;OAGG;IACH,mBAFU,OAAO,CAEQ;;CAPxB;0BA/iByB,0CAA0C;wCAa5B,iDAAiD;oCAGrD,iCAAiC;mBAElD,wBAAwB;+BApBZ,gDAAgD;iCAM9C,+CAA+C;6BAFnD,yBAAyB;uCAIf,6DAA6D;4BASxE,0BAA0B;+BAnBvB,iCAAiC;4CAYpB,qDAAqD;AAgBjG;IACI,gDAA2D;IAC3D,0BAAkC;IAClC,iCAAyC;CAC5C;6BAjC4B,sCAAsC;4DAHP,OAAO;+BAiBpC,8BAA8B;wBAUrC,wBAAwB;sBAE1B,mBAAmB;yBAJhB,yBAAyB;8BALpB,kCAAkC;2BADrC,mCAAmC;8BADhC,kCAAkC;sBAX1C,+BAA+B;+BAItB,qCAAqC;8BAItC,wBAAwB;4BAV1B,kCAAkC;oBAH1C,yBAAyB"}
|
package/src/engine/Engine.js
CHANGED
|
@@ -20,6 +20,7 @@ import { PeriodicConsolePrinter } from "./development/performance/monitor/Period
|
|
|
20
20
|
import { EntityManager } from "./ecs/EntityManager.js";
|
|
21
21
|
import { BinarySerializationRegistry } from "./ecs/storage/binary/BinarySerializationRegistry.js";
|
|
22
22
|
import { GraphicsEngine } from './graphics/GraphicsEngine.js';
|
|
23
|
+
import { GamepadDevice } from "./input/devices/GamepadDevice.js";
|
|
23
24
|
import KeyboardDevice from "./input/devices/KeyboardDevice.js";
|
|
24
25
|
import { PointerDevice } from "./input/devices/PointerDevice.js";
|
|
25
26
|
import { StaticKnowledgeDatabase } from "./knowledge/database/StaticKnowledgeDatabase.js";
|
|
@@ -290,13 +291,15 @@ class Engine {
|
|
|
290
291
|
|
|
291
292
|
this.devices = {
|
|
292
293
|
pointer: new PointerDevice(this.viewStack.el),
|
|
293
|
-
keyboard: new KeyboardDevice(this.viewStack.el)
|
|
294
|
+
keyboard: new KeyboardDevice(this.viewStack.el),
|
|
295
|
+
gamepad: new GamepadDevice()
|
|
294
296
|
};
|
|
295
297
|
|
|
296
298
|
//init level engine
|
|
297
299
|
|
|
298
300
|
this.devices.pointer.start();
|
|
299
301
|
this.devices.keyboard.start();
|
|
302
|
+
this.devices.gamepad.start();
|
|
300
303
|
|
|
301
304
|
//process settings
|
|
302
305
|
this.initializeSettings();
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Per-vertex OUTWARD normal of a closed 2D profile.
|
|
3
|
+
*
|
|
4
|
+
* Each vertex normal is the angle bisector of its two adjacent edge normals,
|
|
5
|
+
* oriented to point away from the profile centroid (assumed at the origin —
|
|
6
|
+
* profiles are authored centred). The result is stored in the convention
|
|
7
|
+
* {@link make_ring_vertices} consumes for its surface-normal mapping: the X
|
|
8
|
+
* component negated, i.e. `(-outX, outY)`. This keeps the lit surface normal
|
|
9
|
+
* radial (pointing out of the tube) regardless of which way the shape winds.
|
|
2
10
|
*
|
|
3
11
|
* @param {number[]|Float32Array} shape
|
|
4
12
|
* @param {number[]|Float32Array} normals
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compute_smooth_profile_normals.d.ts","sourceRoot":"","sources":["../../../../../../../../src/engine/graphics/ecs/path/tube/build/compute_smooth_profile_normals.js"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"compute_smooth_profile_normals.d.ts","sourceRoot":"","sources":["../../../../../../../../src/engine/graphics/ecs/path/tube/build/compute_smooth_profile_normals.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,sDAHW,MAAM,EAAE,GAAC,YAAY,WACrB,MAAM,EAAE,GAAC,YAAY,QAoC/B"}
|