@gg-web-engine/core 0.0.24 → 0.0.28
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/components/physics/i-rigid-body-2d.component.d.ts +1 -0
- package/dist/2d/gg-2d-world.d.ts +1 -2
- package/dist/2d/gg-2d-world.js +4 -5
- package/dist/3d/components/physics/i-raycast-vehicle.component.d.ts +3 -6
- package/dist/3d/components/physics/i-rigid-body-3d.component.d.ts +1 -0
- package/dist/3d/entities/controllers/input/car-keyboard-handling.controller.d.ts +11 -13
- package/dist/3d/entities/controllers/input/car-keyboard-handling.controller.js +29 -72
- package/dist/3d/entities/controllers/input/gg-car-keyboard-handling.controller.d.ts +18 -0
- package/dist/3d/entities/controllers/input/gg-car-keyboard-handling.controller.js +96 -0
- package/dist/3d/entities/gg-car/gg-car.entity.d.ts +79 -0
- package/dist/3d/entities/gg-car/gg-car.entity.js +228 -0
- package/dist/3d/entities/raycast-vehicle-3d.entity.d.ts +43 -76
- package/dist/3d/entities/raycast-vehicle-3d.entity.js +78 -299
- package/dist/3d/gg-3d-world.d.ts +1 -2
- package/dist/3d/gg-3d-world.js +4 -5
- package/dist/3d/index.d.ts +2 -0
- package/dist/3d/index.js +2 -0
- package/dist/base/components/physics/i-body.component.d.ts +14 -0
- package/dist/base/components/physics/i-body.component.js +1 -0
- package/dist/base/components/physics/i-rigid-body.component.d.ts +4 -11
- package/dist/base/components/physics/i-trigger.component.d.ts +3 -1
- package/dist/base/entities/i-entity.js +1 -1
- package/dist/base/gg-world.d.ts +8 -12
- package/dist/base/gg-world.js +32 -64
- package/dist/base/index.d.ts +2 -3
- package/dist/base/index.js +2 -3
- package/dist/base/math/point2.d.ts +4 -0
- package/dist/base/math/point2.js +8 -0
- package/dist/base/math/point3.d.ts +6 -0
- package/dist/base/math/point3.js +12 -0
- package/dist/base/math/splines.d.ts +1 -0
- package/dist/base/math/splines.js +7 -0
- package/dist/{base/ui → dev}/gg-console.ui.d.ts +1 -4
- package/dist/{base/ui → dev}/gg-console.ui.js +35 -17
- package/dist/dev/gg-debugger.ui.d.ts +11 -0
- package/dist/dev/gg-debugger.ui.js +111 -0
- package/dist/dev/gg-static.d.ts +32 -0
- package/dist/dev/gg-static.js +141 -0
- package/dist/dev/index.d.ts +3 -0
- package/dist/dev/index.js +3 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
- package/dist/base/gg-static.d.ts +0 -9
- package/dist/base/gg-static.js +0 -36
- package/dist/base/ui/gg-debugger.ui.d.ts +0 -10
- package/dist/base/ui/gg-debugger.ui.js +0 -61
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { IEntity } from '../../entities/i-entity';
|
|
2
|
+
import { IPhysicsWorldComponent } from './i-physics-world.component';
|
|
3
|
+
import { IWorldComponent } from '../i-world-component';
|
|
4
|
+
import { GgWorld } from '../../gg-world';
|
|
5
|
+
import { IVisualSceneComponent } from '../rendering/i-visual-scene.component';
|
|
6
|
+
export interface IBodyComponent<D, R, PW extends IPhysicsWorldComponent<D, R> = IPhysicsWorldComponent<D, R>> extends IWorldComponent<D, R, IVisualSceneComponent<D, R>, PW> {
|
|
7
|
+
entity: IEntity | null;
|
|
8
|
+
position: D;
|
|
9
|
+
rotation: R;
|
|
10
|
+
name: string;
|
|
11
|
+
clone(): IBodyComponent<D, R, PW>;
|
|
12
|
+
addToWorld(world: GgWorld<D, R, IVisualSceneComponent<D, R>, PW>): void;
|
|
13
|
+
removeFromWorld(world: GgWorld<D, R, IVisualSceneComponent<D, R>, PW>): void;
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,16 +1,9 @@
|
|
|
1
|
-
import { IEntity } from '../../entities/i-entity';
|
|
2
1
|
import { IPhysicsWorldComponent } from './i-physics-world.component';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
entity: IEntity | null;
|
|
8
|
-
position: D;
|
|
9
|
-
rotation: R;
|
|
10
|
-
name: string;
|
|
2
|
+
import { IBodyComponent } from './i-body.component';
|
|
3
|
+
export interface IRigidBodyComponent<D, R, PW extends IPhysicsWorldComponent<D, R> = IPhysicsWorldComponent<D, R>> extends IBodyComponent<D, R, PW> {
|
|
4
|
+
linearVelocity: D;
|
|
5
|
+
angularVelocity: R | D;
|
|
11
6
|
clone(): IRigidBodyComponent<D, R, PW>;
|
|
12
|
-
addToWorld(world: GgWorld<D, R, IVisualSceneComponent<D, R>, PW>): void;
|
|
13
|
-
removeFromWorld(world: GgWorld<D, R, IVisualSceneComponent<D, R>, PW>): void;
|
|
14
7
|
/** clear velocities etc. */
|
|
15
8
|
resetMotion(): void;
|
|
16
9
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Observable } from 'rxjs';
|
|
2
2
|
import { IRigidBodyComponent } from './i-rigid-body.component';
|
|
3
3
|
import { IPhysicsWorldComponent } from './i-physics-world.component';
|
|
4
|
-
|
|
4
|
+
import { IBodyComponent } from './i-body.component';
|
|
5
|
+
export interface ITriggerComponent<D, R, PW extends IPhysicsWorldComponent<D, R> = IPhysicsWorldComponent<D, R>> extends IBodyComponent<D, R, PW> {
|
|
5
6
|
get onEntityEntered(): Observable<IRigidBodyComponent<D, R>>;
|
|
6
7
|
get onEntityLeft(): Observable<IRigidBodyComponent<D, R> | null>;
|
|
8
|
+
clone(): ITriggerComponent<D, R, PW>;
|
|
7
9
|
checkOverlaps(): void;
|
|
8
10
|
}
|
|
@@ -22,7 +22,7 @@ export class IEntity {
|
|
|
22
22
|
* a world reference, where this entity was added to
|
|
23
23
|
*/
|
|
24
24
|
this._world = null;
|
|
25
|
-
this._name = '
|
|
25
|
+
this._name = 'e0x' + (IEntity.default_name_counter++).toString(16);
|
|
26
26
|
/**
|
|
27
27
|
* The flag whether entity should listen to ticks. If set to false, ticks will not be propagated to this entity
|
|
28
28
|
* */
|
package/dist/base/gg-world.d.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import { IEntity, IPhysicsWorldComponent,
|
|
1
|
+
import { IEntity, IPhysicsWorldComponent, IPositionable, IRenderableEntity, IVisualSceneComponent, KeyboardInput, PausableClock } from '../base';
|
|
2
2
|
export declare abstract class GgWorld<D, R, V extends IVisualSceneComponent<D, R> = IVisualSceneComponent<D, R>, P extends IPhysicsWorldComponent<D, R> = IPhysicsWorldComponent<D, R>> {
|
|
3
3
|
readonly visualScene: V;
|
|
4
4
|
readonly physicsWorld: P;
|
|
5
|
-
protected readonly consoleEnabled: boolean;
|
|
6
5
|
readonly worldClock: PausableClock;
|
|
7
6
|
readonly keyboardInput: KeyboardInput;
|
|
7
|
+
private static default_name_counter;
|
|
8
|
+
name: string;
|
|
8
9
|
readonly children: IEntity[];
|
|
9
10
|
protected readonly tickListeners: IEntity[];
|
|
10
|
-
|
|
11
|
+
private static _documentWorlds;
|
|
12
|
+
static get documentWorlds(): GgWorld<any, any>[];
|
|
13
|
+
protected constructor(visualScene: V, physicsWorld: P);
|
|
11
14
|
init(): Promise<void>;
|
|
12
15
|
start(): void;
|
|
13
16
|
pauseWorld(): void;
|
|
@@ -20,13 +23,6 @@ export declare abstract class GgWorld<D, R, V extends IVisualSceneComponent<D, R
|
|
|
20
23
|
abstract addPrimitiveRigidBody(descr: any, position?: D, rotation?: R): IPositionable<D, R> & IRenderableEntity<D, R, V, P>;
|
|
21
24
|
addEntity(entity: IEntity): void;
|
|
22
25
|
removeEntity(entity: IEntity, dispose?: boolean): void;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
handler: (...args: string[]) => Promise<string>;
|
|
26
|
-
doc?: string;
|
|
27
|
-
};
|
|
28
|
-
};
|
|
29
|
-
registerConsoleCommand(command: string, handler: (...args: string[]) => Promise<string>, doc?: string): void;
|
|
30
|
-
runConsoleCommand(command: string, args: string[]): Promise<string>;
|
|
31
|
-
triggerPhysicsDebugView(): void;
|
|
26
|
+
get physicsDebugViewActive(): boolean;
|
|
27
|
+
set physicsDebugViewActive(value: boolean);
|
|
32
28
|
}
|
package/dist/base/gg-world.js
CHANGED
|
@@ -7,67 +7,41 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import {
|
|
11
|
-
import { filter } from 'rxjs';
|
|
10
|
+
import { GgGlobalClock, KeyboardInput, TickOrder, } from '../base';
|
|
12
11
|
export class GgWorld {
|
|
13
|
-
constructor(visualScene, physicsWorld
|
|
12
|
+
constructor(visualScene, physicsWorld) {
|
|
14
13
|
this.visualScene = visualScene;
|
|
15
14
|
this.physicsWorld = physicsWorld;
|
|
16
|
-
this.consoleEnabled = consoleEnabled;
|
|
17
15
|
this.worldClock = GgGlobalClock.instance.createChildClock(false);
|
|
18
16
|
this.keyboardInput = new KeyboardInput();
|
|
17
|
+
this.name = 'w0x' + (GgWorld.default_name_counter++).toString(16);
|
|
19
18
|
this.children = [];
|
|
20
19
|
// the same as children, but sorted by tick order
|
|
21
20
|
this.tickListeners = [];
|
|
22
|
-
this
|
|
23
|
-
GgStatic.instance.worlds.push(this);
|
|
24
|
-
GgStatic.instance.selectedWorld = this;
|
|
21
|
+
GgWorld._documentWorlds.push(this);
|
|
25
22
|
this.keyboardInput.start();
|
|
26
|
-
if (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
.pipe(filter(x => x))
|
|
31
|
-
.subscribe(() => {
|
|
32
|
-
// open console UI
|
|
33
|
-
if (GgConsoleUI.instance.isUIShown) {
|
|
34
|
-
GgConsoleUI.instance.destroyUI();
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
GgConsoleUI.instance.createUI();
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
this.registerConsoleCommand('commandslist', () => __awaiter(this, void 0, void 0, function* () {
|
|
41
|
-
return Object.entries(this.commands)
|
|
42
|
-
.map(([key, value]) => `${key}${value.doc ? '\t// ' + value.doc : ''}`)
|
|
43
|
-
.sort()
|
|
44
|
-
.join('\n\n');
|
|
45
|
-
}), 'no args; print all available commands');
|
|
46
|
-
this.registerConsoleCommand('debugger', (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
47
|
-
const shouldDraw = ['1', 'true', '+'].includes(args[0]);
|
|
48
|
-
if (shouldDraw != GgDebuggerUI.instance.isUIShown) {
|
|
49
|
-
if (GgDebuggerUI.instance.isUIShown) {
|
|
50
|
-
GgDebuggerUI.instance.destroyUI();
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
GgDebuggerUI.instance.createUI();
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return '' + GgDebuggerUI.instance.isUIShown;
|
|
23
|
+
if (window.ggstatic) {
|
|
24
|
+
window.ggstatic.registerConsoleCommand(this, 'show_debugger', (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
25
|
+
window.ggstatic.showDebugControls = ['1', 'true', '+'].includes(args[0]);
|
|
26
|
+
return '' + window.ggstatic.showDebugControls;
|
|
57
27
|
}), 'args: [0 or 1]; turn on/off debug panel. Default value is 0');
|
|
58
|
-
|
|
28
|
+
window.ggstatic.registerConsoleCommand(this, 'show_stats', (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
29
|
+
window.ggstatic.showStats = ['1', 'true', '+'].includes(args[0]);
|
|
30
|
+
return '' + window.ggstatic.showStats;
|
|
31
|
+
}), 'args: [0 or 1]; turn on/off stats. Default value is 0');
|
|
32
|
+
window.ggstatic.registerConsoleCommand(this, 'ph_timescale', (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
59
33
|
this.physicsWorld.timeScale = +args[0];
|
|
60
34
|
return JSON.stringify(this.physicsWorld.timeScale);
|
|
61
35
|
}), 'args: [float]; change time scale of physics engine. Default value is 1.0');
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (shouldDraw != this.physicsWorld.physicsDebugViewActive) {
|
|
65
|
-
this.triggerPhysicsDebugView();
|
|
66
|
-
}
|
|
36
|
+
window.ggstatic.registerConsoleCommand(this, 'dr_drawphysics', (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
this.physicsDebugViewActive = ['1', 'true', '+'].includes(args[0]);
|
|
67
38
|
return '' + this.physicsWorld.physicsDebugViewActive;
|
|
68
39
|
}), 'args: [0 or 1]; turn on/off physics debug view. Default value is 0');
|
|
69
40
|
}
|
|
70
41
|
}
|
|
42
|
+
static get documentWorlds() {
|
|
43
|
+
return [...GgWorld._documentWorlds];
|
|
44
|
+
}
|
|
71
45
|
init() {
|
|
72
46
|
return __awaiter(this, void 0, void 0, function* () {
|
|
73
47
|
yield Promise.all([this.physicsWorld.init(), this.visualScene.init()]);
|
|
@@ -115,6 +89,9 @@ export class GgWorld {
|
|
|
115
89
|
return this.worldClock.createChildClock(autoStart);
|
|
116
90
|
}
|
|
117
91
|
dispose() {
|
|
92
|
+
if (window.ggstatic) {
|
|
93
|
+
window.ggstatic.deregisterWorldCommands(this);
|
|
94
|
+
}
|
|
118
95
|
this.worldClock.stop();
|
|
119
96
|
this.keyboardInput.stop();
|
|
120
97
|
for (let i = 0; i < this.children.length; i++) {
|
|
@@ -149,33 +126,24 @@ export class GgWorld {
|
|
|
149
126
|
entity.dispose();
|
|
150
127
|
}
|
|
151
128
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
throw new Error('Console not enabled for this world');
|
|
155
|
-
}
|
|
156
|
-
this.commands[command] = { handler, doc };
|
|
129
|
+
get physicsDebugViewActive() {
|
|
130
|
+
return this.physicsWorld.physicsDebugViewActive;
|
|
157
131
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
throw new Error('Console not enabled for this world');
|
|
162
|
-
}
|
|
163
|
-
if (!this.commands[command]) {
|
|
164
|
-
return 'Unrecognized command: ' + command;
|
|
165
|
-
}
|
|
166
|
-
return this.commands[command].handler(...args);
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
triggerPhysicsDebugView() {
|
|
170
|
-
if (this.physicsWorld.physicsDebugViewActive) {
|
|
171
|
-
this.physicsWorld.stopDebugger(this);
|
|
132
|
+
set physicsDebugViewActive(value) {
|
|
133
|
+
if (this.physicsDebugViewActive === value) {
|
|
134
|
+
return;
|
|
172
135
|
}
|
|
173
|
-
|
|
136
|
+
if (value) {
|
|
174
137
|
const cls = this.visualScene.debugPhysicsDrawerClass;
|
|
175
138
|
if (!cls) {
|
|
176
139
|
throw new Error('Debug drawer is not available');
|
|
177
140
|
}
|
|
178
141
|
this.physicsWorld.startDebugger(this, new cls());
|
|
179
142
|
}
|
|
143
|
+
else {
|
|
144
|
+
this.physicsWorld.stopDebugger(this);
|
|
145
|
+
}
|
|
180
146
|
}
|
|
181
147
|
}
|
|
148
|
+
GgWorld.default_name_counter = 0;
|
|
149
|
+
GgWorld._documentWorlds = [];
|
package/dist/base/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from './clock/global-clock';
|
|
2
2
|
export * from './clock/i-clock';
|
|
3
3
|
export * from './clock/pausable-clock';
|
|
4
|
+
export * from './components/physics/i-body.component';
|
|
4
5
|
export * from './components/physics/i-rigid-body.component';
|
|
5
6
|
export * from './components/physics/i-trigger.component';
|
|
6
7
|
export * from './components/physics/i-physics-world.component';
|
|
@@ -31,7 +32,5 @@ export * from './math/point3';
|
|
|
31
32
|
export * from './math/quaternion';
|
|
32
33
|
export * from './math/numbers';
|
|
33
34
|
export * from './math/matrix4';
|
|
34
|
-
export * from './
|
|
35
|
-
export * from './ui/gg-debugger.ui';
|
|
36
|
-
export * from './gg-static';
|
|
35
|
+
export * from './math/splines';
|
|
37
36
|
export * from './gg-world';
|
package/dist/base/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from './clock/global-clock';
|
|
2
2
|
export * from './clock/i-clock';
|
|
3
3
|
export * from './clock/pausable-clock';
|
|
4
|
+
export * from './components/physics/i-body.component';
|
|
4
5
|
export * from './components/physics/i-rigid-body.component';
|
|
5
6
|
export * from './components/physics/i-trigger.component';
|
|
6
7
|
export * from './components/physics/i-physics-world.component';
|
|
@@ -31,7 +32,5 @@ export * from './math/point3';
|
|
|
31
32
|
export * from './math/quaternion';
|
|
32
33
|
export * from './math/numbers';
|
|
33
34
|
export * from './math/matrix4';
|
|
34
|
-
export * from './
|
|
35
|
-
export * from './ui/gg-debugger.ui';
|
|
36
|
-
export * from './gg-static';
|
|
35
|
+
export * from './math/splines';
|
|
37
36
|
export * from './gg-world';
|
|
@@ -6,6 +6,10 @@ export declare class Pnt2 {
|
|
|
6
6
|
static get X(): Point2;
|
|
7
7
|
/** basis Y vector */
|
|
8
8
|
static get Y(): Point2;
|
|
9
|
+
/** basis -X vector */
|
|
10
|
+
static get nX(): Point2;
|
|
11
|
+
/** basis -Y vector */
|
|
12
|
+
static get nY(): Point2;
|
|
9
13
|
/** clone point */
|
|
10
14
|
static clone(p: Point2): Point2;
|
|
11
15
|
/** add point b to point a */
|
package/dist/base/math/point2.js
CHANGED
|
@@ -11,6 +11,14 @@ export class Pnt2 {
|
|
|
11
11
|
static get Y() {
|
|
12
12
|
return { x: 0, y: 1 };
|
|
13
13
|
}
|
|
14
|
+
/** basis -X vector */
|
|
15
|
+
static get nX() {
|
|
16
|
+
return { x: -1, y: 0 };
|
|
17
|
+
}
|
|
18
|
+
/** basis -Y vector */
|
|
19
|
+
static get nY() {
|
|
20
|
+
return { x: 0, y: -1 };
|
|
21
|
+
}
|
|
14
22
|
/** clone point */
|
|
15
23
|
static clone(p) {
|
|
16
24
|
return { x: p.x, y: p.y };
|
|
@@ -8,6 +8,12 @@ export declare class Pnt3 {
|
|
|
8
8
|
static get Y(): Point3;
|
|
9
9
|
/** basis Z vector */
|
|
10
10
|
static get Z(): Point3;
|
|
11
|
+
/** basis -X vector */
|
|
12
|
+
static get nX(): Point3;
|
|
13
|
+
/** basis -Y vector */
|
|
14
|
+
static get nY(): Point3;
|
|
15
|
+
/** basis -Z vector */
|
|
16
|
+
static get nZ(): Point3;
|
|
11
17
|
/** clone point */
|
|
12
18
|
static clone(p: Point3): Point3;
|
|
13
19
|
/** add point b to point a */
|
package/dist/base/math/point3.js
CHANGED
|
@@ -16,6 +16,18 @@ export class Pnt3 {
|
|
|
16
16
|
static get Z() {
|
|
17
17
|
return { x: 0, y: 0, z: 1 };
|
|
18
18
|
}
|
|
19
|
+
/** basis -X vector */
|
|
20
|
+
static get nX() {
|
|
21
|
+
return { x: -1, y: 0, z: 0 };
|
|
22
|
+
}
|
|
23
|
+
/** basis -Y vector */
|
|
24
|
+
static get nY() {
|
|
25
|
+
return { x: 0, y: -1, z: 0 };
|
|
26
|
+
}
|
|
27
|
+
/** basis -Z vector */
|
|
28
|
+
static get nZ() {
|
|
29
|
+
return { x: 0, y: 0, z: -1 };
|
|
30
|
+
}
|
|
19
31
|
/** clone point */
|
|
20
32
|
static clone(p) {
|
|
21
33
|
return { x: p.x, y: p.y, z: p.z };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const cubicSplineInterpolation: (x: number, x0: number, x1: number, y0: number, y1: number, m0: number, m1: number) => number;
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
export declare class GgConsoleUI {
|
|
2
|
-
private static _instance;
|
|
3
|
-
static get instance(): GgConsoleUI;
|
|
4
|
-
private constructor();
|
|
5
2
|
private output;
|
|
6
3
|
private commandHistory;
|
|
7
4
|
private currentCommandIndex;
|
|
8
5
|
elements: {
|
|
9
6
|
main: HTMLDivElement;
|
|
10
7
|
input: HTMLInputElement;
|
|
11
|
-
output:
|
|
8
|
+
output: HTMLDivElement;
|
|
12
9
|
} | null;
|
|
13
10
|
get isUIShown(): boolean;
|
|
14
11
|
createUI(): void;
|
|
@@ -7,7 +7,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { GgStatic } from '../gg-static';
|
|
11
10
|
export class GgConsoleUI {
|
|
12
11
|
constructor() {
|
|
13
12
|
this.output = `
|
|
@@ -25,18 +24,11 @@ export class GgConsoleUI {
|
|
|
25
24
|
Welcome to GG web engine UI console.
|
|
26
25
|
Enter command in input below.
|
|
27
26
|
|
|
28
|
-
List of available commands:
|
|
29
|
-
`;
|
|
27
|
+
List of available commands: `.replace(/ /g, ' ') + `<span style="color:yellow">ls_commands</span>`;
|
|
30
28
|
this.commandHistory = [];
|
|
31
29
|
this.currentCommandIndex = 0; // for repeating command using up/down arrow keys
|
|
32
30
|
this.elements = null;
|
|
33
31
|
}
|
|
34
|
-
static get instance() {
|
|
35
|
-
if (!this._instance) {
|
|
36
|
-
this._instance = new GgConsoleUI();
|
|
37
|
-
}
|
|
38
|
-
return this._instance;
|
|
39
|
-
}
|
|
40
32
|
get isUIShown() {
|
|
41
33
|
return !!this.elements;
|
|
42
34
|
}
|
|
@@ -46,28 +38,34 @@ List of available commands: commandslist
|
|
|
46
38
|
}
|
|
47
39
|
const main = document.createElement('div');
|
|
48
40
|
main.innerHTML = `
|
|
49
|
-
<div id=
|
|
50
|
-
|
|
51
|
-
|
|
41
|
+
<div id='gg-console-header' style='padding: 0.2rem 0.2rem 0;cursor:move;display:flex;justify-content:space-between;'>
|
|
42
|
+
<span>CONSOLE</span>
|
|
43
|
+
<a id='gg-console-close-icon' style='display:block;padding:0.3rem;margin:-0.3rem;cursor:pointer;color:white;'>X</a>
|
|
44
|
+
</div>
|
|
45
|
+
<div id='gg-console-output' style='flex-grow:1;background:#232323;color:white;font-family:monospace;overflow-y:auto;overflow-wrap:anywhere;padding:0.2rem;'></div>
|
|
46
|
+
<input id='gg-console-input' style='background:#000000;border:none;outline:none;color:white;font-family:monospace;'/>`;
|
|
52
47
|
main.style.position = 'absolute';
|
|
53
48
|
main.style.zIndex = '1000';
|
|
54
|
-
main.style.backgroundColor = '#
|
|
55
|
-
main.style.border = '1px solid white';
|
|
49
|
+
main.style.backgroundColor = '#343434';
|
|
56
50
|
main.style.width = '640px';
|
|
57
51
|
main.style.height = '480px';
|
|
58
52
|
main.style.display = 'flex';
|
|
59
53
|
main.style.flexDirection = 'column';
|
|
60
54
|
main.style.alignItems = 'stretch';
|
|
61
|
-
main.style.padding = '
|
|
55
|
+
main.style.padding = '0.1rem';
|
|
62
56
|
main.style.rowGap = '3px';
|
|
57
|
+
main.style.fontSize = '14px';
|
|
63
58
|
main.style.fontFamily = 'monospace';
|
|
59
|
+
main.style.fontWeight = 'bold';
|
|
64
60
|
main.style.color = 'white';
|
|
61
|
+
main.style.textAlign = 'left';
|
|
65
62
|
document.body.append(main);
|
|
66
63
|
this.elements = {
|
|
67
64
|
main,
|
|
68
65
|
input: document.getElementById('gg-console-input'),
|
|
69
66
|
output: document.getElementById('gg-console-output'),
|
|
70
67
|
};
|
|
68
|
+
document.getElementById('gg-console-close-icon').onmousedown = () => this.destroyUI();
|
|
71
69
|
this.elements.input.onkeydown = event => {
|
|
72
70
|
if ((event === null || event === void 0 ? void 0 : event.keyCode) === 13) {
|
|
73
71
|
event.preventDefault();
|
|
@@ -82,6 +80,22 @@ List of available commands: commandslist
|
|
|
82
80
|
this.onUseNextCommand();
|
|
83
81
|
}
|
|
84
82
|
};
|
|
83
|
+
this.elements.input.oninput = event => {
|
|
84
|
+
var _a;
|
|
85
|
+
let value = ((_a = this.elements) === null || _a === void 0 ? void 0 : _a.input.value) || '';
|
|
86
|
+
// backspace
|
|
87
|
+
if (value.length > 0 && event.data === null) {
|
|
88
|
+
value = value.substring(0, value.length - 1);
|
|
89
|
+
}
|
|
90
|
+
if (value.trim() === '') {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
let autocompletion = window.ggstatic.availableCommands.find((c) => c[0].startsWith(value));
|
|
94
|
+
if (autocompletion) {
|
|
95
|
+
this.elements.input.value = autocompletion[0];
|
|
96
|
+
this.elements.input.setSelectionRange(value.length, this.elements.input.value.length);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
85
99
|
this.stdout();
|
|
86
100
|
this.setupDragging();
|
|
87
101
|
setTimeout(() => this.elements.input.focus(), 20);
|
|
@@ -115,14 +129,14 @@ List of available commands: commandslist
|
|
|
115
129
|
const command = this.elements.input.value;
|
|
116
130
|
this.elements.input.value = '';
|
|
117
131
|
this.stdout('\n> ' + command);
|
|
118
|
-
this.stdout('\n' + (yield
|
|
132
|
+
this.stdout('\n' + (yield window.ggstatic.console(command)));
|
|
119
133
|
this.commandHistory.push(command);
|
|
120
134
|
this.currentCommandIndex = this.commandHistory.length;
|
|
121
135
|
});
|
|
122
136
|
}
|
|
123
137
|
stdout(s = '') {
|
|
124
138
|
this.output += s;
|
|
125
|
-
this.elements.output.
|
|
139
|
+
this.elements.output.innerHTML = this.output.replace(/\n/g, '<br>');
|
|
126
140
|
this.elements.output.scrollTop = this.elements.output.scrollHeight;
|
|
127
141
|
}
|
|
128
142
|
setupDragging() {
|
|
@@ -138,6 +152,10 @@ List of available commands: commandslist
|
|
|
138
152
|
document.onmousemove = elementDrag;
|
|
139
153
|
};
|
|
140
154
|
const elementDrag = (e) => {
|
|
155
|
+
if (!this.elements) {
|
|
156
|
+
closeDragElement();
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
141
159
|
e.preventDefault();
|
|
142
160
|
// calculate the new cursor position:
|
|
143
161
|
const curX = x - e.clientX;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { GgWorld } from '../base';
|
|
2
|
+
export declare class GgDebuggerUI {
|
|
3
|
+
private ui;
|
|
4
|
+
private statsRemoved$;
|
|
5
|
+
get showStats(): boolean;
|
|
6
|
+
private currentWorld;
|
|
7
|
+
setShowStats(selectedWorld: GgWorld<any, any>, value: boolean): void;
|
|
8
|
+
private debugControlsRemoved$;
|
|
9
|
+
get showDebugControls(): boolean;
|
|
10
|
+
setShowDebugControls(selectedWorld: GgWorld<any, any>, value: boolean): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { createInlineTickController } from '../base';
|
|
2
|
+
import { fromEvent, Subject, takeUntil } from 'rxjs';
|
|
3
|
+
import Stats from 'stats.js';
|
|
4
|
+
export class GgDebuggerUI {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.ui = {
|
|
7
|
+
stats: null,
|
|
8
|
+
debugControlsContainer: null,
|
|
9
|
+
};
|
|
10
|
+
this.statsRemoved$ = new Subject();
|
|
11
|
+
this.currentWorld = null;
|
|
12
|
+
this.debugControlsRemoved$ = new Subject();
|
|
13
|
+
}
|
|
14
|
+
get showStats() {
|
|
15
|
+
return !!this.ui.stats;
|
|
16
|
+
}
|
|
17
|
+
setShowStats(selectedWorld, value) {
|
|
18
|
+
if (value === this.showStats) {
|
|
19
|
+
if (value && this.currentWorld !== selectedWorld) {
|
|
20
|
+
this.setShowStats(this.currentWorld, false);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
this.currentWorld = selectedWorld;
|
|
27
|
+
if (value) {
|
|
28
|
+
const stats = new Stats();
|
|
29
|
+
this.ui.stats = stats;
|
|
30
|
+
stats.dom.style.left = 'unset';
|
|
31
|
+
stats.dom.style.right = '0';
|
|
32
|
+
stats.showPanel(0); // 0: fps, 1: ms, 2: mb
|
|
33
|
+
document.body.appendChild(stats.dom);
|
|
34
|
+
createInlineTickController(selectedWorld, -1)
|
|
35
|
+
.pipe(takeUntil(this.statsRemoved$))
|
|
36
|
+
.subscribe(() => {
|
|
37
|
+
stats === null || stats === void 0 ? void 0 : stats.begin();
|
|
38
|
+
});
|
|
39
|
+
createInlineTickController(selectedWorld, 10000)
|
|
40
|
+
.pipe(takeUntil(this.statsRemoved$))
|
|
41
|
+
.subscribe(() => {
|
|
42
|
+
stats === null || stats === void 0 ? void 0 : stats.end();
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
this.statsRemoved$.next();
|
|
47
|
+
document.body.removeChild(this.ui.stats.dom);
|
|
48
|
+
this.ui.stats.end();
|
|
49
|
+
this.ui.stats = null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
get showDebugControls() {
|
|
53
|
+
return !!this.ui.debugControlsContainer;
|
|
54
|
+
}
|
|
55
|
+
setShowDebugControls(selectedWorld, value) {
|
|
56
|
+
if (value === this.showDebugControls) {
|
|
57
|
+
if (value && this.currentWorld !== selectedWorld) {
|
|
58
|
+
this.setShowDebugControls(this.currentWorld, false);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
this.currentWorld = selectedWorld;
|
|
65
|
+
if (value) {
|
|
66
|
+
const debugControlsContainer = document.createElement('div');
|
|
67
|
+
this.ui.debugControlsContainer = debugControlsContainer;
|
|
68
|
+
const debugLabelCss = "style='display:flex;align-items:center;margin:0.25rem;'";
|
|
69
|
+
debugControlsContainer.style.cssText =
|
|
70
|
+
'position:fixed;top:48px;right:0;opacity:0.9;z-index:9999;background-color:#333;color:white;display:flex;flex-direction:column';
|
|
71
|
+
debugControlsContainer.innerHTML = `
|
|
72
|
+
<div ${debugLabelCss}>
|
|
73
|
+
<input type='checkbox' name='checkbox' id='physics_debugger_checkbox_id' value='1'${this.currentWorld.physicsWorld.physicsDebugViewActive ? ' checked' : ''}>
|
|
74
|
+
<label for='physics_debugger_checkbox_id' style='user-select: none;'>Show physics bodies in scene</label>
|
|
75
|
+
</div>`;
|
|
76
|
+
// <div ${debugLabelCss}>
|
|
77
|
+
// <input id="time_scale_slider" type="range" min="0" max="10" step="0.1" style="flex-grow:1" value="${
|
|
78
|
+
// this.currentWorld.physicsWorld.timeScale
|
|
79
|
+
// }"/>
|
|
80
|
+
// <label for="time_scale_slider" style="user-select: none;">Time scale</label>
|
|
81
|
+
// </div>`;
|
|
82
|
+
document.body.appendChild(debugControlsContainer);
|
|
83
|
+
fromEvent(document.getElementById('physics_debugger_checkbox_id'), 'change')
|
|
84
|
+
.pipe(takeUntil(this.debugControlsRemoved$))
|
|
85
|
+
.subscribe(e => {
|
|
86
|
+
try {
|
|
87
|
+
this.currentWorld.physicsDebugViewActive = e.target.checked;
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
console.error(err);
|
|
91
|
+
}
|
|
92
|
+
e.target.checked = this.currentWorld.physicsDebugViewActive;
|
|
93
|
+
});
|
|
94
|
+
// fromEvent(document.getElementById('time_scale_slider')! as HTMLInputElement, 'change')
|
|
95
|
+
// .pipe(takeUntil(this.debugControlsRemoved$))
|
|
96
|
+
// .subscribe(e => {
|
|
97
|
+
// try {
|
|
98
|
+
// this.currentWorld.physicsWorld.timeScale = +(e.target as HTMLInputElement).value;
|
|
99
|
+
// } catch (err) {
|
|
100
|
+
// console.error(err);
|
|
101
|
+
// }
|
|
102
|
+
// (e.target as HTMLInputElement).value = '' + ( this.currentWorld.physicsWorld.timeScale || 1);
|
|
103
|
+
// });
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
this.debugControlsRemoved$.next();
|
|
107
|
+
document.body.removeChild(this.ui.debugControlsContainer);
|
|
108
|
+
this.ui.debugControlsContainer = null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { GgWorld } from '../base';
|
|
2
|
+
export declare class GgStatic {
|
|
3
|
+
private static _instance;
|
|
4
|
+
static get instance(): GgStatic;
|
|
5
|
+
private readonly debuggerUI;
|
|
6
|
+
private readonly consoleUI;
|
|
7
|
+
private _devConsoleEnabled;
|
|
8
|
+
get devConsoleEnabled(): boolean;
|
|
9
|
+
consoleKeyPressEventListener: (event: KeyboardEvent) => void;
|
|
10
|
+
set devConsoleEnabled(value: boolean);
|
|
11
|
+
get showStats(): boolean;
|
|
12
|
+
set showStats(value: boolean);
|
|
13
|
+
get showDebugControls(): boolean;
|
|
14
|
+
set showDebugControls(value: boolean);
|
|
15
|
+
private _selectedWorld;
|
|
16
|
+
get selectedWorld(): GgWorld<any, any> | null;
|
|
17
|
+
get availableCommands(): [string, {
|
|
18
|
+
handler: (...args: string[]) => Promise<string>;
|
|
19
|
+
doc?: string;
|
|
20
|
+
}][];
|
|
21
|
+
private constructor();
|
|
22
|
+
protected consoleCommands: Map<GgWorld<any, any> | null, {
|
|
23
|
+
[key: string]: {
|
|
24
|
+
handler: (...args: string[]) => Promise<string>;
|
|
25
|
+
doc?: string;
|
|
26
|
+
};
|
|
27
|
+
}>;
|
|
28
|
+
registerConsoleCommand(world: GgWorld<any, any> | null, command: string, handler: (...args: string[]) => Promise<string>, doc?: string): void;
|
|
29
|
+
deregisterWorldCommands(world: GgWorld<any, any> | null): void;
|
|
30
|
+
console(input: string): Promise<string>;
|
|
31
|
+
runConsoleCommand(command: string, args: string[]): Promise<string>;
|
|
32
|
+
}
|