2025-12-03 16:24:08 +08:00
|
|
|
|
import {RawDynamicRayCastVehicleController} from "../raw";
|
|
|
|
|
|
import {Vector, VectorOps} from "../math";
|
|
|
|
|
|
import {
|
|
|
|
|
|
BroadPhase,
|
|
|
|
|
|
Collider,
|
|
|
|
|
|
ColliderSet,
|
|
|
|
|
|
InteractionGroups,
|
|
|
|
|
|
NarrowPhase,
|
|
|
|
|
|
} from "../geometry";
|
|
|
|
|
|
import {QueryFilterFlags} from "../pipeline";
|
|
|
|
|
|
import {RigidBody, RigidBodyHandle, RigidBodySet} from "../dynamics";
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* A character controller to simulate vehicles using ray-casting for the wheels.
|
|
|
|
|
|
*/
|
|
|
|
|
|
export class DynamicRayCastVehicleController {
|
|
|
|
|
|
private raw: RawDynamicRayCastVehicleController;
|
|
|
|
|
|
private broadPhase: BroadPhase;
|
|
|
|
|
|
private narrowPhase: NarrowPhase;
|
|
|
|
|
|
private bodies: RigidBodySet;
|
|
|
|
|
|
private colliders: ColliderSet;
|
|
|
|
|
|
private _chassis: RigidBody;
|
|
|
|
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
|
|
chassis: RigidBody,
|
|
|
|
|
|
broadPhase: BroadPhase,
|
|
|
|
|
|
narrowPhase: NarrowPhase,
|
|
|
|
|
|
bodies: RigidBodySet,
|
|
|
|
|
|
colliders: ColliderSet,
|
|
|
|
|
|
) {
|
2025-12-03 18:08:19 +08:00
|
|
|
|
if (typeof RawDynamicRayCastVehicleController === 'undefined') {
|
|
|
|
|
|
throw new Error('DynamicRayCastVehicleController is not available in 2D mode');
|
|
|
|
|
|
}
|
2025-12-03 16:24:08 +08:00
|
|
|
|
this.raw = new RawDynamicRayCastVehicleController(chassis.handle);
|
|
|
|
|
|
this.broadPhase = broadPhase;
|
|
|
|
|
|
this.narrowPhase = narrowPhase;
|
|
|
|
|
|
this.bodies = bodies;
|
|
|
|
|
|
this.colliders = colliders;
|
|
|
|
|
|
this._chassis = chassis;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** @internal */
|
|
|
|
|
|
public free() {
|
|
|
|
|
|
if (!!this.raw) {
|
|
|
|
|
|
this.raw.free();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.raw = undefined;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Updates the vehicle’s velocity based on its suspension, engine force, and brake.
|
|
|
|
|
|
*
|
|
|
|
|
|
* This directly updates the velocity of its chassis rigid-body.
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param dt - Time increment used to integrate forces.
|
|
|
|
|
|
* @param filterFlags - Flag to exclude categories of objects from the wheels’ ray-cast.
|
|
|
|
|
|
* @param filterGroups - Only colliders compatible with these groups will be hit by the wheels’ ray-casts.
|
|
|
|
|
|
* @param filterPredicate - Callback to filter out which collider will be hit by the wheels’ ray-casts.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public updateVehicle(
|
|
|
|
|
|
dt: number,
|
|
|
|
|
|
filterFlags?: QueryFilterFlags,
|
|
|
|
|
|
filterGroups?: InteractionGroups,
|
|
|
|
|
|
filterPredicate?: (collider: Collider) => boolean,
|
|
|
|
|
|
) {
|
|
|
|
|
|
this.raw.update_vehicle(
|
|
|
|
|
|
dt,
|
|
|
|
|
|
this.broadPhase.raw,
|
|
|
|
|
|
this.narrowPhase.raw,
|
|
|
|
|
|
this.bodies.raw,
|
|
|
|
|
|
this.colliders.raw,
|
|
|
|
|
|
filterFlags,
|
|
|
|
|
|
filterGroups,
|
|
|
|
|
|
this.colliders.castClosure(filterPredicate),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The current forward speed of the vehicle.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public currentVehicleSpeed(): number {
|
|
|
|
|
|
return this.raw.current_vehicle_speed();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The rigid-body used as the chassis.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public chassis(): RigidBody {
|
|
|
|
|
|
return this._chassis;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The chassis’ local _up_ direction (`0 = x, 1 = y, 2 = z`).
|
|
|
|
|
|
*/
|
|
|
|
|
|
get indexUpAxis(): number {
|
|
|
|
|
|
return this.raw.index_up_axis();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Sets the chassis’ local _up_ direction (`0 = x, 1 = y, 2 = z`).
|
|
|
|
|
|
*/
|
|
|
|
|
|
set indexUpAxis(axis: number) {
|
|
|
|
|
|
this.raw.set_index_up_axis(axis);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The chassis’ local _forward_ direction (`0 = x, 1 = y, 2 = z`).
|
|
|
|
|
|
*/
|
|
|
|
|
|
get indexForwardAxis(): number {
|
|
|
|
|
|
return this.raw.index_forward_axis();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Sets the chassis’ local _forward_ direction (`0 = x, 1 = y, 2 = z`).
|
|
|
|
|
|
*/
|
|
|
|
|
|
set setIndexForwardAxis(axis: number) {
|
|
|
|
|
|
this.raw.set_index_forward_axis(axis);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Adds a new wheel attached to this vehicle.
|
|
|
|
|
|
* @param chassisConnectionCs - The position of the wheel relative to the chassis.
|
|
|
|
|
|
* @param directionCs - The direction of the wheel’s suspension, relative to the chassis. The ray-casting will
|
|
|
|
|
|
* happen following this direction to detect the ground.
|
|
|
|
|
|
* @param axleCs - The wheel’s axle axis, relative to the chassis.
|
|
|
|
|
|
* @param suspensionRestLength - The rest length of the wheel’s suspension spring.
|
|
|
|
|
|
* @param radius - The wheel’s radius.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public addWheel(
|
|
|
|
|
|
chassisConnectionCs: Vector,
|
|
|
|
|
|
directionCs: Vector,
|
|
|
|
|
|
axleCs: Vector,
|
|
|
|
|
|
suspensionRestLength: number,
|
|
|
|
|
|
radius: number,
|
|
|
|
|
|
) {
|
|
|
|
|
|
let rawChassisConnectionCs = VectorOps.intoRaw(chassisConnectionCs);
|
|
|
|
|
|
let rawDirectionCs = VectorOps.intoRaw(directionCs);
|
|
|
|
|
|
let rawAxleCs = VectorOps.intoRaw(axleCs);
|
|
|
|
|
|
|
|
|
|
|
|
this.raw.add_wheel(
|
|
|
|
|
|
rawChassisConnectionCs,
|
|
|
|
|
|
rawDirectionCs,
|
|
|
|
|
|
rawAxleCs,
|
|
|
|
|
|
suspensionRestLength,
|
|
|
|
|
|
radius,
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
rawChassisConnectionCs.free();
|
|
|
|
|
|
rawDirectionCs.free();
|
|
|
|
|
|
rawAxleCs.free();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The number of wheels attached to this vehicle.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public numWheels(): number {
|
|
|
|
|
|
return this.raw.num_wheels();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
*
|
|
|
|
|
|
* Access to wheel properties.
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
|
|
|
|
|
/*
|
|
|
|
|
|
* Getters + setters
|
|
|
|
|
|
*/
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The position of the i-th wheel, relative to the chassis.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelChassisConnectionPointCs(i: number): Vector | null {
|
|
|
|
|
|
return VectorOps.fromRaw(this.raw.wheel_chassis_connection_point_cs(i));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Sets the position of the i-th wheel, relative to the chassis.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public setWheelChassisConnectionPointCs(i: number, value: Vector) {
|
|
|
|
|
|
let rawValue = VectorOps.intoRaw(value);
|
|
|
|
|
|
this.raw.set_wheel_chassis_connection_point_cs(i, rawValue);
|
|
|
|
|
|
rawValue.free();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The rest length of the i-th wheel’s suspension spring.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelSuspensionRestLength(i: number): number | null {
|
|
|
|
|
|
return this.raw.wheel_suspension_rest_length(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Sets the rest length of the i-th wheel’s suspension spring.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public setWheelSuspensionRestLength(i: number, value: number) {
|
|
|
|
|
|
this.raw.set_wheel_suspension_rest_length(i, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The maximum distance the i-th wheel suspension can travel before and after its resting length.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelMaxSuspensionTravel(i: number): number | null {
|
|
|
|
|
|
return this.raw.wheel_max_suspension_travel(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Sets the maximum distance the i-th wheel suspension can travel before and after its resting length.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public setWheelMaxSuspensionTravel(i: number, value: number) {
|
|
|
|
|
|
this.raw.set_wheel_max_suspension_travel(i, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The i-th wheel’s radius.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelRadius(i: number): number | null {
|
|
|
|
|
|
return this.raw.wheel_radius(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Sets the i-th wheel’s radius.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public setWheelRadius(i: number, value: number) {
|
|
|
|
|
|
this.raw.set_wheel_radius(i, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The i-th wheel’s suspension stiffness.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Increase this value if the suspension appears to not push the vehicle strong enough.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelSuspensionStiffness(i: number): number | null {
|
|
|
|
|
|
return this.raw.wheel_suspension_stiffness(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Sets the i-th wheel’s suspension stiffness.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Increase this value if the suspension appears to not push the vehicle strong enough.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public setWheelSuspensionStiffness(i: number, value: number) {
|
|
|
|
|
|
this.raw.set_wheel_suspension_stiffness(i, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The i-th wheel’s suspension’s damping when it is being compressed.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelSuspensionCompression(i: number): number | null {
|
|
|
|
|
|
return this.raw.wheel_suspension_compression(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The i-th wheel’s suspension’s damping when it is being compressed.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public setWheelSuspensionCompression(i: number, value: number) {
|
|
|
|
|
|
this.raw.set_wheel_suspension_compression(i, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The i-th wheel’s suspension’s damping when it is being released.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Increase this value if the suspension appears to overshoot.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelSuspensionRelaxation(i: number): number | null {
|
|
|
|
|
|
return this.raw.wheel_suspension_relaxation(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Sets the i-th wheel’s suspension’s damping when it is being released.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Increase this value if the suspension appears to overshoot.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public setWheelSuspensionRelaxation(i: number, value: number) {
|
|
|
|
|
|
this.raw.set_wheel_suspension_relaxation(i, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The maximum force applied by the i-th wheel’s suspension.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelMaxSuspensionForce(i: number): number | null {
|
|
|
|
|
|
return this.raw.wheel_max_suspension_force(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Sets the maximum force applied by the i-th wheel’s suspension.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public setWheelMaxSuspensionForce(i: number, value: number) {
|
|
|
|
|
|
this.raw.set_wheel_max_suspension_force(i, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The maximum amount of braking impulse applied on the i-th wheel to slow down the vehicle.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelBrake(i: number): number | null {
|
|
|
|
|
|
return this.raw.wheel_brake(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Set the maximum amount of braking impulse applied on the i-th wheel to slow down the vehicle.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public setWheelBrake(i: number, value: number) {
|
|
|
|
|
|
this.raw.set_wheel_brake(i, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The steering angle (radians) for the i-th wheel.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelSteering(i: number): number | null {
|
|
|
|
|
|
return this.raw.wheel_steering(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Sets the steering angle (radians) for the i-th wheel.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public setWheelSteering(i: number, value: number) {
|
|
|
|
|
|
this.raw.set_wheel_steering(i, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The forward force applied by the i-th wheel on the chassis.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelEngineForce(i: number): number | null {
|
|
|
|
|
|
return this.raw.wheel_engine_force(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Sets the forward force applied by the i-th wheel on the chassis.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public setWheelEngineForce(i: number, value: number) {
|
|
|
|
|
|
this.raw.set_wheel_engine_force(i, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The direction of the i-th wheel’s suspension, relative to the chassis.
|
|
|
|
|
|
*
|
|
|
|
|
|
* The ray-casting will happen following this direction to detect the ground.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelDirectionCs(i: number): Vector | null {
|
|
|
|
|
|
return VectorOps.fromRaw(this.raw.wheel_direction_cs(i));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Sets the direction of the i-th wheel’s suspension, relative to the chassis.
|
|
|
|
|
|
*
|
|
|
|
|
|
* The ray-casting will happen following this direction to detect the ground.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public setWheelDirectionCs(i: number, value: Vector) {
|
|
|
|
|
|
let rawValue = VectorOps.intoRaw(value);
|
|
|
|
|
|
this.raw.set_wheel_direction_cs(i, rawValue);
|
|
|
|
|
|
rawValue.free();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The i-th wheel’s axle axis, relative to the chassis.
|
|
|
|
|
|
*
|
|
|
|
|
|
* The axis index defined as 0 = X, 1 = Y, 2 = Z.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelAxleCs(i: number): Vector | null {
|
|
|
|
|
|
return VectorOps.fromRaw(this.raw.wheel_axle_cs(i));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Sets the i-th wheel’s axle axis, relative to the chassis.
|
|
|
|
|
|
*
|
|
|
|
|
|
* The axis index defined as 0 = X, 1 = Y, 2 = Z.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public setWheelAxleCs(i: number, value: Vector) {
|
|
|
|
|
|
let rawValue = VectorOps.intoRaw(value);
|
|
|
|
|
|
this.raw.set_wheel_axle_cs(i, rawValue);
|
|
|
|
|
|
rawValue.free();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Parameter controlling how much traction the tire has.
|
|
|
|
|
|
*
|
|
|
|
|
|
* The larger the value, the more instantaneous braking will happen (with the risk of
|
|
|
|
|
|
* causing the vehicle to flip if it’s too strong).
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelFrictionSlip(i: number): number | null {
|
|
|
|
|
|
return this.raw.wheel_friction_slip(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Sets the parameter controlling how much traction the tire has.
|
|
|
|
|
|
*
|
|
|
|
|
|
* The larger the value, the more instantaneous braking will happen (with the risk of
|
|
|
|
|
|
* causing the vehicle to flip if it’s too strong).
|
|
|
|
|
|
*/
|
|
|
|
|
|
public setWheelFrictionSlip(i: number, value: number) {
|
|
|
|
|
|
this.raw.set_wheel_friction_slip(i, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The multiplier of friction between a tire and the collider it’s on top of.
|
|
|
|
|
|
*
|
|
|
|
|
|
* The larger the value, the stronger side friction will be.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelSideFrictionStiffness(i: number): number | null {
|
|
|
|
|
|
return this.raw.wheel_side_friction_stiffness(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The multiplier of friction between a tire and the collider it’s on top of.
|
|
|
|
|
|
*
|
|
|
|
|
|
* The larger the value, the stronger side friction will be.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public setWheelSideFrictionStiffness(i: number, value: number) {
|
|
|
|
|
|
this.raw.set_wheel_side_friction_stiffness(i, value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* Getters only.
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The i-th wheel’s current rotation angle (radians) on its axle.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelRotation(i: number): number | null {
|
|
|
|
|
|
return this.raw.wheel_rotation(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The forward impulses applied by the i-th wheel on the chassis.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelForwardImpulse(i: number): number | null {
|
|
|
|
|
|
return this.raw.wheel_forward_impulse(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The side impulses applied by the i-th wheel on the chassis.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelSideImpulse(i: number): number | null {
|
|
|
|
|
|
return this.raw.wheel_side_impulse(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The force applied by the i-th wheel suspension.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelSuspensionForce(i: number): number | null {
|
|
|
|
|
|
return this.raw.wheel_suspension_force(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The (world-space) contact normal between the i-th wheel and the floor.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelContactNormal(i: number): Vector | null {
|
|
|
|
|
|
return VectorOps.fromRaw(this.raw.wheel_contact_normal_ws(i));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The (world-space) point hit by the wheel’s ray-cast for the i-th wheel.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelContactPoint(i: number): Vector | null {
|
|
|
|
|
|
return VectorOps.fromRaw(this.raw.wheel_contact_point_ws(i));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The suspension length for the i-th wheel.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelSuspensionLength(i: number): number | null {
|
|
|
|
|
|
return this.raw.wheel_suspension_length(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The (world-space) starting point of the ray-cast for the i-th wheel.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelHardPoint(i: number): Vector | null {
|
|
|
|
|
|
return VectorOps.fromRaw(this.raw.wheel_hard_point_ws(i));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Is the i-th wheel in contact with the ground?
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelIsInContact(i: number): boolean {
|
|
|
|
|
|
return this.raw.wheel_is_in_contact(i);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The collider hit by the ray-cast for the i-th wheel.
|
|
|
|
|
|
*/
|
|
|
|
|
|
public wheelGroundObject(i: number): Collider | null {
|
|
|
|
|
|
return this.colliders.get(this.raw.wheel_ground_object(i));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|