@aura3d/physics 1.5.2 → 2.0.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 (81) hide show
  1. package/dist/ArcadeCharacterController.d.ts +53 -0
  2. package/dist/ArcadeCharacterController.d.ts.map +1 -0
  3. package/dist/ArcadeCharacterController.js +98 -0
  4. package/dist/ArcadeCharacterController.js.map +1 -0
  5. package/dist/ArcadeVehicleTelemetry.d.ts +162 -0
  6. package/dist/ArcadeVehicleTelemetry.d.ts.map +1 -0
  7. package/dist/ArcadeVehicleTelemetry.js +363 -0
  8. package/dist/ArcadeVehicleTelemetry.js.map +1 -0
  9. package/dist/CharacterController.d.ts +52 -0
  10. package/dist/CharacterController.d.ts.map +1 -1
  11. package/dist/CharacterController.js +380 -7
  12. package/dist/CharacterController.js.map +1 -1
  13. package/dist/Constraint.d.ts +20 -4
  14. package/dist/Constraint.d.ts.map +1 -1
  15. package/dist/Constraint.js +34 -60
  16. package/dist/Constraint.js.map +1 -1
  17. package/dist/FightingCharacterController.d.ts +32 -0
  18. package/dist/FightingCharacterController.d.ts.map +1 -0
  19. package/dist/FightingCharacterController.js +76 -0
  20. package/dist/FightingCharacterController.js.map +1 -0
  21. package/dist/MeshBVH.d.ts +72 -0
  22. package/dist/MeshBVH.d.ts.map +1 -0
  23. package/dist/MeshBVH.js +244 -0
  24. package/dist/MeshBVH.js.map +1 -0
  25. package/dist/PathFollowDriver.d.ts +162 -0
  26. package/dist/PathFollowDriver.d.ts.map +1 -0
  27. package/dist/PathFollowDriver.js +163 -0
  28. package/dist/PathFollowDriver.js.map +1 -0
  29. package/dist/PhysicsDebugDraw.d.ts +40 -1
  30. package/dist/PhysicsDebugDraw.d.ts.map +1 -1
  31. package/dist/PhysicsDebugDraw.js +87 -17
  32. package/dist/PhysicsDebugDraw.js.map +1 -1
  33. package/dist/PhysicsWorld.d.ts +37 -18
  34. package/dist/PhysicsWorld.d.ts.map +1 -1
  35. package/dist/PhysicsWorld.js +231 -630
  36. package/dist/PhysicsWorld.js.map +1 -1
  37. package/dist/RacingLineProfile.d.ts +116 -0
  38. package/dist/RacingLineProfile.d.ts.map +1 -0
  39. package/dist/RacingLineProfile.js +181 -0
  40. package/dist/RacingLineProfile.js.map +1 -0
  41. package/dist/Raycast.d.ts +11 -0
  42. package/dist/Raycast.d.ts.map +1 -1
  43. package/dist/Raycast.js +62 -8
  44. package/dist/Raycast.js.map +1 -1
  45. package/dist/RigidBody.d.ts +16 -9
  46. package/dist/RigidBody.d.ts.map +1 -1
  47. package/dist/RigidBody.js +23 -75
  48. package/dist/RigidBody.js.map +1 -1
  49. package/dist/SurfaceQuery.d.ts +72 -0
  50. package/dist/SurfaceQuery.d.ts.map +1 -0
  51. package/dist/SurfaceQuery.js +89 -0
  52. package/dist/SurfaceQuery.js.map +1 -0
  53. package/dist/VehicleDynamics.d.ts +10 -0
  54. package/dist/VehicleDynamics.d.ts.map +1 -1
  55. package/dist/VehicleDynamics.js +31 -3
  56. package/dist/VehicleDynamics.js.map +1 -1
  57. package/dist/VehicleMotion.d.ts +125 -0
  58. package/dist/VehicleMotion.d.ts.map +1 -0
  59. package/dist/VehicleMotion.js +373 -0
  60. package/dist/VehicleMotion.js.map +1 -0
  61. package/dist/index.d.ts +62 -17
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +70 -17
  64. package/dist/index.js.map +1 -1
  65. package/dist/solverless-entry.d.ts +41 -0
  66. package/dist/solverless-entry.d.ts.map +1 -0
  67. package/dist/solverless-entry.js +40 -0
  68. package/dist/solverless-entry.js.map +1 -0
  69. package/dist/solverless.d.ts +37 -0
  70. package/dist/solverless.d.ts.map +1 -0
  71. package/dist/solverless.js +36 -0
  72. package/dist/solverless.js.map +1 -0
  73. package/dist/world-entry.d.ts +31 -0
  74. package/dist/world-entry.d.ts.map +1 -0
  75. package/dist/world-entry.js +30 -0
  76. package/dist/world-entry.js.map +1 -0
  77. package/dist/world.d.ts +18 -0
  78. package/dist/world.d.ts.map +1 -0
  79. package/dist/world.js +17 -0
  80. package/dist/world.js.map +1 -0
  81. package/package.json +10 -2
