/*
|
* Java port of Bullet (c) 2008 Martin Dvorak <jezek2@advel.cz>
|
*
|
* Bullet Continuous Collision Detection and Physics Library
|
* Copyright (c) 2003-2008 Erwin Coumans http://www.bulletphysics.com/
|
*
|
* This software is provided 'as-is', without any express or implied warranty.
|
* In no event will the authors be held liable for any damages arising from
|
* the use of this software.
|
*
|
* Permission is granted to anyone to use this software for any purpose,
|
* including commercial applications, and to alter it and redistribute it
|
* freely, subject to the following restrictions:
|
*
|
* 1. The origin of this software must not be misrepresented; you must not
|
* claim that you wrote the original software. If you use this software
|
* in a product, an acknowledgment in the product documentation would be
|
* appreciated but is not required.
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
* misrepresented as being the original software.
|
* 3. This notice may not be removed or altered from any source distribution.
|
*/
|
|
package com.bulletphysics.dynamics.vehicle;
|
|
import com.bulletphysics.dynamics.RigidBody;
|
import com.bulletphysics.linearmath.Transform;
|
import cz.advel.stack.Stack;
|
import javax.vecmath.Vector3f;
|
|
/**
|
* WheelInfo contains information per wheel about friction and suspension.
|
*
|
* @author jezek2
|
*/
|
public class WheelInfo {
|
|
//protected final BulletStack stack = BulletStack.get();
|
|
public final RaycastInfo raycastInfo = new RaycastInfo();
|
|
public final Transform worldTransform = new Transform();
|
|
public final Vector3f chassisConnectionPointCS = new Vector3f(); // const
|
public final Vector3f wheelDirectionCS = new Vector3f(); // const
|
public final Vector3f wheelAxleCS = new Vector3f(); // const or modified by steering
|
public float suspensionRestLength1; // const
|
public float maxSuspensionTravelCm;
|
public float wheelsRadius; // const
|
public float suspensionStiffness; // const
|
public float wheelsDampingCompression; // const
|
public float wheelsDampingRelaxation; // const
|
public float frictionSlip;
|
public float steering;
|
public float rotation;
|
public float deltaRotation;
|
public float rollInfluence;
|
|
public float engineForce;
|
|
public float brake;
|
|
public boolean bIsFrontWheel;
|
|
public Object clientInfo; // can be used to store pointer to sync transforms...
|
|
public float clippedInvContactDotSuspension;
|
public float suspensionRelativeVelocity;
|
// calculated by suspension
|
public float wheelsSuspensionForce;
|
public float skidInfo;
|
|
public WheelInfo(WheelInfoConstructionInfo ci) {
|
suspensionRestLength1 = ci.suspensionRestLength;
|
maxSuspensionTravelCm = ci.maxSuspensionTravelCm;
|
|
wheelsRadius = ci.wheelRadius;
|
suspensionStiffness = ci.suspensionStiffness;
|
wheelsDampingCompression = ci.wheelsDampingCompression;
|
wheelsDampingRelaxation = ci.wheelsDampingRelaxation;
|
chassisConnectionPointCS.set(ci.chassisConnectionCS);
|
wheelDirectionCS.set(ci.wheelDirectionCS);
|
wheelAxleCS.set(ci.wheelAxleCS);
|
frictionSlip = ci.frictionSlip;
|
steering = 0f;
|
engineForce = 0f;
|
rotation = 0f;
|
deltaRotation = 0f;
|
brake = 0f;
|
rollInfluence = 0.1f;
|
bIsFrontWheel = ci.bIsFrontWheel;
|
}
|
|
public float getSuspensionRestLength() {
|
return suspensionRestLength1;
|
}
|
|
public void updateWheel(RigidBody chassis, RaycastInfo raycastInfo) {
|
if (raycastInfo.isInContact) {
|
float project = raycastInfo.contactNormalWS.dot(raycastInfo.wheelDirectionWS);
|
Vector3f chassis_velocity_at_contactPoint = Stack.alloc(Vector3f.class);
|
Vector3f relpos = Stack.alloc(Vector3f.class);
|
relpos.sub(raycastInfo.contactPointWS, chassis.getCenterOfMassPosition(Stack.alloc(Vector3f.class)));
|
chassis.getVelocityInLocalPoint(relpos, chassis_velocity_at_contactPoint);
|
float projVel = raycastInfo.contactNormalWS.dot(chassis_velocity_at_contactPoint);
|
if (project >= -0.1f) {
|
suspensionRelativeVelocity = 0f;
|
clippedInvContactDotSuspension = 1f / 0.1f;
|
}
|
else {
|
float inv = -1f / project;
|
suspensionRelativeVelocity = projVel * inv;
|
clippedInvContactDotSuspension = inv;
|
}
|
}
|
else {
|
// Not in contact : position wheel in a nice (rest length) position
|
raycastInfo.suspensionLength = getSuspensionRestLength();
|
suspensionRelativeVelocity = 0f;
|
raycastInfo.contactNormalWS.negate(raycastInfo.wheelDirectionWS);
|
clippedInvContactDotSuspension = 1f;
|
}
|
}
|
|
////////////////////////////////////////////////////////////////////////////
|
|
public static class RaycastInfo {
|
// set by raycaster
|
public final Vector3f contactNormalWS = new Vector3f(); // contactnormal
|
public final Vector3f contactPointWS = new Vector3f(); // raycast hitpoint
|
public float suspensionLength;
|
public final Vector3f hardPointWS = new Vector3f(); // raycast starting point
|
public final Vector3f wheelDirectionWS = new Vector3f(); // direction in worldspace
|
public final Vector3f wheelAxleWS = new Vector3f(); // axle in worldspace
|
public boolean isInContact;
|
public Object groundObject; // could be general void* ptr
|
}
|
|
}
|