stk-code_catmod/src/physics/btKart.hpp

280 lines
12 KiB
C++

/*
* Copyright (C) 2005-2015 Erwin Coumans http://continuousphysics.com/Bullet/
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies.
* Erwin Coumans makes no representations about the suitability
* of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#ifndef BT_KART_HPP
#define BT_KART_HPP
#include "BulletDynamics/Dynamics/btRigidBody.h"
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
#include "physics/btKartRaycast.hpp"
class btDynamicsWorld;
#include "LinearMath/btAlignedObjectArray.h"
#include "BulletDynamics/Vehicle/btWheelInfo.h"
#include "BulletDynamics/Dynamics/btActionInterface.h"
class btVehicleTuning;
class Kart;
struct btWheelContactPoint;
/** rayCast vehicle, very special constraint that turn a rigidbody into a
* vehicle.
*/
class btKart : public btActionInterface
{
public:
class btVehicleTuning
{
public:
btVehicleTuning()
:m_suspensionStiffness(btScalar(5.88)),
m_suspensionCompression(btScalar(0.83)),
m_suspensionDamping(btScalar(0.88)),
m_maxSuspensionTravel(btScalar(5.)),
m_frictionSlip(btScalar(10.5)),
m_maxSuspensionForce(btScalar(6000.))
{
} // btVehicleTuning
btScalar m_suspensionStiffness;
btScalar m_suspensionCompression;
btScalar m_suspensionDamping;
btScalar m_maxSuspensionTravel;
btScalar m_frictionSlip;
btScalar m_maxSuspensionForce;
}; // class btVehicleTuning
private:
btAlignedObjectArray<btVector3> m_forwardWS;
btAlignedObjectArray<btVector3> m_axle;
btAlignedObjectArray<btScalar> m_forwardImpulse;
btAlignedObjectArray<btScalar> m_sideImpulse;
///backwards compatibility
int m_userConstraintType;
int m_userConstraintId;
static btRigidBody& getFixedBody();
btScalar calcRollingFriction(btWheelContactPoint& contactPoint);
btScalar m_damping;
btVehicleRaycaster *m_vehicleRaycaster;
/** True if a zipper is active for that kart. */
bool m_zipper_active;
/** The zipper velocity (i.e. the velocity the kart should reach in
* the first frame that the zipper is active). */
btScalar m_zipper_velocity;
/** The angular velocity to be applied when the kart skids.
* 0 means no skidding. */
btScalar m_skid_angular_velocity;
/** True if the kart is currently skidding. This is used to detect
* the end of skidding (i.e. m_skid_angular_velocity=0 and
* m_is_skidding=true), and triggers adjusting of the velocity
* direction. */
bool m_is_skidding;
/** Sliding (skidding) will only be permited when this is true. Also check
* the friction parameter in the wheels since friction directly affects
* skidding.
*/
bool m_allow_sliding;
/** An additional impulse that is applied for a certain amount of time. */
btVector3 m_additional_impulse;
/** The time the additional impulse should be applied. */
float m_time_additional_impulse;
/** Additional rotation that is applied over a certain amount of time. */
btVector3 m_additional_rotation;
/** Duration over which the additional rotation is applied. */
float m_time_additional_rotation;
/** The rigid body that is the chassis of the kart. */
btRigidBody *m_chassisBody;
/** Number of wheels that touch the ground. */
int m_num_wheels_on_ground;
/** Index of the right axis. */
int m_indexRightAxis;
/** Index of the up axis. */
int m_indexUpAxis;
/** Index of the forward axis. */
int m_indexForwardAxis;
/** The STK kart object which uses this vehicle. This is mostly used to
* get access to the kart properties, which also define physics
* properties. */
Kart *m_kart;
/** A visual rotation applied to the kart (for skidding).
* The physics use this to provide proper wheel contact points
* for skid marks. */
float m_visual_rotation;
/** True if the visual wheels touch the ground. */
bool m_visual_wheels_touch_ground;
/** Contact point of the visual wheel position. */
btAlignedObjectArray<btVector3> m_visual_contact_point;
btAlignedObjectArray<btWheelInfo> m_wheelInfo;
void defaultInit();
btScalar rayCast(btWheelInfo& wheel, const btVector3& ray);
public:
/** Constructor to create a car from an existing rigidbody.
* \param chassis The rigid body to use as chassis.
* \param raycaster The raycast object to use.
* \paran kart The STK kart object that uses this vehicle
* (this is used to get access to the kart properties).
*/
btKart(btRigidBody* chassis,
btVehicleRaycaster* raycaster,
Kart *kart);
virtual ~btKart();
void reset();
void debugDraw(btIDebugDraw* debugDrawer);
const btTransform& getChassisWorldTransform() const;
btScalar rayCast(unsigned int index);
virtual void updateVehicle(btScalar step);
void resetSuspension();
btScalar getSteeringValue(int wheel) const;
void setSteeringValue(btScalar steering,int wheel);
void applyEngineForce(btScalar force, int wheel);
const btTransform& getWheelTransformWS( int wheelIndex ) const;
void updateWheelTransform(int wheelIndex,
bool interpolatedTransform=true);
btWheelInfo& addWheel(const btVector3& connectionPointCS0,
const btVector3& wheelDirectionCS0,
const btVector3& wheelAxleCS,
btScalar suspensionRestLength,
btScalar wheelRadius,
const btVehicleTuning& tuning,
bool isFrontWheel);
const btWheelInfo& getWheelInfo(int index) const;
btWheelInfo& getWheelInfo(int index);
void updateWheelTransformsWS(btWheelInfo& wheel,
bool interpolatedTransform=true);
void setAllBrakes(btScalar brake);
void updateSuspension(btScalar deltaTime);
virtual void updateFriction(btScalar timeStep);
public:
void setSliding(bool active);
void instantSpeedIncreaseTo(float speed);
void capSpeed(float max_speed);
void updateAllWheelPositions();
// ------------------------------------------------------------------------
/** Returns true if both rear visual wheels touch the ground. */
bool visualWheelsTouchGround() const
{
return m_visual_wheels_touch_ground;
} // visualWheelsTouchGround
// ------------------------------------------------------------------------
/** Returns the contact point of a visual wheel.
* \param n Index of the wheel, must be 2 or 3 since only the two rear
* wheels define the visual position
*/
const btVector3& getVisualContactPoint(int n) const
{
assert(n>=2 && n<=3);
return m_visual_contact_point[n];
} // getVisualContactPoint
// ------------------------------------------------------------------------
/** btActionInterface interface. */
virtual void updateAction(btCollisionWorld* collisionWorld,
btScalar step)
{
(void) collisionWorld;
updateVehicle(step);
} // updateAction
// ------------------------------------------------------------------------
/** Returns the number of wheels of this vehicle. */
inline int getNumWheels() const { return int(m_wheelInfo.size());}
// ------------------------------------------------------------------------
/** Returns the chassis (rigid) body. */
inline btRigidBody* getRigidBody() { return m_chassisBody; }
// ------------------------------------------------------------------------
/** Returns the chassis (rigid) body. */
const btRigidBody* getRigidBody() const { return m_chassisBody; }
// ------------------------------------------------------------------------
/** Returns the index of the right axis. */
inline int getRightAxis() const { return m_indexRightAxis; }
// ------------------------------------------------------------------------
/** Returns the index of the up axis. */
inline int getUpAxis() const { return m_indexUpAxis; }
// ------------------------------------------------------------------------
/** Returns the index of the forward axis. */
inline int getForwardAxis() const { return m_indexForwardAxis; }
// ------------------------------------------------------------------------
/** Backwards compatibility. */
int getUserConstraintType() const { return m_userConstraintType ; }
// ------------------------------------------------------------------------
void setUserConstraintType(int userConstraintType)
{
m_userConstraintType = userConstraintType;
} // setUserConstraintType
// ------------------------------------------------------------------------
void setUserConstraintId(int uid) { m_userConstraintId = uid; }
// ------------------------------------------------------------------------
int getUserConstraintId() const { return m_userConstraintId; }
// ------------------------------------------------------------------------
/** Sets the angular velocity to be used when skidding
* (0 means no skidding). */
void setSkidAngularVelocity(float v) {m_skid_angular_velocity = v; }
// ------------------------------------------------------------------------
/** Returns the number of wheels on the ground. */
unsigned int getNumWheelsOnGround() const {return m_num_wheels_on_ground;}
// ------------------------------------------------------------------------
/** Sets an impulse that is applied for a certain amount of time.
* \param t Time for the impulse to be active.
* \param imp The impulse to apply. */
void setTimedCentralImpulse(float t, const btVector3 &imp)
{
// Only add impulse if no other impulse is active.
if(m_time_additional_impulse>0) return;
m_additional_impulse = imp;
m_time_additional_impulse = t;
} // setTimedImpulse
// ------------------------------------------------------------------------
/** Returns the time an additional impulse is activated. */
float getCentralImpulseTime() const { return m_time_additional_impulse; }
// ------------------------------------------------------------------------
/** Sets a visual rotation to be applied, which the physics use to provide
* the location where the graphical wheels touch the ground (for
* skidmarks). */
void setVisualRotation(float angle)
{
m_visual_rotation = angle;
} // setVisualRotation
// ------------------------------------------------------------------------
/** Sets a rotation that is applied over a certain amount of time (to avoid
* a too rapid changes in the kart).
* \param t Time for the rotation to be applied.
* \param torque The rotation to apply. */
void setTimedRotation(float t, const btVector3 &rot)
{
m_additional_rotation = rot/t;
m_time_additional_rotation = t;
} // setTimedTorque
}; // class btKart
#endif //BT_KART_HPP