chore: 添加第三方依赖库
This commit is contained in:
520
thirdparty/rapier.js/src.ts/geometry/broad_phase.ts
vendored
Normal file
520
thirdparty/rapier.js/src.ts/geometry/broad_phase.ts
vendored
Normal file
@@ -0,0 +1,520 @@
|
||||
import {RawBroadPhase, RawRayColliderIntersection} from "../raw";
|
||||
import {RigidBodyHandle, RigidBodySet} from "../dynamics";
|
||||
import {ColliderSet} from "./collider_set";
|
||||
import {Ray, RayColliderHit, RayColliderIntersection} from "./ray";
|
||||
import {InteractionGroups} from "./interaction_groups";
|
||||
import {ColliderHandle} from "./collider";
|
||||
import {Rotation, RotationOps, Vector, VectorOps} from "../math";
|
||||
import {Shape} from "./shape";
|
||||
import {PointColliderProjection} from "./point";
|
||||
import {ColliderShapeCastHit} from "./toi";
|
||||
import {QueryFilterFlags} from "../pipeline";
|
||||
import {NarrowPhase} from "./narrow_phase";
|
||||
|
||||
/**
|
||||
* The broad-phase used for coarse collision-detection.
|
||||
*
|
||||
* To avoid leaking WASM resources, this MUST be freed manually with `broadPhase.free()`
|
||||
* once you are done using it.
|
||||
*/
|
||||
export class BroadPhase {
|
||||
raw: RawBroadPhase;
|
||||
|
||||
/**
|
||||
* Release the WASM memory occupied by this broad-phase.
|
||||
*/
|
||||
public free() {
|
||||
if (!!this.raw) {
|
||||
this.raw.free();
|
||||
}
|
||||
this.raw = undefined;
|
||||
}
|
||||
|
||||
constructor(raw?: RawBroadPhase) {
|
||||
this.raw = raw || new RawBroadPhase();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the closest intersection between a ray and a set of collider.
|
||||
*
|
||||
* @param colliders - The set of colliders taking part in this pipeline.
|
||||
* @param ray - The ray to cast.
|
||||
* @param maxToi - The maximum time-of-impact that can be reported by this cast. This effectively
|
||||
* limits the length of the ray to `ray.dir.norm() * maxToi`.
|
||||
* @param solid - If `false` then the ray will attempt to hit the boundary of a shape, even if its
|
||||
* origin already lies inside of a shape. In other terms, `true` implies that all shapes are plain,
|
||||
* whereas `false` implies that all shapes are hollow for this ray-cast.
|
||||
* @param groups - Used to filter the colliders that can or cannot be hit by the ray.
|
||||
* @param filter - The callback to filter out which collider will be hit.
|
||||
*/
|
||||
public castRay(
|
||||
narrowPhase: NarrowPhase,
|
||||
bodies: RigidBodySet,
|
||||
colliders: ColliderSet,
|
||||
ray: Ray,
|
||||
maxToi: number,
|
||||
solid: boolean,
|
||||
filterFlags?: QueryFilterFlags,
|
||||
filterGroups?: InteractionGroups,
|
||||
filterExcludeCollider?: ColliderHandle,
|
||||
filterExcludeRigidBody?: RigidBodyHandle,
|
||||
filterPredicate?: (collider: ColliderHandle) => boolean,
|
||||
): RayColliderHit | null {
|
||||
let rawOrig = VectorOps.intoRaw(ray.origin);
|
||||
let rawDir = VectorOps.intoRaw(ray.dir);
|
||||
let result = RayColliderHit.fromRaw(
|
||||
colliders,
|
||||
this.raw.castRay(
|
||||
narrowPhase.raw,
|
||||
bodies.raw,
|
||||
colliders.raw,
|
||||
rawOrig,
|
||||
rawDir,
|
||||
maxToi,
|
||||
solid,
|
||||
filterFlags,
|
||||
filterGroups,
|
||||
filterExcludeCollider,
|
||||
filterExcludeRigidBody,
|
||||
filterPredicate,
|
||||
),
|
||||
);
|
||||
|
||||
rawOrig.free();
|
||||
rawDir.free();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the closest intersection between a ray and a set of collider.
|
||||
*
|
||||
* This also computes the normal at the hit point.
|
||||
* @param colliders - The set of colliders taking part in this pipeline.
|
||||
* @param ray - The ray to cast.
|
||||
* @param maxToi - The maximum time-of-impact that can be reported by this cast. This effectively
|
||||
* limits the length of the ray to `ray.dir.norm() * maxToi`.
|
||||
* @param solid - If `false` then the ray will attempt to hit the boundary of a shape, even if its
|
||||
* origin already lies inside of a shape. In other terms, `true` implies that all shapes are plain,
|
||||
* whereas `false` implies that all shapes are hollow for this ray-cast.
|
||||
* @param groups - Used to filter the colliders that can or cannot be hit by the ray.
|
||||
*/
|
||||
public castRayAndGetNormal(
|
||||
narrowPhase: NarrowPhase,
|
||||
bodies: RigidBodySet,
|
||||
colliders: ColliderSet,
|
||||
ray: Ray,
|
||||
maxToi: number,
|
||||
solid: boolean,
|
||||
filterFlags?: QueryFilterFlags,
|
||||
filterGroups?: InteractionGroups,
|
||||
filterExcludeCollider?: ColliderHandle,
|
||||
filterExcludeRigidBody?: RigidBodyHandle,
|
||||
filterPredicate?: (collider: ColliderHandle) => boolean,
|
||||
): RayColliderIntersection | null {
|
||||
let rawOrig = VectorOps.intoRaw(ray.origin);
|
||||
let rawDir = VectorOps.intoRaw(ray.dir);
|
||||
let result = RayColliderIntersection.fromRaw(
|
||||
colliders,
|
||||
this.raw.castRayAndGetNormal(
|
||||
narrowPhase.raw,
|
||||
bodies.raw,
|
||||
colliders.raw,
|
||||
rawOrig,
|
||||
rawDir,
|
||||
maxToi,
|
||||
solid,
|
||||
filterFlags,
|
||||
filterGroups,
|
||||
filterExcludeCollider,
|
||||
filterExcludeRigidBody,
|
||||
filterPredicate,
|
||||
),
|
||||
);
|
||||
|
||||
rawOrig.free();
|
||||
rawDir.free();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast a ray and collects all the intersections between a ray and the scene.
|
||||
*
|
||||
* @param colliders - The set of colliders taking part in this pipeline.
|
||||
* @param ray - The ray to cast.
|
||||
* @param maxToi - The maximum time-of-impact that can be reported by this cast. This effectively
|
||||
* limits the length of the ray to `ray.dir.norm() * maxToi`.
|
||||
* @param solid - If `false` then the ray will attempt to hit the boundary of a shape, even if its
|
||||
* origin already lies inside of a shape. In other terms, `true` implies that all shapes are plain,
|
||||
* whereas `false` implies that all shapes are hollow for this ray-cast.
|
||||
* @param groups - Used to filter the colliders that can or cannot be hit by the ray.
|
||||
* @param callback - The callback called once per hit (in no particular order) between a ray and a collider.
|
||||
* If this callback returns `false`, then the cast will stop and no further hits will be detected/reported.
|
||||
*/
|
||||
public intersectionsWithRay(
|
||||
narrowPhase: NarrowPhase,
|
||||
bodies: RigidBodySet,
|
||||
colliders: ColliderSet,
|
||||
ray: Ray,
|
||||
maxToi: number,
|
||||
solid: boolean,
|
||||
callback: (intersect: RayColliderIntersection) => boolean,
|
||||
filterFlags?: QueryFilterFlags,
|
||||
filterGroups?: InteractionGroups,
|
||||
filterExcludeCollider?: ColliderHandle,
|
||||
filterExcludeRigidBody?: RigidBodyHandle,
|
||||
filterPredicate?: (collider: ColliderHandle) => boolean,
|
||||
) {
|
||||
let rawOrig = VectorOps.intoRaw(ray.origin);
|
||||
let rawDir = VectorOps.intoRaw(ray.dir);
|
||||
let rawCallback = (rawInter: RawRayColliderIntersection) => {
|
||||
return callback(
|
||||
RayColliderIntersection.fromRaw(colliders, rawInter),
|
||||
);
|
||||
};
|
||||
|
||||
this.raw.intersectionsWithRay(
|
||||
narrowPhase.raw,
|
||||
bodies.raw,
|
||||
colliders.raw,
|
||||
rawOrig,
|
||||
rawDir,
|
||||
maxToi,
|
||||
solid,
|
||||
rawCallback,
|
||||
filterFlags,
|
||||
filterGroups,
|
||||
filterExcludeCollider,
|
||||
filterExcludeRigidBody,
|
||||
filterPredicate,
|
||||
);
|
||||
|
||||
rawOrig.free();
|
||||
rawDir.free();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the handle of up to one collider intersecting the given shape.
|
||||
*
|
||||
* @param colliders - The set of colliders taking part in this pipeline.
|
||||
* @param shapePos - The position of the shape used for the intersection test.
|
||||
* @param shapeRot - The orientation of the shape used for the intersection test.
|
||||
* @param shape - The shape used for the intersection test.
|
||||
* @param groups - The bit groups and filter associated to the ray, in order to only
|
||||
* hit the colliders with collision groups compatible with the ray's group.
|
||||
*/
|
||||
public intersectionWithShape(
|
||||
narrowPhase: NarrowPhase,
|
||||
bodies: RigidBodySet,
|
||||
colliders: ColliderSet,
|
||||
shapePos: Vector,
|
||||
shapeRot: Rotation,
|
||||
shape: Shape,
|
||||
filterFlags?: QueryFilterFlags,
|
||||
filterGroups?: InteractionGroups,
|
||||
filterExcludeCollider?: ColliderHandle,
|
||||
filterExcludeRigidBody?: RigidBodyHandle,
|
||||
filterPredicate?: (collider: ColliderHandle) => boolean,
|
||||
): ColliderHandle | null {
|
||||
let rawPos = VectorOps.intoRaw(shapePos);
|
||||
let rawRot = RotationOps.intoRaw(shapeRot);
|
||||
let rawShape = shape.intoRaw();
|
||||
let result = this.raw.intersectionWithShape(
|
||||
narrowPhase.raw,
|
||||
bodies.raw,
|
||||
colliders.raw,
|
||||
rawPos,
|
||||
rawRot,
|
||||
rawShape,
|
||||
filterFlags,
|
||||
filterGroups,
|
||||
filterExcludeCollider,
|
||||
filterExcludeRigidBody,
|
||||
filterPredicate,
|
||||
);
|
||||
|
||||
rawPos.free();
|
||||
rawRot.free();
|
||||
rawShape.free();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the projection of a point on the closest collider.
|
||||
*
|
||||
* @param colliders - The set of colliders taking part in this pipeline.
|
||||
* @param point - The point to project.
|
||||
* @param solid - If this is set to `true` then the collider shapes are considered to
|
||||
* be plain (if the point is located inside of a plain shape, its projection is the point
|
||||
* itself). If it is set to `false` the collider shapes are considered to be hollow
|
||||
* (if the point is located inside of an hollow shape, it is projected on the shape's
|
||||
* boundary).
|
||||
* @param groups - The bit groups and filter associated to the point to project, in order to only
|
||||
* project on colliders with collision groups compatible with the ray's group.
|
||||
*/
|
||||
public projectPoint(
|
||||
narrowPhase: NarrowPhase,
|
||||
bodies: RigidBodySet,
|
||||
colliders: ColliderSet,
|
||||
point: Vector,
|
||||
solid: boolean,
|
||||
filterFlags?: QueryFilterFlags,
|
||||
filterGroups?: InteractionGroups,
|
||||
filterExcludeCollider?: ColliderHandle,
|
||||
filterExcludeRigidBody?: RigidBodyHandle,
|
||||
filterPredicate?: (collider: ColliderHandle) => boolean,
|
||||
): PointColliderProjection | null {
|
||||
let rawPoint = VectorOps.intoRaw(point);
|
||||
let result = PointColliderProjection.fromRaw(
|
||||
colliders,
|
||||
this.raw.projectPoint(
|
||||
narrowPhase.raw,
|
||||
bodies.raw,
|
||||
colliders.raw,
|
||||
rawPoint,
|
||||
solid,
|
||||
filterFlags,
|
||||
filterGroups,
|
||||
filterExcludeCollider,
|
||||
filterExcludeRigidBody,
|
||||
filterPredicate,
|
||||
),
|
||||
);
|
||||
|
||||
rawPoint.free();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the projection of a point on the closest collider.
|
||||
*
|
||||
* @param colliders - The set of colliders taking part in this pipeline.
|
||||
* @param point - The point to project.
|
||||
* @param groups - The bit groups and filter associated to the point to project, in order to only
|
||||
* project on colliders with collision groups compatible with the ray's group.
|
||||
*/
|
||||
public projectPointAndGetFeature(
|
||||
narrowPhase: NarrowPhase,
|
||||
bodies: RigidBodySet,
|
||||
colliders: ColliderSet,
|
||||
point: Vector,
|
||||
filterFlags?: QueryFilterFlags,
|
||||
filterGroups?: InteractionGroups,
|
||||
filterExcludeCollider?: ColliderHandle,
|
||||
filterExcludeRigidBody?: RigidBodyHandle,
|
||||
filterPredicate?: (collider: ColliderHandle) => boolean,
|
||||
): PointColliderProjection | null {
|
||||
let rawPoint = VectorOps.intoRaw(point);
|
||||
let result = PointColliderProjection.fromRaw(
|
||||
colliders,
|
||||
this.raw.projectPointAndGetFeature(
|
||||
narrowPhase.raw,
|
||||
bodies.raw,
|
||||
colliders.raw,
|
||||
rawPoint,
|
||||
filterFlags,
|
||||
filterGroups,
|
||||
filterExcludeCollider,
|
||||
filterExcludeRigidBody,
|
||||
filterPredicate,
|
||||
),
|
||||
);
|
||||
|
||||
rawPoint.free();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all the colliders containing the given point.
|
||||
*
|
||||
* @param colliders - The set of colliders taking part in this pipeline.
|
||||
* @param point - The point used for the containment test.
|
||||
* @param groups - The bit groups and filter associated to the point to test, in order to only
|
||||
* test on colliders with collision groups compatible with the ray's group.
|
||||
* @param callback - A function called with the handles of each collider with a shape
|
||||
* containing the `point`.
|
||||
*/
|
||||
public intersectionsWithPoint(
|
||||
narrowPhase: NarrowPhase,
|
||||
bodies: RigidBodySet,
|
||||
colliders: ColliderSet,
|
||||
point: Vector,
|
||||
callback: (handle: ColliderHandle) => boolean,
|
||||
filterFlags?: QueryFilterFlags,
|
||||
filterGroups?: InteractionGroups,
|
||||
filterExcludeCollider?: ColliderHandle,
|
||||
filterExcludeRigidBody?: RigidBodyHandle,
|
||||
filterPredicate?: (collider: ColliderHandle) => boolean,
|
||||
) {
|
||||
let rawPoint = VectorOps.intoRaw(point);
|
||||
|
||||
this.raw.intersectionsWithPoint(
|
||||
narrowPhase.raw,
|
||||
bodies.raw,
|
||||
colliders.raw,
|
||||
rawPoint,
|
||||
callback,
|
||||
filterFlags,
|
||||
filterGroups,
|
||||
filterExcludeCollider,
|
||||
filterExcludeRigidBody,
|
||||
filterPredicate,
|
||||
);
|
||||
|
||||
rawPoint.free();
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts a shape at a constant linear velocity and retrieve the first collider it hits.
|
||||
* This is similar to ray-casting except that we are casting a whole shape instead of
|
||||
* just a point (the ray origin).
|
||||
*
|
||||
* @param colliders - The set of colliders taking part in this pipeline.
|
||||
* @param shapePos - The initial position of the shape to cast.
|
||||
* @param shapeRot - The initial rotation of the shape to cast.
|
||||
* @param shapeVel - The constant velocity of the shape to cast (i.e. the cast direction).
|
||||
* @param shape - The shape to cast.
|
||||
* @param targetDistance − If the shape moves closer to this distance from a collider, a hit
|
||||
* will be returned.
|
||||
* @param maxToi - The maximum time-of-impact that can be reported by this cast. This effectively
|
||||
* limits the distance traveled by the shape to `shapeVel.norm() * maxToi`.
|
||||
* @param stopAtPenetration - If set to `false`, the linear shape-cast won’t immediately stop if
|
||||
* the shape is penetrating another shape at its starting point **and** its trajectory is such
|
||||
* that it’s on a path to exit that penetration state.
|
||||
* @param groups - The bit groups and filter associated to the shape to cast, in order to only
|
||||
* test on colliders with collision groups compatible with this group.
|
||||
*/
|
||||
public castShape(
|
||||
narrowPhase: NarrowPhase,
|
||||
bodies: RigidBodySet,
|
||||
colliders: ColliderSet,
|
||||
shapePos: Vector,
|
||||
shapeRot: Rotation,
|
||||
shapeVel: Vector,
|
||||
shape: Shape,
|
||||
targetDistance: number,
|
||||
maxToi: number,
|
||||
stopAtPenetration: boolean,
|
||||
filterFlags?: QueryFilterFlags,
|
||||
filterGroups?: InteractionGroups,
|
||||
filterExcludeCollider?: ColliderHandle,
|
||||
filterExcludeRigidBody?: RigidBodyHandle,
|
||||
filterPredicate?: (collider: ColliderHandle) => boolean,
|
||||
): ColliderShapeCastHit | null {
|
||||
let rawPos = VectorOps.intoRaw(shapePos);
|
||||
let rawRot = RotationOps.intoRaw(shapeRot);
|
||||
let rawVel = VectorOps.intoRaw(shapeVel);
|
||||
let rawShape = shape.intoRaw();
|
||||
|
||||
let result = ColliderShapeCastHit.fromRaw(
|
||||
colliders,
|
||||
this.raw.castShape(
|
||||
narrowPhase.raw,
|
||||
bodies.raw,
|
||||
colliders.raw,
|
||||
rawPos,
|
||||
rawRot,
|
||||
rawVel,
|
||||
rawShape,
|
||||
targetDistance,
|
||||
maxToi,
|
||||
stopAtPenetration,
|
||||
filterFlags,
|
||||
filterGroups,
|
||||
filterExcludeCollider,
|
||||
filterExcludeRigidBody,
|
||||
filterPredicate,
|
||||
),
|
||||
);
|
||||
|
||||
rawPos.free();
|
||||
rawRot.free();
|
||||
rawVel.free();
|
||||
rawShape.free();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all the colliders intersecting the given shape.
|
||||
*
|
||||
* @param colliders - The set of colliders taking part in this pipeline.
|
||||
* @param shapePos - The position of the shape to test.
|
||||
* @param shapeRot - The orientation of the shape to test.
|
||||
* @param shape - The shape to test.
|
||||
* @param groups - The bit groups and filter associated to the shape to test, in order to only
|
||||
* test on colliders with collision groups compatible with this group.
|
||||
* @param callback - A function called with the handles of each collider intersecting the `shape`.
|
||||
*/
|
||||
public intersectionsWithShape(
|
||||
narrowPhase: NarrowPhase,
|
||||
bodies: RigidBodySet,
|
||||
colliders: ColliderSet,
|
||||
shapePos: Vector,
|
||||
shapeRot: Rotation,
|
||||
shape: Shape,
|
||||
callback: (handle: ColliderHandle) => boolean,
|
||||
filterFlags?: QueryFilterFlags,
|
||||
filterGroups?: InteractionGroups,
|
||||
filterExcludeCollider?: ColliderHandle,
|
||||
filterExcludeRigidBody?: RigidBodyHandle,
|
||||
filterPredicate?: (collider: ColliderHandle) => boolean,
|
||||
) {
|
||||
let rawPos = VectorOps.intoRaw(shapePos);
|
||||
let rawRot = RotationOps.intoRaw(shapeRot);
|
||||
let rawShape = shape.intoRaw();
|
||||
|
||||
this.raw.intersectionsWithShape(
|
||||
narrowPhase.raw,
|
||||
bodies.raw,
|
||||
colliders.raw,
|
||||
rawPos,
|
||||
rawRot,
|
||||
rawShape,
|
||||
callback,
|
||||
filterFlags,
|
||||
filterGroups,
|
||||
filterExcludeCollider,
|
||||
filterExcludeRigidBody,
|
||||
filterPredicate,
|
||||
);
|
||||
|
||||
rawPos.free();
|
||||
rawRot.free();
|
||||
rawShape.free();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the handles of all the colliders with an AABB intersecting the given AABB.
|
||||
*
|
||||
* @param aabbCenter - The center of the AABB to test.
|
||||
* @param aabbHalfExtents - The half-extents of the AABB to test.
|
||||
* @param callback - The callback that will be called with the handles of all the colliders
|
||||
* currently intersecting the given AABB.
|
||||
*/
|
||||
public collidersWithAabbIntersectingAabb(
|
||||
narrowPhase: NarrowPhase,
|
||||
bodies: RigidBodySet,
|
||||
colliders: ColliderSet,
|
||||
aabbCenter: Vector,
|
||||
aabbHalfExtents: Vector,
|
||||
callback: (handle: ColliderHandle) => boolean,
|
||||
) {
|
||||
let rawCenter = VectorOps.intoRaw(aabbCenter);
|
||||
let rawHalfExtents = VectorOps.intoRaw(aabbHalfExtents);
|
||||
this.raw.collidersWithAabbIntersectingAabb(
|
||||
narrowPhase.raw,
|
||||
bodies.raw,
|
||||
colliders.raw,
|
||||
rawCenter,
|
||||
rawHalfExtents,
|
||||
callback,
|
||||
);
|
||||
rawCenter.free();
|
||||
rawHalfExtents.free();
|
||||
}
|
||||
}
|
||||
1983
thirdparty/rapier.js/src.ts/geometry/collider.ts
vendored
Normal file
1983
thirdparty/rapier.js/src.ts/geometry/collider.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
213
thirdparty/rapier.js/src.ts/geometry/collider_set.ts
vendored
Normal file
213
thirdparty/rapier.js/src.ts/geometry/collider_set.ts
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
import {RawColliderSet} from "../raw";
|
||||
import {Coarena} from "../coarena";
|
||||
import {RotationOps, VectorOps} from "../math";
|
||||
import {Collider, ColliderDesc, ColliderHandle} from "./collider";
|
||||
import {ImpulseJointHandle, IslandManager, RigidBodyHandle} from "../dynamics";
|
||||
import {RigidBodySet} from "../dynamics";
|
||||
|
||||
/**
|
||||
* A set of rigid bodies that can be handled by a physics pipeline.
|
||||
*
|
||||
* To avoid leaking WASM resources, this MUST be freed manually with `colliderSet.free()`
|
||||
* once you are done using it (and all the rigid-bodies it created).
|
||||
*/
|
||||
export class ColliderSet {
|
||||
raw: RawColliderSet;
|
||||
private map: Coarena<Collider>;
|
||||
|
||||
/**
|
||||
* Release the WASM memory occupied by this collider set.
|
||||
*/
|
||||
public free() {
|
||||
if (!!this.raw) {
|
||||
this.raw.free();
|
||||
}
|
||||
this.raw = undefined;
|
||||
|
||||
if (!!this.map) {
|
||||
this.map.clear();
|
||||
}
|
||||
this.map = undefined;
|
||||
}
|
||||
|
||||
constructor(raw?: RawColliderSet) {
|
||||
this.raw = raw || new RawColliderSet();
|
||||
this.map = new Coarena<Collider>();
|
||||
// Initialize the map with the existing elements, if any.
|
||||
if (raw) {
|
||||
raw.forEachColliderHandle((handle: ColliderHandle) => {
|
||||
this.map.set(handle, new Collider(this, handle, null));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
public castClosure<Res>(
|
||||
f?: (collider: Collider) => Res,
|
||||
): (handle: ColliderHandle) => Res | undefined {
|
||||
return (handle) => {
|
||||
if (!!f) {
|
||||
return f(this.get(handle));
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
public finalizeDeserialization(bodies: RigidBodySet) {
|
||||
this.map.forEach((collider) =>
|
||||
collider.finalizeDeserialization(bodies),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new collider and return its integer handle.
|
||||
*
|
||||
* @param bodies - The set of bodies where the collider's parent can be found.
|
||||
* @param desc - The collider's description.
|
||||
* @param parentHandle - The integer handle of the rigid-body this collider is attached to.
|
||||
*/
|
||||
public createCollider(
|
||||
bodies: RigidBodySet,
|
||||
desc: ColliderDesc,
|
||||
parentHandle: RigidBodyHandle,
|
||||
): Collider {
|
||||
let hasParent = parentHandle != undefined && parentHandle != null;
|
||||
|
||||
if (hasParent && isNaN(parentHandle))
|
||||
throw Error(
|
||||
"Cannot create a collider with a parent rigid-body handle that is not a number.",
|
||||
);
|
||||
|
||||
let rawShape = desc.shape.intoRaw();
|
||||
let rawTra = VectorOps.intoRaw(desc.translation);
|
||||
let rawRot = RotationOps.intoRaw(desc.rotation);
|
||||
let rawCom = VectorOps.intoRaw(desc.centerOfMass);
|
||||
|
||||
// #if DIM3
|
||||
let rawPrincipalInertia = VectorOps.intoRaw(
|
||||
desc.principalAngularInertia,
|
||||
);
|
||||
let rawInertiaFrame = RotationOps.intoRaw(
|
||||
desc.angularInertiaLocalFrame,
|
||||
);
|
||||
// #endif
|
||||
|
||||
let handle = this.raw.createCollider(
|
||||
desc.enabled,
|
||||
rawShape,
|
||||
rawTra,
|
||||
rawRot,
|
||||
desc.massPropsMode,
|
||||
desc.mass,
|
||||
rawCom,
|
||||
// #if DIM2
|
||||
desc.principalAngularInertia,
|
||||
// #endif
|
||||
// #if DIM3
|
||||
rawPrincipalInertia,
|
||||
rawInertiaFrame,
|
||||
// #endif
|
||||
desc.density,
|
||||
desc.friction,
|
||||
desc.restitution,
|
||||
desc.frictionCombineRule,
|
||||
desc.restitutionCombineRule,
|
||||
desc.isSensor,
|
||||
desc.collisionGroups,
|
||||
desc.solverGroups,
|
||||
desc.activeCollisionTypes,
|
||||
desc.activeHooks,
|
||||
desc.activeEvents,
|
||||
desc.contactForceEventThreshold,
|
||||
desc.contactSkin,
|
||||
hasParent,
|
||||
hasParent ? parentHandle : 0,
|
||||
bodies.raw,
|
||||
);
|
||||
|
||||
rawShape.free();
|
||||
rawTra.free();
|
||||
rawRot.free();
|
||||
rawCom.free();
|
||||
|
||||
// #if DIM3
|
||||
rawPrincipalInertia.free();
|
||||
rawInertiaFrame.free();
|
||||
// #endif
|
||||
|
||||
let parent = hasParent ? bodies.get(parentHandle) : null;
|
||||
let collider = new Collider(this, handle, parent, desc.shape);
|
||||
this.map.set(handle, collider);
|
||||
return collider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a collider from this set.
|
||||
*
|
||||
* @param handle - The integer handle of the collider to remove.
|
||||
* @param bodies - The set of rigid-body containing the rigid-body the collider is attached to.
|
||||
* @param wakeUp - If `true`, the rigid-body the removed collider is attached to will be woken-up automatically.
|
||||
*/
|
||||
public remove(
|
||||
handle: ColliderHandle,
|
||||
islands: IslandManager,
|
||||
bodies: RigidBodySet,
|
||||
wakeUp: boolean,
|
||||
) {
|
||||
this.raw.remove(handle, islands.raw, bodies.raw, wakeUp);
|
||||
this.unmap(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function, do not call directly.
|
||||
* @param handle
|
||||
*/
|
||||
public unmap(handle: ImpulseJointHandle) {
|
||||
this.map.delete(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rigid-body with the given handle.
|
||||
*
|
||||
* @param handle - The handle of the rigid-body to retrieve.
|
||||
*/
|
||||
public get(handle: ColliderHandle): Collider | null {
|
||||
return this.map.get(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* The number of colliders on this set.
|
||||
*/
|
||||
public len(): number {
|
||||
return this.map.len();
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this set contain a collider with the given handle?
|
||||
*
|
||||
* @param handle - The collider handle to check.
|
||||
*/
|
||||
public contains(handle: ColliderHandle): boolean {
|
||||
return this.get(handle) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given closure to each collider contained by this set.
|
||||
*
|
||||
* @param f - The closure to apply.
|
||||
*/
|
||||
public forEach(f: (collider: Collider) => void) {
|
||||
this.map.forEach(f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all colliders in the list.
|
||||
*
|
||||
* @returns collider list.
|
||||
*/
|
||||
public getAll(): Collider[] {
|
||||
return this.map.getAll();
|
||||
}
|
||||
}
|
||||
62
thirdparty/rapier.js/src.ts/geometry/contact.ts
vendored
Normal file
62
thirdparty/rapier.js/src.ts/geometry/contact.ts
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
import {Vector, VectorOps} from "../math";
|
||||
import {RawShapeContact} from "../raw";
|
||||
|
||||
/**
|
||||
* The contact info between two shapes.
|
||||
*/
|
||||
export class ShapeContact {
|
||||
/**
|
||||
* Distance between the two contact points.
|
||||
* If this is negative, this contact represents a penetration.
|
||||
*/
|
||||
distance: number;
|
||||
|
||||
/**
|
||||
* Position of the contact on the first shape.
|
||||
*/
|
||||
point1: Vector;
|
||||
|
||||
/**
|
||||
* Position of the contact on the second shape.
|
||||
*/
|
||||
point2: Vector;
|
||||
|
||||
/**
|
||||
* Contact normal, pointing towards the exterior of the first shape.
|
||||
*/
|
||||
normal1: Vector;
|
||||
|
||||
/**
|
||||
* Contact normal, pointing towards the exterior of the second shape.
|
||||
* If these contact data are expressed in world-space, this normal is equal to -normal1.
|
||||
*/
|
||||
normal2: Vector;
|
||||
|
||||
constructor(
|
||||
dist: number,
|
||||
point1: Vector,
|
||||
point2: Vector,
|
||||
normal1: Vector,
|
||||
normal2: Vector,
|
||||
) {
|
||||
this.distance = dist;
|
||||
this.point1 = point1;
|
||||
this.point2 = point2;
|
||||
this.normal1 = normal1;
|
||||
this.normal2 = normal2;
|
||||
}
|
||||
|
||||
public static fromRaw(raw: RawShapeContact): ShapeContact {
|
||||
if (!raw) return null;
|
||||
|
||||
const result = new ShapeContact(
|
||||
raw.distance(),
|
||||
VectorOps.fromRaw(raw.point1()),
|
||||
VectorOps.fromRaw(raw.point2()),
|
||||
VectorOps.fromRaw(raw.normal1()),
|
||||
VectorOps.fromRaw(raw.normal2()),
|
||||
);
|
||||
raw.free();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
16
thirdparty/rapier.js/src.ts/geometry/feature.ts
vendored
Normal file
16
thirdparty/rapier.js/src.ts/geometry/feature.ts
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
// #if DIM2
|
||||
export enum FeatureType {
|
||||
Vertex,
|
||||
Face,
|
||||
Unknown,
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #if DIM3
|
||||
export enum FeatureType {
|
||||
Vertex,
|
||||
Edge,
|
||||
Face,
|
||||
Unknown,
|
||||
}
|
||||
// #endif
|
||||
11
thirdparty/rapier.js/src.ts/geometry/index.ts
vendored
Normal file
11
thirdparty/rapier.js/src.ts/geometry/index.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
export * from "./broad_phase";
|
||||
export * from "./narrow_phase";
|
||||
export * from "./shape";
|
||||
export * from "./collider";
|
||||
export * from "./collider_set";
|
||||
export * from "./feature";
|
||||
export * from "./ray";
|
||||
export * from "./point";
|
||||
export * from "./toi";
|
||||
export * from "./interaction_groups";
|
||||
export * from "./contact";
|
||||
18
thirdparty/rapier.js/src.ts/geometry/interaction_groups.ts
vendored
Normal file
18
thirdparty/rapier.js/src.ts/geometry/interaction_groups.ts
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Pairwise filtering using bit masks.
|
||||
*
|
||||
* This filtering method is based on two 16-bit values:
|
||||
* - The interaction groups (the 16 left-most bits of `self.0`).
|
||||
* - The interaction mask (the 16 right-most bits of `self.0`).
|
||||
*
|
||||
* An interaction is allowed between two filters `a` and `b` two conditions
|
||||
* are met simultaneously:
|
||||
* - The interaction groups of `a` has at least one bit set to `1` in common with the interaction mask of `b`.
|
||||
* - The interaction groups of `b` has at least one bit set to `1` in common with the interaction mask of `a`.
|
||||
* In other words, interactions are allowed between two filter iff. the following condition is met:
|
||||
*
|
||||
* ```
|
||||
* ((a >> 16) & b) != 0 && ((b >> 16) & a) != 0
|
||||
* ```
|
||||
*/
|
||||
export type InteractionGroups = number;
|
||||
203
thirdparty/rapier.js/src.ts/geometry/narrow_phase.ts
vendored
Normal file
203
thirdparty/rapier.js/src.ts/geometry/narrow_phase.ts
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
import {RawNarrowPhase, RawContactManifold} from "../raw";
|
||||
import {ColliderHandle} from "./collider";
|
||||
import {Vector, VectorOps} from "../math";
|
||||
|
||||
/**
|
||||
* The narrow-phase used for precise collision-detection.
|
||||
*
|
||||
* To avoid leaking WASM resources, this MUST be freed manually with `narrowPhase.free()`
|
||||
* once you are done using it.
|
||||
*/
|
||||
export class NarrowPhase {
|
||||
raw: RawNarrowPhase;
|
||||
tempManifold: TempContactManifold;
|
||||
|
||||
/**
|
||||
* Release the WASM memory occupied by this narrow-phase.
|
||||
*/
|
||||
public free() {
|
||||
if (!!this.raw) {
|
||||
this.raw.free();
|
||||
}
|
||||
this.raw = undefined;
|
||||
}
|
||||
|
||||
constructor(raw?: RawNarrowPhase) {
|
||||
this.raw = raw || new RawNarrowPhase();
|
||||
this.tempManifold = new TempContactManifold(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerates all the colliders potentially in contact with the given collider.
|
||||
*
|
||||
* @param collider1 - The second collider involved in the contact.
|
||||
* @param f - Closure that will be called on each collider that is in contact with `collider1`.
|
||||
*/
|
||||
public contactPairsWith(
|
||||
collider1: ColliderHandle,
|
||||
f: (collider2: ColliderHandle) => void,
|
||||
) {
|
||||
this.raw.contact_pairs_with(collider1, f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerates all the colliders intersecting the given colliders, assuming one of them
|
||||
* is a sensor.
|
||||
*/
|
||||
public intersectionPairsWith(
|
||||
collider1: ColliderHandle,
|
||||
f: (collider2: ColliderHandle) => void,
|
||||
) {
|
||||
this.raw.intersection_pairs_with(collider1, f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through all the contact manifolds between the given pair of colliders.
|
||||
*
|
||||
* @param collider1 - The first collider involved in the contact.
|
||||
* @param collider2 - The second collider involved in the contact.
|
||||
* @param f - Closure that will be called on each contact manifold between the two colliders. If the second argument
|
||||
* passed to this closure is `true`, then the contact manifold data is flipped, i.e., methods like `localNormal1`
|
||||
* actually apply to the `collider2` and fields like `localNormal2` apply to the `collider1`.
|
||||
*/
|
||||
public contactPair(
|
||||
collider1: ColliderHandle,
|
||||
collider2: ColliderHandle,
|
||||
f: (manifold: TempContactManifold, flipped: boolean) => void,
|
||||
) {
|
||||
const rawPair = this.raw.contact_pair(collider1, collider2);
|
||||
|
||||
if (!!rawPair) {
|
||||
const flipped = rawPair.collider1() != collider1;
|
||||
|
||||
let i;
|
||||
for (i = 0; i < rawPair.numContactManifolds(); ++i) {
|
||||
this.tempManifold.raw = rawPair.contactManifold(i);
|
||||
if (!!this.tempManifold.raw) {
|
||||
f(this.tempManifold, flipped);
|
||||
}
|
||||
|
||||
// SAFETY: The RawContactManifold stores a raw pointer that will be invalidated
|
||||
// at the next timestep. So we must be sure to free the pair here
|
||||
// to avoid unsoundness in the Rust code.
|
||||
this.tempManifold.free();
|
||||
}
|
||||
rawPair.free();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if `collider1` and `collider2` intersect and at least one of them is a sensor.
|
||||
* @param collider1 − The first collider involved in the intersection.
|
||||
* @param collider2 − The second collider involved in the intersection.
|
||||
*/
|
||||
public intersectionPair(
|
||||
collider1: ColliderHandle,
|
||||
collider2: ColliderHandle,
|
||||
): boolean {
|
||||
return this.raw.intersection_pair(collider1, collider2);
|
||||
}
|
||||
}
|
||||
|
||||
export class TempContactManifold {
|
||||
raw: RawContactManifold;
|
||||
|
||||
public free() {
|
||||
if (!!this.raw) {
|
||||
this.raw.free();
|
||||
}
|
||||
this.raw = undefined;
|
||||
}
|
||||
|
||||
constructor(raw: RawContactManifold) {
|
||||
this.raw = raw;
|
||||
}
|
||||
|
||||
public normal(): Vector {
|
||||
return VectorOps.fromRaw(this.raw.normal());
|
||||
}
|
||||
|
||||
public localNormal1(): Vector {
|
||||
return VectorOps.fromRaw(this.raw.local_n1());
|
||||
}
|
||||
|
||||
public localNormal2(): Vector {
|
||||
return VectorOps.fromRaw(this.raw.local_n2());
|
||||
}
|
||||
|
||||
public subshape1(): number {
|
||||
return this.raw.subshape1();
|
||||
}
|
||||
|
||||
public subshape2(): number {
|
||||
return this.raw.subshape2();
|
||||
}
|
||||
|
||||
public numContacts(): number {
|
||||
return this.raw.num_contacts();
|
||||
}
|
||||
|
||||
public localContactPoint1(i: number): Vector | null {
|
||||
return VectorOps.fromRaw(this.raw.contact_local_p1(i));
|
||||
}
|
||||
|
||||
public localContactPoint2(i: number): Vector | null {
|
||||
return VectorOps.fromRaw(this.raw.contact_local_p2(i));
|
||||
}
|
||||
|
||||
public contactDist(i: number): number {
|
||||
return this.raw.contact_dist(i);
|
||||
}
|
||||
|
||||
public contactFid1(i: number): number {
|
||||
return this.raw.contact_fid1(i);
|
||||
}
|
||||
|
||||
public contactFid2(i: number): number {
|
||||
return this.raw.contact_fid2(i);
|
||||
}
|
||||
|
||||
public contactImpulse(i: number): number {
|
||||
return this.raw.contact_impulse(i);
|
||||
}
|
||||
|
||||
// #if DIM2
|
||||
public contactTangentImpulse(i: number): number {
|
||||
return this.raw.contact_tangent_impulse(i);
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #if DIM3
|
||||
public contactTangentImpulseX(i: number): number {
|
||||
return this.raw.contact_tangent_impulse_x(i);
|
||||
}
|
||||
|
||||
public contactTangentImpulseY(i: number): number {
|
||||
return this.raw.contact_tangent_impulse_y(i);
|
||||
}
|
||||
// #endif
|
||||
|
||||
public numSolverContacts(): number {
|
||||
return this.raw.num_solver_contacts();
|
||||
}
|
||||
|
||||
public solverContactPoint(i: number): Vector {
|
||||
return VectorOps.fromRaw(this.raw.solver_contact_point(i));
|
||||
}
|
||||
|
||||
public solverContactDist(i: number): number {
|
||||
return this.raw.solver_contact_dist(i);
|
||||
}
|
||||
|
||||
public solverContactFriction(i: number): number {
|
||||
return this.raw.solver_contact_friction(i);
|
||||
}
|
||||
|
||||
public solverContactRestitution(i: number): number {
|
||||
return this.raw.solver_contact_restitution(i);
|
||||
}
|
||||
|
||||
public solverContactTangentVelocity(i: number): Vector {
|
||||
return VectorOps.fromRaw(this.raw.solver_contact_tangent_velocity(i));
|
||||
}
|
||||
}
|
||||
98
thirdparty/rapier.js/src.ts/geometry/point.ts
vendored
Normal file
98
thirdparty/rapier.js/src.ts/geometry/point.ts
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
import {Collider, ColliderHandle} from "./collider";
|
||||
import {Vector, VectorOps} from "../math";
|
||||
import {
|
||||
RawFeatureType,
|
||||
RawPointColliderProjection,
|
||||
RawPointProjection,
|
||||
} from "../raw";
|
||||
import {FeatureType} from "./feature";
|
||||
import {ColliderSet} from "./collider_set";
|
||||
|
||||
/**
|
||||
* The projection of a point on a collider.
|
||||
*/
|
||||
export class PointProjection {
|
||||
/**
|
||||
* The projection of the point on the collider.
|
||||
*/
|
||||
point: Vector;
|
||||
/**
|
||||
* Is the point inside of the collider?
|
||||
*/
|
||||
isInside: boolean;
|
||||
|
||||
constructor(point: Vector, isInside: boolean) {
|
||||
this.point = point;
|
||||
this.isInside = isInside;
|
||||
}
|
||||
|
||||
public static fromRaw(raw: RawPointProjection): PointProjection {
|
||||
if (!raw) return null;
|
||||
|
||||
const result = new PointProjection(
|
||||
VectorOps.fromRaw(raw.point()),
|
||||
raw.isInside(),
|
||||
);
|
||||
raw.free();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The projection of a point on a collider (includes the collider handle).
|
||||
*/
|
||||
export class PointColliderProjection {
|
||||
/**
|
||||
* The collider hit by the ray.
|
||||
*/
|
||||
collider: Collider;
|
||||
/**
|
||||
* The projection of the point on the collider.
|
||||
*/
|
||||
point: Vector;
|
||||
/**
|
||||
* Is the point inside of the collider?
|
||||
*/
|
||||
isInside: boolean;
|
||||
|
||||
/**
|
||||
* The type of the geometric feature the point was projected on.
|
||||
*/
|
||||
featureType = FeatureType.Unknown;
|
||||
|
||||
/**
|
||||
* The id of the geometric feature the point was projected on.
|
||||
*/
|
||||
featureId: number | undefined = undefined;
|
||||
|
||||
constructor(
|
||||
collider: Collider,
|
||||
point: Vector,
|
||||
isInside: boolean,
|
||||
featureType?: FeatureType,
|
||||
featureId?: number,
|
||||
) {
|
||||
this.collider = collider;
|
||||
this.point = point;
|
||||
this.isInside = isInside;
|
||||
if (featureId !== undefined) this.featureId = featureId;
|
||||
if (featureType !== undefined) this.featureType = featureType;
|
||||
}
|
||||
|
||||
public static fromRaw(
|
||||
colliderSet: ColliderSet,
|
||||
raw: RawPointColliderProjection,
|
||||
): PointColliderProjection {
|
||||
if (!raw) return null;
|
||||
|
||||
const result = new PointColliderProjection(
|
||||
colliderSet.get(raw.colliderHandle()),
|
||||
VectorOps.fromRaw(raw.point()),
|
||||
raw.isInside(),
|
||||
raw.featureType() as number as FeatureType,
|
||||
raw.featureId(),
|
||||
);
|
||||
raw.free();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
192
thirdparty/rapier.js/src.ts/geometry/ray.ts
vendored
Normal file
192
thirdparty/rapier.js/src.ts/geometry/ray.ts
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
import {Vector, VectorOps} from "../math";
|
||||
import {
|
||||
RawFeatureType,
|
||||
RawRayColliderIntersection,
|
||||
RawRayColliderHit,
|
||||
RawRayIntersection,
|
||||
} from "../raw";
|
||||
import {Collider} from "./collider";
|
||||
import {FeatureType} from "./feature";
|
||||
import {ColliderSet} from "./collider_set";
|
||||
|
||||
/**
|
||||
* A ray. This is a directed half-line.
|
||||
*/
|
||||
export class Ray {
|
||||
/**
|
||||
* The starting point of the ray.
|
||||
*/
|
||||
public origin: Vector;
|
||||
/**
|
||||
* The direction of propagation of the ray.
|
||||
*/
|
||||
public dir: Vector;
|
||||
|
||||
/**
|
||||
* Builds a ray from its origin and direction.
|
||||
*
|
||||
* @param origin - The ray's starting point.
|
||||
* @param dir - The ray's direction of propagation.
|
||||
*/
|
||||
constructor(origin: Vector, dir: Vector) {
|
||||
this.origin = origin;
|
||||
this.dir = dir;
|
||||
}
|
||||
|
||||
public pointAt(t: number): Vector {
|
||||
return {
|
||||
x: this.origin.x + this.dir.x * t,
|
||||
y: this.origin.y + this.dir.y * t,
|
||||
// #if DIM3
|
||||
z: this.origin.z + this.dir.z * t,
|
||||
// #endif
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The intersection between a ray and a collider.
|
||||
*/
|
||||
export class RayIntersection {
|
||||
/**
|
||||
* The time-of-impact of the ray with the collider.
|
||||
*
|
||||
* The hit point is obtained from the ray's origin and direction: `origin + dir * timeOfImpact`.
|
||||
*/
|
||||
timeOfImpact: number;
|
||||
/**
|
||||
* The normal of the collider at the hit point.
|
||||
*/
|
||||
normal: Vector;
|
||||
|
||||
/**
|
||||
* The type of the geometric feature the point was projected on.
|
||||
*/
|
||||
featureType = FeatureType.Unknown;
|
||||
|
||||
/**
|
||||
* The id of the geometric feature the point was projected on.
|
||||
*/
|
||||
featureId: number | undefined = undefined;
|
||||
|
||||
constructor(
|
||||
timeOfImpact: number,
|
||||
normal: Vector,
|
||||
featureType?: FeatureType,
|
||||
featureId?: number,
|
||||
) {
|
||||
this.timeOfImpact = timeOfImpact;
|
||||
this.normal = normal;
|
||||
if (featureId !== undefined) this.featureId = featureId;
|
||||
if (featureType !== undefined) this.featureType = featureType;
|
||||
}
|
||||
|
||||
public static fromRaw(raw: RawRayIntersection): RayIntersection {
|
||||
if (!raw) return null;
|
||||
|
||||
const result = new RayIntersection(
|
||||
raw.time_of_impact(),
|
||||
VectorOps.fromRaw(raw.normal()),
|
||||
raw.featureType() as number as FeatureType,
|
||||
raw.featureId(),
|
||||
);
|
||||
raw.free();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The intersection between a ray and a collider (includes the collider handle).
|
||||
*/
|
||||
export class RayColliderIntersection {
|
||||
/**
|
||||
* The collider hit by the ray.
|
||||
*/
|
||||
collider: Collider;
|
||||
/**
|
||||
* The time-of-impact of the ray with the collider.
|
||||
*
|
||||
* The hit point is obtained from the ray's origin and direction: `origin + dir * timeOfImpact`.
|
||||
*/
|
||||
timeOfImpact: number;
|
||||
/**
|
||||
* The normal of the collider at the hit point.
|
||||
*/
|
||||
normal: Vector;
|
||||
|
||||
/**
|
||||
* The type of the geometric feature the point was projected on.
|
||||
*/
|
||||
featureType = FeatureType.Unknown;
|
||||
|
||||
/**
|
||||
* The id of the geometric feature the point was projected on.
|
||||
*/
|
||||
featureId: number | undefined = undefined;
|
||||
|
||||
constructor(
|
||||
collider: Collider,
|
||||
timeOfImpact: number,
|
||||
normal: Vector,
|
||||
featureType?: FeatureType,
|
||||
featureId?: number,
|
||||
) {
|
||||
this.collider = collider;
|
||||
this.timeOfImpact = timeOfImpact;
|
||||
this.normal = normal;
|
||||
if (featureId !== undefined) this.featureId = featureId;
|
||||
if (featureType !== undefined) this.featureType = featureType;
|
||||
}
|
||||
|
||||
public static fromRaw(
|
||||
colliderSet: ColliderSet,
|
||||
raw: RawRayColliderIntersection,
|
||||
): RayColliderIntersection {
|
||||
if (!raw) return null;
|
||||
|
||||
const result = new RayColliderIntersection(
|
||||
colliderSet.get(raw.colliderHandle()),
|
||||
raw.time_of_impact(),
|
||||
VectorOps.fromRaw(raw.normal()),
|
||||
raw.featureType() as number as FeatureType,
|
||||
raw.featureId(),
|
||||
);
|
||||
raw.free();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The time of impact between a ray and a collider.
|
||||
*/
|
||||
export class RayColliderHit {
|
||||
/**
|
||||
* The handle of the collider hit by the ray.
|
||||
*/
|
||||
collider: Collider;
|
||||
/**
|
||||
* The time-of-impact of the ray with the collider.
|
||||
*
|
||||
* The hit point is obtained from the ray's origin and direction: `origin + dir * timeOfImpact`.
|
||||
*/
|
||||
timeOfImpact: number;
|
||||
|
||||
constructor(collider: Collider, timeOfImpact: number) {
|
||||
this.collider = collider;
|
||||
this.timeOfImpact = timeOfImpact;
|
||||
}
|
||||
|
||||
public static fromRaw(
|
||||
colliderSet: ColliderSet,
|
||||
raw: RawRayColliderHit,
|
||||
): RayColliderHit {
|
||||
if (!raw) return null;
|
||||
|
||||
const result = new RayColliderHit(
|
||||
colliderSet.get(raw.colliderHandle()),
|
||||
raw.timeOfImpact(),
|
||||
);
|
||||
raw.free();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
1558
thirdparty/rapier.js/src.ts/geometry/shape.ts
vendored
Normal file
1558
thirdparty/rapier.js/src.ts/geometry/shape.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
105
thirdparty/rapier.js/src.ts/geometry/toi.ts
vendored
Normal file
105
thirdparty/rapier.js/src.ts/geometry/toi.ts
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
import {Collider} from "./collider";
|
||||
import {Vector, VectorOps} from "../math";
|
||||
import {RawShapeCastHit, RawColliderShapeCastHit} from "../raw";
|
||||
import {ColliderSet} from "./collider_set";
|
||||
|
||||
/**
|
||||
* The intersection between a ray and a collider.
|
||||
*/
|
||||
export class ShapeCastHit {
|
||||
/**
|
||||
* The time of impact of the two shapes.
|
||||
*/
|
||||
time_of_impact: number;
|
||||
/**
|
||||
* The local-space contact point on the first shape, at
|
||||
* the time of impact.
|
||||
*/
|
||||
witness1: Vector;
|
||||
/**
|
||||
* The local-space contact point on the second shape, at
|
||||
* the time of impact.
|
||||
*/
|
||||
witness2: Vector;
|
||||
/**
|
||||
* The local-space normal on the first shape, at
|
||||
* the time of impact.
|
||||
*/
|
||||
normal1: Vector;
|
||||
/**
|
||||
* The local-space normal on the second shape, at
|
||||
* the time of impact.
|
||||
*/
|
||||
normal2: Vector;
|
||||
|
||||
constructor(
|
||||
time_of_impact: number,
|
||||
witness1: Vector,
|
||||
witness2: Vector,
|
||||
normal1: Vector,
|
||||
normal2: Vector,
|
||||
) {
|
||||
this.time_of_impact = time_of_impact;
|
||||
this.witness1 = witness1;
|
||||
this.witness2 = witness2;
|
||||
this.normal1 = normal1;
|
||||
this.normal2 = normal2;
|
||||
}
|
||||
|
||||
public static fromRaw(
|
||||
colliderSet: ColliderSet,
|
||||
raw: RawShapeCastHit,
|
||||
): ShapeCastHit {
|
||||
if (!raw) return null;
|
||||
|
||||
const result = new ShapeCastHit(
|
||||
raw.time_of_impact(),
|
||||
VectorOps.fromRaw(raw.witness1()),
|
||||
VectorOps.fromRaw(raw.witness2()),
|
||||
VectorOps.fromRaw(raw.normal1()),
|
||||
VectorOps.fromRaw(raw.normal2()),
|
||||
);
|
||||
raw.free();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The intersection between a ray and a collider.
|
||||
*/
|
||||
export class ColliderShapeCastHit extends ShapeCastHit {
|
||||
/**
|
||||
* The handle of the collider hit by the ray.
|
||||
*/
|
||||
collider: Collider;
|
||||
|
||||
constructor(
|
||||
collider: Collider,
|
||||
time_of_impact: number,
|
||||
witness1: Vector,
|
||||
witness2: Vector,
|
||||
normal1: Vector,
|
||||
normal2: Vector,
|
||||
) {
|
||||
super(time_of_impact, witness1, witness2, normal1, normal2);
|
||||
this.collider = collider;
|
||||
}
|
||||
|
||||
public static fromRaw(
|
||||
colliderSet: ColliderSet,
|
||||
raw: RawColliderShapeCastHit,
|
||||
): ColliderShapeCastHit {
|
||||
if (!raw) return null;
|
||||
|
||||
const result = new ColliderShapeCastHit(
|
||||
colliderSet.get(raw.colliderHandle()),
|
||||
raw.time_of_impact(),
|
||||
VectorOps.fromRaw(raw.witness1()),
|
||||
VectorOps.fromRaw(raw.witness2()),
|
||||
VectorOps.fromRaw(raw.normal1()),
|
||||
VectorOps.fromRaw(raw.normal2()),
|
||||
);
|
||||
raw.free();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user