@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.
Files changed (47) hide show
  1. package/dist/2d/components/physics/i-rigid-body-2d.component.d.ts +1 -0
  2. package/dist/2d/gg-2d-world.d.ts +1 -2
  3. package/dist/2d/gg-2d-world.js +4 -5
  4. package/dist/3d/components/physics/i-raycast-vehicle.component.d.ts +3 -6
  5. package/dist/3d/components/physics/i-rigid-body-3d.component.d.ts +1 -0
  6. package/dist/3d/entities/controllers/input/car-keyboard-handling.controller.d.ts +11 -13
  7. package/dist/3d/entities/controllers/input/car-keyboard-handling.controller.js +29 -72
  8. package/dist/3d/entities/controllers/input/gg-car-keyboard-handling.controller.d.ts +18 -0
  9. package/dist/3d/entities/controllers/input/gg-car-keyboard-handling.controller.js +96 -0
  10. package/dist/3d/entities/gg-car/gg-car.entity.d.ts +79 -0
  11. package/dist/3d/entities/gg-car/gg-car.entity.js +228 -0
  12. package/dist/3d/entities/raycast-vehicle-3d.entity.d.ts +43 -76
  13. package/dist/3d/entities/raycast-vehicle-3d.entity.js +78 -299
  14. package/dist/3d/gg-3d-world.d.ts +1 -2
  15. package/dist/3d/gg-3d-world.js +4 -5
  16. package/dist/3d/index.d.ts +2 -0
  17. package/dist/3d/index.js +2 -0
  18. package/dist/base/components/physics/i-body.component.d.ts +14 -0
  19. package/dist/base/components/physics/i-body.component.js +1 -0
  20. package/dist/base/components/physics/i-rigid-body.component.d.ts +4 -11
  21. package/dist/base/components/physics/i-trigger.component.d.ts +3 -1
  22. package/dist/base/entities/i-entity.js +1 -1
  23. package/dist/base/gg-world.d.ts +8 -12
  24. package/dist/base/gg-world.js +32 -64
  25. package/dist/base/index.d.ts +2 -3
  26. package/dist/base/index.js +2 -3
  27. package/dist/base/math/point2.d.ts +4 -0
  28. package/dist/base/math/point2.js +8 -0
  29. package/dist/base/math/point3.d.ts +6 -0
  30. package/dist/base/math/point3.js +12 -0
  31. package/dist/base/math/splines.d.ts +1 -0
  32. package/dist/base/math/splines.js +7 -0
  33. package/dist/{base/ui → dev}/gg-console.ui.d.ts +1 -4
  34. package/dist/{base/ui → dev}/gg-console.ui.js +35 -17
  35. package/dist/dev/gg-debugger.ui.d.ts +11 -0
  36. package/dist/dev/gg-debugger.ui.js +111 -0
  37. package/dist/dev/gg-static.d.ts +32 -0
  38. package/dist/dev/gg-static.js +141 -0
  39. package/dist/dev/index.d.ts +3 -0
  40. package/dist/dev/index.js +3 -0
  41. package/dist/index.d.ts +1 -0
  42. package/dist/index.js +1 -0
  43. package/package.json +1 -1
  44. package/dist/base/gg-static.d.ts +0 -9
  45. package/dist/base/gg-static.js +0 -36
  46. package/dist/base/ui/gg-debugger.ui.d.ts +0 -10
  47. 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 { IWorldComponent } from '../i-world-component';
4
- import { GgWorld } from '../../gg-world';
5
- import { IVisualSceneComponent } from '../rendering/i-visual-scene.component';
6
- export interface IRigidBodyComponent<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;
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
- export interface ITriggerComponent<D, R, PW extends IPhysicsWorldComponent<D, R> = IPhysicsWorldComponent<D, R>> extends IRigidBodyComponent<D, R, PW> {
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 = '0x' + (IEntity.default_name_counter++).toString(16);
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
  * */
@@ -1,13 +1,16 @@
1
- import { IEntity, IPhysicsWorldComponent, IVisualSceneComponent, KeyboardInput, PausableClock, IPositionable, IRenderableEntity } from '../base';
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
- constructor(visualScene: V, physicsWorld: P, consoleEnabled?: boolean);
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
- protected commands: {
24
- [key: string]: {
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
  }
@@ -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 { GgConsoleUI, GgDebuggerUI, GgGlobalClock, GgStatic, TickOrder, KeyboardInput, } from '../base';
11
- import { filter } from 'rxjs';
10
+ import { GgGlobalClock, KeyboardInput, TickOrder, } from '../base';
12
11
  export class GgWorld {
13
- constructor(visualScene, physicsWorld, consoleEnabled = false) {
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.commands = {};
23
- GgStatic.instance.worlds.push(this);
24
- GgStatic.instance.selectedWorld = this;
21
+ GgWorld._documentWorlds.push(this);
25
22
  this.keyboardInput.start();
26
- if (consoleEnabled) {
27
- // TODO this listener should be outside of the world
28
- this.keyboardInput
29
- .bind('Backquote')
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
- this.registerConsoleCommand('ph_timescale', (...args) => __awaiter(this, void 0, void 0, function* () {
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
- this.registerConsoleCommand('dr_drawphysics', (...args) => __awaiter(this, void 0, void 0, function* () {
63
- const shouldDraw = ['1', 'true', '+'].includes(args[0]);
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
- registerConsoleCommand(command, handler, doc) {
153
- if (!this.consoleEnabled) {
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
- runConsoleCommand(command, args) {
159
- return __awaiter(this, void 0, void 0, function* () {
160
- if (!this.consoleEnabled) {
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
- else {
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 = [];
@@ -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 './ui/gg-console.ui';
35
- export * from './ui/gg-debugger.ui';
36
- export * from './gg-static';
35
+ export * from './math/splines';
37
36
  export * from './gg-world';
@@ -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 './ui/gg-console.ui';
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 */
@@ -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 */
@@ -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;
@@ -0,0 +1,7 @@
1
+ export const cubicSplineInterpolation = (x, x0, x1, y0, y1, m0, m1) => {
2
+ const h = x1 - x0;
3
+ return (((m0 + m1 - (2 * (y1 - y0)) / h) / h ** 2) * (x - x0) ** 3 +
4
+ (((3 * (y1 - y0)) / h - 2 * m0 - m1) / h) * (x - x0) ** 2 +
5
+ m0 * (x - x0) +
6
+ y0);
7
+ };
@@ -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: HTMLTextAreaElement;
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: commandslist
29
- `;
27
+ List of available commands: `.replace(/ /g, '&nbsp;') + `<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="gg-console-header" style="padding: 10px; cursor: move; z-index: 10; background-color: #054a81; border: 1px solid white; font-size: large;">GG web engine UI console</div>
50
- <textarea id="gg-console-output" disabled style="resize: none; flex-grow: 1; background: #555555; border: 1px solid white; color: white; font-family: monospace;" ></textarea>
51
- <input id="gg-console-input" style="background: #555555; border: 1px solid white; color: white; font-family: monospace;"/>`;
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 = '#222222';
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 = '3px';
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 GgStatic.instance.console(command)));
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.value = this.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
+ }