@@ -1,4 +1,4 @@
1
- import { addVec3, dotVec3, normalizeVec3, rotateVec3ByQuat, scaleVec3, subVec3, validateFiniteVec3 } from "./Shape.js";
1
+ import { addVec3, normalizeVec3, rotateVec3ByQuat, subVec3, validateFiniteVec3 } from "./Shape.js";
2
2
  export class Constraint {
3
3
  type;
4
4
  bodyA;
@@ -9,6 +9,11 @@ export class Constraint {
9
9
  restLength;
10
10
  stiffness;
11
11
  axis;
12
+ damping;
13
+ maxMotorTorque;
14
+ limits;
15
+ motorSpeedValue;
16
+ enabled = true;
12
17
  constructor(descriptor) {
13
18
  if (descriptor.bodyA.id === descriptor.bodyB.id) {
14
19
  throw new Error("Constraint requires two different bodies.");
@@ -26,6 +31,19 @@ export class Constraint {
26
31
  this.restOffset = subVec3(anchorB, anchorA);
27
32
  this.restLength = descriptor.restLength ?? Math.hypot(this.restOffset[0], this.restOffset[1], this.restOffset[2]);
28
33
  this.stiffness = descriptor.stiffness ?? 1;
34
+ this.damping = descriptor.damping ?? 0;
35
+ this.motorSpeedValue = descriptor.motorSpeed ?? 0;
36
+ this.maxMotorTorque = descriptor.maxMotorTorque ?? Infinity;
37
+ this.limits = descriptor.limits;
38
+ if (this.limits && !(this.limits[0] <= this.limits[1])) {
39
+ throw new Error("Constraint limits must be ordered [lower, upper].");
40
+ }
41
+ if (descriptor.type === "motorised-hinge" && descriptor.motorSpeed === undefined) {
42
+ throw new Error("A motorised-hinge constraint requires motorSpeed.");
43
+ }
44
+ if (!Number.isFinite(this.damping) || this.damping < 0) {
45
+ throw new Error("Constraint damping must be finite and non-negative.");
46
+ }
29
47
  if (!Number.isFinite(this.restLength) || this.restLength < 0) {
30
48
  throw new Error("Constraint restLength must be finite and non-negative.");
31
49
  }
@@ -33,39 +51,21 @@ export class Constraint {
33
51
  throw new Error("Constraint stiffness must be in the [0, 1] range.");
34
52
  }
35
53
  }
36
- solve() {
37
- if (this.stiffness === 0) {
38
- return;
39
- }
40
- if (this.type === "fixed") {
41
- const currentOffset = subVec3(this.anchorBWorld(), this.anchorAWorld());
42
- this.applyError(subVec3(currentOffset, this.restOffset));
43
- this.applyVelocityError(subVec3(this.bodyB.velocity, this.bodyA.velocity));
44
- }
45
- else if (this.type === "hinge") {
46
- this.applyError(subVec3(this.anchorBWorld(), this.anchorAWorld()));
47
- this.applyVelocityError(subVec3(this.bodyB.velocity, this.bodyA.velocity));
48
- }
49
- else if (this.type === "slider") {
50
- const currentOffset = subVec3(this.anchorBWorld(), this.anchorAWorld());
51
- const projected = scaleVec3(this.axis, dotVec3(currentOffset, this.axis));
52
- this.applyError(subVec3(currentOffset, projected));
53
- const relativeVelocity = subVec3(this.bodyB.velocity, this.bodyA.velocity);
54
- const projectedVelocity = scaleVec3(this.axis, dotVec3(relativeVelocity, this.axis));
55
- this.applyVelocityError(subVec3(relativeVelocity, projectedVelocity));
56
- }
57
- else if (this.type === "spring") {
58
- const currentOffset = subVec3(this.anchorBWorld(), this.anchorAWorld());
59
- const currentLength = Math.hypot(currentOffset[0], currentOffset[1], currentOffset[2]);
60
- if (currentLength <= 1e-9) {
61
- return;
62
- }
63
- const lengthError = currentLength - this.restLength;
64
- this.applyError(scaleVec3(currentOffset, lengthError / currentLength));
65
- const relativeVelocity = subVec3(this.bodyB.velocity, this.bodyA.velocity);
66
- const axis = scaleVec3(currentOffset, 1 / currentLength);
67
- this.applyVelocityError(scaleVec3(axis, dotVec3(relativeVelocity, axis) * Math.min(1, this.stiffness)));
68
- }
54
+ /** `motorised-hinge` only: change the driven speed at runtime. */
55
+ setMotorSpeed(speed) {
56
+ if (!Number.isFinite(speed))
57
+ throw new Error("Constraint motorSpeed must be finite.");
58
+ this.motorSpeedValue = speed;
59
+ }
60
+ motorSpeed() {
61
+ return this.motorSpeedValue;
62
+ }
63
+ /** Turn the constraint off without destroying it. */
64
+ setEnabled(enabled) {
65
+ this.enabled = enabled;
66
+ }
67
+ isEnabled() {
68
+ return this.enabled;
69
69
  }
70
70
  anchorAWorld() {
71
71
  return addVec3(this.bodyA.position, rotateVec3ByQuat(this.localAnchorA, this.bodyA.rotation));
@@ -73,31 +73,5 @@ export class Constraint {
73
73
  anchorBWorld() {
74
74
  return addVec3(this.bodyB.position, rotateVec3ByQuat(this.localAnchorB, this.bodyB.rotation));
75
75
  }
76
- applyError(error) {
77
- const inverseMassSum = this.bodyA.inverseMass + this.bodyB.inverseMass;
78
- if (inverseMassSum <= 0) {
79
- return;
80
- }
81
- const weightedError = scaleVec3(error, this.stiffness);
82
- if (this.bodyA.inverseMass > 0) {
83
- this.bodyA.setPosition(addVec3(this.bodyA.position, scaleVec3(weightedError, this.bodyA.inverseMass / inverseMassSum)));
84
- }
85
- if (this.bodyB.inverseMass > 0) {
86
- this.bodyB.setPosition(subVec3(this.bodyB.position, scaleVec3(weightedError, this.bodyB.inverseMass / inverseMassSum)));
87
- }
88
- }
89
- applyVelocityError(errorVelocity) {
90
- const inverseMassSum = this.bodyA.inverseMass + this.bodyB.inverseMass;
91
- if (inverseMassSum <= 0) {
92
- return;
93
- }
94
- const correctionImpulse = scaleVec3(errorVelocity, -this.stiffness / inverseMassSum);
95
- if (this.bodyA.inverseMass > 0) {
96
- this.bodyA.applyImpulse(scaleVec3(correctionImpulse, -1));
97
- }
98
- if (this.bodyB.inverseMass > 0) {
99
- this.bodyB.applyImpulse(correctionImpulse);
100
- }
101
- }
102
76
  }
103
77
  //# sourceMappingURL=Constraint.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Constraint.js","sourceRoot":"","sources":["../../../../packages/physics/src/Constraint.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Constraint.js","sourceRoot":"","sources":["../../../../packages/physics/src/Constraint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { KinematicBody, type KinematicBodyDescriptor, type KinematicBodyEvent, type KinematicBodySnapshot, type KinematicStepOptions } from "./KinematicBody.js";
2
+ export type FightingCharacterControllerState = "idle" | "walk" | "dash" | "jump" | "fast-fall" | "crouch" | "landing";
3
+ export type FightingCharacterControllerDescriptor = KinematicBodyDescriptor & {
4
+ readonly walkSpeed?: number;
5
+ readonly crouchSpeed?: number;
6
+ readonly fastFallSpeed?: number;
7
+ };
8
+ export type FightingCharacterControllerSnapshot = KinematicBodySnapshot & {
9
+ readonly state: FightingCharacterControllerState;
10
+ readonly walkSpeed: number;
11
+ readonly crouchSpeed: number;
12
+ readonly fastFallSpeed: number;
13
+ };
14
+ /** Authored-unit fighting movement; this is not a physical-simulation controller. */
15
+ export declare class FightingCharacterController {
16
+ #private;
17
+ readonly body: KinematicBody;
18
+ readonly walkSpeed: number;
19
+ readonly crouchSpeed: number;
20
+ readonly fastFallSpeed: number;
21
+ constructor(descriptor?: FightingCharacterControllerDescriptor);
22
+ walk(direction: number, speed?: number): void;
23
+ stop(): void;
24
+ jump(): void;
25
+ dash(direction?: number): void;
26
+ fastFall(speed?: number): void;
27
+ crouch(active?: boolean): void;
28
+ step(dt: number, options?: KinematicStepOptions): readonly KinematicBodyEvent[];
29
+ snapshot(): FightingCharacterControllerSnapshot;
30
+ }
31
+ export declare function createFightingCharacterController(descriptor?: FightingCharacterControllerDescriptor): FightingCharacterController;
32
+ //# sourceMappingURL=FightingCharacterController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FightingCharacterController.d.ts","sourceRoot":"","sources":["../../../../packages/physics/src/FightingCharacterController.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,uBAAuB,EAAE,KAAK,kBAAkB,EAAE,KAAK,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAEjK,MAAM,MAAM,gCAAgC,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEtH,MAAM,MAAM,qCAAqC,GAAG,uBAAuB,GAAG;IAC5E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,mCAAmC,GAAG,qBAAqB,GAAG;IACxE,QAAQ,CAAC,KAAK,EAAE,gCAAgC,CAAC;IACjD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF,qFAAqF;AACrF,qBAAa,2BAA2B;;IACtC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;gBAGnB,UAAU,GAAE,qCAA0C;IAwBlE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAS7C,IAAI,IAAI,IAAI;IACZ,IAAI,IAAI,IAAI;IACZ,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAC9B,QAAQ,CAAC,KAAK,SAAqB,GAAG,IAAI;IAC1C,MAAM,CAAC,MAAM,UAAO,GAAG,IAAI;IAE3B,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,SAAS,kBAAkB,EAAE;IAMnF,QAAQ,IAAI,mCAAmC;CAYhD;AAED,wBAAgB,iCAAiC,CAAC,UAAU,GAAE,qCAA0C,GAAG,2BAA2B,CAErI"}
@@ -0,0 +1,76 @@
1
+ import { KinematicBody } from "./KinematicBody.js";
2
+ /** Authored-unit fighting movement; this is not a physical-simulation controller. */
3
+ export class FightingCharacterController {
4
+ body;
5
+ walkSpeed;
6
+ crouchSpeed;
7
+ fastFallSpeed;
8
+ #state = "idle";
9
+ constructor(descriptor = {}) {
10
+ this.walkSpeed = positive(descriptor.walkSpeed ?? descriptor.maxSpeed ?? 4.5, "fighting controller walkSpeed");
11
+ this.crouchSpeed = positive(descriptor.crouchSpeed ?? this.walkSpeed * 0.45, "fighting controller crouchSpeed");
12
+ this.fastFallSpeed = positive(descriptor.fastFallSpeed ?? descriptor.maxFallSpeed ?? 20, "fighting controller fastFallSpeed");
13
+ this.body = new KinematicBody({
14
+ ...descriptor,
15
+ id: descriptor.id ?? "fighter",
16
+ halfExtents: descriptor.halfExtents ?? [0.32, 0.9, 0.25],
17
+ maxSpeed: descriptor.maxSpeed ?? this.walkSpeed,
18
+ acceleration: descriptor.acceleration ?? 54,
19
+ airAcceleration: descriptor.airAcceleration ?? 24,
20
+ groundFriction: descriptor.groundFriction ?? 56,
21
+ airFriction: descriptor.airFriction ?? 4,
22
+ gravity: descriptor.gravity ?? 26,
23
+ jumpSpeed: descriptor.jumpSpeed ?? 9.4,
24
+ maxFallSpeed: descriptor.maxFallSpeed ?? Math.max(this.fastFallSpeed, 20),
25
+ dashSpeed: descriptor.dashSpeed ?? 8.6,
26
+ dashDuration: descriptor.dashDuration ?? 0.12,
27
+ dashCooldown: descriptor.dashCooldown ?? 0.18,
28
+ groundSnapDistance: descriptor.groundSnapDistance ?? 0.06,
29
+ lockDepth: descriptor.lockDepth ?? true
30
+ });
31
+ }
32
+ walk(direction, speed) {
33
+ const magnitude = Math.min(1, Math.abs(finiteOrZero(direction)));
34
+ const facing = direction < 0 ? -1 : 1;
35
+ const targetSpeed = speed ?? (this.body.snapshot().crouching ? this.crouchSpeed : this.walkSpeed);
36
+ const normalizedSpeed = this.body.maxSpeed > 0 ? Math.min(1, positive(targetSpeed, "fighting controller walk speed") / this.body.maxSpeed) : 0;
37
+ this.body.move(facing * magnitude * normalizedSpeed);
38
+ this.#state = magnitude > 0 ? "walk" : this.#derive([]);
39
+ }
40
+ stop() { this.body.move(0); this.#state = this.#derive([]); }
41
+ jump() { this.body.jump(); this.#state = "jump"; }
42
+ dash(direction) { this.body.dash(direction); this.#state = "dash"; }
43
+ fastFall(speed = this.fastFallSpeed) { this.body.fastFall(speed); if (!this.body.grounded)
44
+ this.#state = "fast-fall"; }
45
+ crouch(active = true) { this.body.crouch(active); this.#state = active ? "crouch" : this.#derive([]); }
46
+ step(dt, options = {}) {
47
+ const events = this.body.step(dt, options);
48
+ this.#state = this.#derive(events);
49
+ return events;
50
+ }
51
+ snapshot() {
52
+ return { ...this.body.snapshot(), state: this.#state, walkSpeed: this.walkSpeed, crouchSpeed: this.crouchSpeed, fastFallSpeed: this.fastFallSpeed };
53
+ }
54
+ #derive(events) {
55
+ if (events.some((event) => event.type === "land"))
56
+ return "landing";
57
+ const snapshot = this.body.snapshot();
58
+ if (snapshot.crouching)
59
+ return "crouch";
60
+ if (snapshot.dashFramesRemaining > 0)
61
+ return "dash";
62
+ if (!snapshot.grounded)
63
+ return snapshot.velocity[1] < -this.fastFallSpeed * 0.5 ? "fast-fall" : "jump";
64
+ return Math.abs(snapshot.velocity[0]) > 0.05 ? "walk" : "idle";
65
+ }
66
+ }
67
+ export function createFightingCharacterController(descriptor = {}) {
68
+ return new FightingCharacterController(descriptor);
69
+ }
70
+ function positive(value, label) {
71
+ if (!Number.isFinite(value) || value <= 0)
72
+ throw new RangeError(`${label} must be finite and positive.`);
73
+ return value;
74
+ }
75
+ function finiteOrZero(value) { return Number.isFinite(value) ? value : 0; }
76
+ //# sourceMappingURL=FightingCharacterController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FightingCharacterController.js","sourceRoot":"","sources":["../../../../packages/physics/src/FightingCharacterController.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ import type { Vec3 } from "./Shape.js";
2
+ /**
3
+ * Bounding volume hierarchy over an indexed triangle mesh.
4
+ *
5
+ * ## Why this exists
6
+ *
7
+ * Every grounding system in the library was solving against an *approximation of* a
8
+ * surface rather than the surface itself. Turbo Drift sampled
9
+ * `TRACK_SURFACE_Y - VERGE_DROP * shoulderFraction` — a flat plane plus an analytic
10
+ * ramp — so on a banked or crowned corner the returned height was wrong and the car's
11
+ * tyres passed through the visible road. The fix is to ask the real triangles, which
12
+ * needs a spatial index: a naive per-sample scan over a 40k-triangle circuit is far too
13
+ * slow to run four times per frame.
14
+ *
15
+ * ## Determinism
16
+ *
17
+ * Construction must not depend on iteration order or floating-point tie-breaking, or two
18
+ * runs over the same mesh produce different trees and the same query returns different
19
+ * hits. Splits use the median along the widest axis with a stable index-based tiebreak,
20
+ * so the tree is a pure function of the input arrays.
21
+ */
22
+ export interface MeshBVHBuildOptions {
23
+ /** Stop splitting at this triangle count. Larger leaves trade traversal for tests. */
24
+ readonly maxLeafTriangles?: number | undefined;
25
+ /** Hard depth cap, a safety valve against degenerate geometry. */
26
+ readonly maxDepth?: number | undefined;
27
+ }
28
+ interface BVHNode {
29
+ readonly min: [number, number, number];
30
+ readonly max: [number, number, number];
31
+ /** Triangle indices, leaf nodes only. */
32
+ readonly triangles?: readonly number[] | undefined;
33
+ readonly left?: number | undefined;
34
+ readonly right?: number | undefined;
35
+ }
36
+ export interface MeshBVH {
37
+ readonly kind: "aura-mesh-bvh";
38
+ readonly nodes: readonly BVHNode[];
39
+ readonly positions: Float32Array;
40
+ readonly indices: Uint32Array;
41
+ readonly triangleCount: number;
42
+ readonly maxDepth: number;
43
+ }
44
+ export declare function buildMeshBVH(positions: Float32Array, indices: Uint32Array, options?: MeshBVHBuildOptions): MeshBVH;
45
+ export interface MeshRayHit {
46
+ readonly triangle: number;
47
+ readonly distance: number;
48
+ readonly point: Vec3;
49
+ /** Geometric normal, unit length, oriented against the ray. */
50
+ readonly normal: Vec3;
51
+ /** Barycentric coordinates, for interpolating vertex attributes. */
52
+ readonly barycentric: Vec3;
53
+ /** True when the ray struck the back face. */
54
+ readonly backFace: boolean;
55
+ }
56
+ export interface RaycastMeshOptions {
57
+ readonly maxDistance?: number | undefined;
58
+ /** Skip back faces. Off by default so a ray starting inside geometry still reports. */
59
+ readonly cullBackFaces?: boolean | undefined;
60
+ }
61
+ /**
62
+ * Nearest triangle hit along a ray, using the BVH.
63
+ *
64
+ * The direction is normalised internally so `distance` is always in world units; a
65
+ * caller passing an unnormalised direction otherwise gets a distance scaled by its
66
+ * length, which is a silent and very confusing error.
67
+ */
68
+ export declare function raycastMesh(bvh: MeshBVH, origin: Vec3, direction: Vec3, options?: RaycastMeshOptions): MeshRayHit | undefined;
69
+ /** Reference implementation, for testing the BVH. Never use in a hot path. */
70
+ export declare function raycastMeshBruteForce(bvh: MeshBVH, origin: Vec3, direction: Vec3, options?: RaycastMeshOptions): MeshRayHit | undefined;
71
+ export {};
72
+ //# sourceMappingURL=MeshBVH.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MeshBVH.d.ts","sourceRoot":"","sources":["../../../../packages/physics/src/MeshBVH.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,WAAW,mBAAmB;IAClC,sFAAsF;IACtF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/C,kEAAkE;IAClE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC;AAED,UAAU,OAAO;IACf,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,yCAAyC;IACzC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IACnD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AA0BD,wBAAgB,YAAY,CAC1B,SAAS,EAAE,YAAY,EACvB,OAAO,EAAE,WAAW,EACpB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CA0ET;AA2BD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IACrB,+DAA+D;IAC/D,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;IACtB,oEAAoE;IACpE,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;IAC3B,8CAA8C;IAC9C,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAiED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,uFAAuF;IACvF,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC9C;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,IAAI,EACZ,SAAS,EAAE,IAAI,EACf,OAAO,GAAE,kBAAuB,GAC/B,UAAU,GAAG,SAAS,CAkCxB;AAED,8EAA8E;AAC9E,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,IAAI,EACZ,SAAS,EAAE,IAAI,EACf,OAAO,GAAE,kBAAuB,GAC/B,UAAU,GAAG,SAAS,CAaxB"}
@@ -0,0 +1,244 @@
1
+ function triangleBounds(positions, indices, triangle) {
2
+ const a = indices[triangle * 3] * 3;
3
+ const b = indices[triangle * 3 + 1] * 3;
4
+ const c = indices[triangle * 3 + 2] * 3;
5
+ const min = [Infinity, Infinity, Infinity];
6
+ const max = [-Infinity, -Infinity, -Infinity];
7
+ for (const base of [a, b, c]) {
8
+ for (let axis = 0; axis < 3; axis += 1) {
9
+ const value = positions[base + axis];
10
+ if (value < min[axis])
11
+ min[axis] = value;
12
+ if (value > max[axis])
13
+ max[axis] = value;
14
+ }
15
+ }
16
+ return {
17
+ min,
18
+ max,
19
+ centroid: [(min[0] + max[0]) / 2, (min[1] + max[1]) / 2, (min[2] + max[2]) / 2]
20
+ };
21
+ }
22
+ export function buildMeshBVH(positions, indices, options = {}) {
23
+ if (indices.length % 3 !== 0) {
24
+ throw new Error("buildMeshBVH requires an index count divisible by 3.");
25
+ }
26
+ const triangleCount = indices.length / 3;
27
+ const maxLeafTriangles = Math.max(1, options.maxLeafTriangles ?? 8);
28
+ const maxDepth = Math.max(1, options.maxDepth ?? 32);
29
+ const bounds = Array.from({ length: triangleCount }, (_, index) => triangleBounds(positions, indices, index));
30
+ const nodes = [];
31
+ let observedDepth = 0;
32
+ function build(triangles, depth) {
33
+ observedDepth = Math.max(observedDepth, depth);
34
+ const min = [Infinity, Infinity, Infinity];
35
+ const max = [-Infinity, -Infinity, -Infinity];
36
+ for (const triangle of triangles) {
37
+ const b = bounds[triangle];
38
+ for (let axis = 0; axis < 3; axis += 1) {
39
+ if (b.min[axis] < min[axis])
40
+ min[axis] = b.min[axis];
41
+ if (b.max[axis] > max[axis])
42
+ max[axis] = b.max[axis];
43
+ }
44
+ }
45
+ const index = nodes.length;
46
+ if (triangles.length <= maxLeafTriangles || depth >= maxDepth) {
47
+ nodes.push({ min, max, triangles: [...triangles] });
48
+ return index;
49
+ }
50
+ // Split on the widest axis; median split keeps the tree balanced regardless of
51
+ // how the mesh was authored.
52
+ let axis = 0;
53
+ let widest = -Infinity;
54
+ for (let candidate = 0; candidate < 3; candidate += 1) {
55
+ const extent = max[candidate] - min[candidate];
56
+ if (extent > widest) {
57
+ widest = extent;
58
+ axis = candidate;
59
+ }
60
+ }
61
+ // Stable sort: centroid, then triangle index. Without the index tiebreak, equal
62
+ // centroids order differently between runs and the tree stops being deterministic.
63
+ const sorted = [...triangles].sort((left, right) => {
64
+ const delta = bounds[left].centroid[axis] - bounds[right].centroid[axis];
65
+ return delta !== 0 ? delta : left - right;
66
+ });
67
+ const mid = Math.floor(sorted.length / 2);
68
+ const leftTriangles = sorted.slice(0, mid);
69
+ const rightTriangles = sorted.slice(mid);
70
+ if (leftTriangles.length === 0 || rightTriangles.length === 0) {
71
+ nodes.push({ min, max, triangles: [...triangles] });
72
+ return index;
73
+ }
74
+ // Reserve this slot before recursing so child indices are stable.
75
+ nodes.push({ min, max });
76
+ const left = build(leftTriangles, depth + 1);
77
+ const right = build(rightTriangles, depth + 1);
78
+ nodes[index] = { min, max, left, right };
79
+ return index;
80
+ }
81
+ if (triangleCount > 0) {
82
+ build(Array.from({ length: triangleCount }, (_, index) => index), 0);
83
+ }
84
+ else {
85
+ nodes.push({ min: [0, 0, 0], max: [0, 0, 0], triangles: [] });
86
+ }
87
+ return {
88
+ kind: "aura-mesh-bvh",
89
+ nodes,
90
+ positions,
91
+ indices,
92
+ triangleCount,
93
+ maxDepth: observedDepth
94
+ };
95
+ }
96
+ /** Slab test. `tMax` lets a caller reject nodes beyond an existing best hit. */
97
+ function rayHitsAabb(origin, inverseDirection, node, tMax) {
98
+ let tMin = 0;
99
+ let tFar = tMax;
100
+ for (let axis = 0; axis < 3; axis += 1) {
101
+ const inv = inverseDirection[axis];
102
+ let tNear = (node.min[axis] - origin[axis]) * inv;
103
+ let tFarAxis = (node.max[axis] - origin[axis]) * inv;
104
+ if (tNear > tFarAxis) {
105
+ const swap = tNear;
106
+ tNear = tFarAxis;
107
+ tFarAxis = swap;
108
+ }
109
+ if (tNear > tMin)
110
+ tMin = tNear;
111
+ if (tFarAxis < tFar)
112
+ tFar = tFarAxis;
113
+ if (tMin > tFar)
114
+ return false;
115
+ }
116
+ return true;
117
+ }
118
+ /** Möller–Trumbore. Returns undefined for a miss or a degenerate triangle. */
119
+ function intersectTriangle(positions, indices, triangle, origin, direction) {
120
+ const ia = indices[triangle * 3] * 3;
121
+ const ib = indices[triangle * 3 + 1] * 3;
122
+ const ic = indices[triangle * 3 + 2] * 3;
123
+ const ax = positions[ia], ay = positions[ia + 1], az = positions[ia + 2];
124
+ const bx = positions[ib], by = positions[ib + 1], bz = positions[ib + 2];
125
+ const cx = positions[ic], cy = positions[ic + 1], cz = positions[ic + 2];
126
+ const e1x = bx - ax, e1y = by - ay, e1z = bz - az;
127
+ const e2x = cx - ax, e2y = cy - ay, e2z = cz - az;
128
+ const px = direction[1] * e2z - direction[2] * e2y;
129
+ const py = direction[2] * e2x - direction[0] * e2z;
130
+ const pz = direction[0] * e2y - direction[1] * e2x;
131
+ const det = e1x * px + e1y * py + e1z * pz;
132
+ // A near-zero determinant means the ray is parallel to the plane, or the triangle is
133
+ // degenerate (zero area). Both are misses, and both would divide by ~0 below.
134
+ if (Math.abs(det) < 1e-12)
135
+ return undefined;
136
+ const invDet = 1 / det;
137
+ const tx = origin[0] - ax, ty = origin[1] - ay, tz = origin[2] - az;
138
+ const u = (tx * px + ty * py + tz * pz) * invDet;
139
+ if (u < -1e-9 || u > 1 + 1e-9)
140
+ return undefined;
141
+ const qx = ty * e1z - tz * e1y;
142
+ const qy = tz * e1x - tx * e1z;
143
+ const qz = tx * e1y - ty * e1x;
144
+ const v = (direction[0] * qx + direction[1] * qy + direction[2] * qz) * invDet;
145
+ if (v < -1e-9 || u + v > 1 + 1e-9)
146
+ return undefined;
147
+ const t = (e2x * qx + e2y * qy + e2z * qz) * invDet;
148
+ if (t < 0)
149
+ return undefined;
150
+ let nx = e1y * e2z - e1z * e2y;
151
+ let ny = e1z * e2x - e1x * e2z;
152
+ let nz = e1x * e2y - e1y * e2x;
153
+ const length = Math.hypot(nx, ny, nz);
154
+ if (length < 1e-12)
155
+ return undefined;
156
+ nx /= length;
157
+ ny /= length;
158
+ nz /= length;
159
+ // Orient the normal against the ray so callers always get an outward-facing surface.
160
+ const facing = nx * direction[0] + ny * direction[1] + nz * direction[2];
161
+ const backFace = facing > 0;
162
+ if (backFace) {
163
+ nx = -nx;
164
+ ny = -ny;
165
+ nz = -nz;
166
+ }
167
+ return {
168
+ triangle,
169
+ distance: t,
170
+ point: [origin[0] + direction[0] * t, origin[1] + direction[1] * t, origin[2] + direction[2] * t],
171
+ normal: [nx, ny, nz],
172
+ barycentric: [1 - u - v, u, v],
173
+ backFace
174
+ };
175
+ }
176
+ /**
177
+ * Nearest triangle hit along a ray, using the BVH.
178
+ *
179
+ * The direction is normalised internally so `distance` is always in world units; a
180
+ * caller passing an unnormalised direction otherwise gets a distance scaled by its
181
+ * length, which is a silent and very confusing error.
182
+ */
183
+ export function raycastMesh(bvh, origin, direction, options = {}) {
184
+ const length = Math.hypot(direction[0], direction[1], direction[2]);
185
+ if (!Number.isFinite(length) || length < 1e-12)
186
+ return undefined;
187
+ const dir = [direction[0] / length, direction[1] / length, direction[2] / length];
188
+ const maxDistance = options.maxDistance ?? Infinity;
189
+ const inverse = [
190
+ 1 / (dir[0] === 0 ? 1e-30 : dir[0]),
191
+ 1 / (dir[1] === 0 ? 1e-30 : dir[1]),
192
+ 1 / (dir[2] === 0 ? 1e-30 : dir[2])
193
+ ];
194
+ let best;
195
+ let bestDistance = maxDistance;
196
+ const stack = bvh.nodes.length > 0 ? [0] : [];
197
+ while (stack.length > 0) {
198
+ const nodeIndex = stack.pop();
199
+ const node = bvh.nodes[nodeIndex];
200
+ if (!node)
201
+ continue;
202
+ if (!rayHitsAabb(origin, inverse, node, bestDistance))
203
+ continue;
204
+ if (node.triangles) {
205
+ for (const triangle of node.triangles) {
206
+ const hit = intersectTriangle(bvh.positions, bvh.indices, triangle, origin, dir);
207
+ if (!hit)
208
+ continue;
209
+ if (hit.distance > bestDistance)
210
+ continue;
211
+ if (options.cullBackFaces && hit.backFace)
212
+ continue;
213
+ best = hit;
214
+ bestDistance = hit.distance;
215
+ }
216
+ continue;
217
+ }
218
+ if (node.left !== undefined)
219
+ stack.push(node.left);
220
+ if (node.right !== undefined)
221
+ stack.push(node.right);
222
+ }
223
+ return best;
224
+ }
225
+ /** Reference implementation, for testing the BVH. Never use in a hot path. */
226
+ export function raycastMeshBruteForce(bvh, origin, direction, options = {}) {
227
+ const length = Math.hypot(direction[0], direction[1], direction[2]);
228
+ if (!Number.isFinite(length) || length < 1e-12)
229
+ return undefined;
230
+ const dir = [direction[0] / length, direction[1] / length, direction[2] / length];
231
+ const maxDistance = options.maxDistance ?? Infinity;
232
+ let best;
233
+ for (let triangle = 0; triangle < bvh.triangleCount; triangle += 1) {
234
+ const hit = intersectTriangle(bvh.positions, bvh.indices, triangle, origin, dir);
235
+ if (!hit || hit.distance > maxDistance)
236
+ continue;
237
+ if (options.cullBackFaces && hit.backFace)
238
+ continue;
239
+ if (!best || hit.distance < best.distance)
240
+ best = hit;
241
+ }
242
+ return best;
243
+ }
244
+ //# sourceMappingURL=MeshBVH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MeshBVH.js","sourceRoot":"","sources":["../../../../packages/physics/src/MeshBVH.ts"],"names":[],"mappings":"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"}