File: src/objects/WheelInfo.js
var Vec3 = require('../math/Vec3');
var Transform = require('../math/Transform');
var RaycastResult = require('../collision/RaycastResult');
var Utils = require('../utils/Utils');
module.exports = WheelInfo;
/**
* @class WheelInfo
* @constructor
* @param {Object} [options]
*
* @param {Vec3} [options.chassisConnectionPointLocal]
* @param {Vec3} [options.chassisConnectionPointWorld]
* @param {Vec3} [options.directionLocal]
* @param {Vec3} [options.directionWorld]
* @param {Vec3} [options.axleLocal]
* @param {Vec3} [options.axleWorld]
* @param {number} [options.suspensionRestLength=1]
* @param {number} [options.suspensionMaxLength=2]
* @param {number} [options.radius=1]
* @param {number} [options.suspensionStiffness=100]
* @param {number} [options.dampingCompression=10]
* @param {number} [options.dampingRelaxation=10]
* @param {number} [options.frictionSlip=10000]
* @param {number} [options.steering=0]
* @param {number} [options.rotation=0]
* @param {number} [options.deltaRotation=0]
* @param {number} [options.rollInfluence=0.01]
* @param {number} [options.maxSuspensionForce]
* @param {boolean} [options.isFrontWheel=true]
* @param {number} [options.clippedInvContactDotSuspension=1]
* @param {number} [options.suspensionRelativeVelocity=0]
* @param {number} [options.suspensionForce=0]
* @param {number} [options.skidInfo=0]
* @param {number} [options.suspensionLength=0]
* @param {number} [options.maxSuspensionTravel=1]
* @param {boolean} [options.useCustomSlidingRotationalSpeed=false]
* @param {number} [options.customSlidingRotationalSpeed=-0.1]
*/
function WheelInfo(options){
options = Utils.defaults(options, {
chassisConnectionPointLocal: new Vec3(),
chassisConnectionPointWorld: new Vec3(),
directionLocal: new Vec3(),
directionWorld: new Vec3(),
axleLocal: new Vec3(),
axleWorld: new Vec3(),
suspensionRestLength: 1,
suspensionMaxLength: 2,
radius: 1,
suspensionStiffness: 100,
dampingCompression: 10,
dampingRelaxation: 10,
frictionSlip: 10000,
steering: 0,
rotation: 0,
deltaRotation: 0,
rollInfluence: 0.01,
maxSuspensionForce: Number.MAX_VALUE,
isFrontWheel: true,
clippedInvContactDotSuspension: 1,
suspensionRelativeVelocity: 0,
suspensionForce: 0,
skidInfo: 0,
suspensionLength: 0,
maxSuspensionTravel: 1,
useCustomSlidingRotationalSpeed: false,
customSlidingRotationalSpeed: -0.1
});
/**
* Max travel distance of the suspension, in meters.
* @property {number} maxSuspensionTravel
*/
this.maxSuspensionTravel = options.maxSuspensionTravel;
/**
* Speed to apply to the wheel rotation when the wheel is sliding.
* @property {number} customSlidingRotationalSpeed
*/
this.customSlidingRotationalSpeed = options.customSlidingRotationalSpeed;
/**
* If the customSlidingRotationalSpeed should be used.
* @property {Boolean} useCustomSlidingRotationalSpeed
*/
this.useCustomSlidingRotationalSpeed = options.useCustomSlidingRotationalSpeed;
/**
* @property {Boolean} sliding
*/
this.sliding = false;
/**
* Connection point, defined locally in the chassis body frame.
* @property {Vec3} chassisConnectionPointLocal
*/
this.chassisConnectionPointLocal = options.chassisConnectionPointLocal.clone();
/**
* @property {Vec3} chassisConnectionPointWorld
*/
this.chassisConnectionPointWorld = options.chassisConnectionPointWorld.clone();
/**
* @property {Vec3} directionLocal
*/
this.directionLocal = options.directionLocal.clone();
/**
* @property {Vec3} directionWorld
*/
this.directionWorld = options.directionWorld.clone();
/**
* @property {Vec3} axleLocal
*/
this.axleLocal = options.axleLocal.clone();
/**
* @property {Vec3} axleWorld
*/
this.axleWorld = options.axleWorld.clone();
/**
* @property {number} suspensionRestLength
*/
this.suspensionRestLength = options.suspensionRestLength;
/**
* @property {number} suspensionMaxLength
*/
this.suspensionMaxLength = options.suspensionMaxLength;
/**
* @property {number} radius
*/
this.radius = options.radius;
/**
* @property {number} suspensionStiffness
*/
this.suspensionStiffness = options.suspensionStiffness;
/**
* @property {number} dampingCompression
*/
this.dampingCompression = options.dampingCompression;
/**
* @property {number} dampingRelaxation
*/
this.dampingRelaxation = options.dampingRelaxation;
/**
* @property {number} frictionSlip
*/
this.frictionSlip = options.frictionSlip;
/**
* @property {number} steering
*/
this.steering = 0;
/**
* Rotation value, in radians.
* @property {number} rotation
*/
this.rotation = 0;
/**
* @property {number} deltaRotation
*/
this.deltaRotation = 0;
/**
* @property {number} rollInfluence
*/
this.rollInfluence = options.rollInfluence;
/**
* @property {number} maxSuspensionForce
*/
this.maxSuspensionForce = options.maxSuspensionForce;
/**
* @property {number} engineForce
*/
this.engineForce = 0;
/**
* @property {number} brake
*/
this.brake = 0;
/**
* @property {number} isFrontWheel
*/
this.isFrontWheel = options.isFrontWheel;
/**
* @property {number} clippedInvContactDotSuspension
*/
this.clippedInvContactDotSuspension = 1;
/**
* @property {number} suspensionRelativeVelocity
*/
this.suspensionRelativeVelocity = 0;
/**
* @property {number} suspensionForce
*/
this.suspensionForce = 0;
/**
* @property {number} skidInfo
*/
this.skidInfo = 0;
/**
* @property {number} suspensionLength
*/
this.suspensionLength = 0;
/**
* @property {number} sideImpulse
*/
this.sideImpulse = 0;
/**
* @property {number} forwardImpulse
*/
this.forwardImpulse = 0;
/**
* The result from raycasting
* @property {RaycastResult} raycastResult
*/
this.raycastResult = new RaycastResult();
/**
* Wheel world transform
* @property {Transform} worldTransform
*/
this.worldTransform = new Transform();
/**
* @property {boolean} isInContact
*/
this.isInContact = false;
}
var chassis_velocity_at_contactPoint = new Vec3();
var relpos = new Vec3();
var chassis_velocity_at_contactPoint = new Vec3();
WheelInfo.prototype.updateWheel = function(chassis){
var raycastResult = this.raycastResult;
if (this.isInContact){
var project= raycastResult.hitNormalWorld.dot(raycastResult.directionWorld);
raycastResult.hitPointWorld.vsub(chassis.position, relpos);
chassis.getVelocityAtWorldPoint(relpos, chassis_velocity_at_contactPoint);
var projVel = raycastResult.hitNormalWorld.dot( chassis_velocity_at_contactPoint );
if (project >= -0.1) {
this.suspensionRelativeVelocity = 0.0;
this.clippedInvContactDotSuspension = 1.0 / 0.1;
} else {
var inv = -1 / project;
this.suspensionRelativeVelocity = projVel * inv;
this.clippedInvContactDotSuspension = inv;
}
} else {
// Not in contact : position wheel in a nice (rest length) position
raycastResult.suspensionLength = this.suspensionRestLength;
this.suspensionRelativeVelocity = 0.0;
raycastResult.directionWorld.scale(-1, raycastResult.hitNormalWorld);
this.clippedInvContactDotSuspension = 1.0;
}
};