@gg-web-engine/core 0.0.3 → 0.0.5
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/dist/2d/entities/controllers/entity-2d-positioning.animator.js +1 -1
- package/dist/2d/entities/gg-2d-entity.d.ts +3 -5
- package/dist/2d/entities/gg-2d-entity.js +2 -4
- package/dist/3d/entities/controllers/animators/camera-3d.animator.d.ts +17 -0
- package/dist/3d/entities/controllers/animators/camera-3d.animator.js +32 -0
- package/dist/3d/entities/controllers/animators/entity-3d-positioning.animator.d.ts +16 -0
- package/dist/3d/entities/controllers/animators/entity-3d-positioning.animator.js +26 -0
- package/dist/3d/entities/controllers/input/car-keyboard-handling.controller.d.ts +25 -0
- package/dist/3d/entities/controllers/input/car-keyboard-handling.controller.js +105 -0
- package/dist/3d/entities/controllers/input/free-camera.controller.d.ts +54 -0
- package/dist/3d/entities/controllers/input/free-camera.controller.js +102 -0
- package/dist/3d/entities/gg-3d-entity.d.ts +3 -5
- package/dist/3d/entities/gg-3d-entity.js +2 -4
- package/dist/3d/entities/gg-3d-map-graph.entity.d.ts +20 -6
- package/dist/3d/entities/gg-3d-map-graph.entity.js +21 -3
- package/dist/3d/inputs/car-keyboard.input.d.ts +25 -0
- package/dist/3d/inputs/car-keyboard.input.js +100 -0
- package/dist/3d/inputs/free-camera.input.d.ts +22 -0
- package/dist/3d/inputs/free-camera.input.js +80 -0
- package/dist/base/clock/global-clock.d.ts +4 -3
- package/dist/base/clock/global-clock.js +2 -2
- package/dist/base/clock/i-clock.d.ts +7 -0
- package/dist/base/clock/i-clock.js +2 -0
- package/dist/base/clock/pausable-clock.d.ts +25 -0
- package/dist/base/clock/pausable-clock.js +79 -0
- package/dist/base/data-structures/graph.d.ts +17 -1
- package/dist/base/data-structures/graph.js +20 -1
- package/dist/base/entities/base-gg-renderer.d.ts +8 -16
- package/dist/base/entities/base-gg-renderer.js +16 -32
- package/dist/base/entities/controllers/animation-mixer.d.ts +1 -8
- package/dist/base/entities/controllers/animation-mixer.js +2 -11
- package/dist/base/entities/gg-entity.d.ts +30 -0
- package/dist/base/entities/gg-entity.js +37 -2
- package/dist/base/entities/inline-controller.js +1 -6
- package/dist/base/entities/interfaces/i-tick-listener.d.ts +25 -1
- package/dist/base/entities/interfaces/i-tick-listener.js +17 -1
- package/dist/base/gg-viewport-manager.d.ts +1 -0
- package/dist/base/gg-viewport-manager.js +10 -0
- package/dist/base/gg-world.d.ts +9 -6
- package/dist/base/gg-world.js +45 -29
- package/dist/base/inputs/direction.keyboard-input.d.ts +41 -0
- package/dist/base/inputs/direction.keyboard-input.js +85 -0
- package/dist/base/inputs/input.d.ts +50 -0
- package/dist/base/inputs/input.js +80 -0
- package/dist/base/inputs/keyboard.input.d.ts +45 -0
- package/dist/base/inputs/keyboard.input.js +130 -0
- package/dist/base/inputs/mouse.input.d.ts +57 -0
- package/dist/base/inputs/mouse.input.js +81 -0
- package/dist/base/math/point2.d.ts +2 -0
- package/dist/base/math/point2.js +6 -0
- package/dist/base/math/point3.d.ts +2 -0
- package/dist/base/math/point3.js +6 -0
- package/dist/index.d.ts +10 -10
- package/dist/index.js +10 -10
- package/package.json +1 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.CarKeyboardInput = void 0;
|
|
13
|
+
const rxjs_1 = require("rxjs");
|
|
14
|
+
const operators_1 = require("rxjs/operators");
|
|
15
|
+
const input_1 = require("../../base/inputs/input");
|
|
16
|
+
const direction_keyboard_input_1 = require("../../base/inputs/direction.keyboard-input");
|
|
17
|
+
// TODO pass as settings
|
|
18
|
+
// TODO smooth y?
|
|
19
|
+
const TICKER_INTERVAL = 16;
|
|
20
|
+
const TICKER_MAX_STEPS = 10;
|
|
21
|
+
class CarKeyboardInput extends input_1.Input {
|
|
22
|
+
constructor(keyboard, car, options = { keymap: 'arrows', gearUpDownKeys: ['KeyA', 'KeyZ'] }) {
|
|
23
|
+
super();
|
|
24
|
+
this.keyboard = keyboard;
|
|
25
|
+
this.options = options;
|
|
26
|
+
// emits values -1 - 1; -1 = full turn left; 1 = full turn right
|
|
27
|
+
this.x$ = new rxjs_1.BehaviorSubject(0);
|
|
28
|
+
// emits values -1 - 1; -1 = full brake; 1 = full acceleration
|
|
29
|
+
this.y$ = new rxjs_1.BehaviorSubject(0);
|
|
30
|
+
this.lastX = 0;
|
|
31
|
+
this.car$ = new rxjs_1.BehaviorSubject(null);
|
|
32
|
+
this.switchingGearsEnabled = true;
|
|
33
|
+
this.pairTickerPipe = (0, rxjs_1.pipe)((0, operators_1.startWith)(0), (0, operators_1.pairwise)(), (0, operators_1.map)(([beforeValue, afterValue]) => [this.lastX, afterValue]), (0, operators_1.switchMap)(([beforeValue, afterValue]) => (0, rxjs_1.interval)(TICKER_INTERVAL).pipe((0, operators_1.take)(TICKER_MAX_STEPS), (0, operators_1.map)(count => ++count), (0, operators_1.map)(count => beforeValue * ((TICKER_MAX_STEPS - count) / TICKER_MAX_STEPS) + afterValue * (count / TICKER_MAX_STEPS)), (0, operators_1.tap)(x => {
|
|
34
|
+
this.lastX = x;
|
|
35
|
+
}))));
|
|
36
|
+
this.car$.next(car);
|
|
37
|
+
this.directionsInput = new direction_keyboard_input_1.DirectionKeyboardInput(keyboard, options.keymap);
|
|
38
|
+
}
|
|
39
|
+
set car(value) {
|
|
40
|
+
this.car$.next(value);
|
|
41
|
+
}
|
|
42
|
+
get car() {
|
|
43
|
+
return this.car$.getValue();
|
|
44
|
+
}
|
|
45
|
+
startInternal() {
|
|
46
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
47
|
+
let moveDirection = {};
|
|
48
|
+
this.keyboard
|
|
49
|
+
.bind(this.options.gearUpDownKeys[0])
|
|
50
|
+
.pipe((0, rxjs_1.takeUntil)(this.stop$), (0, rxjs_1.filter)(x => this.switchingGearsEnabled && !!x))
|
|
51
|
+
.subscribe(() => {
|
|
52
|
+
if (this.car$.getValue() &&
|
|
53
|
+
(!this.car$.getValue().carProperties.transmission.isAuto || this.car$.getValue().gear <= 0)) {
|
|
54
|
+
this.car$.getValue().gear++;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
this.keyboard
|
|
58
|
+
.bind(this.options.gearUpDownKeys[1])
|
|
59
|
+
.pipe((0, rxjs_1.takeUntil)(this.stop$), (0, rxjs_1.filter)(x => this.switchingGearsEnabled && !!x))
|
|
60
|
+
.subscribe(() => {
|
|
61
|
+
if (this.car$.getValue().carProperties.transmission.isAuto && this.car.gear > 1) {
|
|
62
|
+
this.car$.getValue().gear = 0;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
this.car$.getValue().gear--;
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
this.directionsInput.output$.pipe((0, rxjs_1.takeUntil)(this.stop$)).subscribe(d => {
|
|
69
|
+
moveDirection = d;
|
|
70
|
+
});
|
|
71
|
+
this.car$
|
|
72
|
+
.pipe((0, rxjs_1.takeUntil)(this.stop$), (0, operators_1.switchMap)(c => c.tick$), (0, rxjs_1.takeUntil)(this.stop$), (0, operators_1.map)(() => {
|
|
73
|
+
const direction = [0, 0];
|
|
74
|
+
if (moveDirection.leftRight !== undefined)
|
|
75
|
+
direction[0] = moveDirection.leftRight ? -1 : 1;
|
|
76
|
+
if (moveDirection.upDown !== undefined)
|
|
77
|
+
direction[1] = moveDirection.upDown ? 1 : -1;
|
|
78
|
+
return direction;
|
|
79
|
+
}))
|
|
80
|
+
.subscribe(([x, y]) => {
|
|
81
|
+
this.x$.next(x);
|
|
82
|
+
this.y$.next(y);
|
|
83
|
+
});
|
|
84
|
+
(0, rxjs_1.combineLatest)([
|
|
85
|
+
this.x$.pipe((0, rxjs_1.takeUntil)(this.stop$), (0, operators_1.distinctUntilChanged)(), this.pairTickerPipe),
|
|
86
|
+
this.y$.pipe((0, rxjs_1.takeUntil)(this.stop$), (0, operators_1.distinctUntilChanged)()),
|
|
87
|
+
]).subscribe(([x, y]) => {
|
|
88
|
+
this.car$.getValue().setXAxisControlValue(x);
|
|
89
|
+
this.car$.getValue().setYAxisControlValue(y);
|
|
90
|
+
});
|
|
91
|
+
yield this.directionsInput.start();
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
stopInternal() {
|
|
95
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
96
|
+
yield this.directionsInput.stop();
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.CarKeyboardInput = CarKeyboardInput;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Input } from '../../base/inputs/input';
|
|
2
|
+
import { MouseControllerOptions, MouseInput } from '../../base/inputs/mouse.input';
|
|
3
|
+
import { Gg3dCameraEntity } from '../entities/gg-3d-camera.entity';
|
|
4
|
+
import { KeyboardInput } from '../../base/inputs/keyboard.input';
|
|
5
|
+
import { DirectionKeyboardInput, DirectionKeyboardKeymap } from '../../base/inputs/direction.keyboard-input';
|
|
6
|
+
export declare type FreeCameraControllerOptions = {
|
|
7
|
+
keymap: DirectionKeyboardKeymap;
|
|
8
|
+
movementOptions: {
|
|
9
|
+
speed: number;
|
|
10
|
+
};
|
|
11
|
+
mouseOptions: MouseControllerOptions;
|
|
12
|
+
};
|
|
13
|
+
export declare class FreeCameraInput extends Input<[], [unlockPointer?: boolean]> {
|
|
14
|
+
protected readonly keyboard: KeyboardInput;
|
|
15
|
+
protected readonly camera: Gg3dCameraEntity;
|
|
16
|
+
protected readonly options: FreeCameraControllerOptions;
|
|
17
|
+
protected readonly mouseInput: MouseInput;
|
|
18
|
+
protected readonly directionsInput: DirectionKeyboardInput;
|
|
19
|
+
constructor(keyboard: KeyboardInput, camera: Gg3dCameraEntity, options?: FreeCameraControllerOptions);
|
|
20
|
+
protected startInternal(): Promise<void>;
|
|
21
|
+
protected stopInternal(unlockPointer?: boolean): Promise<void>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.FreeCameraInput = void 0;
|
|
13
|
+
const input_1 = require("../../base/inputs/input");
|
|
14
|
+
const rxjs_1 = require("rxjs");
|
|
15
|
+
const mouse_input_1 = require("../../base/inputs/mouse.input");
|
|
16
|
+
const point3_1 = require("../../base/math/point3");
|
|
17
|
+
const point2_1 = require("../../base/math/point2");
|
|
18
|
+
const quaternion_1 = require("../../base/math/quaternion");
|
|
19
|
+
const direction_keyboard_input_1 = require("../../base/inputs/direction.keyboard-input");
|
|
20
|
+
class FreeCameraInput extends input_1.Input {
|
|
21
|
+
constructor(keyboard, camera, options = {
|
|
22
|
+
keymap: 'wasd',
|
|
23
|
+
movementOptions: { speed: 0.5 },
|
|
24
|
+
mouseOptions: {},
|
|
25
|
+
}) {
|
|
26
|
+
super();
|
|
27
|
+
this.keyboard = keyboard;
|
|
28
|
+
this.camera = camera;
|
|
29
|
+
this.options = options;
|
|
30
|
+
this.mouseInput = new mouse_input_1.MouseInput(options.mouseOptions);
|
|
31
|
+
this.directionsInput = new direction_keyboard_input_1.DirectionKeyboardInput(keyboard, options.keymap);
|
|
32
|
+
}
|
|
33
|
+
startInternal() {
|
|
34
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
35
|
+
let controls = { direction: {}, rest: [] };
|
|
36
|
+
const keys = ['KeyE', 'KeyQ'];
|
|
37
|
+
if (this.camera.object3D.supportsFov) {
|
|
38
|
+
keys.push('KeyZ', 'KeyC');
|
|
39
|
+
}
|
|
40
|
+
this.directionsInput.output$.pipe((0, rxjs_1.takeUntil)(this.stop$)).subscribe(d => {
|
|
41
|
+
controls.direction = d;
|
|
42
|
+
});
|
|
43
|
+
(0, rxjs_1.combineLatest)(keys.map(c => this.keyboard.bind(c)))
|
|
44
|
+
.pipe((0, rxjs_1.takeUntil)(this.stop$))
|
|
45
|
+
.subscribe((d) => {
|
|
46
|
+
controls.rest = d;
|
|
47
|
+
});
|
|
48
|
+
let rotationDelta = { x: 0, y: 0 };
|
|
49
|
+
this.mouseInput.delta$.pipe((0, rxjs_1.takeUntil)(this.stop$)).subscribe(delta => {
|
|
50
|
+
rotationDelta = point2_1.Pnt2.add(rotationDelta, delta);
|
|
51
|
+
});
|
|
52
|
+
this.camera.tick$.pipe((0, rxjs_1.takeUntil)(this.stop$)).subscribe(() => {
|
|
53
|
+
let translateVector = { x: 0, y: 0, z: 0 };
|
|
54
|
+
const [u, d, zo, zi] = controls.rest;
|
|
55
|
+
if (controls.direction.upDown !== undefined)
|
|
56
|
+
translateVector.z = controls.direction.upDown ? -1 : 1;
|
|
57
|
+
if (controls.direction.leftRight !== undefined)
|
|
58
|
+
translateVector.x = controls.direction.leftRight ? -1 : 1;
|
|
59
|
+
if (u != d)
|
|
60
|
+
translateVector.y = d ? -1 : 1;
|
|
61
|
+
if (zo != zi)
|
|
62
|
+
this.camera.object3D.fov += zo ? 1 : -1;
|
|
63
|
+
this.camera.position = point3_1.Pnt3.add(this.camera.position, point3_1.Pnt3.rot(point3_1.Pnt3.scalarMult(point3_1.Pnt3.norm(translateVector), this.options.movementOptions.speed), this.camera.rotation));
|
|
64
|
+
if (rotationDelta.x != 0 || rotationDelta.y != 0) {
|
|
65
|
+
this.camera.rotation = quaternion_1.Qtrn.combineRotations(quaternion_1.Qtrn.fromAngle({ x: 0, y: 0, z: 1 }, -rotationDelta.x / 300), this.camera.rotation, quaternion_1.Qtrn.fromAngle({ x: 1, y: 0, z: 0 }, -rotationDelta.y / 300));
|
|
66
|
+
rotationDelta = { x: 0, y: 0 };
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
yield this.mouseInput.start();
|
|
70
|
+
yield this.directionsInput.start();
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
stopInternal(unlockPointer = true) {
|
|
74
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
75
|
+
yield this.mouseInput.stop(unlockPointer);
|
|
76
|
+
yield this.directionsInput.stop();
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.FreeCameraInput = FreeCameraInput;
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { Observable } from 'rxjs';
|
|
2
|
-
import {
|
|
2
|
+
import { PausableClock } from './pausable-clock';
|
|
3
|
+
import { IClock } from './i-clock';
|
|
3
4
|
/**
|
|
4
5
|
* A singleton class, providing ability to track time, fire ticks, provide time elapsed + tick delta.
|
|
5
6
|
* Starts as soon as accessed and counts time from 01/01/1970
|
|
6
7
|
*/
|
|
7
|
-
export declare class GgGlobalClock {
|
|
8
|
+
export declare class GgGlobalClock implements IClock {
|
|
8
9
|
private static _instance;
|
|
9
10
|
static get instance(): GgGlobalClock;
|
|
10
11
|
private readonly _tick$;
|
|
11
12
|
get tick$(): Observable<[number, number]>;
|
|
12
13
|
get elapsedTime(): number;
|
|
13
|
-
createChildClock(autoStart: boolean):
|
|
14
|
+
createChildClock(autoStart: boolean): PausableClock;
|
|
14
15
|
private constructor();
|
|
15
16
|
}
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.GgGlobalClock = void 0;
|
|
4
4
|
const rxjs_1 = require("rxjs");
|
|
5
5
|
const operators_1 = require("rxjs/operators");
|
|
6
|
-
const
|
|
6
|
+
const pausable_clock_1 = require("./pausable-clock");
|
|
7
7
|
/**
|
|
8
8
|
* A singleton class, providing ability to track time, fire ticks, provide time elapsed + tick delta.
|
|
9
9
|
* Starts as soon as accessed and counts time from 01/01/1970
|
|
@@ -30,7 +30,7 @@ class GgGlobalClock {
|
|
|
30
30
|
return (typeof performance === 'undefined' ? Date : performance).now();
|
|
31
31
|
}
|
|
32
32
|
createChildClock(autoStart) {
|
|
33
|
-
return new
|
|
33
|
+
return new pausable_clock_1.PausableClock(autoStart, this);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
exports.GgGlobalClock = GgGlobalClock;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
import { IClock } from './i-clock';
|
|
3
|
+
/**
|
|
4
|
+
* A class, providing ability to track time, fire ticks, provide time elapsed + tick delta with ability to suspend/resume it.
|
|
5
|
+
*/
|
|
6
|
+
export declare class PausableClock implements IClock {
|
|
7
|
+
protected readonly parentClock: IClock;
|
|
8
|
+
private tickSub;
|
|
9
|
+
private readonly _tick$;
|
|
10
|
+
get tick$(): Observable<[number, number]>;
|
|
11
|
+
get isRunning(): boolean;
|
|
12
|
+
get isPaused(): boolean;
|
|
13
|
+
get elapsedTime(): number;
|
|
14
|
+
private startedAt;
|
|
15
|
+
private oldRelativeTime;
|
|
16
|
+
private pausedAt;
|
|
17
|
+
constructor(autoStart?: boolean, parentClock?: IClock);
|
|
18
|
+
createChildClock(autoStart: boolean): PausableClock;
|
|
19
|
+
start(): void;
|
|
20
|
+
stop(): void;
|
|
21
|
+
pause(): void;
|
|
22
|
+
resume(): void;
|
|
23
|
+
protected startListeningTicks(): void;
|
|
24
|
+
protected stopListeningTicks(): void;
|
|
25
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PausableClock = void 0;
|
|
4
|
+
const rxjs_1 = require("rxjs");
|
|
5
|
+
const operators_1 = require("rxjs/operators");
|
|
6
|
+
const global_clock_1 = require("./global-clock");
|
|
7
|
+
/**
|
|
8
|
+
* A class, providing ability to track time, fire ticks, provide time elapsed + tick delta with ability to suspend/resume it.
|
|
9
|
+
*/
|
|
10
|
+
class PausableClock {
|
|
11
|
+
constructor(autoStart = false, parentClock = global_clock_1.GgGlobalClock.instance) {
|
|
12
|
+
this.parentClock = parentClock;
|
|
13
|
+
this.tickSub = null;
|
|
14
|
+
this._tick$ = new rxjs_1.Subject();
|
|
15
|
+
// state
|
|
16
|
+
this.startedAt = -1;
|
|
17
|
+
this.oldRelativeTime = 0; // "elapsed", emitted on last tick
|
|
18
|
+
this.pausedAt = -1;
|
|
19
|
+
if (autoStart) {
|
|
20
|
+
this.start();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
get tick$() {
|
|
24
|
+
return this._tick$.pipe((0, operators_1.map)(([oldTime, newTime]) => [newTime, newTime - oldTime]));
|
|
25
|
+
}
|
|
26
|
+
get isRunning() {
|
|
27
|
+
return !!this.tickSub;
|
|
28
|
+
}
|
|
29
|
+
get isPaused() {
|
|
30
|
+
return this.pausedAt !== -1;
|
|
31
|
+
}
|
|
32
|
+
get elapsedTime() {
|
|
33
|
+
if (this.isPaused) {
|
|
34
|
+
return this.pausedAt - this.startedAt;
|
|
35
|
+
}
|
|
36
|
+
return this.parentClock.elapsedTime - this.startedAt;
|
|
37
|
+
}
|
|
38
|
+
createChildClock(autoStart) {
|
|
39
|
+
return new PausableClock(autoStart, this);
|
|
40
|
+
}
|
|
41
|
+
start() {
|
|
42
|
+
if (this.isRunning) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
this.oldRelativeTime = 0;
|
|
46
|
+
this.startedAt = this.parentClock.elapsedTime;
|
|
47
|
+
this.startListeningTicks();
|
|
48
|
+
}
|
|
49
|
+
stop() {
|
|
50
|
+
this.stopListeningTicks();
|
|
51
|
+
this.startedAt = this.pausedAt = -1;
|
|
52
|
+
}
|
|
53
|
+
pause() {
|
|
54
|
+
this.stopListeningTicks();
|
|
55
|
+
this.pausedAt = this.parentClock.elapsedTime;
|
|
56
|
+
}
|
|
57
|
+
resume() {
|
|
58
|
+
if (this.isRunning || this.pausedAt == -1) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
this.startedAt += this.parentClock.elapsedTime - this.pausedAt;
|
|
62
|
+
this.pausedAt = -1;
|
|
63
|
+
this.startListeningTicks();
|
|
64
|
+
}
|
|
65
|
+
startListeningTicks() {
|
|
66
|
+
if (this.tickSub) {
|
|
67
|
+
throw new Error('Clock is already ticking!');
|
|
68
|
+
}
|
|
69
|
+
this.tickSub = this.parentClock.tick$
|
|
70
|
+
.pipe((0, operators_1.map)(([parentElapsed, _]) => [this.oldRelativeTime, parentElapsed - this.startedAt]), (0, operators_1.tap)(([_, cur]) => (this.oldRelativeTime = cur)))
|
|
71
|
+
.subscribe(this._tick$);
|
|
72
|
+
}
|
|
73
|
+
stopListeningTicks() {
|
|
74
|
+
var _a;
|
|
75
|
+
(_a = this.tickSub) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
76
|
+
this.tickSub = null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.PausableClock = PausableClock;
|
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
export declare class Graph<T> {
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Creates a new Graph instance from an array of elements, where each element in the array is a node in the graph.
|
|
4
|
+
* The first element of the array is used as the root node of the graph.
|
|
5
|
+
* @param array The array of elements to create the graph from.
|
|
6
|
+
* @param closed An optional boolean indicating whether the graph is closed, meaning that the last node is adjacent to the first node.
|
|
7
|
+
* @returns A new Graph instance created from the array.
|
|
8
|
+
* @typeparam T The type of elements in the array and nodes in the graph.
|
|
9
|
+
*/
|
|
10
|
+
static fromArray<T>(array: T[], closed?: boolean): Graph<T>;
|
|
11
|
+
/**
|
|
12
|
+
* Creates a new Graph instance from a two-dimensional square grid of elements, where each element in the grid is a node in the graph.
|
|
13
|
+
* The top-left element of the grid is used as the root node of the graph.
|
|
14
|
+
* The nodes in the graph are created in the same order as the elements in the grid, from left to right and then from top to bottom.
|
|
15
|
+
* @param grid The two-dimensional square grid of elements to create the graph from.
|
|
16
|
+
* @returns A new Graph instance created from the square grid.
|
|
17
|
+
* @typeparam T The type of elements in the square grid and nodes in the graph.
|
|
18
|
+
*/
|
|
3
19
|
static fromSquareGrid<T>(grid: T[][]): Graph<T>;
|
|
4
20
|
data: T;
|
|
5
21
|
private adjacent;
|
|
@@ -6,7 +6,15 @@ class Graph {
|
|
|
6
6
|
this.data = data;
|
|
7
7
|
this.adjacent = new Set();
|
|
8
8
|
}
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new Graph instance from an array of elements, where each element in the array is a node in the graph.
|
|
11
|
+
* The first element of the array is used as the root node of the graph.
|
|
12
|
+
* @param array The array of elements to create the graph from.
|
|
13
|
+
* @param closed An optional boolean indicating whether the graph is closed, meaning that the last node is adjacent to the first node.
|
|
14
|
+
* @returns A new Graph instance created from the array.
|
|
15
|
+
* @typeparam T The type of elements in the array and nodes in the graph.
|
|
16
|
+
*/
|
|
17
|
+
static fromArray(array, closed = false) {
|
|
10
18
|
const root = new Graph(array[0]);
|
|
11
19
|
let tail = root;
|
|
12
20
|
for (let i = 1; i < array.length; i++) {
|
|
@@ -14,8 +22,19 @@ class Graph {
|
|
|
14
22
|
tail.addAdjacent(newTail);
|
|
15
23
|
tail = newTail;
|
|
16
24
|
}
|
|
25
|
+
if (closed) {
|
|
26
|
+
tail.addAdjacent(root);
|
|
27
|
+
}
|
|
17
28
|
return root;
|
|
18
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new Graph instance from a two-dimensional square grid of elements, where each element in the grid is a node in the graph.
|
|
32
|
+
* The top-left element of the grid is used as the root node of the graph.
|
|
33
|
+
* The nodes in the graph are created in the same order as the elements in the grid, from left to right and then from top to bottom.
|
|
34
|
+
* @param grid The two-dimensional square grid of elements to create the graph from.
|
|
35
|
+
* @returns A new Graph instance created from the square grid.
|
|
36
|
+
* @typeparam T The type of elements in the square grid and nodes in the graph.
|
|
37
|
+
*/
|
|
19
38
|
static fromSquareGrid(grid) {
|
|
20
39
|
const nodes = grid.map(sgrid => sgrid.map(item => new Graph(item)));
|
|
21
40
|
// bind them
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Subject, Subscription } from 'rxjs';
|
|
3
|
-
import { GgEntity } from './gg-entity';
|
|
1
|
+
import { GgEntity, GGTickOrder } from './gg-entity';
|
|
4
2
|
import { Point2 } from '../models/points';
|
|
3
|
+
import { GgWorld } from '../gg-world';
|
|
5
4
|
export declare type RendererOptions = {
|
|
6
5
|
transparent: boolean;
|
|
7
6
|
background: number;
|
|
@@ -9,20 +8,13 @@ export declare type RendererOptions = {
|
|
|
9
8
|
forceResolution?: number;
|
|
10
9
|
antialias: boolean;
|
|
11
10
|
};
|
|
12
|
-
export declare abstract class BaseGgRenderer extends GgEntity
|
|
13
|
-
protected
|
|
14
|
-
|
|
15
|
-
private initialized;
|
|
16
|
-
readonly tick$: Subject<[number, number]>;
|
|
17
|
-
readonly tickOrder = 1000;
|
|
18
|
-
protected tickListener: Subscription | null;
|
|
11
|
+
export declare abstract class BaseGgRenderer extends GgEntity {
|
|
12
|
+
protected readonly canvas?: HTMLCanvasElement | undefined;
|
|
13
|
+
readonly tickOrder = GGTickOrder.RENDERING;
|
|
19
14
|
readonly rendererOptions: RendererOptions;
|
|
20
|
-
protected constructor(canvas?: HTMLCanvasElement, options?: Partial<RendererOptions>);
|
|
21
|
-
get isActive(): boolean;
|
|
22
|
-
activate(): void;
|
|
23
|
-
deactivate(): void;
|
|
24
|
-
init(): void;
|
|
15
|
+
protected constructor(canvas?: HTMLCanvasElement | undefined, options?: Partial<RendererOptions>);
|
|
25
16
|
abstract render(): void;
|
|
26
17
|
abstract resize(newSize: Point2): void;
|
|
27
|
-
|
|
18
|
+
onSpawned(world: GgWorld<any, any>): void;
|
|
19
|
+
onRemoved(): void;
|
|
28
20
|
}
|
|
@@ -1,49 +1,33 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BaseGgRenderer = void 0;
|
|
4
|
-
const rxjs_1 = require("rxjs");
|
|
5
4
|
const gg_entity_1 = require("./gg-entity");
|
|
6
5
|
const gg_viewport_manager_1 = require("../gg-viewport-manager");
|
|
7
6
|
class BaseGgRenderer extends gg_entity_1.GgEntity {
|
|
8
7
|
constructor(canvas, options = {}) {
|
|
9
8
|
super();
|
|
10
|
-
this.
|
|
11
|
-
this.tickOrder =
|
|
12
|
-
this.tickListener = null;
|
|
9
|
+
this.canvas = canvas;
|
|
10
|
+
this.tickOrder = gg_entity_1.GGTickOrder.RENDERING;
|
|
13
11
|
this.rendererOptions = Object.assign({ transparent: false, background: 0x000000, antialias: true }, (options || {}));
|
|
14
|
-
this.
|
|
15
|
-
this._singularRenderMethods = new Map();
|
|
16
|
-
this.tick$ = new rxjs_1.Subject();
|
|
17
|
-
if (canvas) {
|
|
18
|
-
setTimeout(() => {
|
|
19
|
-
gg_viewport_manager_1.GgViewportManager.instance.assignRendererToCanvas(this, canvas).then();
|
|
20
|
-
}, 0);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
get isActive() {
|
|
24
|
-
return !!this.tickListener;
|
|
25
|
-
}
|
|
26
|
-
activate() {
|
|
27
|
-
if (this.isActive) {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
if (!this.initialized) {
|
|
31
|
-
this.init();
|
|
32
|
-
}
|
|
33
|
-
this.tickListener = this.tick$.subscribe(() => {
|
|
12
|
+
this.tick$.subscribe(() => {
|
|
34
13
|
this.render();
|
|
35
14
|
});
|
|
36
15
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (
|
|
40
|
-
|
|
16
|
+
onSpawned(world) {
|
|
17
|
+
super.onSpawned(world);
|
|
18
|
+
if (this.canvas) {
|
|
19
|
+
setTimeout(() => {
|
|
20
|
+
gg_viewport_manager_1.GgViewportManager.instance.assignRendererToCanvas(this, this.canvas).then();
|
|
21
|
+
}, 0);
|
|
41
22
|
}
|
|
42
|
-
(_a = this.tickListener) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
43
|
-
this.tickListener = null;
|
|
44
23
|
}
|
|
45
|
-
|
|
46
|
-
|
|
24
|
+
onRemoved() {
|
|
25
|
+
super.onRemoved();
|
|
26
|
+
if (this.canvas) {
|
|
27
|
+
setTimeout(() => {
|
|
28
|
+
gg_viewport_manager_1.GgViewportManager.instance.deregisterCanvas(this.canvas).then();
|
|
29
|
+
}, 0);
|
|
30
|
+
}
|
|
47
31
|
}
|
|
48
32
|
}
|
|
49
33
|
exports.BaseGgRenderer = BaseGgRenderer;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { GgEntity } from '../gg-entity';
|
|
2
|
-
import { ITickListener } from '../interfaces/i-tick-listener';
|
|
3
2
|
import { Observable, Subject } from 'rxjs';
|
|
4
3
|
import { GgWorld } from '../../gg-world';
|
|
5
4
|
export declare type AnimationFunction<T> = (elapsed: number, delta: number) => T;
|
|
@@ -9,19 +8,14 @@ export declare type AnimationFunction<T> = (elapsed: number, delta: number) => T
|
|
|
9
8
|
* The current value of the animation can be subscribed to using the `subscribeToValue` property.
|
|
10
9
|
* The animation function can be changed with `transitAnimationFunction` or `transitFromStaticState`.
|
|
11
10
|
*/
|
|
12
|
-
export declare class AnimationMixer<T> extends GgEntity
|
|
11
|
+
export declare class AnimationMixer<T> extends GgEntity {
|
|
13
12
|
protected _animationFunction: AnimationFunction<T>;
|
|
14
13
|
protected _lerp: (a: T, b: T, t: number) => T;
|
|
15
|
-
readonly tick$: Subject<[number, number]>;
|
|
16
14
|
readonly tickOrder: number;
|
|
17
15
|
/**
|
|
18
16
|
* A subject that emits the current value of the animation on every tick.
|
|
19
17
|
*/
|
|
20
18
|
protected readonly _value$: Subject<T>;
|
|
21
|
-
/**
|
|
22
|
-
* A subject that emits when the animator has been removed from the world.
|
|
23
|
-
*/
|
|
24
|
-
protected readonly removed$: Subject<void>;
|
|
25
19
|
/**
|
|
26
20
|
* The current transition time reference `[elapsed, delta]` that interpolates between the old and new functions.
|
|
27
21
|
*/
|
|
@@ -78,6 +72,5 @@ export declare class AnimationMixer<T> extends GgEntity implements ITickListener
|
|
|
78
72
|
*/
|
|
79
73
|
transitAnimationFunction(newFunc: AnimationFunction<T>, transitionDuration: number, easing?: (t: number) => number): void;
|
|
80
74
|
onSpawned(world: GgWorld<any, any>): void;
|
|
81
|
-
onRemoved(): void;
|
|
82
75
|
dispose(): void;
|
|
83
76
|
}
|
|
@@ -20,16 +20,11 @@ class AnimationMixer extends gg_entity_1.GgEntity {
|
|
|
20
20
|
super();
|
|
21
21
|
this._animationFunction = _animationFunction;
|
|
22
22
|
this._lerp = _lerp;
|
|
23
|
-
this.
|
|
24
|
-
this.tickOrder = 850;
|
|
23
|
+
this.tickOrder = gg_entity_1.GGTickOrder.ANIMATION_MIXERS;
|
|
25
24
|
/**
|
|
26
25
|
* A subject that emits the current value of the animation on every tick.
|
|
27
26
|
*/
|
|
28
27
|
this._value$ = new rxjs_1.Subject();
|
|
29
|
-
/**
|
|
30
|
-
* A subject that emits when the animator has been removed from the world.
|
|
31
|
-
*/
|
|
32
|
-
this.removed$ = new rxjs_1.Subject();
|
|
33
28
|
/**
|
|
34
29
|
* The current transition time reference `[elapsed, delta]` that interpolates between the old and new functions.
|
|
35
30
|
*/
|
|
@@ -136,13 +131,9 @@ class AnimationMixer extends gg_entity_1.GgEntity {
|
|
|
136
131
|
onSpawned(world) {
|
|
137
132
|
super.onSpawned(world);
|
|
138
133
|
this.tick$
|
|
139
|
-
.pipe((0, rxjs_1.takeUntil)(this.
|
|
134
|
+
.pipe((0, rxjs_1.takeUntil)(this._onRemoved$), (0, operators_1.tap)(([elapsed, delta]) => this.currentTransition && this.currentTransition([elapsed, delta])), (0, operators_1.map)(([elapsed, delta]) => this._animationFunction(elapsed, delta)))
|
|
140
135
|
.subscribe(value => this._value$.next(value));
|
|
141
136
|
}
|
|
142
|
-
onRemoved() {
|
|
143
|
-
super.onRemoved();
|
|
144
|
-
this.removed$.next();
|
|
145
|
-
}
|
|
146
137
|
dispose() {
|
|
147
138
|
super.dispose();
|
|
148
139
|
this.tick$.complete();
|
|
@@ -1,11 +1,41 @@
|
|
|
1
1
|
import { GgWorld } from '../gg-world';
|
|
2
2
|
import { Subject } from 'rxjs';
|
|
3
|
+
/**
|
|
4
|
+
* Engine's default tick orders: the less value, the earlier tick will be run.
|
|
5
|
+
*/
|
|
6
|
+
export declare enum GGTickOrder {
|
|
7
|
+
INPUT_CONTROLLERS = 0,
|
|
8
|
+
PHYSICS_SIMULATION = 200,
|
|
9
|
+
OBJECTS_BINDING = 400,
|
|
10
|
+
ANIMATION_MIXERS = 600,
|
|
11
|
+
CONTROLLERS = 800,
|
|
12
|
+
RENDERING = 1000,
|
|
13
|
+
POST_RENDERING = 1200
|
|
14
|
+
}
|
|
3
15
|
export declare abstract class GgEntity {
|
|
16
|
+
private static default_name_counter;
|
|
17
|
+
/**
|
|
18
|
+
* will receive [elapsed time, delta] of each world clock tick
|
|
19
|
+
*/
|
|
20
|
+
readonly tick$: Subject<[number, number]>;
|
|
21
|
+
/**
|
|
22
|
+
* the priority of ticker: the less value, the earlier tick will be run.
|
|
23
|
+
*/
|
|
24
|
+
abstract readonly tickOrder: GGTickOrder | number;
|
|
25
|
+
/**
|
|
26
|
+
* a world reference, where this entity was added to
|
|
27
|
+
*/
|
|
4
28
|
protected _world: GgWorld<any, any> | null;
|
|
5
29
|
get world(): GgWorld<any, any> | null;
|
|
6
30
|
protected _name: string;
|
|
7
31
|
get name(): string;
|
|
8
32
|
set name(value: string);
|
|
33
|
+
/**
|
|
34
|
+
* The flag whether entity should listen to ticks. If set to false, ticks will not be propagated to this entity
|
|
35
|
+
* */
|
|
36
|
+
protected _active: boolean;
|
|
37
|
+
get active(): boolean;
|
|
38
|
+
set active(value: boolean);
|
|
9
39
|
protected _children: GgEntity[];
|
|
10
40
|
addChildren(...entities: GgEntity[]): void;
|
|
11
41
|
removeChildren(entities: GgEntity[], dispose?: boolean): void;
|