@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
@@ -1,35 +1,15 @@
1
- import { Subject } from 'rxjs';
1
+ import { filter, Subject } from 'rxjs';
2
2
  import { map, tap } from 'rxjs/operators';
3
3
  import { GgGlobalClock } from './global-clock';
4
4
  /**
5
5
  * A class providing the ability to track time, fire ticks, provide time elapsed, and tick delta with the ability to suspend/resume it.
6
6
  */
7
7
  export class PausableClock {
8
- /**
9
- * Constructs a new PausableClock instance.
10
- * @param autoStart Indicates whether the clock should start automatically upon creation.
11
- * @param parentClock The parent clock to synchronize with. Defaults to GgGlobalClock instance.
12
- */
13
- constructor(autoStart = false, parentClock = GgGlobalClock.instance) {
14
- this.parentClock = parentClock;
15
- this.tickSub = null;
16
- this._tick$ = new Subject();
17
- // State variables
18
- this.startedAt = -1;
19
- this.oldRelativeTime = 0; // "elapsed", emitted on last tick
20
- this.pausedAt = -1;
21
- this.lastStopElapsed = 0;
22
- this._timeScale = 1;
23
- this.pausedByTimescale = false;
24
- if (autoStart) {
25
- this.start();
26
- }
27
- }
28
8
  /**
29
9
  * Observable stream of ticks, emitting an array containing the current time and the tick delta.
30
10
  */
31
11
  get tick$() {
32
- return this._tick$.pipe(map(([oldTime, newTime]) => [newTime, newTime - oldTime]));
12
+ return this._tick$.asObservable();
33
13
  }
34
14
  /**
35
15
  * Checks if the clock is currently running.
@@ -90,6 +70,39 @@ export class PausableClock {
90
70
  }
91
71
  return this._timeScale * (this.parentClock.elapsedTime - this.startedAt);
92
72
  }
73
+ /**
74
+ * Constructs a new PausableClock instance.
75
+ * @param autoStart Indicates whether the clock should start automatically upon creation.
76
+ * @param parentClock The parent clock to synchronize with. Defaults to GgGlobalClock instance.
77
+ */
78
+ constructor(autoStart = false, parentClock = GgGlobalClock.instance) {
79
+ this.parentClock = parentClock;
80
+ this.tickSub = null;
81
+ this._internalTick$ = new Subject();
82
+ this._tick$ = new Subject();
83
+ /**
84
+ * Tick rate limiter. If set to 0 - tick rate is unlimited, 15 means "allow at most 15 ticks per second"
85
+ */
86
+ this.tickRateLimit = 0;
87
+ // events
88
+ this.paused$ = new Subject();
89
+ // State variables
90
+ this.startedAt = -1;
91
+ this.oldRelativeTime = 0; // "elapsed", emitted on last tick
92
+ this.pausedAt = -1;
93
+ this.lastStopElapsed = 0;
94
+ this._timeScale = 1;
95
+ this.pausedByTimescale = false;
96
+ this.lastFiredTickElapsed = 0;
97
+ if (autoStart) {
98
+ this.start();
99
+ }
100
+ this._internalTick$
101
+ .pipe(map(([_, newTime]) => [newTime, newTime - this.lastFiredTickElapsed]), filter(([elapsed]) => !this.tickRateLimit ||
102
+ Math.floor((this.lastFiredTickElapsed * this.tickRateLimit) / 1000) <
103
+ Math.floor((elapsed * this.tickRateLimit) / 1000)), tap(([elapsed]) => (this.lastFiredTickElapsed = elapsed)))
104
+ .subscribe(this._tick$);
105
+ }
93
106
  /**
94
107
  * Creates a child clock.
95
108
  * @param autoStart Indicates whether the child clock should start automatically.
@@ -124,6 +137,7 @@ export class PausableClock {
124
137
  this.stopListeningTicks();
125
138
  this.pausedAt = this.parentClock.elapsedTime;
126
139
  this.pausedByTimescale = false;
140
+ this.paused$.next(true);
127
141
  }
128
142
  /**
129
143
  * Resumes the clock.
@@ -135,6 +149,7 @@ export class PausableClock {
135
149
  this.startedAt += this.parentClock.elapsedTime - this.pausedAt;
136
150
  this.pausedAt = -1;
137
151
  this.startListeningTicks();
152
+ this.paused$.next(false);
138
153
  }
139
154
  /**
140
155
  * Starts listening for ticks from the parent clock.
@@ -145,7 +160,7 @@ export class PausableClock {
145
160
  }
146
161
  this.tickSub = this.parentClock.tick$
147
162
  .pipe(map(([_, d]) => [this.oldRelativeTime, this.oldRelativeTime + d * this.timeScale]), tap(([_, cur]) => (this.oldRelativeTime = cur)))
148
- .subscribe(this._tick$);
163
+ .subscribe(this._internalTick$);
149
164
  }
150
165
  /**
151
166
  * Stops listening for ticks from the parent clock.
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -13,7 +13,7 @@ import { IVisualSceneComponent } from './i-visual-scene.component';
13
13
  * @property {number} [forceResolution] - Specifies the pixel resolution. Not set by default, which means "use device resolution".
14
14
  * @property {boolean} antialias - Specifies whether antialiasing is turned on/off. true by default.
15
15
  */
16
- export declare type RendererOptions = {
16
+ export type RendererOptions = {
17
17
  transparent: boolean;
18
18
  background: number;
19
19
  size: Point2 | 'fullscreen' | ((pageSize: Point2) => Point2) | Observable<Point2>;
@@ -25,12 +25,12 @@ export declare abstract class IRendererComponent<D, R, VTypeDoc extends VisualTy
25
25
  readonly canvas?: HTMLCanvasElement | undefined;
26
26
  entity: IEntity | null;
27
27
  /** Specifies the options for the renderer. */
28
- readonly rendererOptions: RendererOptions;
28
+ readonly rendererOptions: RendererOptions & Partial<VTypeDoc['rendererExtraOpts']>;
29
29
  /** get flag whether renderer shows physics debugger view */
30
30
  abstract get physicsDebugViewActive(): boolean;
31
31
  /** turns on/off physics debugger view for this renderer */
32
32
  abstract set physicsDebugViewActive(value: boolean);
33
- protected constructor(scene: IVisualSceneComponent<D, R, VTypeDoc>, canvas?: HTMLCanvasElement | undefined, options?: Partial<RendererOptions>);
33
+ protected constructor(scene: IVisualSceneComponent<D, R, VTypeDoc>, canvas?: HTMLCanvasElement | undefined, options?: Partial<RendererOptions & VTypeDoc['rendererExtraOpts']>);
34
34
  /**
35
35
  * Renders the scene.
36
36
  */
File without changes
File without changes
File without changes
@@ -1,8 +1,4 @@
1
1
  export class Graph {
2
- constructor(data) {
3
- this.data = data;
4
- this.adjacent = new Set();
5
- }
6
2
  /**
7
3
  * Creates a new Graph instance from an array of elements, where each element in the array is a node in the graph.
8
4
  * The first element of the array is used as the root node of the graph.
@@ -47,6 +43,10 @@ export class Graph {
47
43
  }
48
44
  return nodes[0][0];
49
45
  }
46
+ constructor(data) {
47
+ this.data = data;
48
+ this.adjacent = new Set();
49
+ }
50
50
  addAdjacent(node) {
51
51
  if (this.adjacent.has(node)) {
52
52
  return false;
@@ -1,7 +1,7 @@
1
1
  import { IEntity } from '../i-entity';
2
2
  import { Observable, Subject } from 'rxjs';
3
3
  import { GgWorld, PhysicsTypeDocRepo, VisualTypeDocRepo } from '../../gg-world';
4
- export declare type AnimationFunction<T> = (elapsed: number, delta: number) => T;
4
+ export type AnimationFunction<T> = (elapsed: number, delta: number) => T;
5
5
  /**
6
6
  * A class that performs property animations for a specific type `T` by using provided animation function.
7
7
  * Supports smooth transition between animation function by interpolating between values over time.
@@ -8,33 +8,6 @@ import { map, tap } from 'rxjs/operators';
8
8
  * The animation function can be changed with `transitAnimationFunction` or `transitFromStaticState`.
9
9
  */
10
10
  export class AnimationMixer extends IEntity {
11
- /**
12
- * Creates a new `AnimationMixer` entity.
13
- * @param _animationFunction The initial motion control function that determines the animation.
14
- * @param _lerp The linear interpolation between two values of type `T`.
15
- */
16
- constructor(_animationFunction, _lerp = (a, b, t) => b) {
17
- super();
18
- this._animationFunction = _animationFunction;
19
- this._lerp = _lerp;
20
- this.tickOrder = TickOrder.ANIMATION_MIXERS;
21
- /**
22
- * A subject that emits the current value of the animation on every tick.
23
- */
24
- this._value$ = new Subject();
25
- /**
26
- * The current transition time reference `[elapsed, delta]` that interpolates between the old and new functions.
27
- */
28
- this._currentTransitionK = [0, 0];
29
- /**
30
- * The current transition subscription, which is null if no transition is currently active.
31
- */
32
- this._currentTransition = null;
33
- /**
34
- * A behavior subject that emits whether the animator is currently in a transition.
35
- */
36
- this._isInTransition$ = new BehaviorSubject(false);
37
- }
38
11
  /**
39
12
  * Gets an observable of the current value of the animation.
40
13
  */
@@ -76,6 +49,33 @@ export class AnimationMixer extends IEntity {
76
49
  this._currentTransition = value;
77
50
  this._isInTransition$.next(!!value);
78
51
  }
52
+ /**
53
+ * Creates a new `AnimationMixer` entity.
54
+ * @param _animationFunction The initial motion control function that determines the animation.
55
+ * @param _lerp The linear interpolation between two values of type `T`.
56
+ */
57
+ constructor(_animationFunction, _lerp = (a, b, t) => b) {
58
+ super();
59
+ this._animationFunction = _animationFunction;
60
+ this._lerp = _lerp;
61
+ this.tickOrder = TickOrder.ANIMATION_MIXERS;
62
+ /**
63
+ * A subject that emits the current value of the animation on every tick.
64
+ */
65
+ this._value$ = new Subject();
66
+ /**
67
+ * The current transition time reference `[elapsed, delta]` that interpolates between the old and new functions.
68
+ */
69
+ this._currentTransitionK = [0, 0];
70
+ /**
71
+ * The current transition subscription, which is null if no transition is currently active.
72
+ */
73
+ this._currentTransition = null;
74
+ /**
75
+ * A behavior subject that emits whether the animator is currently in a transition.
76
+ */
77
+ this._isInTransition$ = new BehaviorSubject(false);
78
+ }
79
79
  /**
80
80
  * Set output to static value and smoothly transit to new control function
81
81
  * @param newFunc a new function
@@ -1,3 +1,3 @@
1
1
  import { GgWorld } from '../../gg-world';
2
2
  import { Observable } from 'rxjs';
3
- export declare function createInlineTickController(world: GgWorld<any, any>, tickOrder?: number): Observable<[number, number]>;
3
+ export declare function createInlineTickController(world: GgWorld<any, any>, tickOrder?: number, name?: string): Observable<[number, number]>;
@@ -6,8 +6,11 @@ class InlineTickController extends IEntity {
6
6
  this.tickOrder = tickOrder;
7
7
  }
8
8
  }
9
- export function createInlineTickController(world, tickOrder = TickOrder.CONTROLLERS) {
9
+ export function createInlineTickController(world, tickOrder = TickOrder.CONTROLLERS, name) {
10
10
  const controller = new InlineTickController(tickOrder);
11
+ if (name) {
12
+ controller.name = name;
13
+ }
11
14
  world.addEntity(controller);
12
15
  return controller.tick$.pipe(finalize(() => {
13
16
  world.removeEntity(controller, true);
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -6,21 +6,6 @@ import { distinctUntilChanged, map } from 'rxjs/operators';
6
6
  * @class
7
7
  */
8
8
  export class IRendererEntity extends IEntity {
9
- /**
10
- Initializes a new instance of the BaseGgRenderer class.
11
- * @param renderer
12
- */
13
- constructor(renderer) {
14
- super();
15
- this.renderer = renderer;
16
- this.tickOrder = TickOrder.RENDERING;
17
- /** Represents the current size of the renderer. */
18
- this._rendererSize$ = new BehaviorSubject(null);
19
- this.addComponents(renderer);
20
- this.tick$.subscribe(() => {
21
- this.renderer.render();
22
- });
23
- }
24
9
  /**
25
10
  * Gets the observable that represents the current size of the renderer.
26
11
  * @returns {Observable<Point2 | null>} - An observable that represents the size of the renderer.
@@ -46,6 +31,21 @@ export class IRendererEntity extends IEntity {
46
31
  set physicsDebugViewActive(value) {
47
32
  this.renderer.physicsDebugViewActive = value;
48
33
  }
34
+ /**
35
+ Initializes a new instance of the BaseGgRenderer class.
36
+ * @param renderer
37
+ */
38
+ constructor(renderer) {
39
+ super();
40
+ this.renderer = renderer;
41
+ this.tickOrder = TickOrder.RENDERING;
42
+ /** Represents the current size of the renderer. */
43
+ this._rendererSize$ = new BehaviorSubject(null);
44
+ this.addComponents(renderer);
45
+ this.tick$.subscribe(() => {
46
+ this.renderer.render();
47
+ });
48
+ }
49
49
  onSpawned(world) {
50
50
  this._rendererSize$.next(null);
51
51
  if (this.rendererOptions.size == 'fullscreen' || typeof this.rendererOptions.size === 'function') {
@@ -1,10 +1,12 @@
1
1
  import { IDisplayObjectComponent, IEntity, IPhysicsWorldComponent, IPositionable, IRenderableEntity, IRendererComponent, IRigidBodyComponent, ITriggerComponent, IVisualSceneComponent, KeyboardInput, PausableClock } from '../base';
2
- export declare type VisualTypeDocRepo<D, R> = {
2
+ import { Subject } from 'rxjs';
3
+ export type VisualTypeDocRepo<D, R> = {
3
4
  factory: unknown;
4
5
  displayObject: IDisplayObjectComponent<D, R>;
5
6
  renderer: IRendererComponent<D, R>;
7
+ rendererExtraOpts: {};
6
8
  };
7
- export declare type PhysicsTypeDocRepo<D, R> = {
9
+ export type PhysicsTypeDocRepo<D, R> = {
8
10
  factory: unknown;
9
11
  rigidBody: IRigidBodyComponent<D, R>;
10
12
  trigger: ITriggerComponent<D, R>;
@@ -12,14 +14,18 @@ export declare type PhysicsTypeDocRepo<D, R> = {
12
14
  export declare abstract class GgWorld<D, R, VTypeDoc extends VisualTypeDocRepo<D, R> = VisualTypeDocRepo<D, R>, PTypeDoc extends PhysicsTypeDocRepo<D, R> = PhysicsTypeDocRepo<D, R>, VS extends IVisualSceneComponent<D, R, VTypeDoc> = IVisualSceneComponent<D, R, VTypeDoc>, PW extends IPhysicsWorldComponent<D, R, PTypeDoc> = IPhysicsWorldComponent<D, R, PTypeDoc>> {
13
15
  readonly visualScene: VS;
14
16
  readonly physicsWorld: PW;
17
+ private static default_name_counter;
18
+ private static _documentWorlds;
19
+ static get documentWorlds(): GgWorld<any, any>[];
15
20
  readonly worldClock: PausableClock;
16
21
  readonly keyboardInput: KeyboardInput;
17
- private static default_name_counter;
18
22
  name: string;
19
23
  readonly children: IEntity[];
20
24
  protected readonly tickListeners: IEntity[];
21
- private static _documentWorlds;
22
- static get documentWorlds(): GgWorld<any, any>[];
25
+ readonly tickStarted$: Subject<void>;
26
+ readonly tickForwardTo$: Subject<IEntity | 'PHYSICS_WORLD'>;
27
+ readonly tickForwardedTo$: Subject<IEntity | 'PHYSICS_WORLD'>;
28
+ readonly paused$: Subject<boolean>;
23
29
  protected constructor(visualScene: VS, physicsWorld: PW);
24
30
  init(): Promise<void>;
25
31
  start(): void;
@@ -8,7 +8,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { GgGlobalClock, IRendererEntity, KeyboardInput, TickOrder, } from '../base';
11
+ import { lastValueFrom, Subject, take } from 'rxjs';
12
+ import { PerformanceMeterEntity } from '../dev';
11
13
  export class GgWorld {
14
+ static get documentWorlds() {
15
+ return [...GgWorld._documentWorlds];
16
+ }
12
17
  constructor(visualScene, physicsWorld) {
13
18
  this.visualScene = visualScene;
14
19
  this.physicsWorld = physicsWorld;
@@ -18,17 +23,14 @@ export class GgWorld {
18
23
  this.children = [];
19
24
  // the same as children, but sorted by tick order
20
25
  this.tickListeners = [];
26
+ // events
27
+ this.tickStarted$ = new Subject();
28
+ this.tickForwardTo$ = new Subject();
29
+ this.tickForwardedTo$ = new Subject();
30
+ this.paused$ = new Subject();
21
31
  GgWorld._documentWorlds.push(this);
22
32
  this.keyboardInput.start();
23
33
  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;
27
- }), 'args: [0 or 1]; turn on/off debug panel. Default value is 0');
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
34
  window.ggstatic.registerConsoleCommand(this, 'ph_timescale', (...args) => __awaiter(this, void 0, void 0, function* () {
33
35
  this.worldClock.timeScale = +args[0];
34
36
  return JSON.stringify(this.worldClock.timeScale);
@@ -56,32 +58,70 @@ export class GgWorld {
56
58
  return 'false';
57
59
  }), 'args: [0 or 1] or [0 or 1, string]; turn on/off physics debug view. Second argument expects renderer ' +
58
60
  'name, if not provided first renderer will be picked. Look up for renderer names using command "ls_renderers"');
61
+ window.ggstatic.registerConsoleCommand(this, 'performance_report', (...args) => __awaiter(this, void 0, void 0, function* () {
62
+ let mode = 'avg';
63
+ let samples = 20;
64
+ for (let i = 0; i < 2; i++) {
65
+ if (['avg', 'peak'].includes(args[i])) {
66
+ mode = args[i];
67
+ }
68
+ else if (!isNaN(+args[i])) {
69
+ samples = +args[i];
70
+ }
71
+ }
72
+ const meter = new PerformanceMeterEntity(samples, 250);
73
+ this.addEntity(meter);
74
+ yield lastValueFrom(this.worldClock.tick$.pipe(take(samples)));
75
+ const report = mode === 'avg' ? meter.avgReport : meter.peakReport;
76
+ this.removeEntity(meter);
77
+ const renderItems = report.entries.map(([name, value]) => `<span style='color:lightgray;'>${name}:</span>` +
78
+ new Array(Math.max(0, 26 - name.length)).join('&nbsp;') +
79
+ `${value.toFixed(2)} ms` +
80
+ (mode === 'avg' ? ` (${((value * 100) / report.totalTime).toFixed(2)}%)` : ''));
81
+ let totalColor = 'lightgreen';
82
+ if (report.totalTime > 12) {
83
+ totalColor = report.totalTime < 16 ? 'yellow' : 'red';
84
+ }
85
+ const title = `${mode === 'avg' ? 'Average' : 'Peak'} Frame time`;
86
+ renderItems.unshift(title +
87
+ ':' +
88
+ new Array(Math.max(0, 26 - title.length)).join('&nbsp;') +
89
+ `<span style='color:${totalColor};'>${report.totalTime.toFixed(2)} ms</span>`);
90
+ renderItems.unshift(`Performance report (${samples} samples)`);
91
+ return renderItems.join('\n');
92
+ }), 'args: [int, avg|peak]; [avg|peak, int]; [avg|peak]; [int] or []; measure how much time was spent per ' +
93
+ 'entity in world. Arguments are samples amount (20 by default) and "peak" or "avg" choice, both arguments are ' +
94
+ 'optional. "avg" report sorts entities by average time consumed, "peak" records highest value for each entity');
59
95
  }
60
- }
61
- static get documentWorlds() {
62
- return [...GgWorld._documentWorlds];
96
+ this.worldClock.paused$.subscribe(this.paused$);
63
97
  }
64
98
  init() {
65
99
  return __awaiter(this, void 0, void 0, function* () {
66
100
  yield Promise.all([this.physicsWorld.init(), this.visualScene.init()]);
101
+ const forwardTick = (listener, elapsed, delta) => {
102
+ if (listener.active) {
103
+ this.tickForwardTo$.next(listener);
104
+ listener.tick$.next([elapsed, delta]);
105
+ this.tickForwardedTo$.next(listener);
106
+ }
107
+ };
67
108
  this.worldClock.tick$.subscribe(([elapsed, delta]) => {
109
+ this.tickStarted$.next();
68
110
  let i = 0;
69
111
  // emit tick to all entities with tick order < GGTickOrder.PHYSICS_SIMULATION
70
112
  for (i; i < this.tickListeners.length; i++) {
71
113
  if (this.tickListeners[i].tickOrder >= TickOrder.PHYSICS_SIMULATION) {
72
114
  break;
73
115
  }
74
- if (this.tickListeners[i].active) {
75
- this.tickListeners[i].tick$.next([elapsed, delta]);
76
- }
116
+ forwardTick(this.tickListeners[i], elapsed, delta);
77
117
  }
78
118
  // run physics simulation
119
+ this.tickForwardTo$.next('PHYSICS_WORLD');
79
120
  this.physicsWorld.simulate(delta);
121
+ this.tickForwardedTo$.next('PHYSICS_WORLD');
80
122
  // emit tick to all remained entities
81
123
  for (i; i < this.tickListeners.length; i++) {
82
- if (this.tickListeners[i].active) {
83
- this.tickListeners[i].tick$.next([elapsed, delta]);
84
- }
124
+ forwardTick(this.tickListeners[i], elapsed, delta);
85
125
  }
86
126
  });
87
127
  });
@@ -113,6 +153,9 @@ export class GgWorld {
113
153
  }
114
154
  this.worldClock.stop();
115
155
  this.keyboardInput.stop();
156
+ this.tickStarted$.complete();
157
+ this.tickForwardTo$.complete();
158
+ this.tickForwardedTo$.complete();
116
159
  for (let i = 0; i < this.children.length; i++) {
117
160
  this.children[i].onRemoved();
118
161
  this.children[i].dispose();
File without changes
File without changes
@@ -4,11 +4,11 @@ import { IInput } from './i-input';
4
4
  /**
5
5
  * The type representing desired keymap for DirectionKeyboardInput
6
6
  */
7
- export declare type DirectionKeyboardKeymap = 'arrows' | 'wasd' | 'wasd+arrows';
7
+ export type DirectionKeyboardKeymap = 'arrows' | 'wasd' | 'wasd+arrows';
8
8
  /**
9
9
  * The type of DirectionKeyboardInput output value
10
10
  */
11
- export declare type DirectionKeyboardOutput = {
11
+ export type DirectionKeyboardOutput = {
12
12
  upDown?: boolean;
13
13
  leftRight?: boolean;
14
14
  };
@@ -6,6 +6,12 @@ import { IInput } from './i-input';
6
6
  * Supports two the most popular keyboard layouts: WASD and arrows.
7
7
  */
8
8
  export class DirectionKeyboardInput extends IInput {
9
+ /**
10
+ * Returns an observable that emits `DirectionKeyboardOutput` objects whenever the input changes.
11
+ */
12
+ get output$() {
13
+ return this._output$.asObservable();
14
+ }
9
15
  /**
10
16
  * Creates a new instance of the `DirectionKeyboardInput` class.
11
17
  *
@@ -21,12 +27,6 @@ export class DirectionKeyboardInput extends IInput {
21
27
  */
22
28
  this._output$ = new Subject();
23
29
  }
24
- /**
25
- * Returns an observable that emits `DirectionKeyboardOutput` objects whenever the input changes.
26
- */
27
- get output$() {
28
- return this._output$.asObservable();
29
- }
30
30
  /**
31
31
  * Called when the input handling should start.
32
32
  */
File without changes
File without changes
File without changes
File without changes
@@ -7,7 +7,7 @@ import { Point2 } from '../models/points';
7
7
  * canvas?: Canvas element. If not provided, mouse events will be listened on the whole window
8
8
  * pointerLock: The flag to enable pointer lock when clicking on canvas
9
9
  */
10
- export declare type MouseInputOptions = {
10
+ export type MouseInputOptions = {
11
11
  canvas?: HTMLCanvasElement;
12
12
  pointerLock: boolean;
13
13
  };
@@ -35,24 +35,6 @@ export var MouseInputState;
35
35
  * A class representing mouse input.
36
36
  */
37
37
  export class MouseInput extends IInput {
38
- /**
39
- Creates an instance of MouseInput.
40
- @param {MouseInputOptions} options - The options for the MouseInput.
41
- */
42
- constructor(options = {}) {
43
- super();
44
- /**
45
- An observable of the wheel scrolling.
46
- */
47
- this._wheel$ = null;
48
- this._delta$ = new Subject();
49
- this._position$ = new BehaviorSubject(Pnt2.O);
50
- this._multiTouchPositions$ = new BehaviorSubject([]);
51
- this.stopped$ = new Subject();
52
- this._state$ = new BehaviorSubject(MouseInputState.NONE);
53
- this.options = Object.assign(Object.assign({}, DEFAULT_MOUSE_INPUT_OPTIONS), options);
54
- this.canvasClickListener = this.canvasClickListener.bind(this);
55
- }
56
38
  static isTouchDevice() {
57
39
  return ('createTouch' in document ||
58
40
  !!navigator.userAgent.match(/(iPhone|iPod|iPad)/) ||
@@ -104,6 +86,24 @@ export class MouseInput extends IInput {
104
86
  get _element() {
105
87
  return this.options.canvas || window;
106
88
  }
89
+ /**
90
+ Creates an instance of MouseInput.
91
+ @param {MouseInputOptions} options - The options for the MouseInput.
92
+ */
93
+ constructor(options = {}) {
94
+ super();
95
+ /**
96
+ An observable of the wheel scrolling.
97
+ */
98
+ this._wheel$ = null;
99
+ this._delta$ = new Subject();
100
+ this._position$ = new BehaviorSubject(Pnt2.O);
101
+ this._multiTouchPositions$ = new BehaviorSubject([]);
102
+ this.stopped$ = new Subject();
103
+ this._state$ = new BehaviorSubject(MouseInputState.NONE);
104
+ this.options = Object.assign(Object.assign({}, DEFAULT_MOUSE_INPUT_OPTIONS), options);
105
+ this.canvasClickListener = this.canvasClickListener.bind(this);
106
+ }
107
107
  startInternal() {
108
108
  if (this.options.canvas) {
109
109
  this.options.canvas.style.touchAction = 'none';
@@ -162,11 +162,16 @@ export class MouseInput extends IInput {
162
162
  .pipe(takeUntil(this.stopped$))
163
163
  .subscribe((event) => {
164
164
  if (pointers.length === 0) {
165
- if (this.options.canvas) {
166
- this.options.canvas.setPointerCapture(event.pointerId);
165
+ try {
166
+ if (this.options.canvas) {
167
+ this.options.canvas.setPointerCapture(event.pointerId);
168
+ }
169
+ this._element.addEventListener('pointerup', onPointerUp);
170
+ this._element.addEventListener('pointercancel', onPointerUp);
171
+ }
172
+ catch (err) {
173
+ console.error(err);
167
174
  }
168
- this._element.addEventListener('pointerup', onPointerUp);
169
- this._element.addEventListener('pointercancel', onPointerUp);
170
175
  }
171
176
  pointers.push(event);
172
177
  if (event.pointerType === 'touch') {
File without changes