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
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { VectorOps } from '../../../../../../../engine/math-lib';
|
|
2
|
+
import { INTERSECTION_EPSILON } from '../utils';
|
|
3
|
+
/**
|
|
4
|
+
* Checks a ray against a convex box using half-space clipping.
|
|
5
|
+
*
|
|
6
|
+
* The intersection interval is clipped against each box face.
|
|
7
|
+
* - `tEnter` tracks the first point where the ray enters the box
|
|
8
|
+
* - `tExit` tracks the first point where the ray leaves the box
|
|
9
|
+
*
|
|
10
|
+
* When the ray starts inside the box, the first hit is the exit point.
|
|
11
|
+
*/
|
|
12
|
+
export const checkRayAndBoxIntersection = (arg1, arg2) => {
|
|
13
|
+
const isBoxFirst = 'edges' in arg1.geometry;
|
|
14
|
+
const box = (isBoxFirst ? arg1.geometry : arg2.geometry);
|
|
15
|
+
const ray = (isBoxFirst ? arg2.geometry : arg1.geometry);
|
|
16
|
+
let tEnter = -Infinity;
|
|
17
|
+
let tExit = ray.maxDistance;
|
|
18
|
+
let enterEdge = null;
|
|
19
|
+
let exitEdge = null;
|
|
20
|
+
for (const edge of box.edges) {
|
|
21
|
+
const signedDistance = VectorOps.dotProduct({
|
|
22
|
+
x: ray.origin.x - edge.point1.x,
|
|
23
|
+
y: ray.origin.y - edge.point1.y,
|
|
24
|
+
}, edge.normal);
|
|
25
|
+
const denominator = VectorOps.dotProduct(ray.direction, edge.normal);
|
|
26
|
+
if (Math.abs(denominator) <= INTERSECTION_EPSILON) {
|
|
27
|
+
if (signedDistance > INTERSECTION_EPSILON) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const t = -signedDistance / denominator;
|
|
33
|
+
if (denominator < 0) {
|
|
34
|
+
if (t > tEnter) {
|
|
35
|
+
tEnter = t;
|
|
36
|
+
enterEdge = edge;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
if (t < tExit) {
|
|
41
|
+
tExit = t;
|
|
42
|
+
exitEdge = edge;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (tEnter - tExit > INTERSECTION_EPSILON) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (tExit < -INTERSECTION_EPSILON ||
|
|
50
|
+
tEnter > ray.maxDistance + INTERSECTION_EPSILON) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
const hitDistance = tEnter >= 0 ? tEnter : tExit;
|
|
54
|
+
const hitEdge = tEnter >= 0 ? enterEdge : exitEdge;
|
|
55
|
+
if (hitEdge === null) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
const hitPoint = {
|
|
59
|
+
x: ray.origin.x + ray.direction.x * hitDistance,
|
|
60
|
+
y: ray.origin.y + ray.direction.y * hitDistance,
|
|
61
|
+
};
|
|
62
|
+
const normal = hitEdge.normal.clone();
|
|
63
|
+
return {
|
|
64
|
+
normal,
|
|
65
|
+
distance: hitDistance,
|
|
66
|
+
penetration: 0,
|
|
67
|
+
contactPoints: [hitPoint],
|
|
68
|
+
};
|
|
69
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Proxy, Intersection } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Checks a ray against a circle.
|
|
4
|
+
*
|
|
5
|
+
* The ray/circle equation is solved in parametric form. The first valid
|
|
6
|
+
* distance on the finite ray is used as the contact point. When the ray
|
|
7
|
+
* starts at the circle center, the normal falls back to the opposite ray
|
|
8
|
+
* direction.
|
|
9
|
+
*/
|
|
10
|
+
export declare const checkRayAndCircleIntersection: (arg1: Proxy, arg2: Proxy) => Intersection | false;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Vector2 } from '../../../../../../../engine/math-lib';
|
|
2
|
+
import { INTERSECTION_EPSILON } from '../utils';
|
|
3
|
+
/**
|
|
4
|
+
* Checks a ray against a circle.
|
|
5
|
+
*
|
|
6
|
+
* The ray/circle equation is solved in parametric form. The first valid
|
|
7
|
+
* distance on the finite ray is used as the contact point. When the ray
|
|
8
|
+
* starts at the circle center, the normal falls back to the opposite ray
|
|
9
|
+
* direction.
|
|
10
|
+
*/
|
|
11
|
+
export const checkRayAndCircleIntersection = (arg1, arg2) => {
|
|
12
|
+
const isCircleFirst = 'radius' in arg1.geometry;
|
|
13
|
+
const circle = (isCircleFirst ? arg1.geometry : arg2.geometry);
|
|
14
|
+
const ray = (isCircleFirst ? arg2.geometry : arg1.geometry);
|
|
15
|
+
const offsetX = ray.origin.x - circle.center.x;
|
|
16
|
+
const offsetY = ray.origin.y - circle.center.y;
|
|
17
|
+
const b = offsetX * ray.direction.x + offsetY * ray.direction.y;
|
|
18
|
+
const c = offsetX ** 2 + offsetY ** 2 - circle.radius ** 2;
|
|
19
|
+
if (c > INTERSECTION_EPSILON && b > 0) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
const discriminant = b ** 2 - c;
|
|
23
|
+
if (discriminant < -INTERSECTION_EPSILON) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
const hitDistance = Math.max(0, -b - Math.sqrt(Math.max(0, discriminant)));
|
|
27
|
+
if (hitDistance > ray.maxDistance + INTERSECTION_EPSILON) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
const hitPoint = {
|
|
31
|
+
x: ray.origin.x + ray.direction.x * hitDistance,
|
|
32
|
+
y: ray.origin.y + ray.direction.y * hitDistance,
|
|
33
|
+
};
|
|
34
|
+
const normal = new Vector2(hitPoint.x - circle.center.x, hitPoint.y - circle.center.y).normalize();
|
|
35
|
+
if (normal.magnitude === 0) {
|
|
36
|
+
normal.x = -ray.direction.x;
|
|
37
|
+
normal.y = -ray.direction.y;
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
normal,
|
|
41
|
+
distance: hitDistance,
|
|
42
|
+
penetration: 0,
|
|
43
|
+
contactPoints: [hitPoint],
|
|
44
|
+
};
|
|
45
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Proxy, Intersection } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Checks a ray against a finite segment.
|
|
4
|
+
*
|
|
5
|
+
* Both primitives are treated parametrically:
|
|
6
|
+
* - the ray is `origin + direction * t`
|
|
7
|
+
* - the segment is `point1 + (point2 - point1) * u`
|
|
8
|
+
*
|
|
9
|
+
* Solving the 2D line intersection gives `t` on the ray and `u` on the
|
|
10
|
+
* segment. A hit is valid only when `t` lies within the ray length and
|
|
11
|
+
* `u` lies within the finite segment interval `[0, 1]`.
|
|
12
|
+
*
|
|
13
|
+
* The contact normal comes from the segment normal and is flipped when needed
|
|
14
|
+
* so it opposes the incoming ray direction.
|
|
15
|
+
*/
|
|
16
|
+
export declare const checkRayAndSegmentIntersection: (arg1: Proxy, arg2: Proxy) => Intersection | false;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { VectorOps } from '../../../../../../../engine/math-lib';
|
|
2
|
+
import { INTERSECTION_EPSILON } from '../utils';
|
|
3
|
+
import { subtractPoints } from './utils';
|
|
4
|
+
/**
|
|
5
|
+
* Checks a ray against a finite segment.
|
|
6
|
+
*
|
|
7
|
+
* Both primitives are treated parametrically:
|
|
8
|
+
* - the ray is `origin + direction * t`
|
|
9
|
+
* - the segment is `point1 + (point2 - point1) * u`
|
|
10
|
+
*
|
|
11
|
+
* Solving the 2D line intersection gives `t` on the ray and `u` on the
|
|
12
|
+
* segment. A hit is valid only when `t` lies within the ray length and
|
|
13
|
+
* `u` lies within the finite segment interval `[0, 1]`.
|
|
14
|
+
*
|
|
15
|
+
* The contact normal comes from the segment normal and is flipped when needed
|
|
16
|
+
* so it opposes the incoming ray direction.
|
|
17
|
+
*/
|
|
18
|
+
export const checkRayAndSegmentIntersection = (arg1, arg2) => {
|
|
19
|
+
const isSegmentFirst = 'point1' in arg1.geometry;
|
|
20
|
+
const segment = (isSegmentFirst ? arg1.geometry : arg2.geometry);
|
|
21
|
+
const ray = (isSegmentFirst ? arg2.geometry : arg1.geometry);
|
|
22
|
+
const segmentDirection = subtractPoints(segment.point2, segment.point1);
|
|
23
|
+
const delta = subtractPoints(segment.point1, ray.origin);
|
|
24
|
+
const denominator = VectorOps.crossProduct(ray.direction, segmentDirection);
|
|
25
|
+
if (Math.abs(denominator) <= INTERSECTION_EPSILON) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
const rayDistance = VectorOps.crossProduct(delta, segmentDirection) / denominator;
|
|
29
|
+
const segmentDistance = VectorOps.crossProduct(delta, ray.direction) / denominator;
|
|
30
|
+
if (rayDistance < -INTERSECTION_EPSILON ||
|
|
31
|
+
rayDistance > ray.maxDistance + INTERSECTION_EPSILON ||
|
|
32
|
+
segmentDistance < -INTERSECTION_EPSILON ||
|
|
33
|
+
segmentDistance > 1 + INTERSECTION_EPSILON) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const point = {
|
|
37
|
+
x: ray.origin.x + ray.direction.x * rayDistance,
|
|
38
|
+
y: ray.origin.y + ray.direction.y * rayDistance,
|
|
39
|
+
};
|
|
40
|
+
const normal = segment.normal.clone();
|
|
41
|
+
if (normal.x * ray.direction.x + normal.y * ray.direction.y >
|
|
42
|
+
INTERSECTION_EPSILON) {
|
|
43
|
+
normal.multiplyNumber(-1);
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
normal,
|
|
47
|
+
distance: rayDistance,
|
|
48
|
+
penetration: 0,
|
|
49
|
+
contactPoints: [point],
|
|
50
|
+
};
|
|
51
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { BoxGeometry, CircleGeometry, Intersection, PointGeometry, Proxy, RayGeometry, SegmentGeometry } from '../../types';
|
|
2
|
+
export declare const createBoxGeometry: (centerX: number, centerY: number, sizeX: number, sizeY: number) => BoxGeometry;
|
|
3
|
+
export declare const createRotatedBoxGeometry: (centerX: number, centerY: number, sizeX: number, sizeY: number, rotation: number) => BoxGeometry;
|
|
4
|
+
export declare const createCircleGeometry: (centerX: number, centerY: number, radius: number) => CircleGeometry;
|
|
5
|
+
export declare const createSegmentGeometry: (point1X: number, point1Y: number, point2X: number, point2Y: number) => SegmentGeometry;
|
|
6
|
+
export declare const createPointGeometry: (centerX: number, centerY: number) => PointGeometry;
|
|
7
|
+
export declare const createRayGeometry: (originX: number, originY: number, directionX: number, directionY: number, maxDistance: number) => RayGeometry;
|
|
8
|
+
export declare const createProxy: (geometry: BoxGeometry | CircleGeometry | SegmentGeometry | PointGeometry | RayGeometry) => Proxy;
|
|
9
|
+
export declare const expectToBeClose: (point: {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
}, x: number, y: number, digits?: number) => void;
|
|
13
|
+
export declare const expectIntersection: (intersection: Intersection | false) => Intersection;
|
|
14
|
+
export declare const sortPoints: (points: {
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
}[]) => {
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
}[];
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Vector2 } from '../../../../../../../engine/math-lib';
|
|
2
|
+
import { Collider, Transform } from '../../../../../../components';
|
|
3
|
+
import { buildBoxGeometry } from '../../geometry-builders/build-box-geometry';
|
|
4
|
+
import { buildCircleGeometry } from '../../geometry-builders/build-circle-geometry';
|
|
5
|
+
import { buildPointGeometry } from '../../geometry-builders/build-point-geometry';
|
|
6
|
+
import { buildRayGeometry } from '../../geometry-builders/build-ray-geometry';
|
|
7
|
+
import { buildSegmentGeometry } from '../../geometry-builders/build-segment-geometry';
|
|
8
|
+
export const createBoxGeometry = (centerX, centerY, sizeX, sizeY) => {
|
|
9
|
+
return createRotatedBoxGeometry(centerX, centerY, sizeX, sizeY, 0);
|
|
10
|
+
};
|
|
11
|
+
export const createRotatedBoxGeometry = (centerX, centerY, sizeX, sizeY, rotation) => {
|
|
12
|
+
return buildBoxGeometry({
|
|
13
|
+
center: { x: centerX, y: centerY },
|
|
14
|
+
size: { x: sizeX, y: sizeY },
|
|
15
|
+
rotation,
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
export const createCircleGeometry = (centerX, centerY, radius) => buildCircleGeometry({
|
|
19
|
+
center: { x: centerX, y: centerY },
|
|
20
|
+
radius,
|
|
21
|
+
});
|
|
22
|
+
export const createSegmentGeometry = (point1X, point1Y, point2X, point2Y) => {
|
|
23
|
+
const centerX = (point1X + point2X) / 2;
|
|
24
|
+
const centerY = (point1Y + point2Y) / 2;
|
|
25
|
+
return buildSegmentGeometry(new Collider({
|
|
26
|
+
type: 'segment',
|
|
27
|
+
centerX,
|
|
28
|
+
centerY,
|
|
29
|
+
point1X: point1X - centerX,
|
|
30
|
+
point1Y: point1Y - centerY,
|
|
31
|
+
point2X: point2X - centerX,
|
|
32
|
+
point2Y: point2Y - centerY,
|
|
33
|
+
layer: 'default',
|
|
34
|
+
}), new Transform({
|
|
35
|
+
offsetX: 0,
|
|
36
|
+
offsetY: 0,
|
|
37
|
+
rotation: 0,
|
|
38
|
+
scaleX: 1,
|
|
39
|
+
scaleY: 1,
|
|
40
|
+
}));
|
|
41
|
+
};
|
|
42
|
+
export const createPointGeometry = (centerX, centerY) => buildPointGeometry({
|
|
43
|
+
point: { x: centerX, y: centerY },
|
|
44
|
+
});
|
|
45
|
+
export const createRayGeometry = (originX, originY, directionX, directionY, maxDistance) => buildRayGeometry({
|
|
46
|
+
origin: { x: originX, y: originY },
|
|
47
|
+
direction: new Vector2(directionX, directionY),
|
|
48
|
+
maxDistance,
|
|
49
|
+
});
|
|
50
|
+
export const createProxy = (geometry) => ({
|
|
51
|
+
geometry,
|
|
52
|
+
});
|
|
53
|
+
export const expectToBeClose = (point, x, y, digits = 6) => {
|
|
54
|
+
expect(point.x).toBeCloseTo(x, digits);
|
|
55
|
+
expect(point.y).toBeCloseTo(y, digits);
|
|
56
|
+
};
|
|
57
|
+
export const expectIntersection = (intersection) => {
|
|
58
|
+
expect(intersection).not.toBe(false);
|
|
59
|
+
if (intersection === false) {
|
|
60
|
+
throw new Error('Expected intersection, received false');
|
|
61
|
+
}
|
|
62
|
+
return intersection;
|
|
63
|
+
};
|
|
64
|
+
export const sortPoints = (points) => [...points].sort((point1, point2) => {
|
|
65
|
+
if (point1.x !== point2.x) {
|
|
66
|
+
return point1.x - point2.x;
|
|
67
|
+
}
|
|
68
|
+
return point1.y - point2.y;
|
|
69
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Vector2 } from '../../../../../../engine/math-lib';
|
|
2
|
+
import type { Point } from '../types';
|
|
3
|
+
export declare const INTERSECTION_EPSILON = 0.000001;
|
|
4
|
+
export declare const orientNormal: (normal: Vector2, from: Point, to: Point) => Vector2;
|
|
5
|
+
export interface Projection {
|
|
6
|
+
min: number;
|
|
7
|
+
max: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const projectPolygon: (points: Point[], axis: Vector2) => Projection;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Vector2, VectorOps } from '../../../../../../engine/math-lib';
|
|
2
|
+
export const INTERSECTION_EPSILON = 1e-6;
|
|
3
|
+
export const orientNormal = (normal, from, to) => {
|
|
4
|
+
const direction = new Vector2(to.x - from.x, to.y - from.y);
|
|
5
|
+
if (VectorOps.dotProduct(direction, normal) < 0) {
|
|
6
|
+
return normal.clone().multiplyNumber(-1);
|
|
7
|
+
}
|
|
8
|
+
return normal;
|
|
9
|
+
};
|
|
10
|
+
export const projectPolygon = (points, axis) => {
|
|
11
|
+
let min = VectorOps.dotProduct(points[0], axis);
|
|
12
|
+
let max = min;
|
|
13
|
+
for (let i = 1; i < points.length; i += 1) {
|
|
14
|
+
const value = VectorOps.dotProduct(points[i], axis);
|
|
15
|
+
if (value < min) {
|
|
16
|
+
min = value;
|
|
17
|
+
}
|
|
18
|
+
else if (value > max) {
|
|
19
|
+
max = value;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return { min, max };
|
|
23
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Actor } from '../../../../../engine/actor';
|
|
2
|
+
import type { OverlapBoxParams, OverlapCircleParams, OverlapPointParams, RaycastParams, RaycastHit } from '../../types';
|
|
3
|
+
import type { ActorProxy, QueryProxy } from './types';
|
|
4
|
+
type QueryType = 'point' | 'circle' | 'box' | 'ray';
|
|
5
|
+
type QueryParams = OverlapBoxParams | OverlapCircleParams | OverlapPointParams | RaycastParams;
|
|
6
|
+
export declare function buildQueryProxy(type: QueryType, params: QueryParams): QueryProxy;
|
|
7
|
+
export declare const overlap: (type: QueryType, queryProxy: QueryProxy, proxies: Iterable<ActorProxy>) => Actor[];
|
|
8
|
+
export declare const raycast: (queryProxy: QueryProxy, proxies: Iterable<ActorProxy>) => RaycastHit | null;
|
|
9
|
+
export declare const raycastAll: (queryProxy: QueryProxy, proxies: Iterable<ActorProxy>) => RaycastHit[];
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Collider } from '../../../../components';
|
|
2
|
+
import { geometryBuilders } from './geometry-builders';
|
|
3
|
+
import { aabbBuilders } from './aabb-builders';
|
|
4
|
+
import { intersectionCheckers } from './intersection-checkers';
|
|
5
|
+
export function buildQueryProxy(type, params) {
|
|
6
|
+
const geometry = geometryBuilders[type](params);
|
|
7
|
+
return {
|
|
8
|
+
aabb: aabbBuilders[type](geometry),
|
|
9
|
+
geometry,
|
|
10
|
+
layer: params.layer,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export const overlap = (type, queryProxy, proxies) => {
|
|
14
|
+
const actors = [];
|
|
15
|
+
for (const proxy of proxies) {
|
|
16
|
+
const collider = proxy.actor.getComponent(Collider);
|
|
17
|
+
const intersection = intersectionCheckers[type][collider.type](queryProxy, proxy);
|
|
18
|
+
if (intersection) {
|
|
19
|
+
actors.push(proxy.actor);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return actors;
|
|
23
|
+
};
|
|
24
|
+
export const raycast = (queryProxy, proxies) => {
|
|
25
|
+
let nearestIntersection = null;
|
|
26
|
+
let nearestActor = null;
|
|
27
|
+
let nearestDistance = Infinity;
|
|
28
|
+
for (const proxy of proxies) {
|
|
29
|
+
const collider = proxy.actor.getComponent(Collider);
|
|
30
|
+
const intersection = intersectionCheckers.ray[collider.type](queryProxy, proxy);
|
|
31
|
+
if (intersection && intersection.distance < nearestDistance) {
|
|
32
|
+
nearestIntersection = intersection;
|
|
33
|
+
nearestActor = proxy.actor;
|
|
34
|
+
nearestDistance = intersection.distance;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (!nearestIntersection || !nearestActor) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
actor: nearestActor,
|
|
42
|
+
point: nearestIntersection.contactPoints[0],
|
|
43
|
+
normal: nearestIntersection.normal,
|
|
44
|
+
distance: nearestDistance,
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
export const raycastAll = (queryProxy, proxies) => {
|
|
48
|
+
const hits = [];
|
|
49
|
+
for (const proxy of proxies) {
|
|
50
|
+
const collider = proxy.actor.getComponent(Collider);
|
|
51
|
+
const intersection = intersectionCheckers.ray[collider.type](queryProxy, proxy);
|
|
52
|
+
if (intersection) {
|
|
53
|
+
hits.push({
|
|
54
|
+
actor: proxy.actor,
|
|
55
|
+
point: intersection.contactPoints[0],
|
|
56
|
+
normal: intersection.normal,
|
|
57
|
+
distance: intersection.distance,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
hits.sort((arg1, arg2) => arg1.distance - arg2.distance);
|
|
62
|
+
return hits;
|
|
63
|
+
};
|
|
@@ -2,13 +2,22 @@ export const checkCollider = (collider, colliderOld) => {
|
|
|
2
2
|
if (collider.type !== colliderOld.type) {
|
|
3
3
|
return true;
|
|
4
4
|
}
|
|
5
|
+
if (collider.layer !== colliderOld.layer) {
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
if (collider.centerX !== colliderOld.centerX ||
|
|
9
|
+
collider.centerY !== colliderOld.centerY) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
5
12
|
if (collider.type === 'box') {
|
|
6
|
-
return collider.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
return (collider.sizeX !== colliderOld.sizeX ||
|
|
14
|
+
collider.sizeY !== colliderOld.sizeY);
|
|
15
|
+
}
|
|
16
|
+
if (collider.type === 'circle') {
|
|
17
|
+
return collider.radius !== colliderOld.radius;
|
|
18
|
+
}
|
|
19
|
+
return (collider.point1?.x !== colliderOld.point1?.x ||
|
|
20
|
+
collider.point1?.y !== colliderOld.point1?.y ||
|
|
21
|
+
collider.point2?.x !== colliderOld.point2?.x ||
|
|
22
|
+
collider.point2?.y !== colliderOld.point2?.y);
|
|
14
23
|
};
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import type { Vector2 } from '../../../../../engine/math-lib';
|
|
1
|
+
import type { Vector2, Point } from '../../../../../engine/math-lib';
|
|
2
2
|
import type { Actor } from '../../../../../engine/actor';
|
|
3
3
|
import type { DispersionCalculator } from './dispersion-calculator';
|
|
4
|
-
export
|
|
5
|
-
x: number;
|
|
6
|
-
y: number;
|
|
7
|
-
}
|
|
4
|
+
export type { Point };
|
|
8
5
|
export interface AABB {
|
|
9
6
|
min: Point;
|
|
10
7
|
max: Point;
|
|
@@ -25,7 +22,21 @@ export interface CircleGeometry {
|
|
|
25
22
|
center: Point;
|
|
26
23
|
radius: number;
|
|
27
24
|
}
|
|
28
|
-
export
|
|
25
|
+
export interface SegmentGeometry {
|
|
26
|
+
center: Point;
|
|
27
|
+
point1: Point;
|
|
28
|
+
point2: Point;
|
|
29
|
+
normal: Vector2;
|
|
30
|
+
}
|
|
31
|
+
export interface PointGeometry {
|
|
32
|
+
center: Point;
|
|
33
|
+
}
|
|
34
|
+
export interface RayGeometry {
|
|
35
|
+
origin: Point;
|
|
36
|
+
direction: Vector2;
|
|
37
|
+
maxDistance: number;
|
|
38
|
+
}
|
|
39
|
+
export type Geometry = BoxGeometry | CircleGeometry | SegmentGeometry | PointGeometry | RayGeometry;
|
|
29
40
|
export interface OrientationData {
|
|
30
41
|
transform: {
|
|
31
42
|
positionX: number;
|
|
@@ -36,22 +47,32 @@ export interface OrientationData {
|
|
|
36
47
|
};
|
|
37
48
|
collider: {
|
|
38
49
|
type: string;
|
|
50
|
+
layer: string;
|
|
39
51
|
centerX: number;
|
|
40
52
|
centerY: number;
|
|
41
53
|
radius?: number;
|
|
42
54
|
sizeX?: number;
|
|
43
55
|
sizeY?: number;
|
|
56
|
+
point1?: Point;
|
|
57
|
+
point2?: Point;
|
|
44
58
|
};
|
|
45
59
|
}
|
|
46
|
-
export interface
|
|
60
|
+
export interface ActorProxy {
|
|
47
61
|
actor: Actor;
|
|
48
62
|
aabb: AABB;
|
|
49
63
|
geometry: Geometry;
|
|
50
64
|
orientationData: OrientationData;
|
|
51
65
|
edges: Record<Axis, [SortedItem, SortedItem]>;
|
|
66
|
+
layer: string;
|
|
67
|
+
}
|
|
68
|
+
export interface QueryProxy {
|
|
69
|
+
aabb: AABB;
|
|
70
|
+
geometry: Geometry;
|
|
71
|
+
layer?: string;
|
|
52
72
|
}
|
|
73
|
+
export type Proxy = ActorProxy | QueryProxy;
|
|
53
74
|
export interface SortedItem {
|
|
54
|
-
|
|
75
|
+
proxy: ActorProxy;
|
|
55
76
|
value: number;
|
|
56
77
|
}
|
|
57
78
|
export interface AxisEntry {
|
|
@@ -63,8 +84,17 @@ export interface Axes {
|
|
|
63
84
|
x: AxisEntry;
|
|
64
85
|
y: AxisEntry;
|
|
65
86
|
}
|
|
66
|
-
export type
|
|
87
|
+
export type ProxyPair = [ActorProxy, ActorProxy];
|
|
88
|
+
export interface Contact {
|
|
89
|
+
actor1: Actor;
|
|
90
|
+
actor2: Actor;
|
|
91
|
+
normal: Vector2;
|
|
92
|
+
penetration: number;
|
|
93
|
+
contactPoints: Point[];
|
|
94
|
+
}
|
|
67
95
|
export interface Intersection {
|
|
68
|
-
|
|
69
|
-
|
|
96
|
+
normal: Vector2;
|
|
97
|
+
penetration: number;
|
|
98
|
+
contactPoints: Point[];
|
|
99
|
+
distance?: number;
|
|
70
100
|
}
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Contact } from '../collision-detection/types';
|
|
2
2
|
export declare class ConstraintSolver {
|
|
3
|
-
private
|
|
4
|
-
private processedPairs;
|
|
5
|
-
private mtvMap;
|
|
6
|
-
constructor(options: SceneSystemOptions);
|
|
7
|
-
destroy(): void;
|
|
8
|
-
private handleCollision;
|
|
3
|
+
private validContacts;
|
|
9
4
|
private validateCollision;
|
|
10
|
-
private
|
|
11
|
-
private
|
|
12
|
-
|
|
5
|
+
private getInverseMass;
|
|
6
|
+
private applyNormalImpulse;
|
|
7
|
+
private applyFrictionImpulse;
|
|
8
|
+
private applyPositionCorrection;
|
|
9
|
+
update(contacts: Contact[]): void;
|
|
13
10
|
}
|