dacha 0.18.0-alpha.9 → 0.18.0

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 (49) hide show
  1. package/build/contrib/components/index.d.ts +1 -0
  2. package/build/contrib/components/index.js +1 -0
  3. package/build/contrib/components/interpolation/index.d.ts +85 -0
  4. package/build/contrib/components/interpolation/index.js +101 -0
  5. package/build/contrib/components/rigid-body/index.d.ts +8 -0
  6. package/build/contrib/components/rigid-body/index.js +8 -0
  7. package/build/contrib/systems/index.d.ts +2 -0
  8. package/build/contrib/systems/index.js +1 -0
  9. package/build/contrib/systems/interpolator/api.d.ts +40 -0
  10. package/build/contrib/systems/interpolator/api.js +70 -0
  11. package/build/contrib/systems/interpolator/index.d.ts +3 -0
  12. package/build/contrib/systems/interpolator/index.js +2 -0
  13. package/build/contrib/systems/interpolator/system.d.ts +31 -0
  14. package/build/contrib/systems/interpolator/system.js +96 -0
  15. package/build/contrib/systems/interpolator/tests/helpers.d.ts +13 -0
  16. package/build/contrib/systems/interpolator/tests/helpers.js +45 -0
  17. package/build/contrib/systems/interpolator/utils.d.ts +5 -0
  18. package/build/contrib/systems/interpolator/utils.js +41 -0
  19. package/build/contrib/systems/physics-system/api.d.ts +45 -1
  20. package/build/contrib/systems/physics-system/api.js +49 -0
  21. package/build/contrib/systems/physics-system/consts.d.ts +3 -1
  22. package/build/contrib/systems/physics-system/consts.js +4 -1
  23. package/build/contrib/systems/physics-system/physics-system.js +7 -1
  24. package/build/contrib/systems/physics-system/subsystems/collision-detection/dynamic-aabb-tree/index.d.ts +1 -1
  25. package/build/contrib/systems/physics-system/subsystems/collision-detection/dynamic-aabb-tree/index.js +21 -15
  26. package/build/contrib/systems/physics-system/subsystems/collision-detection/index.d.ts +11 -11
  27. package/build/contrib/systems/physics-system/subsystems/collision-detection/index.js +130 -124
  28. package/build/contrib/systems/physics-system/subsystems/collision-detection/query-utils.d.ts +5 -0
  29. package/build/contrib/systems/physics-system/subsystems/collision-detection/query-utils.js +97 -81
  30. package/build/contrib/systems/physics-system/subsystems/collision-detection/types.d.ts +0 -15
  31. package/build/contrib/systems/physics-system/subsystems/collision-detection/utils.d.ts +3 -0
  32. package/build/contrib/systems/physics-system/subsystems/collision-detection/utils.js +9 -0
  33. package/build/contrib/systems/physics-system/subsystems/physics/mass-properties.js +1 -1
  34. package/build/contrib/systems/physics-system/types.d.ts +12 -2
  35. package/build/contrib/systems/renderer/actor-render-tree.js +15 -6
  36. package/build/engine/data-lib/index.d.ts +1 -1
  37. package/build/engine/data-lib/index.js +1 -1
  38. package/build/engine/data-lib/pool.d.ts +9 -0
  39. package/build/engine/data-lib/pool.js +19 -0
  40. package/build/engine/game-loop.js +3 -3
  41. package/build/engine/math-lib/math/ops.d.ts +16 -0
  42. package/build/engine/math-lib/math/ops.js +25 -0
  43. package/package.json +1 -1
  44. package/build/contrib/systems/physics-system/subsystems/collision-detection/dispersion-calculator/index.d.ts +0 -11
  45. package/build/contrib/systems/physics-system/subsystems/collision-detection/dispersion-calculator/index.js +0 -41
  46. package/build/engine/data-lib/sort/index.d.ts +0 -1
  47. package/build/engine/data-lib/sort/index.js +0 -1
  48. package/build/engine/data-lib/sort/insertion-sort.d.ts +0 -1
  49. package/build/engine/data-lib/sort/insertion-sort.js +0 -14
