@gg-web-engine/core 0.0.39 → 0.0.48

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 (185) hide show
  1. package/README.md +0 -0
  2. package/blender_exporter/build_blender_scene.py +0 -1
  3. package/blender_exporter/spherical_to_cube_texture.py +0 -0
  4. package/dist/2d/components/physics/i-physics-world-2d.component.d.ts +0 -0
  5. package/dist/2d/components/physics/i-physics-world-2d.component.js +0 -0
  6. package/dist/2d/components/physics/i-rigid-body-2d.component.d.ts +0 -0
  7. package/dist/2d/components/physics/i-rigid-body-2d.component.js +0 -0
  8. package/dist/2d/components/physics/i-trigger-2d.component.d.ts +0 -0
  9. package/dist/2d/components/physics/i-trigger-2d.component.js +0 -0
  10. package/dist/2d/components/rendering/i-display-object-2d.component.d.ts +0 -0
  11. package/dist/2d/components/rendering/i-display-object-2d.component.js +0 -0
  12. package/dist/2d/components/rendering/i-renderer-2d.component.d.ts +0 -0
  13. package/dist/2d/components/rendering/i-renderer-2d.component.js +0 -0
  14. package/dist/2d/components/rendering/i-visual-scene-2d.component.d.ts +1 -1
  15. package/dist/2d/components/rendering/i-visual-scene-2d.component.js +0 -0
  16. package/dist/2d/entities/controllers/entity-2d-positioning.animator.d.ts +1 -1
  17. package/dist/2d/entities/controllers/entity-2d-positioning.animator.js +0 -0
  18. package/dist/2d/entities/entity-2d.d.ts +0 -0
  19. package/dist/2d/entities/entity-2d.js +25 -25
  20. package/dist/2d/entities/i-renderable-2d.entity.d.ts +3 -1
  21. package/dist/2d/entities/i-renderable-2d.entity.js +7 -0
  22. package/dist/2d/entities/renderer-2d.entity.d.ts +0 -0
  23. package/dist/2d/entities/renderer-2d.entity.js +0 -0
  24. package/dist/2d/entities/trigger-2d.entity.d.ts +0 -0
  25. package/dist/2d/entities/trigger-2d.entity.js +11 -11
  26. package/dist/2d/factories.d.ts +1 -1
  27. package/dist/2d/factories.js +0 -0
  28. package/dist/2d/gg-2d-world.d.ts +4 -3
  29. package/dist/2d/gg-2d-world.js +0 -0
  30. package/dist/2d/index.d.ts +0 -0
  31. package/dist/2d/index.js +0 -0
  32. package/dist/2d/interfaces/i-positionable-2d.d.ts +0 -0
  33. package/dist/2d/interfaces/i-positionable-2d.js +0 -0
  34. package/dist/2d/models/body-options.d.ts +1 -1
  35. package/dist/2d/models/body-options.js +0 -0
  36. package/dist/2d/models/shapes.d.ts +2 -2
  37. package/dist/2d/models/shapes.js +0 -0
  38. package/dist/3d/components/physics/i-physics-world-3d.component.d.ts +0 -0
  39. package/dist/3d/components/physics/i-physics-world-3d.component.js +0 -0
  40. package/dist/3d/components/physics/i-raycast-vehicle.component.d.ts +2 -2
  41. package/dist/3d/components/physics/i-raycast-vehicle.component.js +0 -0
  42. package/dist/3d/components/physics/i-rigid-body-3d.component.d.ts +0 -0
  43. package/dist/3d/components/physics/i-rigid-body-3d.component.js +0 -0
  44. package/dist/3d/components/physics/i-trigger-3d.component.d.ts +0 -0
  45. package/dist/3d/components/physics/i-trigger-3d.component.js +0 -0
  46. package/dist/3d/components/rendering/i-camera.component.d.ts +0 -0
  47. package/dist/3d/components/rendering/i-camera.component.js +0 -0
  48. package/dist/3d/components/rendering/i-display-object-3d.component.d.ts +0 -0
  49. package/dist/3d/components/rendering/i-display-object-3d.component.js +0 -0
  50. package/dist/3d/components/rendering/i-renderer-3d.component.d.ts +0 -0
  51. package/dist/3d/components/rendering/i-renderer-3d.component.js +0 -0
  52. package/dist/3d/components/rendering/i-visual-scene-3d.component.d.ts +1 -1
  53. package/dist/3d/components/rendering/i-visual-scene-3d.component.js +0 -0
  54. package/dist/3d/entities/controllers/animators/camera-3d.animator.d.ts +1 -1
  55. package/dist/3d/entities/controllers/animators/camera-3d.animator.js +0 -0
  56. package/dist/3d/entities/controllers/animators/entity-3d-positioning.animator.d.ts +1 -1
  57. package/dist/3d/entities/controllers/animators/entity-3d-positioning.animator.js +0 -0
  58. package/dist/3d/entities/controllers/input/car-keyboard-handling.controller.d.ts +2 -2
  59. package/dist/3d/entities/controllers/input/car-keyboard-handling.controller.js +3 -3
  60. package/dist/3d/entities/controllers/input/free-camera.controller.d.ts +1 -1
  61. package/dist/3d/entities/controllers/input/free-camera.controller.js +0 -0
  62. package/dist/3d/entities/controllers/input/gg-car-keyboard-handling.controller.d.ts +1 -1
  63. package/dist/3d/entities/controllers/input/gg-car-keyboard-handling.controller.js +0 -0
  64. package/dist/3d/entities/controllers/input/orbit-camera.controller.d.ts +1 -1
  65. package/dist/3d/entities/controllers/input/orbit-camera.controller.js +10 -10
  66. package/dist/3d/entities/entity-3d.d.ts +0 -0
  67. package/dist/3d/entities/entity-3d.js +25 -25
  68. package/dist/3d/entities/gg-car/gg-car.entity.d.ts +1 -1
  69. package/dist/3d/entities/gg-car/gg-car.entity.js +16 -16
  70. package/dist/3d/entities/i-renderable-3d.entity.d.ts +3 -1
  71. package/dist/3d/entities/i-renderable-3d.entity.js +7 -0
  72. package/dist/3d/entities/map-graph-3d.entity.d.ts +9 -6
  73. package/dist/3d/entities/map-graph-3d.entity.js +70 -26
  74. package/dist/3d/entities/raycast-vehicle-3d.entity.d.ts +6 -4
  75. package/dist/3d/entities/raycast-vehicle-3d.entity.js +44 -30
  76. package/dist/3d/entities/renderer-3d.entity.d.ts +0 -0
  77. package/dist/3d/entities/renderer-3d.entity.js +0 -0
  78. package/dist/3d/entities/trigger-3d.entity.d.ts +0 -0
  79. package/dist/3d/entities/trigger-3d.entity.js +11 -11
  80. package/dist/3d/factories.d.ts +1 -1
  81. package/dist/3d/factories.js +0 -0
  82. package/dist/3d/gg-3d-world.d.ts +4 -3
  83. package/dist/3d/gg-3d-world.js +0 -0
  84. package/dist/3d/index.d.ts +0 -0
  85. package/dist/3d/index.js +0 -0
  86. package/dist/3d/interfaces/i-positionable-3d.d.ts +0 -0
  87. package/dist/3d/interfaces/i-positionable-3d.js +0 -0
  88. package/dist/3d/loader.d.ts +4 -4
  89. package/dist/3d/loader.js +7 -7
  90. package/dist/3d/loaders.d.ts +0 -0
  91. package/dist/3d/loaders.js +0 -0
  92. package/dist/3d/models/body-options.d.ts +1 -1
  93. package/dist/3d/models/body-options.js +0 -0
  94. package/dist/3d/models/gg-meta.d.ts +4 -4
  95. package/dist/3d/models/gg-meta.js +0 -0
  96. package/dist/3d/models/shapes.d.ts +3 -3
  97. package/dist/3d/models/shapes.js +0 -0
  98. package/dist/base/clock/global-clock.d.ts +0 -0
  99. package/dist/base/clock/global-clock.js +8 -8
  100. package/dist/base/clock/i-clock.d.ts +0 -0
  101. package/dist/base/clock/i-clock.js +0 -0
  102. package/dist/base/clock/pausable-clock.d.ts +8 -1
  103. package/dist/base/clock/pausable-clock.js +38 -23
  104. package/dist/base/components/i-component.d.ts +0 -0
  105. package/dist/base/components/i-component.js +0 -0
  106. package/dist/base/components/i-world-component.d.ts +0 -0
  107. package/dist/base/components/i-world-component.js +0 -0
  108. package/dist/base/components/physics/i-body.component.d.ts +0 -0
  109. package/dist/base/components/physics/i-body.component.js +0 -0
  110. package/dist/base/components/physics/i-physics-world.component.d.ts +0 -0
  111. package/dist/base/components/physics/i-physics-world.component.js +0 -0
  112. package/dist/base/components/physics/i-rigid-body.component.d.ts +0 -0
  113. package/dist/base/components/physics/i-rigid-body.component.js +0 -0
  114. package/dist/base/components/physics/i-trigger.component.d.ts +0 -0
  115. package/dist/base/components/physics/i-trigger.component.js +0 -0
  116. package/dist/base/components/rendering/i-display-object.component.d.ts +0 -0
  117. package/dist/base/components/rendering/i-display-object.component.js +0 -0
  118. package/dist/base/components/rendering/i-renderer.component.d.ts +3 -3
  119. package/dist/base/components/rendering/i-renderer.component.js +0 -0
  120. package/dist/base/components/rendering/i-visual-scene.component.d.ts +0 -0
  121. package/dist/base/components/rendering/i-visual-scene.component.js +0 -0
  122. package/dist/base/data-structures/bitmask.d.ts +0 -0
  123. package/dist/base/data-structures/bitmask.js +0 -0
  124. package/dist/base/data-structures/graph.d.ts +0 -0
  125. package/dist/base/data-structures/graph.js +4 -4
  126. package/dist/base/entities/controllers/animation-mixer.d.ts +1 -1
  127. package/dist/base/entities/controllers/animation-mixer.js +27 -27
  128. package/dist/base/entities/controllers/inline-controller.d.ts +1 -1
  129. package/dist/base/entities/controllers/inline-controller.js +4 -1
  130. package/dist/base/entities/i-entity.d.ts +0 -0
  131. package/dist/base/entities/i-entity.js +0 -0
  132. package/dist/base/entities/i-renderable.entity.d.ts +0 -0
  133. package/dist/base/entities/i-renderable.entity.js +0 -0
  134. package/dist/base/entities/i-renderer.entity.d.ts +0 -0
  135. package/dist/base/entities/i-renderer.entity.js +15 -15
  136. package/dist/base/gg-world.d.ts +11 -5
  137. package/dist/base/gg-world.js +60 -17
  138. package/dist/base/index.d.ts +0 -0
  139. package/dist/base/index.js +0 -0
  140. package/dist/base/inputs/direction.keyboard.input.d.ts +2 -2
  141. package/dist/base/inputs/direction.keyboard.input.js +6 -6
  142. package/dist/base/inputs/i-input.d.ts +0 -0
  143. package/dist/base/inputs/i-input.js +0 -0
  144. package/dist/base/inputs/keyboard.input.d.ts +0 -0
  145. package/dist/base/inputs/keyboard.input.js +0 -0
  146. package/dist/base/inputs/mouse.input.d.ts +1 -1
  147. package/dist/base/inputs/mouse.input.js +27 -22
  148. package/dist/base/interfaces/i-positionable.d.ts +0 -0
  149. package/dist/base/interfaces/i-positionable.js +0 -0
  150. package/dist/base/math/box.d.ts +0 -0
  151. package/dist/base/math/box.js +0 -0
  152. package/dist/base/math/matrix4.d.ts +0 -0
  153. package/dist/base/math/matrix4.js +0 -0
  154. package/dist/base/math/numbers.d.ts +0 -0
  155. package/dist/base/math/numbers.js +0 -0
  156. package/dist/base/math/point2.d.ts +0 -0
  157. package/dist/base/math/point2.js +0 -0
  158. package/dist/base/math/point3.d.ts +0 -0
  159. package/dist/base/math/point3.js +0 -0
  160. package/dist/base/math/quaternion.d.ts +6 -0
  161. package/dist/base/math/quaternion.js +38 -0
  162. package/dist/base/math/splines.d.ts +0 -0
  163. package/dist/base/math/splines.js +0 -0
  164. package/dist/base/models/axis-directions.d.ts +3 -3
  165. package/dist/base/models/axis-directions.js +0 -0
  166. package/dist/base/models/body-options.d.ts +2 -2
  167. package/dist/base/models/body-options.js +0 -0
  168. package/dist/base/models/geometry-nodes.d.ts +3 -3
  169. package/dist/base/models/geometry-nodes.js +0 -0
  170. package/dist/base/models/points.d.ts +5 -5
  171. package/dist/base/models/points.js +0 -0
  172. package/dist/dev/gg-console.ui.d.ts +0 -0
  173. package/dist/dev/gg-console.ui.js +0 -0
  174. package/dist/dev/gg-debugger.ui.d.ts +5 -0
  175. package/dist/dev/gg-debugger.ui.js +129 -8
  176. package/dist/dev/gg-static.d.ts +0 -0
  177. package/dist/dev/gg-static.js +49 -41
  178. package/dist/dev/index.d.ts +1 -0
  179. package/dist/dev/index.js +1 -0
  180. package/dist/dev/performance-meter.entity.d.ts +21 -0
  181. package/dist/dev/performance-meter.entity.js +120 -0
  182. package/dist/index.d.ts +0 -0
  183. package/dist/index.js +0 -0
  184. package/package.json +7 -7
  185. package/tsconfig.json +0 -0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -88,6 +88,12 @@ export declare class Qtrn {
88
88
  * @returns a quaternion representing the rotation
89
89
  */
90
90
  static fromMatrix4(m: number[]): Point4;
91
+ /**
92
+ * Converts a 3x3 rotation matrix into a quaternion
93
+ * @param m the matrix representing the rotation
94
+ * @returns a quaternion representing the rotation
95
+ */
96
+ static fromMatrix3(m: number[][]): Point4;
91
97
  /**
92
98
  * Creates a quaternion from euler
93
99
  * @param e the euler vector
@@ -178,6 +178,44 @@ export class Qtrn {
178
178
  };
179
179
  }
180
180
  }
181
+ /**
182
+ * Converts a 3x3 rotation matrix into a quaternion
183
+ * @param m the matrix representing the rotation
184
+ * @returns a quaternion representing the rotation
185
+ */
186
+ static fromMatrix3(m) {
187
+ const trace = m[0][0] + m[1][1] + m[2][2];
188
+ let w, x, y, z;
189
+ if (trace > 0) {
190
+ const s = 0.5 / Math.sqrt(trace + 1);
191
+ w = 0.25 / s;
192
+ x = (m[2][1] - m[1][2]) * s;
193
+ y = (m[0][2] - m[2][0]) * s;
194
+ z = (m[1][0] - m[0][1]) * s;
195
+ }
196
+ else if (m[0][0] > m[1][1] && m[0][0] > m[2][2]) {
197
+ const s = 2 * Math.sqrt(1 + m[0][0] - m[1][1] - m[2][2]);
198
+ w = (m[2][1] - m[1][2]) / s;
199
+ x = 0.25 * s;
200
+ y = (m[0][1] + m[1][0]) / s;
201
+ z = (m[0][2] + m[2][0]) / s;
202
+ }
203
+ else if (m[1][1] > m[2][2]) {
204
+ const s = 2 * Math.sqrt(1 + m[1][1] - m[0][0] - m[2][2]);
205
+ w = (m[0][2] - m[2][0]) / s;
206
+ x = (m[0][1] + m[1][0]) / s;
207
+ y = 0.25 * s;
208
+ z = (m[1][2] + m[2][1]) / s;
209
+ }
210
+ else {
211
+ const s = 2 * Math.sqrt(1 + m[2][2] - m[0][0] - m[1][1]);
212
+ w = (m[1][0] - m[0][1]) / s;
213
+ x = (m[0][2] + m[2][0]) / s;
214
+ y = (m[1][2] + m[2][1]) / s;
215
+ z = 0.25 * s;
216
+ }
217
+ return { w, x, y, z };
218
+ }
181
219
  /**
182
220
  * Creates a quaternion from euler
183
221
  * @param e the euler vector
File without changes
File without changes
@@ -1,3 +1,3 @@
1
- export declare type AxisDirection2 = 'x' | 'y' | '-x' | '-y';
2
- export declare type AxisDirection3 = AxisDirection2 | 'z' | '-z';
3
- export declare type AxisDirection4 = AxisDirection3 | 'w' | '-w';
1
+ export type AxisDirection2 = 'x' | 'y' | '-x' | '-y';
2
+ export type AxisDirection3 = AxisDirection2 | 'z' | '-z';
3
+ export type AxisDirection4 = AxisDirection3 | 'w' | '-w';
File without changes
@@ -1,4 +1,4 @@
1
- export declare type CollisionGroup = number;
1
+ export type CollisionGroup = number;
2
2
  export interface BodyOptions {
3
3
  dynamic: boolean;
4
4
  mass: number;
@@ -7,7 +7,7 @@ export interface BodyOptions {
7
7
  ownCollisionGroups: CollisionGroup[] | 'all';
8
8
  interactWithCollisionGroups: CollisionGroup[] | 'all';
9
9
  }
10
- export declare type DebugBodySettings = {
10
+ export type DebugBodySettings = {
11
11
  shape: any;
12
12
  ignoreTransform?: boolean;
13
13
  } & ({
File without changes
@@ -1,7 +1,7 @@
1
1
  import { Point2, Point3 } from './points';
2
- export declare type GgBox<T> = {
2
+ export type GgBox<T> = {
3
3
  min: T;
4
4
  max: T;
5
5
  };
6
- export declare type GgBox2d = GgBox<Point2>;
7
- export declare type GgBox3d = GgBox<Point3>;
6
+ export type GgBox2d = GgBox<Point2>;
7
+ export type GgBox3d = GgBox<Point3>;
File without changes
@@ -1,24 +1,24 @@
1
- export declare type Point2 = {
1
+ export type Point2 = {
2
2
  readonly x: number;
3
3
  readonly y: number;
4
4
  };
5
- export declare type Point3 = {
5
+ export type Point3 = {
6
6
  readonly x: number;
7
7
  readonly y: number;
8
8
  readonly z: number;
9
9
  };
10
- export declare type Point4 = {
10
+ export type Point4 = {
11
11
  readonly x: number;
12
12
  readonly y: number;
13
13
  readonly z: number;
14
14
  readonly w: number;
15
15
  };
16
- export declare type Spherical = {
16
+ export type Spherical = {
17
17
  readonly radius: number;
18
18
  readonly phi: number;
19
19
  readonly theta: number;
20
20
  };
21
- export declare type MutableSpherical = {
21
+ export type MutableSpherical = {
22
22
  radius: number;
23
23
  phi: number;
24
24
  theta: number;
File without changes
File without changes
File without changes
@@ -10,6 +10,11 @@ export declare class GgDebuggerUI {
10
10
  get showDebugControls(): boolean;
11
11
  setShowDebugControls(selectedWorld: GgWorld<any, any>, value: boolean): void;
12
12
  private snapshot;
13
+ perfStatsMode: 'AVG' | 'PEAK';
14
+ private performanceStatsSnapshot;
13
15
  private makeSnapshot;
16
+ private makePerformanceStatsSnapshot;
17
+ css: string;
14
18
  private renderControls;
19
+ private renderPerformanceStats;
15
20
  }
@@ -2,9 +2,12 @@ import { createInlineTickController, IRendererEntity } from '../base';
2
2
  import { animationFrameScheduler, fromEvent, of, Subject, takeUntil } from 'rxjs';
3
3
  import Stats from 'stats.js';
4
4
  import { repeat } from 'rxjs/operators';
5
+ import { PerformanceMeterEntity } from './performance-meter.entity';
5
6
  const snapshotEqual = (a, b) => {
6
7
  if (a.timeScale !== b.timeScale)
7
8
  return false;
9
+ if (a.performanceStatsEnabled !== b.performanceStatsEnabled)
10
+ return false;
8
11
  if (a.renderers.length !== b.renderers.length)
9
12
  return false;
10
13
  for (let i = 0; i < a.renderers.length; i++) {
@@ -17,6 +20,23 @@ const snapshotEqual = (a, b) => {
17
20
  }
18
21
  return true;
19
22
  };
23
+ const performanceStatsSnapshotEqual = (a, b) => {
24
+ if (!!a !== !!b)
25
+ return false;
26
+ if (a && b) {
27
+ if (a.totalTime !== b.totalTime)
28
+ return false;
29
+ if (a.entries.length !== b.entries.length)
30
+ return false;
31
+ for (let i = 0; i < a.entries.length; i++) {
32
+ if (a.entries[i][0] !== b.entries[i][0])
33
+ return false;
34
+ if (a.entries[i][1] !== b.entries[i][1])
35
+ return false;
36
+ }
37
+ }
38
+ return true;
39
+ };
20
40
  export class GgDebuggerUI {
21
41
  constructor() {
22
42
  this.ui = {
@@ -30,7 +50,11 @@ export class GgDebuggerUI {
30
50
  this.snapshot = {
31
51
  timeScale: 1,
32
52
  renderers: [],
53
+ performanceStatsEnabled: false,
33
54
  };
55
+ this.perfStatsMode = 'AVG';
56
+ this.performanceStatsSnapshot = null;
57
+ this.css = "style='display:flex;align-items:center;margin:0.25rem;'";
34
58
  }
35
59
  get showStats() {
36
60
  return !!this.ui.stats;
@@ -52,12 +76,12 @@ export class GgDebuggerUI {
52
76
  stats.dom.style.right = '0';
53
77
  stats.showPanel(0); // 0: fps, 1: ms, 2: mb
54
78
  document.body.appendChild(stats.dom);
55
- createInlineTickController(selectedWorld, -1)
79
+ createInlineTickController(selectedWorld, -1, 'fps_meter_init')
56
80
  .pipe(takeUntil(this.statsRemoved$))
57
81
  .subscribe(() => {
58
82
  stats === null || stats === void 0 ? void 0 : stats.begin();
59
83
  });
60
- createInlineTickController(selectedWorld, 10000)
84
+ createInlineTickController(selectedWorld, 10000, 'fps_meter')
61
85
  .pipe(takeUntil(this.statsRemoved$))
62
86
  .subscribe(() => {
63
87
  stats === null || stats === void 0 ? void 0 : stats.end();
@@ -90,7 +114,9 @@ export class GgDebuggerUI {
90
114
  debugControlsContainer.style.cssText =
91
115
  'position:fixed;top:48px;right:0;opacity:0.9;z-index:9999;background-color:#333;color:white;display:flex;flex-direction:column';
92
116
  this.snapshot = this.makeSnapshot();
117
+ this.performanceStatsSnapshot = this.makePerformanceStatsSnapshot();
93
118
  this.renderControls(debugControlsContainer);
119
+ this.renderPerformanceStats();
94
120
  of(undefined, animationFrameScheduler)
95
121
  .pipe(repeat(), takeUntil(this.debugControlsRemoved$))
96
122
  .subscribe(() => {
@@ -99,6 +125,11 @@ export class GgDebuggerUI {
99
125
  this.snapshot = newSnapshot;
100
126
  this.renderControls(debugControlsContainer);
101
127
  }
128
+ const newPerformanceStats = this.makePerformanceStatsSnapshot();
129
+ if (!performanceStatsSnapshotEqual(this.performanceStatsSnapshot, newPerformanceStats)) {
130
+ this.performanceStatsSnapshot = newPerformanceStats;
131
+ this.renderPerformanceStats();
132
+ }
102
133
  });
103
134
  }
104
135
  else {
@@ -108,33 +139,74 @@ export class GgDebuggerUI {
108
139
  }
109
140
  }
110
141
  makeSnapshot() {
142
+ const renderers = [];
143
+ let performanceMeter = null;
144
+ for (const e of this.currentWorld.children) {
145
+ if (e instanceof IRendererEntity) {
146
+ renderers.push(e);
147
+ }
148
+ else if (e instanceof PerformanceMeterEntity) {
149
+ performanceMeter = e;
150
+ }
151
+ }
111
152
  return {
112
153
  timeScale: this.currentWorld.worldClock.timeScale,
113
- renderers: this.currentWorld.children
114
- .filter(x => x instanceof IRendererEntity)
115
- .map(r => ({
154
+ renderers: renderers.map(r => ({
116
155
  name: r.name,
117
156
  entity: r,
118
157
  physicsDebugViewActive: r.physicsDebugViewActive,
119
158
  })),
159
+ performanceStatsEnabled: !!performanceMeter,
120
160
  };
121
161
  }
162
+ makePerformanceStatsSnapshot() {
163
+ if (!this.snapshot.performanceStatsEnabled)
164
+ return null;
165
+ let performanceMeter = this.currentWorld.children.find(e => e instanceof PerformanceMeterEntity);
166
+ if (performanceMeter) {
167
+ if (this.perfStatsMode === 'AVG') {
168
+ return performanceMeter.avgReport;
169
+ }
170
+ else if (this.perfStatsMode === 'PEAK') {
171
+ return performanceMeter.peakReport;
172
+ }
173
+ }
174
+ return null;
175
+ }
122
176
  renderControls(debugControlsContainer) {
123
- const debugLabelCss = "style='display:flex;align-items:center;margin:0.25rem;'";
124
177
  let html = '';
125
178
  for (const { entity, physicsDebugViewActive } of this.snapshot.renderers) {
126
179
  html += `
127
- <div ${debugLabelCss}>
180
+ <div ${this.css}>
128
181
  <input type='checkbox' name='checkbox' id='physics_debugger_checkbox_id_${entity.name}' value='1'${physicsDebugViewActive ? ' checked' : ''}>
129
182
  <label for='physics_debugger_checkbox_id_${entity.name}' style='user-select: none;'>Physics debugger${this.snapshot.renderers.length > 1 ? ' (' + entity.name + ')' : ''}</label>
130
183
  </div>`;
131
184
  }
132
185
  html += `
133
- <div ${debugLabelCss}>
186
+ <div ${this.css}>
134
187
  <input id='time_scale_slider' type='range' min='0' max='5' step='0.01' style='flex-grow:1' value='${this.snapshot.timeScale}'/>
135
188
  <label for='time_scale_slider' style='user-select: none;'>Time scale</label>
136
189
  </div>`;
190
+ html +=
191
+ `
192
+ <div ${this.css}>
193
+ <input type='checkbox' name='checkbox' id='perf_stats_checkbox_id' value='1'${this.snapshot.performanceStatsEnabled ? ' checked' : ''}>
194
+ <label for='perf_stats_checkbox_id' style='user-select: none;'>Entities performance distribution</label>
195
+ </div>
196
+ ` +
197
+ (this.snapshot.performanceStatsEnabled
198
+ ? `<div ${this.css}>
199
+ <label for='per_mode'>Mode:</label>
200
+ <select id='per_mode'>
201
+ <option value='AVG' ${this.perfStatsMode === 'AVG' ? 'selected' : ''}>Average</option>
202
+ <option value='PEAK' ${this.perfStatsMode === 'PEAK' ? 'selected' : ''}>Peak</option>
203
+ </select>
204
+ </div>`
205
+ : '') +
206
+ `
207
+ <div style='display: contents' id='perf_stats_container'></div>`;
137
208
  debugControlsContainer.innerHTML = html;
209
+ debugControlsContainer.style.minWidth = '25rem';
138
210
  this.viewUpdated$.next();
139
211
  for (const { entity } of this.snapshot.renderers) {
140
212
  fromEvent(document.getElementById('physics_debugger_checkbox_id_' + entity.name), 'change')
@@ -158,5 +230,54 @@ export class GgDebuggerUI {
158
230
  console.error(err);
159
231
  }
160
232
  });
233
+ fromEvent(document.getElementById('perf_stats_checkbox_id'), 'change')
234
+ .pipe(takeUntil(this.debugControlsRemoved$), takeUntil(this.viewUpdated$))
235
+ .subscribe(e => {
236
+ const entity = this.currentWorld.children.find(x => x instanceof PerformanceMeterEntity);
237
+ if (e.target.checked == !entity) {
238
+ if (entity) {
239
+ this.currentWorld.removeEntity(entity);
240
+ }
241
+ else {
242
+ this.currentWorld.addEntity(new PerformanceMeterEntity());
243
+ }
244
+ }
245
+ });
246
+ if (this.snapshot.performanceStatsEnabled) {
247
+ fromEvent(document.getElementById('per_mode'), 'change')
248
+ .pipe(takeUntil(this.debugControlsRemoved$), takeUntil(this.viewUpdated$))
249
+ .subscribe(e => {
250
+ this.perfStatsMode = e.target.value;
251
+ });
252
+ }
253
+ }
254
+ renderPerformanceStats() {
255
+ const pCss = "style='display:flex;align-items:center;margin:0.25rem;max-width:25rem'";
256
+ const em = document.getElementById('perf_stats_container');
257
+ if (!em)
258
+ return;
259
+ let html = '';
260
+ if (this.performanceStatsSnapshot) {
261
+ const total = this.performanceStatsSnapshot.totalTime;
262
+ const labelCss = `style='user-select:none;width:3.5rem;text-align:left;flex-shrink:0;'`;
263
+ const progressCss = `style='width:11.5rem;margin:4px;flex-shrink:0;'`;
264
+ const spanCss = `style='user-select:none;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;width:calc(9.5rem - 8px);'`;
265
+ html += `
266
+ <div ${pCss}>
267
+ <label for='stat_progress' ${labelCss}>${total.toFixed(2)}ms</label>
268
+ <progress id="stat_progress" ${progressCss} max="16" value="${total}"></progress>
269
+ <span ${spanCss}>Total frame time</span>
270
+ </div>`;
271
+ for (const [i, [name, value]] of this.performanceStatsSnapshot.entries.entries()) {
272
+ const strVal = this.perfStatsMode == 'AVG' ? ((value * 100) / total).toFixed(2) + '%' : value.toFixed(2) + 'ms';
273
+ html += `
274
+ <div ${pCss}>
275
+ <label for='stat_progress_${i}' ${labelCss}>${strVal}</label>
276
+ <progress id='stat_progress_${i}' ${progressCss} max='${total}' value='${value}'></progress>
277
+ <span ${spanCss}>${name}</span>
278
+ </div>`;
279
+ }
280
+ }
281
+ em.innerHTML = html;
161
282
  }
162
283
  }
File without changes
@@ -11,45 +11,6 @@ import { GgWorld } from '../base';
11
11
  import { GgConsoleUI } from './gg-console.ui';
12
12
  import { GgDebuggerUI } from './gg-debugger.ui';
13
13
  export class GgStatic {
14
- constructor() {
15
- this.debuggerUI = new GgDebuggerUI();
16
- this.consoleUI = new GgConsoleUI();
17
- this._devConsoleEnabled = false;
18
- this.consoleKeyPressEventListener = (event) => {
19
- if (event.code === 'Backquote') {
20
- event.preventDefault();
21
- if (this.consoleUI.isUIShown) {
22
- this.consoleUI.destroyUI();
23
- }
24
- else {
25
- this.consoleUI.createUI();
26
- }
27
- }
28
- };
29
- this._selectedWorld = null;
30
- this.consoleCommands = new Map();
31
- this.registerConsoleCommand(null, 'ls_commands', () => __awaiter(this, void 0, void 0, function* () {
32
- return this.availableCommands
33
- .map(([key, value]) => `<span style="color:yellow">${key}</span>${value.doc ? '\t<span style="color:#aaa">// ' + value.doc + '</span>' : ''}`)
34
- .sort()
35
- .join('\n\n');
36
- }), 'no args; print all available commands');
37
- this.registerConsoleCommand(null, 'ls_worlds', () => __awaiter(this, void 0, void 0, function* () {
38
- return GgWorld.documentWorlds
39
- .map(w => (w === this.selectedWorld ? `<span style="color:green;">* ${w.name}</span>` : ` ${w.name}`))
40
- .join('\n');
41
- }), 'no args; print all available worlds');
42
- this.registerConsoleCommand(null, 'select_world', (...args) => __awaiter(this, void 0, void 0, function* () {
43
- var _a;
44
- for (const w of GgWorld.documentWorlds) {
45
- if (w.name === args[0]) {
46
- this._selectedWorld = w;
47
- break;
48
- }
49
- }
50
- return ((_a = this.selectedWorld) === null || _a === void 0 ? void 0 : _a.name) || 'null';
51
- }), 'args: [string]; select world by name');
52
- }
53
14
  static get instance() {
54
15
  if (!window.ggstatic) {
55
16
  window.ggstatic = new GgStatic();
@@ -96,6 +57,53 @@ export class GgStatic {
96
57
  }
97
58
  return Object.entries(commands);
98
59
  }
60
+ constructor() {
61
+ this.debuggerUI = new GgDebuggerUI();
62
+ this.consoleUI = new GgConsoleUI();
63
+ this._devConsoleEnabled = false;
64
+ this.consoleKeyPressEventListener = (event) => {
65
+ if (event.code === 'Backquote') {
66
+ event.preventDefault();
67
+ if (this.consoleUI.isUIShown) {
68
+ this.consoleUI.destroyUI();
69
+ }
70
+ else {
71
+ this.consoleUI.createUI();
72
+ }
73
+ }
74
+ };
75
+ this._selectedWorld = null;
76
+ this.consoleCommands = new Map();
77
+ this.registerConsoleCommand(null, 'ls_commands', () => __awaiter(this, void 0, void 0, function* () {
78
+ return this.availableCommands
79
+ .map(([key, value]) => `<span style='color:yellow'>${key}</span>${value.doc ? '\t<span style="color:#aaa">// ' + value.doc + '</span>' : ''}`)
80
+ .sort()
81
+ .join('\n\n');
82
+ }), 'no args; print all available commands');
83
+ this.registerConsoleCommand(null, 'ls_worlds', () => __awaiter(this, void 0, void 0, function* () {
84
+ return GgWorld.documentWorlds
85
+ .map(w => (w === this.selectedWorld ? `<span style='color:lightgreen;'>* ${w.name}</span>` : ` ${w.name}`))
86
+ .join('\n');
87
+ }), 'no args; print all available worlds');
88
+ this.registerConsoleCommand(null, 'select_world', (...args) => __awaiter(this, void 0, void 0, function* () {
89
+ var _a;
90
+ for (const w of GgWorld.documentWorlds) {
91
+ if (w.name === args[0]) {
92
+ this._selectedWorld = w;
93
+ break;
94
+ }
95
+ }
96
+ return ((_a = this.selectedWorld) === null || _a === void 0 ? void 0 : _a.name) || 'null';
97
+ }), 'args: [string]; select world by name');
98
+ this.registerConsoleCommand(null, 'show_debugger', (...args) => __awaiter(this, void 0, void 0, function* () {
99
+ this.showDebugControls = ['1', 'true', '+'].includes(args[0]);
100
+ return '' + this.showDebugControls;
101
+ }), 'args: [0 or 1]; turn on/off debug panel. Default value is 0');
102
+ this.registerConsoleCommand(null, 'show_stats', (...args) => __awaiter(this, void 0, void 0, function* () {
103
+ this.showStats = ['1', 'true', '+'].includes(args[0]);
104
+ return '' + this.showStats;
105
+ }), 'args: [0 or 1]; turn on/off stats. Default value is 0');
106
+ }
99
107
  registerConsoleCommand(world, command, handler, doc) {
100
108
  let commands = {};
101
109
  if (!this.consoleCommands.has(world)) {
@@ -126,14 +134,14 @@ export class GgStatic {
126
134
  if (!action) {
127
135
  action = (this.consoleCommands.get(this.selectedWorld) || {})[command];
128
136
  if (!action) {
129
- return `<span style="color:red">Unrecognized command: ${command}</span>`;
137
+ return `<span style='color:red'>Unrecognized command: ${command}</span>`;
130
138
  }
131
139
  }
132
140
  try {
133
141
  return yield action.handler(...args);
134
142
  }
135
143
  catch (err) {
136
- return `<span style="color:red">${err}</span>`;
144
+ return `<span style='color:red'>${err}</span>`;
137
145
  }
138
146
  });
139
147
  }
@@ -1,3 +1,4 @@
1
1
  export * from './gg-console.ui';
2
2
  export * from './gg-debugger.ui';
3
3
  export * from './gg-static';
4
+ export * from './performance-meter.entity';
package/dist/dev/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './gg-console.ui';
2
2
  export * from './gg-debugger.ui';
3
3
  export * from './gg-static';
4
+ export * from './performance-meter.entity';
@@ -0,0 +1,21 @@
1
+ import { GgWorld, IEntity, TickOrder } from '../base';
2
+ export declare class PerformanceMeterEntity extends IEntity {
3
+ private readonly maxSamples;
4
+ private readonly maxRows;
5
+ readonly tickOrder: TickOrder | number;
6
+ private sampleIndex;
7
+ private collectedData;
8
+ private _avgReport;
9
+ get avgReport(): {
10
+ totalTime: number;
11
+ entries: [string, number][];
12
+ };
13
+ private _peakReport;
14
+ get peakReport(): {
15
+ totalTime: number;
16
+ entries: [string, number][];
17
+ };
18
+ constructor(maxSamples?: number, maxRows?: number);
19
+ onSpawned(world: GgWorld<unknown, unknown>): void;
20
+ onRemoved(): void;
21
+ }