dacha 0.17.2 → 0.18.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/contrib/components/collider/index.d.ts +17 -4
- package/build/contrib/components/collider/index.js +30 -2
- package/build/contrib/components/rigid-body/index.d.ts +29 -17
- package/build/contrib/components/rigid-body/index.js +64 -21
- package/build/contrib/components/shape/index.d.ts +17 -2
- package/build/contrib/components/shape/index.js +16 -0
- package/build/contrib/events/index.d.ts +10 -75
- package/build/contrib/events/index.js +0 -36
- package/build/contrib/systems/camera-system/{service.d.ts → api.d.ts} +4 -4
- package/build/contrib/systems/camera-system/{service.js → api.js} +2 -2
- package/build/contrib/systems/camera-system/index.d.ts +1 -1
- package/build/contrib/systems/camera-system/index.js +1 -1
- package/build/contrib/systems/camera-system/system.d.ts +1 -1
- package/build/contrib/systems/camera-system/system.js +5 -4
- package/build/contrib/systems/index.d.ts +3 -3
- package/build/contrib/systems/index.js +3 -3
- package/build/contrib/systems/mouse-input-system/subsystems/coordinates-projector/index.d.ts +0 -1
- package/build/contrib/systems/mouse-input-system/subsystems/coordinates-projector/index.js +4 -5
- package/build/contrib/systems/physics-system/api.d.ts +58 -0
- package/build/contrib/systems/physics-system/api.js +67 -0
- package/build/contrib/systems/physics-system/index.d.ts +2 -21
- package/build/contrib/systems/physics-system/index.js +2 -40
- package/build/contrib/systems/physics-system/physics-system.d.ts +24 -0
- package/build/contrib/systems/physics-system/physics-system.js +47 -0
- package/build/contrib/systems/physics-system/subsystems/collision-broadcast/collision.d.ts +5 -3
- package/build/contrib/systems/physics-system/subsystems/collision-broadcast/collision.js +7 -5
- package/build/contrib/systems/physics-system/subsystems/collision-broadcast/index.d.ts +4 -6
- package/build/contrib/systems/physics-system/subsystems/collision-broadcast/index.js +20 -17
- package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-circle-aabb.js +1 -2
- package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-point-aabb.d.ts +2 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-point-aabb.js +7 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-ray-aabb.d.ts +2 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-ray-aabb.js +9 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-segment-aabb.d.ts +2 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/build-segment-aabb.js +14 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/aabb-builders/index.js +6 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-box-geometry.d.ts +3 -1
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-box-geometry.js +52 -16
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-circle-geometry.d.ts +3 -1
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-circle-geometry.js +32 -7
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-point-geometry.d.ts +3 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-point-geometry.js +5 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-ray-geometry.d.ts +3 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-ray-geometry.js +7 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-segment-geometry.d.ts +3 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/build-segment-geometry.js +33 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/index.d.ts +12 -1
- package/build/contrib/systems/physics-system/subsystems/collision-detection/geometry-builders/index.js +6 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/index.d.ts +21 -9
- package/build/contrib/systems/physics-system/subsystems/collision-detection/index.js +177 -92
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/check-boxes-intersection.d.ts +10 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/check-boxes-intersection.js +36 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/utils.d.ts +17 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-box/utils.js +126 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-circle/check-box-and-circle-intersection.d.ts +9 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-circle/check-box-and-circle-intersection.js +46 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-segment/check-box-and-segment-intersection.d.ts +10 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-segment/check-box-and-segment-intersection.js +28 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-segment/utils.d.ts +19 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/box-segment/utils.js +76 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/circle-circle/check-circles-intersection.d.ts +12 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/circle-circle/check-circles-intersection.js +47 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/circle-segment/check-circle-and-segment-intersection.d.ts +10 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/circle-segment/check-circle-and-segment-intersection.js +33 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/index.d.ts +2 -2
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/index.js +27 -3
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-box/check-point-and-box-intersection.d.ts +9 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-box/check-point-and-box-intersection.js +36 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-circle/check-point-and-circle-intersection.d.ts +9 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-circle/check-point-and-circle-intersection.js +33 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-segment/check-point-and-segment-intersection.d.ts +9 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/point-segment/check-point-and-segment-intersection.js +26 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-box/check-ray-and-box-intersection.d.ts +11 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-box/check-ray-and-box-intersection.js +69 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-circle/check-ray-and-circle-intersection.d.ts +10 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-circle/check-ray-and-circle-intersection.js +45 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-segment/check-ray-and-segment-intersection.d.ts +16 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-segment/check-ray-and-segment-intersection.js +51 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-segment/utils.d.ts +2 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/ray-segment/utils.js +4 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/tests/helpers.d.ts +20 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/tests/helpers.js +69 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/utils.d.ts +9 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/utils.js +23 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/query-utils.d.ts +10 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/query-utils.js +63 -0
- package/build/contrib/systems/physics-system/subsystems/collision-detection/reorientation-checkers/check-collider.js +17 -8
- package/build/contrib/systems/physics-system/subsystems/collision-detection/types.d.ts +41 -11
- package/build/contrib/systems/physics-system/subsystems/collision-detection/types.js +0 -3
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/index.d.ts +7 -10
- package/build/contrib/systems/physics-system/subsystems/constraint-solver/index.js +117 -79
- package/build/contrib/systems/physics-system/subsystems/index.d.ts +0 -1
- package/build/contrib/systems/physics-system/subsystems/index.js +0 -1
- package/build/contrib/systems/physics-system/subsystems/physics/index.d.ts +3 -9
- package/build/contrib/systems/physics-system/subsystems/physics/index.js +57 -93
- package/build/contrib/systems/physics-system/types.d.ts +37 -0
- package/build/contrib/systems/renderer/actor-render-tree.js +1 -2
- package/build/contrib/systems/renderer/{service → api}/index.d.ts +6 -6
- package/build/contrib/systems/renderer/{service → api}/index.js +14 -16
- package/build/contrib/systems/renderer/api/utils.d.ts +4 -0
- package/build/contrib/systems/renderer/{service → api}/utils.js +5 -0
- package/build/contrib/systems/renderer/builders/shape-builder/index.js +9 -1
- package/build/contrib/systems/renderer/builders/shape-builder/utils.js +16 -0
- package/build/contrib/systems/renderer/index.d.ts +1 -1
- package/build/contrib/systems/renderer/index.js +1 -1
- package/build/contrib/systems/renderer/renderer.d.ts +2 -1
- package/build/contrib/systems/renderer/renderer.js +9 -7
- package/build/engine/actor/actor-creator.js +6 -4
- package/build/engine/math-lib/math/ops.d.ts +1 -2
- package/build/engine/math-lib/math/ops.js +3 -3
- package/build/engine/math-lib/vector/ops.d.ts +18 -3
- package/build/engine/math-lib/vector/ops.js +28 -5
- package/build/engine/math-lib/vector/vector2.d.ts +22 -7
- package/build/engine/math-lib/vector/vector2.js +29 -5
- package/build/engine/template/template-collection.js +1 -1
- package/build/engine/world/index.d.ts +4 -24
- package/build/engine/world/index.js +5 -33
- package/build/engine/world/system-api-registry.d.ts +17 -0
- package/build/engine/world/system-api-registry.js +34 -0
- package/build/events/index.d.ts +2 -2
- package/build/events/index.js +1 -1
- package/build/types/global.d.ts +4 -0
- package/package.json +4 -1
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-box-and-circle-intersection.d.ts +0 -16
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-box-and-circle-intersection.js +0 -80
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-boxes-intersection.d.ts +0 -6
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-boxes-intersection.js +0 -72
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-circles-intersection.d.ts +0 -11
- package/build/contrib/systems/physics-system/subsystems/collision-detection/intersection-checkers/check-circles-intersection.js +0 -39
- package/build/contrib/systems/physics-system/subsystems/collision-solver/index.d.ts +0 -10
- package/build/contrib/systems/physics-system/subsystems/collision-solver/index.js +0 -50
- package/build/contrib/systems/renderer/service/utils.d.ts +0 -3
|
@@ -1,13 +1,38 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export function buildCircleGeometry(colliderOrOverlap, transform) {
|
|
2
|
+
let centerX;
|
|
3
|
+
let centerY;
|
|
4
|
+
let radius;
|
|
5
|
+
let positionX;
|
|
6
|
+
let positionY;
|
|
7
|
+
let scaleX;
|
|
8
|
+
let scaleY;
|
|
9
|
+
if (transform !== undefined) {
|
|
10
|
+
const collider = colliderOrOverlap;
|
|
11
|
+
centerX = collider.centerX;
|
|
12
|
+
centerY = collider.centerY;
|
|
13
|
+
radius = collider.radius;
|
|
14
|
+
positionX = transform.world.position.x;
|
|
15
|
+
positionY = transform.world.position.y;
|
|
16
|
+
scaleX = transform.world.scale.x;
|
|
17
|
+
scaleY = transform.world.scale.y;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
const overlap = colliderOrOverlap;
|
|
21
|
+
centerX = 0;
|
|
22
|
+
centerY = 0;
|
|
23
|
+
radius = overlap.radius;
|
|
24
|
+
positionX = overlap.center.x;
|
|
25
|
+
positionY = overlap.center.y;
|
|
26
|
+
scaleX = 1;
|
|
27
|
+
scaleY = 1;
|
|
28
|
+
}
|
|
4
29
|
const center = {
|
|
5
|
-
x: centerX +
|
|
6
|
-
y: centerY +
|
|
30
|
+
x: centerX + positionX,
|
|
31
|
+
y: centerY + positionY,
|
|
7
32
|
};
|
|
8
|
-
const scaledRadius = radius * Math.max(
|
|
33
|
+
const scaledRadius = radius * Math.max(scaleX, scaleY);
|
|
9
34
|
return {
|
|
10
35
|
center,
|
|
11
36
|
radius: scaledRadius,
|
|
12
37
|
};
|
|
13
|
-
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { VectorOps } from '../../../../../../engine/math-lib';
|
|
2
|
+
export function buildSegmentGeometry(collider, transform) {
|
|
3
|
+
const centerX = collider.centerX + transform.world.position.x;
|
|
4
|
+
const centerY = collider.centerY + transform.world.position.y;
|
|
5
|
+
const point1X = collider.point1?.x ?? 0;
|
|
6
|
+
const point1Y = collider.point1?.y ?? 0;
|
|
7
|
+
const point2X = collider.point2?.x ?? 0;
|
|
8
|
+
const point2Y = collider.point2?.y ?? 0;
|
|
9
|
+
const rotation = transform.world.rotation;
|
|
10
|
+
const scaleX = transform.world.scale.x;
|
|
11
|
+
const scaleY = transform.world.scale.y;
|
|
12
|
+
const cos = Math.cos(rotation);
|
|
13
|
+
const sin = Math.sin(rotation);
|
|
14
|
+
const buildPoint = (x, y) => {
|
|
15
|
+
const scaledX = x * scaleX;
|
|
16
|
+
const scaledY = y * scaleY;
|
|
17
|
+
return {
|
|
18
|
+
x: scaledX * cos - scaledY * sin + centerX,
|
|
19
|
+
y: scaledX * sin + scaledY * cos + centerY,
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
const point1 = buildPoint(point1X, point1Y);
|
|
23
|
+
const point2 = buildPoint(point2X, point2Y);
|
|
24
|
+
return {
|
|
25
|
+
center: {
|
|
26
|
+
x: (point1.x + point2.x) / 2,
|
|
27
|
+
y: (point1.y + point2.y) / 2,
|
|
28
|
+
},
|
|
29
|
+
point1,
|
|
30
|
+
point2,
|
|
31
|
+
normal: VectorOps.getNormal(point1.x, point2.x, point1.y, point2.y),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import type { Collider, Transform } from '../../../../../components';
|
|
2
2
|
import type { Geometry } from '../types';
|
|
3
|
+
import { buildBoxGeometry } from './build-box-geometry';
|
|
4
|
+
import { buildCircleGeometry } from './build-circle-geometry';
|
|
5
|
+
import { buildPointGeometry } from './build-point-geometry';
|
|
6
|
+
import { buildRayGeometry } from './build-ray-geometry';
|
|
7
|
+
import { buildSegmentGeometry } from './build-segment-geometry';
|
|
3
8
|
export type BuildGeometryFn = (collider: Collider, transform: Transform) => Geometry;
|
|
4
|
-
export declare const geometryBuilders:
|
|
9
|
+
export declare const geometryBuilders: {
|
|
10
|
+
box: typeof buildBoxGeometry;
|
|
11
|
+
circle: typeof buildCircleGeometry;
|
|
12
|
+
segment: typeof buildSegmentGeometry;
|
|
13
|
+
point: typeof buildPointGeometry;
|
|
14
|
+
ray: typeof buildRayGeometry;
|
|
15
|
+
};
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { buildBoxGeometry } from './build-box-geometry';
|
|
2
2
|
import { buildCircleGeometry } from './build-circle-geometry';
|
|
3
|
+
import { buildPointGeometry } from './build-point-geometry';
|
|
4
|
+
import { buildRayGeometry } from './build-ray-geometry';
|
|
5
|
+
import { buildSegmentGeometry } from './build-segment-geometry';
|
|
3
6
|
export const geometryBuilders = {
|
|
4
7
|
box: buildBoxGeometry,
|
|
5
8
|
circle: buildCircleGeometry,
|
|
9
|
+
segment: buildSegmentGeometry,
|
|
10
|
+
point: buildPointGeometry,
|
|
11
|
+
ray: buildRayGeometry,
|
|
6
12
|
};
|
|
@@ -1,28 +1,40 @@
|
|
|
1
1
|
import type { SceneSystemOptions } from '../../../../../engine/system';
|
|
2
|
+
import type { Actor } from '../../../../../engine/actor';
|
|
3
|
+
import type { RaycastParams, RaycastHit, OverlapPointParams, OverlapCircleParams, OverlapBoxParams } from '../../types';
|
|
4
|
+
import type { Contact } from './types';
|
|
2
5
|
export declare class CollisionDetectionSubsystem {
|
|
3
6
|
private actorQuery;
|
|
4
|
-
private scene;
|
|
5
7
|
private axis;
|
|
6
|
-
private
|
|
7
|
-
private
|
|
8
|
-
private
|
|
8
|
+
private proxiesByActorId;
|
|
9
|
+
private proxyPairs;
|
|
10
|
+
private contacts;
|
|
11
|
+
private actorIdsToDelete;
|
|
12
|
+
private collisionMatrix;
|
|
13
|
+
private queryCandidates;
|
|
9
14
|
constructor(options: SceneSystemOptions);
|
|
10
15
|
destroy(): void;
|
|
16
|
+
raycast(params: RaycastParams): RaycastHit | null;
|
|
17
|
+
raycastAll(params: RaycastParams): RaycastHit[];
|
|
18
|
+
overlapPoint(params: OverlapPointParams): Actor[];
|
|
19
|
+
overlapCircle(params: OverlapCircleParams): Actor[];
|
|
20
|
+
overlapBox(params: OverlapBoxParams): Actor[];
|
|
11
21
|
private handleActorAdd;
|
|
12
22
|
private handleActorRemove;
|
|
13
23
|
private checkOnReorientation;
|
|
14
24
|
private getOrientationData;
|
|
15
|
-
private
|
|
16
|
-
private
|
|
25
|
+
private addProxy;
|
|
26
|
+
private updateProxy;
|
|
17
27
|
private addToSortedList;
|
|
18
28
|
private updateSortedList;
|
|
19
29
|
private clearSortedList;
|
|
20
30
|
private getAxes;
|
|
21
31
|
private areStaticBodies;
|
|
22
32
|
private testAABB;
|
|
33
|
+
private testCollisionLayers;
|
|
34
|
+
private sweepAndPruneQuery;
|
|
23
35
|
private sweepAndPrune;
|
|
24
36
|
private checkOnIntersection;
|
|
25
|
-
private
|
|
26
|
-
private
|
|
27
|
-
update():
|
|
37
|
+
private storeContact;
|
|
38
|
+
private clearDeletedProxies;
|
|
39
|
+
update(): Contact[];
|
|
28
40
|
}
|
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
import { ActorQuery } from '../../../../../engine/actor';
|
|
2
2
|
import { Transform, Collider, RigidBody } from '../../../../components';
|
|
3
3
|
import { AddActor, RemoveActor } from '../../../../../engine/events';
|
|
4
|
-
import { Collision } from '../../../../events';
|
|
5
4
|
import { insertionSort } from '../../../../../engine/data-lib';
|
|
6
5
|
import { geometryBuilders } from './geometry-builders';
|
|
7
6
|
import { aabbBuilders } from './aabb-builders';
|
|
8
7
|
import { intersectionCheckers } from './intersection-checkers';
|
|
9
8
|
import { DispersionCalculator } from './dispersion-calculator';
|
|
10
9
|
import { checkTransform, checkCollider } from './reorientation-checkers';
|
|
10
|
+
import { buildQueryProxy, raycast, raycastAll, overlap } from './query-utils';
|
|
11
11
|
export class CollisionDetectionSubsystem {
|
|
12
12
|
actorQuery;
|
|
13
|
-
scene;
|
|
14
13
|
axis;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
proxiesByActorId;
|
|
15
|
+
proxyPairs;
|
|
16
|
+
contacts;
|
|
17
|
+
actorIdsToDelete;
|
|
18
|
+
collisionMatrix;
|
|
19
|
+
queryCandidates;
|
|
18
20
|
constructor(options) {
|
|
21
|
+
const settings = options.globalOptions.physics;
|
|
19
22
|
this.actorQuery = new ActorQuery({
|
|
20
23
|
scene: options.scene,
|
|
21
24
|
filter: [Collider, Transform],
|
|
22
25
|
});
|
|
23
|
-
this.scene = options.scene;
|
|
24
26
|
this.axis = {
|
|
25
27
|
x: {
|
|
26
28
|
sortedList: [],
|
|
@@ -31,34 +33,61 @@ export class CollisionDetectionSubsystem {
|
|
|
31
33
|
dispersionCalculator: new DispersionCalculator('y'),
|
|
32
34
|
},
|
|
33
35
|
};
|
|
34
|
-
this.
|
|
35
|
-
this.
|
|
36
|
-
this.
|
|
37
|
-
this.
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
this.proxiesByActorId = new Map();
|
|
37
|
+
this.proxyPairs = [];
|
|
38
|
+
this.contacts = [];
|
|
39
|
+
this.actorIdsToDelete = new Set();
|
|
40
|
+
this.collisionMatrix = settings?.collisionMatrix ?? {};
|
|
41
|
+
this.queryCandidates = [];
|
|
42
|
+
this.actorQuery.getActors().forEach((actor) => this.addProxy(actor));
|
|
40
43
|
this.actorQuery.addEventListener(AddActor, this.handleActorAdd);
|
|
41
44
|
this.actorQuery.addEventListener(RemoveActor, this.handleActorRemove);
|
|
42
45
|
}
|
|
43
46
|
destroy() {
|
|
44
47
|
this.actorQuery.removeEventListener(AddActor, this.handleActorAdd);
|
|
45
48
|
this.actorQuery.removeEventListener(RemoveActor, this.handleActorRemove);
|
|
49
|
+
this.actorQuery.destroy();
|
|
50
|
+
}
|
|
51
|
+
raycast(params) {
|
|
52
|
+
const queryProxy = buildQueryProxy('ray', params);
|
|
53
|
+
this.sweepAndPruneQuery(queryProxy);
|
|
54
|
+
return raycast(queryProxy, this.queryCandidates);
|
|
55
|
+
}
|
|
56
|
+
raycastAll(params) {
|
|
57
|
+
const queryProxy = buildQueryProxy('ray', params);
|
|
58
|
+
this.sweepAndPruneQuery(queryProxy);
|
|
59
|
+
return raycastAll(queryProxy, this.queryCandidates);
|
|
60
|
+
}
|
|
61
|
+
overlapPoint(params) {
|
|
62
|
+
const queryProxy = buildQueryProxy('point', params);
|
|
63
|
+
this.sweepAndPruneQuery(queryProxy);
|
|
64
|
+
return overlap('point', queryProxy, this.queryCandidates);
|
|
65
|
+
}
|
|
66
|
+
overlapCircle(params) {
|
|
67
|
+
const queryProxy = buildQueryProxy('circle', params);
|
|
68
|
+
this.sweepAndPruneQuery(queryProxy);
|
|
69
|
+
return overlap('circle', queryProxy, this.queryCandidates);
|
|
70
|
+
}
|
|
71
|
+
overlapBox(params) {
|
|
72
|
+
const queryProxy = buildQueryProxy('box', params);
|
|
73
|
+
this.sweepAndPruneQuery(queryProxy);
|
|
74
|
+
return overlap('box', queryProxy, this.queryCandidates);
|
|
46
75
|
}
|
|
47
76
|
handleActorAdd = (event) => {
|
|
48
|
-
this.
|
|
77
|
+
this.addProxy(event.actor);
|
|
49
78
|
};
|
|
50
79
|
handleActorRemove = (event) => {
|
|
51
|
-
this.
|
|
80
|
+
this.actorIdsToDelete.add(event.actor.id);
|
|
52
81
|
};
|
|
53
82
|
checkOnReorientation(actor) {
|
|
54
|
-
const
|
|
55
|
-
if (!
|
|
83
|
+
const proxy = this.proxiesByActorId.get(actor.id);
|
|
84
|
+
if (!proxy) {
|
|
56
85
|
return true;
|
|
57
86
|
}
|
|
58
87
|
const transform = actor.getComponent(Transform);
|
|
59
88
|
const collider = actor.getComponent(Collider);
|
|
60
|
-
const transformOld =
|
|
61
|
-
const colliderOld =
|
|
89
|
+
const transformOld = proxy.orientationData.transform;
|
|
90
|
+
const colliderOld = proxy.orientationData.collider;
|
|
62
91
|
return (checkTransform(transform, transformOld) ||
|
|
63
92
|
checkCollider(collider, colliderOld));
|
|
64
93
|
}
|
|
@@ -75,160 +104,216 @@ export class CollisionDetectionSubsystem {
|
|
|
75
104
|
},
|
|
76
105
|
collider: {
|
|
77
106
|
type: collider.type,
|
|
107
|
+
layer: collider.layer,
|
|
78
108
|
centerX: collider.centerX,
|
|
79
109
|
centerY: collider.centerY,
|
|
80
110
|
sizeX: collider.sizeX,
|
|
81
111
|
sizeY: collider.sizeY,
|
|
82
112
|
radius: collider.radius,
|
|
113
|
+
point1: collider.point1 ? { ...collider.point1 } : undefined,
|
|
114
|
+
point2: collider.point2 ? { ...collider.point2 } : undefined,
|
|
83
115
|
},
|
|
84
116
|
};
|
|
85
117
|
}
|
|
86
|
-
|
|
118
|
+
addProxy(actor) {
|
|
87
119
|
const transform = actor.getComponent(Transform);
|
|
88
120
|
const collider = actor.getComponent(Collider);
|
|
89
121
|
const geometry = geometryBuilders[collider.type](collider, transform);
|
|
90
122
|
const aabb = aabbBuilders[collider.type](geometry);
|
|
91
|
-
const
|
|
123
|
+
const proxy = {
|
|
92
124
|
actor,
|
|
93
125
|
aabb,
|
|
94
126
|
geometry,
|
|
95
127
|
orientationData: this.getOrientationData(actor),
|
|
128
|
+
layer: collider.layer,
|
|
96
129
|
};
|
|
97
130
|
this.axis.x.dispersionCalculator.addToSample(aabb);
|
|
98
|
-
this.addToSortedList(
|
|
131
|
+
this.addToSortedList(proxy, 'x');
|
|
99
132
|
this.axis.y.dispersionCalculator.addToSample(aabb);
|
|
100
|
-
this.addToSortedList(
|
|
101
|
-
this.
|
|
133
|
+
this.addToSortedList(proxy, 'y');
|
|
134
|
+
this.proxiesByActorId.set(actor.id, proxy);
|
|
102
135
|
}
|
|
103
|
-
|
|
136
|
+
updateProxy(actor) {
|
|
104
137
|
const transform = actor.getComponent(Transform);
|
|
105
138
|
const collider = actor.getComponent(Collider);
|
|
106
139
|
const geometry = geometryBuilders[collider.type](collider, transform);
|
|
107
140
|
const aabb = aabbBuilders[collider.type](geometry);
|
|
108
|
-
const
|
|
109
|
-
const prevAABB =
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
141
|
+
const proxy = this.proxiesByActorId.get(actor.id);
|
|
142
|
+
const prevAABB = proxy.aabb;
|
|
143
|
+
proxy.aabb = aabb;
|
|
144
|
+
proxy.geometry = geometry;
|
|
145
|
+
proxy.orientationData = this.getOrientationData(actor);
|
|
146
|
+
proxy.layer = collider.layer;
|
|
113
147
|
this.axis.x.dispersionCalculator.removeFromSample(prevAABB);
|
|
114
148
|
this.axis.x.dispersionCalculator.addToSample(aabb);
|
|
115
|
-
this.updateSortedList(
|
|
149
|
+
this.updateSortedList(proxy, 'x');
|
|
116
150
|
this.axis.y.dispersionCalculator.removeFromSample(prevAABB);
|
|
117
151
|
this.axis.y.dispersionCalculator.addToSample(aabb);
|
|
118
|
-
this.updateSortedList(
|
|
152
|
+
this.updateSortedList(proxy, 'y');
|
|
119
153
|
}
|
|
120
|
-
addToSortedList(
|
|
121
|
-
const min = { value:
|
|
122
|
-
const max = { value:
|
|
154
|
+
addToSortedList(proxy, axis) {
|
|
155
|
+
const min = { value: proxy.aabb.min[axis], proxy };
|
|
156
|
+
const max = { value: proxy.aabb.max[axis], proxy };
|
|
123
157
|
this.axis[axis].sortedList.push(min, max);
|
|
124
|
-
|
|
125
|
-
|
|
158
|
+
proxy.edges ??= {};
|
|
159
|
+
proxy.edges[axis] = [min, max];
|
|
126
160
|
}
|
|
127
|
-
updateSortedList(
|
|
128
|
-
const [min, max] =
|
|
129
|
-
min.value =
|
|
130
|
-
min.
|
|
131
|
-
max.value =
|
|
132
|
-
max.
|
|
161
|
+
updateSortedList(proxy, axis) {
|
|
162
|
+
const [min, max] = proxy.edges[axis];
|
|
163
|
+
min.value = proxy.aabb.min[axis];
|
|
164
|
+
min.proxy = proxy;
|
|
165
|
+
max.value = proxy.aabb.max[axis];
|
|
166
|
+
max.proxy = proxy;
|
|
133
167
|
}
|
|
134
168
|
clearSortedList(axis) {
|
|
135
|
-
this.axis[axis].sortedList = this.axis[axis].sortedList.filter((item) => !this.
|
|
169
|
+
this.axis[axis].sortedList = this.axis[axis].sortedList.filter((item) => !this.actorIdsToDelete.has(item.proxy.actor.id));
|
|
136
170
|
}
|
|
137
171
|
getAxes() {
|
|
138
172
|
const xDispersion = this.axis.x.dispersionCalculator.getDispersion();
|
|
139
173
|
const yDispersion = this.axis.y.dispersionCalculator.getDispersion();
|
|
140
174
|
return xDispersion >= yDispersion ? ['x', 'y'] : ['y', 'x'];
|
|
141
175
|
}
|
|
142
|
-
areStaticBodies(
|
|
143
|
-
const { actor: actor1 } =
|
|
144
|
-
const { actor: actor2 } =
|
|
176
|
+
areStaticBodies(proxy1, proxy2) {
|
|
177
|
+
const { actor: actor1 } = proxy1;
|
|
178
|
+
const { actor: actor2 } = proxy2;
|
|
145
179
|
const rigidBody1 = actor1.getComponent(RigidBody);
|
|
146
180
|
const rigidBody2 = actor2.getComponent(RigidBody);
|
|
147
181
|
return rigidBody1?.type === 'static' && rigidBody2?.type === 'static';
|
|
148
182
|
}
|
|
149
|
-
testAABB(
|
|
150
|
-
const aabb1 =
|
|
151
|
-
const aabb2 =
|
|
183
|
+
testAABB(proxy1, proxy2, axis) {
|
|
184
|
+
const aabb1 = proxy1.aabb;
|
|
185
|
+
const aabb2 = proxy2.aabb;
|
|
152
186
|
return (aabb1.max[axis] > aabb2.min[axis] && aabb1.min[axis] < aabb2.max[axis]);
|
|
153
187
|
}
|
|
188
|
+
testCollisionLayers(proxy1, proxy2) {
|
|
189
|
+
return this.collisionMatrix[proxy1.layer]?.[proxy2.layer] ?? true;
|
|
190
|
+
}
|
|
191
|
+
sweepAndPruneQuery(queryProxy) {
|
|
192
|
+
const [mainAxis, secondAxis] = this.getAxes();
|
|
193
|
+
const sortedList = this.axis[mainAxis].sortedList;
|
|
194
|
+
const candidates = new Set();
|
|
195
|
+
for (const item of sortedList) {
|
|
196
|
+
const { proxy, value } = item;
|
|
197
|
+
if (value < queryProxy.aabb.min[mainAxis]) {
|
|
198
|
+
if (candidates.has(proxy)) {
|
|
199
|
+
candidates.delete(proxy);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
candidates.add(proxy);
|
|
203
|
+
}
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
if (value > queryProxy.aabb.max[mainAxis]) {
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
if (!candidates.has(proxy)) {
|
|
210
|
+
candidates.add(proxy);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
let candidateIndex = 0;
|
|
214
|
+
candidates.forEach((proxy) => {
|
|
215
|
+
if (!this.testAABB(proxy, queryProxy, secondAxis)) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
if (queryProxy.layer !== undefined &&
|
|
219
|
+
!this.testCollisionLayers(proxy, queryProxy)) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
this.queryCandidates[candidateIndex] = proxy;
|
|
223
|
+
candidateIndex += 1;
|
|
224
|
+
});
|
|
225
|
+
this.queryCandidates.length = candidateIndex;
|
|
226
|
+
}
|
|
154
227
|
sweepAndPrune() {
|
|
155
228
|
const [mainAxis, secondAxis] = this.getAxes();
|
|
156
229
|
const { sortedList } = this.axis[mainAxis];
|
|
157
230
|
insertionSort(sortedList, (arg1, arg2) => arg1.value - arg2.value);
|
|
158
|
-
const
|
|
159
|
-
let
|
|
231
|
+
const activeProxies = new Set();
|
|
232
|
+
let proxyPairIndex = 0;
|
|
160
233
|
for (const item of sortedList) {
|
|
161
|
-
const {
|
|
162
|
-
if (!
|
|
163
|
-
|
|
164
|
-
if (!this.testAABB(
|
|
234
|
+
const { proxy } = item;
|
|
235
|
+
if (!activeProxies.has(proxy)) {
|
|
236
|
+
activeProxies.forEach((activeProxy) => {
|
|
237
|
+
if (!this.testAABB(proxy, activeProxy, secondAxis)) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (this.areStaticBodies(proxy, activeProxy)) {
|
|
165
241
|
return;
|
|
166
242
|
}
|
|
167
|
-
if (this.
|
|
243
|
+
if (!this.testCollisionLayers(proxy, activeProxy)) {
|
|
168
244
|
return;
|
|
169
245
|
}
|
|
170
|
-
this.
|
|
171
|
-
|
|
246
|
+
this.proxyPairs[proxyPairIndex] = [proxy, activeProxy];
|
|
247
|
+
proxyPairIndex += 1;
|
|
172
248
|
});
|
|
173
|
-
|
|
249
|
+
activeProxies.add(proxy);
|
|
174
250
|
}
|
|
175
251
|
else {
|
|
176
|
-
|
|
252
|
+
activeProxies.delete(proxy);
|
|
177
253
|
}
|
|
178
254
|
}
|
|
179
|
-
if (this.
|
|
180
|
-
this.
|
|
255
|
+
if (this.proxyPairs.length > proxyPairIndex) {
|
|
256
|
+
this.proxyPairs.length = proxyPairIndex;
|
|
181
257
|
}
|
|
182
258
|
}
|
|
183
|
-
checkOnIntersection(
|
|
184
|
-
const [
|
|
185
|
-
const type1 =
|
|
186
|
-
const type2 =
|
|
187
|
-
|
|
259
|
+
checkOnIntersection(proxyPair) {
|
|
260
|
+
const [proxy1, proxy2] = proxyPair;
|
|
261
|
+
const type1 = proxy1.actor.getComponent(Collider).type;
|
|
262
|
+
const type2 = proxy2.actor.getComponent(Collider).type;
|
|
263
|
+
const intersectionChecker = intersectionCheckers[type1]?.[type2];
|
|
264
|
+
if (!intersectionChecker) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
return intersectionChecker(proxy1, proxy2);
|
|
188
268
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
this.scene.dispatchEventImmediately(Collision, {
|
|
269
|
+
storeContact(contactIndex, actor1, actor2, intersection) {
|
|
270
|
+
this.contacts[contactIndex] ??= {
|
|
192
271
|
actor1,
|
|
193
272
|
actor2,
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
273
|
+
normal: intersection.normal,
|
|
274
|
+
penetration: intersection.penetration,
|
|
275
|
+
contactPoints: intersection.contactPoints,
|
|
276
|
+
};
|
|
277
|
+
this.contacts[contactIndex].actor1 = actor1;
|
|
278
|
+
this.contacts[contactIndex].actor2 = actor2;
|
|
279
|
+
this.contacts[contactIndex].normal = intersection.normal;
|
|
280
|
+
this.contacts[contactIndex].penetration = intersection.penetration;
|
|
281
|
+
this.contacts[contactIndex].contactPoints = intersection.contactPoints;
|
|
203
282
|
}
|
|
204
|
-
|
|
205
|
-
if (this.
|
|
283
|
+
clearDeletedProxies() {
|
|
284
|
+
if (this.actorIdsToDelete.size === 0) {
|
|
206
285
|
return;
|
|
207
286
|
}
|
|
208
287
|
this.clearSortedList('x');
|
|
209
288
|
this.clearSortedList('y');
|
|
210
|
-
this.
|
|
211
|
-
const
|
|
212
|
-
this.axis.x.dispersionCalculator.removeFromSample(
|
|
213
|
-
this.axis.y.dispersionCalculator.removeFromSample(
|
|
214
|
-
this.
|
|
289
|
+
this.actorIdsToDelete.forEach((id) => {
|
|
290
|
+
const proxy = this.proxiesByActorId.get(id);
|
|
291
|
+
this.axis.x.dispersionCalculator.removeFromSample(proxy.aabb);
|
|
292
|
+
this.axis.y.dispersionCalculator.removeFromSample(proxy.aabb);
|
|
293
|
+
this.proxiesByActorId.delete(id);
|
|
215
294
|
});
|
|
216
|
-
this.
|
|
295
|
+
this.actorIdsToDelete.clear();
|
|
217
296
|
}
|
|
218
297
|
update() {
|
|
219
|
-
this.
|
|
298
|
+
this.clearDeletedProxies();
|
|
220
299
|
this.actorQuery.getActors().forEach((actor) => {
|
|
221
300
|
if (!this.checkOnReorientation(actor)) {
|
|
222
301
|
return;
|
|
223
302
|
}
|
|
224
|
-
this.
|
|
303
|
+
this.updateProxy(actor);
|
|
225
304
|
});
|
|
226
305
|
this.sweepAndPrune();
|
|
227
|
-
|
|
228
|
-
|
|
306
|
+
let contactIndex = 0;
|
|
307
|
+
this.proxyPairs.forEach((proxyPair) => {
|
|
308
|
+
const intersection = this.checkOnIntersection(proxyPair);
|
|
229
309
|
if (intersection) {
|
|
230
|
-
this.
|
|
310
|
+
this.storeContact(contactIndex, proxyPair[0].actor, proxyPair[1].actor, intersection);
|
|
311
|
+
contactIndex += 1;
|
|
231
312
|
}
|
|
232
313
|
});
|
|
314
|
+
if (this.contacts.length > contactIndex) {
|
|
315
|
+
this.contacts.length = contactIndex;
|
|
316
|
+
}
|
|
317
|
+
return this.contacts;
|
|
233
318
|
}
|
|
234
319
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Proxy, Intersection } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Checks box colliders for intersection.
|
|
4
|
+
*
|
|
5
|
+
* The SAT (separating axis theorem) is used to find the collision normal
|
|
6
|
+
* and penetration depth. Once the best axis is known, the incident edge is
|
|
7
|
+
* clipped against the reference edge to produce up to two stable contact
|
|
8
|
+
* points for impulse-based collision resolution.
|
|
9
|
+
*/
|
|
10
|
+
export declare const checkBoxesIntersection: (arg1: Proxy, arg2: Proxy) => Intersection | false;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { orientNormal } from '../utils';
|
|
2
|
+
import { findMinBoxesOverlap, buildContactPoints } from './utils';
|
|
3
|
+
/**
|
|
4
|
+
* Checks box colliders for intersection.
|
|
5
|
+
*
|
|
6
|
+
* The SAT (separating axis theorem) is used to find the collision normal
|
|
7
|
+
* and penetration depth. Once the best axis is known, the incident edge is
|
|
8
|
+
* clipped against the reference edge to produce up to two stable contact
|
|
9
|
+
* points for impulse-based collision resolution.
|
|
10
|
+
*/
|
|
11
|
+
export const checkBoxesIntersection = (arg1, arg2) => {
|
|
12
|
+
const geometry1 = arg1.geometry;
|
|
13
|
+
const geometry2 = arg2.geometry;
|
|
14
|
+
const overlap1 = findMinBoxesOverlap(geometry1, geometry2);
|
|
15
|
+
if (overlap1 === false) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
const overlap2 = findMinBoxesOverlap(geometry2, geometry1);
|
|
19
|
+
if (overlap2 === false) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
const isArg1Reference = overlap1.overlap <= overlap2.overlap;
|
|
23
|
+
const referenceGeometry = isArg1Reference ? geometry1 : geometry2;
|
|
24
|
+
const incidentGeometry = isArg1Reference ? geometry2 : geometry1;
|
|
25
|
+
const referenceOverlap = isArg1Reference ? overlap1 : overlap2;
|
|
26
|
+
const normal = orientNormal(referenceOverlap.axis.clone(), geometry1.center, geometry2.center);
|
|
27
|
+
const referenceNormal = normal.clone();
|
|
28
|
+
if (!isArg1Reference) {
|
|
29
|
+
referenceNormal.multiplyNumber(-1);
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
normal,
|
|
33
|
+
penetration: referenceOverlap.overlap,
|
|
34
|
+
contactPoints: buildContactPoints(referenceGeometry, referenceNormal, incidentGeometry),
|
|
35
|
+
};
|
|
36
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Vector2 } from '../../../../../../../engine/math-lib';
|
|
2
|
+
import type { BoxGeometry, Point } from '../../types';
|
|
3
|
+
export declare const CONTACT_EPSILON = 0.0001;
|
|
4
|
+
export declare const MAX_CONTACT_POINTS = 2;
|
|
5
|
+
export interface AxisOverlap {
|
|
6
|
+
axis: Vector2;
|
|
7
|
+
overlap: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const findMinBoxesOverlap: (geometry1: BoxGeometry, geometry2: BoxGeometry) => AxisOverlap | false;
|
|
10
|
+
/**
|
|
11
|
+
* Builds up to two box-vs-box contact points by clipping the incident edge
|
|
12
|
+
* against the side planes of the reference edge.
|
|
13
|
+
*
|
|
14
|
+
* The returned points lie on the reference face plane, which makes them
|
|
15
|
+
* suitable to use as world-space contact points in a simple impulse solver.
|
|
16
|
+
*/
|
|
17
|
+
export declare const buildContactPoints: (referencePolygon: BoxGeometry, referenceNormal: Vector2, incidentPolygon: BoxGeometry) => Point[];
|