@@ -1,5 +1,8 @@
1
+ import type { ActorProxy } from './types';
1
2
  export declare const isZero: (value: number) => boolean;
2
3
  export declare const isDefinitelyPositive: (value: number) => boolean;
3
4
  export declare const isDefinitelyNegative: (value: number) => boolean;
4
5
  export declare const isGreaterThan: (left: number, right: number) => boolean;
5
6
  export declare const isLessThan: (left: number, right: number) => boolean;
7
+ export declare const isStatic: (proxy: ActorProxy) => boolean;
8
+ export declare const isDisabled: (proxy: ActorProxy) => boolean;
@@ -1,6 +1,15 @@
1
+ import { RigidBody, Collider } from '../../../../components';
1
2
  import { INTERSECTION_EPSILON } from './constants';
2
3
  export const isZero = (value) => Math.abs(value) <= INTERSECTION_EPSILON;
3
4
  export const isDefinitelyPositive = (value) => value > INTERSECTION_EPSILON;
4
5
  export const isDefinitelyNegative = (value) => value < -INTERSECTION_EPSILON;
5
6
  export const isGreaterThan = (left, right) => isDefinitelyPositive(left - right);
6
7
  export const isLessThan = (left, right) => isDefinitelyNegative(left - right);
8
+ export const isStatic = (proxy) => {
9
+ const rigidBody = proxy.actor.getComponent(RigidBody);
10
+ return rigidBody?.type === 'static';
11
+ };
12
+ export const isDisabled = (proxy) => {
13
+ const collider = proxy.actor.getComponent(Collider);
14
+ return collider?.disabled === true;
15
+ };
@@ -47,7 +47,7 @@ export const calculateInertia = (mass, collider, transform) => {
47
47
  if (length <= 0) {
48
48
  return 0;
49
49
  }
50
- inertia = (mass * (length * length + 1)) / 12;
50
+ inertia = (mass * length * length) / 12;
51
51
  break;
52
52
  }
53
53
  }
@@ -2,8 +2,8 @@ import type { SceneSystemOptions } from '../../../engine/system';
2
2
  import type { Actor } from '../../../engine/actor';
3
3
  import type { Vector2, Point } from '../../../engine/math-lib';
