@gg-web-engine/core 0.0.2 → 0.0.4
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.d.ts +16 -0
- package/dist/2d/entities/controllers/entity-2d-positioning.animator.js +26 -0
- package/dist/2d/entities/gg-2d-entity.d.ts +12 -6
- package/dist/2d/entities/gg-2d-entity.js +52 -20
- package/dist/2d/gg-2d-world.d.ts +3 -0
- package/dist/2d/gg-2d-world.js +11 -0
- package/dist/3d/controllers/car-keyboard.controller.d.ts +10 -10
- package/dist/3d/controllers/car-keyboard.controller.js +21 -20
- package/dist/3d/controllers/free-camera.controller.d.ts +8 -8
- 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/camera-3d.animator.d.ts +17 -0
- package/dist/3d/entities/controllers/camera-3d.animator.js +32 -0
- package/dist/3d/entities/controllers/entity-3d-positioning.animator.d.ts +16 -0
- package/dist/3d/entities/controllers/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-camera.entity.d.ts +2 -0
- package/dist/3d/entities/gg-3d-camera.entity.js +6 -0
- package/dist/3d/entities/gg-3d-entity.d.ts +7 -6
- package/dist/3d/entities/gg-3d-entity.js +21 -13
- package/dist/3d/entities/gg-3d-map-graph.entity.d.ts +10 -10
- package/dist/3d/entities/gg-3d-map-graph.entity.js +2 -3
- package/dist/3d/entities/gg-3d-raycast-vehicle.entity.d.ts +6 -5
- package/dist/3d/gg-3d-world.d.ts +3 -0
- package/dist/3d/gg-3d-world.js +12 -0
- 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/clock.d.ts +25 -0
- package/dist/base/clock/clock.js +79 -0
- package/dist/base/clock/global-clock.d.ts +16 -0
- package/dist/base/clock/global-clock.js +36 -0
- 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/entities/base-gg-renderer.d.ts +3 -15
- package/dist/base/entities/base-gg-renderer.js +2 -30
- package/dist/base/entities/controllers/animation-mixer.d.ts +76 -0
- package/dist/base/entities/controllers/animation-mixer.js +143 -0
- package/dist/base/entities/gg-entity.d.ts +33 -1
- package/dist/base/entities/gg-entity.js +42 -1
- package/dist/base/entities/inline-controller.js +1 -7
- 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 +4 -0
- package/dist/base/gg-world.d.ts +11 -6
- package/dist/base/gg-world.js +50 -31
- 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/matrix4.js +3 -3
- package/dist/base/math/point2.js +1 -1
- package/dist/base/math/point3.js +1 -1
- package/dist/base/math/quaternion.d.ts +83 -9
- package/dist/base/math/quaternion.js +93 -10
- package/dist/base/models/points.d.ts +9 -9
- package/dist/index.d.ts +13 -9
- package/dist/index.js +13 -9
- package/package.json +1 -1
- package/.prettierrc +0 -8
|
@@ -0,0 +1,105 @@
|
|
|
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.CarKeyboardHandlingController = void 0;
|
|
13
|
+
const rxjs_1 = require("rxjs");
|
|
14
|
+
const operators_1 = require("rxjs/operators");
|
|
15
|
+
const direction_keyboard_input_1 = require("../../../../base/inputs/direction.keyboard-input");
|
|
16
|
+
const gg_entity_1 = require("../../../../base/entities/gg-entity");
|
|
17
|
+
// TODO pass as settings
|
|
18
|
+
// TODO smooth y?
|
|
19
|
+
const TICKER_INTERVAL = 16;
|
|
20
|
+
const TICKER_MAX_STEPS = 10;
|
|
21
|
+
class CarKeyboardHandlingController extends gg_entity_1.GgEntity {
|
|
22
|
+
constructor(keyboard, car, options = { keymap: 'arrows', gearUpDownKeys: ['KeyA', 'KeyZ'] }) {
|
|
23
|
+
super();
|
|
24
|
+
this.keyboard = keyboard;
|
|
25
|
+
this.car = car;
|
|
26
|
+
this.options = options;
|
|
27
|
+
this.tickOrder = gg_entity_1.GGTickOrder.INPUT_CONTROLLERS;
|
|
28
|
+
// emits values -1 - 1; -1 = full turn left; 1 = full turn right
|
|
29
|
+
this.x$ = new rxjs_1.BehaviorSubject(0);
|
|
30
|
+
// emits values -1 - 1; -1 = full brake; 1 = full acceleration
|
|
31
|
+
this.y$ = new rxjs_1.BehaviorSubject(0);
|
|
32
|
+
this.lastX = 0;
|
|
33
|
+
this.switchingGearsEnabled = true;
|
|
34
|
+
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 => {
|
|
35
|
+
this.lastX = x;
|
|
36
|
+
}))));
|
|
37
|
+
this.directionsInput = new direction_keyboard_input_1.DirectionKeyboardInput(keyboard, options.keymap);
|
|
38
|
+
}
|
|
39
|
+
onSpawned(world) {
|
|
40
|
+
const _super = Object.create(null, {
|
|
41
|
+
onSpawned: { get: () => super.onSpawned }
|
|
42
|
+
});
|
|
43
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
_super.onSpawned.call(this, world);
|
|
45
|
+
let moveDirection = {};
|
|
46
|
+
this.keyboard
|
|
47
|
+
.bind(this.options.gearUpDownKeys[0])
|
|
48
|
+
.pipe((0, rxjs_1.takeUntil)(this._onRemoved$), (0, rxjs_1.filter)(x => this.switchingGearsEnabled && !!x))
|
|
49
|
+
.subscribe(() => {
|
|
50
|
+
if (this.car && (!this.car.carProperties.transmission.isAuto || this.car.gear <= 0)) {
|
|
51
|
+
this.car.gear++;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
this.keyboard
|
|
55
|
+
.bind(this.options.gearUpDownKeys[1])
|
|
56
|
+
.pipe((0, rxjs_1.takeUntil)(this._onRemoved$), (0, rxjs_1.filter)(x => this.switchingGearsEnabled && !!x))
|
|
57
|
+
.subscribe(() => {
|
|
58
|
+
if (this.car) {
|
|
59
|
+
if (this.car.carProperties.transmission.isAuto && this.car.gear > 1) {
|
|
60
|
+
this.car.gear = 0;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
this.car.gear--;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
this.directionsInput.output$.pipe((0, rxjs_1.takeUntil)(this._onRemoved$)).subscribe(d => {
|
|
68
|
+
moveDirection = d;
|
|
69
|
+
});
|
|
70
|
+
this.tick$
|
|
71
|
+
.pipe((0, rxjs_1.takeUntil)(this._onRemoved$), (0, operators_1.map)(() => {
|
|
72
|
+
const direction = [0, 0];
|
|
73
|
+
if (moveDirection.leftRight !== undefined)
|
|
74
|
+
direction[0] = moveDirection.leftRight ? -1 : 1;
|
|
75
|
+
if (moveDirection.upDown !== undefined)
|
|
76
|
+
direction[1] = moveDirection.upDown ? 1 : -1;
|
|
77
|
+
return direction;
|
|
78
|
+
}))
|
|
79
|
+
.subscribe(([x, y]) => {
|
|
80
|
+
this.x$.next(x);
|
|
81
|
+
this.y$.next(y);
|
|
82
|
+
});
|
|
83
|
+
(0, rxjs_1.combineLatest)([
|
|
84
|
+
this.x$.pipe((0, rxjs_1.takeUntil)(this._onRemoved$), (0, operators_1.distinctUntilChanged)(), this.pairTickerPipe),
|
|
85
|
+
this.y$.pipe((0, rxjs_1.takeUntil)(this._onRemoved$), (0, operators_1.distinctUntilChanged)()),
|
|
86
|
+
]).subscribe(([x, y]) => {
|
|
87
|
+
if (this.car) {
|
|
88
|
+
this.car.setXAxisControlValue(x);
|
|
89
|
+
this.car.setYAxisControlValue(y);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
yield this.directionsInput.start();
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
onRemoved() {
|
|
96
|
+
const _super = Object.create(null, {
|
|
97
|
+
onRemoved: { get: () => super.onRemoved }
|
|
98
|
+
});
|
|
99
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
100
|
+
yield _super.onRemoved.call(this);
|
|
101
|
+
yield this.directionsInput.stop();
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.CarKeyboardHandlingController = CarKeyboardHandlingController;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { MouseInput, MouseInputOptions } from '../../../../base/inputs/mouse.input';
|
|
2
|
+
import { Gg3dCameraEntity } from '../../gg-3d-camera.entity';
|
|
3
|
+
import { KeyboardInput } from '../../../../base/inputs/keyboard.input';
|
|
4
|
+
import { DirectionKeyboardInput, DirectionKeyboardKeymap } from '../../../../base/inputs/direction.keyboard-input';
|
|
5
|
+
import { GgEntity, GGTickOrder } from '../../../../base/entities/gg-entity';
|
|
6
|
+
import { GgWorld } from '../../../../base/gg-world';
|
|
7
|
+
/**
|
|
8
|
+
* Options for configuring a FreeCameraInput controller.
|
|
9
|
+
*/
|
|
10
|
+
export declare type FreeCameraControllerOptions = {
|
|
11
|
+
/**
|
|
12
|
+
* A keymap for controlling camera movement, where each key corresponds to a movement direction.
|
|
13
|
+
*/
|
|
14
|
+
keymap: DirectionKeyboardKeymap;
|
|
15
|
+
/**
|
|
16
|
+
* Options for configuring camera movement.
|
|
17
|
+
*/
|
|
18
|
+
movementOptions: {
|
|
19
|
+
/**
|
|
20
|
+
* The speed of camera movement.
|
|
21
|
+
*/
|
|
22
|
+
speed: number;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Options for configuring mouse input.
|
|
26
|
+
*/
|
|
27
|
+
mouseOptions: MouseInputOptions;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* A controller for a free-moving camera.
|
|
31
|
+
*/
|
|
32
|
+
export declare class FreeCameraController extends GgEntity {
|
|
33
|
+
protected readonly keyboard: KeyboardInput;
|
|
34
|
+
protected readonly camera: Gg3dCameraEntity;
|
|
35
|
+
protected readonly options: FreeCameraControllerOptions;
|
|
36
|
+
readonly tickOrder = GGTickOrder.INPUT_CONTROLLERS;
|
|
37
|
+
/**
|
|
38
|
+
* The mouse input controller used for camera rotation.
|
|
39
|
+
*/
|
|
40
|
+
protected readonly mouseInput: MouseInput;
|
|
41
|
+
/**
|
|
42
|
+
* The keyboard input controller used for camera movement.
|
|
43
|
+
*/
|
|
44
|
+
protected readonly directionsInput: DirectionKeyboardInput;
|
|
45
|
+
/**
|
|
46
|
+
* Creates a new FreeCameraInput instance.
|
|
47
|
+
* @param keyboard The keyboard input controller to use for camera movement.
|
|
48
|
+
* @param camera The camera entity to control.
|
|
49
|
+
* @param options Optional configuration options for the controller.
|
|
50
|
+
*/
|
|
51
|
+
constructor(keyboard: KeyboardInput, camera: Gg3dCameraEntity, options?: FreeCameraControllerOptions);
|
|
52
|
+
onSpawned(world: GgWorld<any, any>): Promise<void>;
|
|
53
|
+
onRemoved(): Promise<void>;
|
|
54
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
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.FreeCameraController = void 0;
|
|
13
|
+
const rxjs_1 = require("rxjs");
|
|
14
|
+
const mouse_input_1 = require("../../../../base/inputs/mouse.input");
|
|
15
|
+
const point3_1 = require("../../../../base/math/point3");
|
|
16
|
+
const point2_1 = require("../../../../base/math/point2");
|
|
17
|
+
const quaternion_1 = require("../../../../base/math/quaternion");
|
|
18
|
+
const direction_keyboard_input_1 = require("../../../../base/inputs/direction.keyboard-input");
|
|
19
|
+
const gg_entity_1 = require("../../../../base/entities/gg-entity");
|
|
20
|
+
/**
|
|
21
|
+
* A controller for a free-moving camera.
|
|
22
|
+
*/
|
|
23
|
+
class FreeCameraController extends gg_entity_1.GgEntity {
|
|
24
|
+
/**
|
|
25
|
+
* Creates a new FreeCameraInput instance.
|
|
26
|
+
* @param keyboard The keyboard input controller to use for camera movement.
|
|
27
|
+
* @param camera The camera entity to control.
|
|
28
|
+
* @param options Optional configuration options for the controller.
|
|
29
|
+
*/
|
|
30
|
+
constructor(keyboard, camera, options = {
|
|
31
|
+
keymap: 'wasd',
|
|
32
|
+
movementOptions: { speed: 0.5 },
|
|
33
|
+
mouseOptions: {},
|
|
34
|
+
}) {
|
|
35
|
+
super();
|
|
36
|
+
this.keyboard = keyboard;
|
|
37
|
+
this.camera = camera;
|
|
38
|
+
this.options = options;
|
|
39
|
+
this.tickOrder = gg_entity_1.GGTickOrder.INPUT_CONTROLLERS;
|
|
40
|
+
this.mouseInput = new mouse_input_1.MouseInput(options.mouseOptions);
|
|
41
|
+
this.directionsInput = new direction_keyboard_input_1.DirectionKeyboardInput(keyboard, options.keymap);
|
|
42
|
+
}
|
|
43
|
+
onSpawned(world) {
|
|
44
|
+
const _super = Object.create(null, {
|
|
45
|
+
onSpawned: { get: () => super.onSpawned }
|
|
46
|
+
});
|
|
47
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
48
|
+
yield _super.onSpawned.call(this, world);
|
|
49
|
+
// Subscribe to keyboard input for movement controls
|
|
50
|
+
let controls = { direction: {}, rest: [] };
|
|
51
|
+
const keys = ['KeyE', 'KeyQ'];
|
|
52
|
+
if (this.camera.object3D.supportsFov) {
|
|
53
|
+
keys.push('KeyZ', 'KeyC');
|
|
54
|
+
}
|
|
55
|
+
this.directionsInput.output$.pipe((0, rxjs_1.takeUntil)(this._onRemoved$)).subscribe(d => {
|
|
56
|
+
controls.direction = d;
|
|
57
|
+
});
|
|
58
|
+
(0, rxjs_1.combineLatest)(keys.map(c => this.keyboard.bind(c)))
|
|
59
|
+
.pipe((0, rxjs_1.takeUntil)(this._onRemoved$))
|
|
60
|
+
.subscribe((d) => {
|
|
61
|
+
controls.rest = d;
|
|
62
|
+
});
|
|
63
|
+
// Subscribe to mouse input for camera rotation
|
|
64
|
+
let rotationDelta = { x: 0, y: 0 };
|
|
65
|
+
this.mouseInput.delta$.pipe((0, rxjs_1.takeUntil)(this._onRemoved$)).subscribe(delta => {
|
|
66
|
+
rotationDelta = point2_1.Pnt2.add(rotationDelta, delta);
|
|
67
|
+
});
|
|
68
|
+
// Setup updating camera position and rotation based on input
|
|
69
|
+
this.camera.tick$.pipe((0, rxjs_1.takeUntil)(this._onRemoved$)).subscribe(() => {
|
|
70
|
+
let translateVector = { x: 0, y: 0, z: 0 };
|
|
71
|
+
const [u, d, zo, zi] = controls.rest;
|
|
72
|
+
if (controls.direction.upDown !== undefined)
|
|
73
|
+
translateVector.z = controls.direction.upDown ? -1 : 1;
|
|
74
|
+
if (controls.direction.leftRight !== undefined)
|
|
75
|
+
translateVector.x = controls.direction.leftRight ? -1 : 1;
|
|
76
|
+
if (u != d)
|
|
77
|
+
translateVector.y = d ? -1 : 1;
|
|
78
|
+
if (zo != zi)
|
|
79
|
+
this.camera.object3D.fov += zo ? 1 : -1;
|
|
80
|
+
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));
|
|
81
|
+
if (rotationDelta.x != 0 || rotationDelta.y != 0) {
|
|
82
|
+
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));
|
|
83
|
+
rotationDelta = { x: 0, y: 0 };
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
// start input
|
|
87
|
+
yield this.mouseInput.start();
|
|
88
|
+
yield this.directionsInput.start();
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
onRemoved() {
|
|
92
|
+
const _super = Object.create(null, {
|
|
93
|
+
onRemoved: { get: () => super.onRemoved }
|
|
94
|
+
});
|
|
95
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
96
|
+
yield _super.onRemoved.call(this);
|
|
97
|
+
yield this.mouseInput.stop(true);
|
|
98
|
+
yield this.directionsInput.stop();
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.FreeCameraController = FreeCameraController;
|
|
@@ -3,5 +3,7 @@ import { Gg3dEntity } from './gg-3d-entity';
|
|
|
3
3
|
export declare class Gg3dCameraEntity<T extends IGg3dCamera = IGg3dCamera> extends Gg3dEntity {
|
|
4
4
|
readonly object3D: T;
|
|
5
5
|
readonly objectBody: IGg3dBody | null;
|
|
6
|
+
get fov(): number;
|
|
7
|
+
set fov(value: number);
|
|
6
8
|
constructor(object3D: T, objectBody?: IGg3dBody | null);
|
|
7
9
|
}
|
|
@@ -8,5 +8,11 @@ class Gg3dCameraEntity extends gg_3d_entity_1.Gg3dEntity {
|
|
|
8
8
|
this.object3D = object3D;
|
|
9
9
|
this.objectBody = objectBody;
|
|
10
10
|
}
|
|
11
|
+
get fov() {
|
|
12
|
+
return this.object3D.fov;
|
|
13
|
+
}
|
|
14
|
+
set fov(value) {
|
|
15
|
+
this.object3D.fov = value;
|
|
16
|
+
}
|
|
11
17
|
}
|
|
12
18
|
exports.Gg3dCameraEntity = Gg3dCameraEntity;
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import { Subject } from 'rxjs';
|
|
2
1
|
import { GgPositionable3dEntity } from './gg-positionable-3d-entity';
|
|
3
|
-
import { ITickListener } from '../../base/entities/interfaces/i-tick-listener';
|
|
4
2
|
import { Point3, Point4 } from '../../base/models/points';
|
|
5
3
|
import { Gg3dWorld } from '../gg-3d-world';
|
|
6
4
|
import { IGg3dBody, IGg3dObject } from '../interfaces';
|
|
7
|
-
|
|
5
|
+
import { GGTickOrder } from '../../base/entities/gg-entity';
|
|
6
|
+
export declare class Gg3dEntity extends GgPositionable3dEntity {
|
|
8
7
|
readonly object3D: IGg3dObject | null;
|
|
9
8
|
readonly objectBody: IGg3dBody | null;
|
|
10
|
-
readonly
|
|
11
|
-
readonly tickOrder = 750;
|
|
9
|
+
readonly tickOrder = GGTickOrder.OBJECTS_BINDING;
|
|
12
10
|
get position(): Point3;
|
|
13
11
|
set position(value: Point3);
|
|
14
12
|
get rotation(): Point4;
|
|
@@ -17,7 +15,10 @@ export declare class Gg3dEntity extends GgPositionable3dEntity implements ITickL
|
|
|
17
15
|
set scale(value: Point3);
|
|
18
16
|
get visible(): boolean;
|
|
19
17
|
set visible(value: boolean);
|
|
20
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Synchronize physics body transform with entity (and mesh if defined)
|
|
20
|
+
* */
|
|
21
|
+
protected runTransformBinding(objectBody: IGg3dBody, object3D: IGg3dObject | null): void;
|
|
21
22
|
constructor(object3D: IGg3dObject | null, objectBody?: IGg3dBody | null);
|
|
22
23
|
onSpawned(world: Gg3dWorld): void;
|
|
23
24
|
onRemoved(): void;
|
|
@@ -1,26 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Gg3dEntity = void 0;
|
|
4
|
-
const rxjs_1 = require("rxjs");
|
|
5
4
|
const gg_positionable_3d_entity_1 = require("./gg-positionable-3d-entity");
|
|
5
|
+
const gg_entity_1 = require("../../base/entities/gg-entity");
|
|
6
6
|
class Gg3dEntity extends gg_positionable_3d_entity_1.GgPositionable3dEntity {
|
|
7
7
|
constructor(object3D, objectBody = null) {
|
|
8
8
|
super();
|
|
9
9
|
this.object3D = object3D;
|
|
10
10
|
this.objectBody = objectBody;
|
|
11
|
-
this.
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
this.tickOrder = gg_entity_1.GGTickOrder.OBJECTS_BINDING;
|
|
12
|
+
if (objectBody) {
|
|
13
|
+
objectBody.entity = this;
|
|
14
14
|
this.tick$.subscribe(() => {
|
|
15
15
|
this.runTransformBinding(objectBody, object3D);
|
|
16
16
|
});
|
|
17
17
|
this.runTransformBinding(objectBody, object3D);
|
|
18
|
+
this.name = objectBody.name;
|
|
18
19
|
}
|
|
19
|
-
else if (
|
|
20
|
-
|
|
20
|
+
else if (object3D) {
|
|
21
|
+
super.position = object3D.position;
|
|
22
|
+
super.rotation = object3D.rotation;
|
|
23
|
+
super.scale = object3D.scale;
|
|
24
|
+
this.name = object3D.name;
|
|
21
25
|
}
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
else {
|
|
27
|
+
throw new Error('Cannot create entity without a mesh and a body');
|
|
24
28
|
}
|
|
25
29
|
}
|
|
26
30
|
get position() {
|
|
@@ -68,17 +72,21 @@ class Gg3dEntity extends gg_positionable_3d_entity_1.GgPositionable3dEntity {
|
|
|
68
72
|
this.object3D.visible = value;
|
|
69
73
|
}
|
|
70
74
|
for (const entity of this._children) {
|
|
71
|
-
if (entity instanceof Gg3dEntity
|
|
72
|
-
entity.
|
|
75
|
+
if (entity instanceof Gg3dEntity) {
|
|
76
|
+
entity.visible = value;
|
|
73
77
|
}
|
|
74
78
|
}
|
|
75
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Synchronize physics body transform with entity (and mesh if defined)
|
|
82
|
+
* */
|
|
76
83
|
runTransformBinding(objectBody, object3D) {
|
|
77
|
-
// bind physics body transform to mesh transform
|
|
78
84
|
const pos = objectBody.position;
|
|
79
85
|
const quat = objectBody.rotation;
|
|
80
|
-
object3D
|
|
81
|
-
|
|
86
|
+
if (object3D) {
|
|
87
|
+
object3D.position = pos;
|
|
88
|
+
object3D.rotation = quat;
|
|
89
|
+
}
|
|
82
90
|
this._position$.next(pos);
|
|
83
91
|
this._rotation$.next(quat);
|
|
84
92
|
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { BehaviorSubject, Observable, Subject } from 'rxjs';
|
|
2
2
|
import { Point3, Point4 } from '../../base/models/points';
|
|
3
3
|
import { Graph } from '../../base/data-structures/graph';
|
|
4
|
-
import { GgEntity } from '../../base/entities/gg-entity';
|
|
5
|
-
import { ITickListener } from '../../base/entities/interfaces/i-tick-listener';
|
|
4
|
+
import { GgEntity, GGTickOrder } from '../../base/entities/gg-entity';
|
|
6
5
|
import { GgPositionable3dEntity } from './gg-positionable-3d-entity';
|
|
7
6
|
import { Gg3dWorld } from '../gg-3d-world';
|
|
8
7
|
import { Gg3dEntity } from './gg-3d-entity';
|
|
9
8
|
import { LoadOptions, LoadResultWithProps } from '../loader';
|
|
10
|
-
declare type MapGraphNodeType = {
|
|
9
|
+
export declare type MapGraphNodeType = {
|
|
11
10
|
path: string;
|
|
12
11
|
position: Point3;
|
|
13
12
|
rotation?: Point4;
|
|
@@ -23,29 +22,30 @@ export declare type Gg3dMapGraphEntityOptions = {
|
|
|
23
22
|
loadDepth: number;
|
|
24
23
|
inertia: number;
|
|
25
24
|
};
|
|
26
|
-
export declare class Gg3dMapGraphEntity extends GgEntity
|
|
25
|
+
export declare class Gg3dMapGraphEntity extends GgEntity {
|
|
27
26
|
readonly mapGraph: MapGraph;
|
|
28
|
-
readonly
|
|
29
|
-
readonly tickOrder = 1500;
|
|
27
|
+
readonly tickOrder = GGTickOrder.POST_RENDERING;
|
|
30
28
|
readonly loaderCursorEntity$: BehaviorSubject<GgPositionable3dEntity | null>;
|
|
31
29
|
readonly loaded: Map<MapGraphNodeType, GgPositionable3dEntity[]>;
|
|
32
30
|
private _initialLoadComplete$;
|
|
33
31
|
get initialLoadComplete$(): Observable<boolean>;
|
|
34
32
|
private _nearestDummy$;
|
|
35
33
|
get nearestDummy(): Graph<MapGraphNodeType> | null;
|
|
36
|
-
|
|
34
|
+
protected _chunkLoaded$: Subject<[LoadResultWithProps, {
|
|
35
|
+
position: Point3;
|
|
36
|
+
rotation: Point4;
|
|
37
|
+
}]>;
|
|
37
38
|
get chunkLoaded$(): Observable<[LoadResultWithProps, {
|
|
38
39
|
position: Point3;
|
|
39
40
|
rotation: Point4;
|
|
40
41
|
}]>;
|
|
41
42
|
get world(): Gg3dWorld | null;
|
|
42
43
|
protected _world: Gg3dWorld | null;
|
|
43
|
-
|
|
44
|
+
protected readonly mapGraphNodes: MapGraph[];
|
|
44
45
|
protected readonly options: Gg3dMapGraphEntityOptions;
|
|
45
46
|
constructor(mapGraph: MapGraph, options?: Partial<Gg3dMapGraphEntityOptions>);
|
|
46
47
|
onSpawned(world: Gg3dWorld): void;
|
|
47
48
|
onRemoved(): void;
|
|
48
|
-
protected loadChunk(node: MapGraphNodeType): Promise<Gg3dEntity[]>;
|
|
49
|
+
protected loadChunk(node: MapGraphNodeType): Promise<[Gg3dEntity[], LoadResultWithProps]>;
|
|
49
50
|
protected disposeChunk(node: MapGraphNodeType): void;
|
|
50
51
|
}
|
|
51
|
-
export {};
|
|
@@ -69,8 +69,7 @@ class Gg3dMapGraphEntity extends gg_entity_1.GgEntity {
|
|
|
69
69
|
constructor(mapGraph, options = {}) {
|
|
70
70
|
super();
|
|
71
71
|
this.mapGraph = mapGraph;
|
|
72
|
-
this.
|
|
73
|
-
this.tickOrder = 1500;
|
|
72
|
+
this.tickOrder = gg_entity_1.GGTickOrder.POST_RENDERING;
|
|
74
73
|
this.loaderCursorEntity$ = new rxjs_1.BehaviorSubject(null);
|
|
75
74
|
this.loaded = new Map();
|
|
76
75
|
this._initialLoadComplete$ = new rxjs_1.BehaviorSubject(false);
|
|
@@ -150,7 +149,7 @@ class Gg3dMapGraphEntity extends gg_entity_1.GgEntity {
|
|
|
150
149
|
loaded,
|
|
151
150
|
{ position: node.position, rotation: node.rotation || { x: 0, y: 0, z: 0, w: 1 } },
|
|
152
151
|
]);
|
|
153
|
-
return entities;
|
|
152
|
+
return [entities, loaded];
|
|
154
153
|
});
|
|
155
154
|
}
|
|
156
155
|
disposeChunk(node) {
|
|
@@ -2,6 +2,7 @@ import { Point3, Point4 } from '../../base/models/points';
|
|
|
2
2
|
import { Gg3dEntity } from './gg-3d-entity';
|
|
3
3
|
import { IGg3dBody, IGg3dObject, IGg3dRaycastVehicle } from '../interfaces';
|
|
4
4
|
import { BehaviorSubject, Observable } from 'rxjs';
|
|
5
|
+
import { GgPositionable3dEntity } from './gg-positionable-3d-entity';
|
|
5
6
|
import { Gg3dWorld } from '../gg-3d-world';
|
|
6
7
|
import { AxisDirection3 } from '../../base/models/axis-directions';
|
|
7
8
|
export declare type WheelOptions = {
|
|
@@ -52,9 +53,9 @@ export declare class Gg3dRaycastVehicleEntity extends Gg3dEntity {
|
|
|
52
53
|
readonly chassisBody: IGg3dRaycastVehicle;
|
|
53
54
|
readonly wheelObject: IGg3dObject | null;
|
|
54
55
|
readonly wheelObjectDirection: AxisDirection3;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
protected readonly wheels: (GgPositionable3dEntity | null)[];
|
|
57
|
+
protected readonly wheelLocalRotation: (Point4 | null)[];
|
|
58
|
+
protected readonly wheelLocalTranslation: Point3[];
|
|
58
59
|
protected readonly frontWheelsIndices: number[];
|
|
59
60
|
protected readonly tractionWheelIndices: number[];
|
|
60
61
|
readonly tractionWheelRadius: number;
|
|
@@ -96,8 +97,8 @@ export declare class Gg3dRaycastVehicleEntity extends Gg3dEntity {
|
|
|
96
97
|
constructor(carProperties: CarProperties, chassis3D: IGg3dObject | null, chassisBody: IGg3dRaycastVehicle, wheelObject?: IGg3dObject | null, wheelObjectDirection?: AxisDirection3);
|
|
97
98
|
onSpawned(world: Gg3dWorld): void;
|
|
98
99
|
protected runTransformBinding(objectBody: IGg3dBody, object3D: IGg3dObject): void;
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
protected get isTouchingGround(): boolean;
|
|
101
|
+
protected updateEngine(delta: number): void;
|
|
101
102
|
resetTo(options?: {
|
|
102
103
|
position?: Point3;
|
|
103
104
|
rotation?: Point4;
|
package/dist/3d/gg-3d-world.d.ts
CHANGED
|
@@ -2,10 +2,13 @@ import { GgWorld } from '../base/gg-world';
|
|
|
2
2
|
import { Point3, Point4 } from '../base/models/points';
|
|
3
3
|
import { IGg3dPhysicsWorld, IGg3dVisualScene } from './interfaces';
|
|
4
4
|
import { Gg3dLoader } from './loader';
|
|
5
|
+
import { Gg3dEntity } from './entities/gg-3d-entity';
|
|
6
|
+
import { BodyShape3DDescriptor } from './models/shapes';
|
|
5
7
|
export declare class Gg3dWorld<V extends IGg3dVisualScene = IGg3dVisualScene, P extends IGg3dPhysicsWorld = IGg3dPhysicsWorld> extends GgWorld<Point3, Point4, V, P> {
|
|
6
8
|
readonly visualScene: V;
|
|
7
9
|
readonly physicsWorld: P;
|
|
8
10
|
protected readonly consoleEnabled: boolean;
|
|
9
11
|
readonly loader: Gg3dLoader;
|
|
10
12
|
constructor(visualScene: V, physicsWorld: P, consoleEnabled?: boolean);
|
|
13
|
+
addPrimitiveRigidBody(descr: BodyShape3DDescriptor, position?: Point3, rotation?: Point4): Gg3dEntity;
|
|
11
14
|
}
|
package/dist/3d/gg-3d-world.js
CHANGED
|
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.Gg3dWorld = void 0;
|
|
13
13
|
const gg_world_1 = require("../base/gg-world");
|
|
14
14
|
const loader_1 = require("./loader");
|
|
15
|
+
const gg_3d_entity_1 = require("./entities/gg-3d-entity");
|
|
15
16
|
class Gg3dWorld extends gg_world_1.GgWorld {
|
|
16
17
|
constructor(visualScene, physicsWorld, consoleEnabled = false) {
|
|
17
18
|
super(visualScene, physicsWorld, consoleEnabled);
|
|
@@ -32,5 +33,16 @@ class Gg3dWorld extends gg_world_1.GgWorld {
|
|
|
32
33
|
'{x: 0, y: 0, z: -value}, 3 arguments set the whole vector. Default value is "9.82" or "0 0 -9.82"');
|
|
33
34
|
}
|
|
34
35
|
}
|
|
36
|
+
addPrimitiveRigidBody(descr, position = {
|
|
37
|
+
x: 0,
|
|
38
|
+
y: 0,
|
|
39
|
+
z: 0,
|
|
40
|
+
}, rotation = { x: 0, y: 0, z: 0, w: 1 }) {
|
|
41
|
+
const entity = new gg_3d_entity_1.Gg3dEntity(this.visualScene.factory.createPrimitive(descr.shape), this.physicsWorld.factory.createRigidBody(descr));
|
|
42
|
+
entity.position = position;
|
|
43
|
+
entity.rotation = rotation;
|
|
44
|
+
this.addEntity(entity);
|
|
45
|
+
return entity;
|
|
46
|
+
}
|
|
35
47
|
}
|
|
36
48
|
exports.Gg3dWorld = Gg3dWorld;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BehaviorSubject } from 'rxjs';
|
|
2
|
+
import { Input } from '../../base/inputs/input';
|
|
3
|
+
import { KeyboardInput } from '../../base/inputs/keyboard.input';
|
|
4
|
+
import { Gg3dRaycastVehicleEntity } from '../entities/gg-3d-raycast-vehicle.entity';
|
|
5
|
+
import { DirectionKeyboardInput, DirectionKeyboardKeymap } from '../../base/inputs/direction.keyboard-input';
|
|
6
|
+
export declare type CarKeyboardControllerOptions = {
|
|
7
|
+
keymap: DirectionKeyboardKeymap;
|
|
8
|
+
gearUpDownKeys: [string, string];
|
|
9
|
+
};
|
|
10
|
+
export declare class CarKeyboardInput extends Input {
|
|
11
|
+
protected readonly keyboard: KeyboardInput;
|
|
12
|
+
protected readonly options: CarKeyboardControllerOptions;
|
|
13
|
+
protected readonly directionsInput: DirectionKeyboardInput;
|
|
14
|
+
protected readonly x$: BehaviorSubject<number>;
|
|
15
|
+
protected readonly y$: BehaviorSubject<number>;
|
|
16
|
+
protected lastX: number;
|
|
17
|
+
protected readonly car$: BehaviorSubject<Gg3dRaycastVehicleEntity>;
|
|
18
|
+
set car(value: Gg3dRaycastVehicleEntity);
|
|
19
|
+
get car(): Gg3dRaycastVehicleEntity;
|
|
20
|
+
switchingGearsEnabled: boolean;
|
|
21
|
+
pairTickerPipe: import("rxjs").UnaryFunction<import("rxjs").Observable<number>, import("rxjs").Observable<number>>;
|
|
22
|
+
constructor(keyboard: KeyboardInput, car: Gg3dRaycastVehicleEntity, options?: CarKeyboardControllerOptions);
|
|
23
|
+
protected startInternal(): Promise<void>;
|
|
24
|
+
protected stopInternal(): Promise<void>;
|
|
25
|
+
}
|
|
@@ -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;
|