4
4
  export interface PhysicsSystemOptions extends SceneSystemOptions {
5
- gravityX: number;
6
- gravityY: number;
5
+ gravityX?: number;
6
+ gravityY?: number;
7
7
  solverIterations?: number;
8
8
  linearSleepThreshold?: number;
9
9
  angularSleepThreshold?: number;
@@ -24,6 +24,14 @@ export interface PhysicsQueryFilter<T> {
24
24
  layer?: string;
25
25
  excludeActors?: Actor[];
26
26
  actorFilter?: (actor: Actor) => boolean;
27
+ /**
28
+ * Called once per candidate hit to decide whether to keep it.
29
+ *
30
+ * The `hit` object passed to this callback may be reused and is only valid
31
+ * for the duration of the call.
32
+ * Inspect it and return a boolean; do not retain the reference or store it
33
+ * in an external collection.
34
+ */
27
35
  hitFilter?: (hit: T) => boolean;
28
36
  }
29
37
  export interface CommonCastParams extends PhysicsQueryFilter<CastHit> {
@@ -45,6 +53,8 @@ export interface OverlapHit {
45
53
  penetration: number;
46
54
  contactPoints: Point[];
47
55
  }
56
+ export type CastHitCallback = (hit: CastHit) => void;
57
+ export type OverlapHitCallback = (hit: OverlapHit) => void;
48
58
  export interface PointQueryShape {
49
59
  type: 'point';
50
60
  point: Point;
@@ -1,6 +1,7 @@
1
1
  import { Container } from 'pixi.js';
2
2
  import { Actor } from '../../../engine/actor';
3
3
  import { Transform } from '../../components/transform';
4
+ import { Interpolation } from '../../components/interpolation';
4
5
  import { Sprite } from '../../components/sprite';
5
6
  import { Shape } from '../../components/shape';
6
7
  import { PixiView } from '../../components/pixi-view';
@@ -146,17 +147,25 @@ export class ActorRenderTree {
146
147
  this.actorParentMap.set(actor, actor.parent);
147
148
  }
148
149
  updatePosition(container, actor) {
149
- const { local: { position, rotation, scale }, } = actor.getComponent(Transform);
150
+ const { local } = actor.getComponent(Transform);
151
+ const interpolation = actor.getComponent(Interpolation);
152
+ const useRender = interpolation !== undefined &&
153
+ !interpolation.disabled &&
154
+ interpolation.initialized;
155
+ const positionX = useRender ? interpolation.renderX : local.position.x;
156
+ const positionY = useRender ? interpolation.renderY : local.position.y;
157
+ const rotation = useRender ? interpolation.renderRotation : local.rotation;
158
+ const { scale } = local;
150
159
  const meta = container.__dacha.meta;
151
160
  if (rotation !== meta.rotation) {
152
161
  container.rotation = rotation;
153
162
  meta.rotation = rotation;
154
163
  }
155
- if (!floatEquals(position.x, meta.positionX) ||
156
- !floatEquals(position.y, meta.positionY)) {
157
- container.position.set(position.x, position.y);
158
- meta.positionX = position.x;
159
- meta.positionY = position.y;
164
+ if (!floatEquals(positionX, meta.positionX) ||
165
+ !floatEquals(positionY, meta.positionY)) {
166
+ container.position.set(positionX, positionY);
167
+ meta.positionX = positionX;
168
+ meta.positionY = positionY;
160
169
  }
161
170
  if (scale.x !== meta.scaleX || scale.y !== meta.scaleY) {
162
171
  container.scale.set(scale.x, scale.y);
@@ -1,3 +1,3 @@
1
1
  export { Queue } from './queue';
2
2
  export { CacheStore } from './cache-store';
3
- export { insertionSort } from './sort';
3
+ export { Pool } from './pool';
@@ -1,3 +1,3 @@
1
1
  export { Queue } from './queue';
2
2
  export { CacheStore } from './cache-store';
3
- export { insertionSort } from './sort';
3
+ export { Pool } from './pool';
@@ -0,0 +1,9 @@
1
+ export declare class Pool<T> {
2
+ private factory;
3
+ private reset?;
4
+ private items;
5
+ constructor(factory: () => T, reset?: ((item: T) => void) | undefined);
6
+ acquire(): T;
7
+ release(item: T): void;
8
+ clear(): void;
9
+ }
@@ -0,0 +1,19 @@
1
+ export class Pool {
2
+ factory;
3
+ reset;
4
+ items = [];
5
+ constructor(factory, reset) {
6
+ this.factory = factory;
7
+ this.reset = reset;
8
+ }
9
+ acquire() {
10
+ return this.items.pop() ?? this.factory();
11
+ }
12
+ release(item) {
13
+ this.reset?.(item);
14
+ this.items.push(item);
15
+ }
16
+ clear() {
17
+ this.items.length = 0;
18
+ }
19
+ }
@@ -27,10 +27,10 @@ export class GameLoop {
27
27
  this.lag = 0;
28
28
  this.bindedTick = this.tick.bind(this);
29
29
  }
30
- tick() {
30
+ tick(timestamp) {
31
31
  this.gameLoopId = requestAnimationFrame(this.bindedTick);
32
- const current = performance.now();
33
- const elapsed = Math.min(current - this.previous, this.maxFrameDelta);
32
+ const current = timestamp;
33
+ const elapsed = Math.min(Math.max(current - this.previous, 0), this.maxFrameDelta);
34
34
  if (elapsed < this.msPerUpdate) {
35
35
  return;
36
36
  }
@@ -118,4 +118,20 @@ export declare class MathOps {
118
118
  * ```
119
119
  */
120
120
  static clamp(value: number, min: number, max: number): number;
121
+ /**
122
+ * Signed shortest angular difference between two angles in radians
123
+ *
124
+ * The result is in (-PI, PI], so `from + delta` is angle-equivalent
125
+ * to `to` while rotating the short way around.
126
+ *
127
+ * @param from - Start angle in radians
128
+ * @param to - End angle in radians
129
+ * @returns Signed delta in radians
130
+ *
131
+ * @example
132
+ * ```typescript
133
+ * const delta = MathOps.getAngleDelta(3, -3); // ~0.283, crosses PI
134
+ * ```
135
+ */
136
+ static getAngleDelta(from: number, to: number): number;
121
137
  }
@@ -134,4 +134,29 @@ export class MathOps {
134
134
  }
135
135
  return value;
136
136
  }
137
+ /**
138
+ * Signed shortest angular difference between two angles in radians
139
+ *
140
+ * The result is in (-PI, PI], so `from + delta` is angle-equivalent
141
+ * to `to` while rotating the short way around.
142
+ *
143
+ * @param from - Start angle in radians
144
+ * @param to - End angle in radians
145
+ * @returns Signed delta in radians
146
+ *
147
+ * @example
148
+ * ```typescript
149
+ * const delta = MathOps.getAngleDelta(3, -3); // ~0.283, crosses PI
150
+ * ```
151
+ */
152
+ static getAngleDelta(from, to) {
153
+ let delta = (to - from) % (2 * Math.PI);
154
+ if (delta > Math.PI) {
155
+ delta -= 2 * Math.PI;
156
+ }
157
+ else if (delta <= -Math.PI) {
158
+ delta += 2 * Math.PI;
159
+ }
160
+ return delta;
161
+ }
137
162
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dacha",
3
- "version": "0.18.0-alpha.9",
3
+ "version": "0.18.0",
4
4
  "main": "./build/index.js",
5
5
  "types": "./build/index.d.ts",
6
6
  "exports": {
@@ -1,11 +0,0 @@
1
- import type { Axis, AABB } from '../types';
2
- export declare class DispersionCalculator {
3
- private axis;
4
- private sampleSize;
5
- private sum;
6
- private squaredSum;
7
- constructor(axis: Axis);
8
- addToSample(aabb: AABB): void;
9
- removeFromSample(aabb: AABB): void;
10
- getDispersion(): number;
11
- }
@@ -1,41 +0,0 @@
1
- export class DispersionCalculator {
2
- axis;
3
- sampleSize;
4
- sum;
5
- squaredSum;
6
- constructor(axis) {
7
- this.axis = axis;
8
- this.sampleSize = 0;
9
- this.sum = 0;
10
- this.squaredSum = 0;
11
- }
12
- addToSample(aabb) {
13
- const average = (aabb.min[this.axis] + aabb.max[this.axis]) * 0.5;
14
- this.sum += average;
15
- this.squaredSum += average ** 2;
16
- this.sampleSize += 1;
17
- }
18
- removeFromSample(aabb) {
19
- if (this.sampleSize === 0) {
20
- return;
21
- }
22
- this.sampleSize -= 1;
23
- if (this.sampleSize === 0) {
24
- this.sum = 0;
25
- this.squaredSum = 0;
26
- }
27
- else {
28
- const average = (aabb.min[this.axis] + aabb.max[this.axis]) * 0.5;
29
- this.sum -= average;
30
- this.squaredSum -= average ** 2;
31
- }
32
- }
33
- getDispersion() {
34
- if (this.sampleSize <= 1) {
35
- return 0;
36
- }
37
- const average = this.sum / this.sampleSize;
38
- const dispersion = this.squaredSum / this.sampleSize - average ** 2;
39
- return Math.max(0, dispersion);
40
- }
41
- }
@@ -1 +0,0 @@
1
- export { insertionSort } from './insertion-sort';
@@ -1 +0,0 @@
1
- export { insertionSort } from './insertion-sort';
@@ -1 +0,0 @@
1
- export declare const insertionSort: <T>(array: T[], compareFn: (arg1: T, arg2: T) => number) => T[];
@@ -1,14 +0,0 @@
1
- export const insertionSort = (array, compareFn) => {
2
- let i = 1;
3
- while (i < array.length) {
4
- let j = i;
5
- const x = array[j];
6
- while (j > 0 && compareFn(x, array[j - 1]) < 0) {
7
- array[j] = array[j - 1];
8
- j -= 1;
9
- }
10
- array[j] = x;
11
- i += 1;
12
- }
13
- return array;
14
- };