1 /*
2  * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/
3  *
4  * Permission to use, copy, modify, distribute and sell this software
5  * and its documentation for any purpose is hereby granted without fee,
6  * provided that the above copyright notice appear in all copies.
7  * Erwin Coumans makes no representations about the suitability
8  * of this software for any purpose.
9  * It is provided "as is" without express or implied warranty.
10 */
11 #ifndef BT_RAYCASTVEHICLE_H
12 #define BT_RAYCASTVEHICLE_H
13 
14 #include "BulletDynamics/Dynamics/btRigidBody.h"
15 #include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
16 #include "btVehicleRaycaster.h"
17 class btDynamicsWorld;
18 #include "LinearMath/btAlignedObjectArray.h"
19 #include "btWheelInfo.h"
20 #include "BulletDynamics/Dynamics/btActionInterface.h"
21 
22 //class btVehicleTuning;
23 
24 ///rayCast vehicle, very special constraint that turn a rigidbody into a vehicle.
25 class btRaycastVehicle : public btActionInterface
26 {
27 	btAlignedObjectArray<btVector3> m_forwardWS;
28 	btAlignedObjectArray<btVector3> m_axle;
29 	btAlignedObjectArray<btScalar> m_forwardImpulse;
30 	btAlignedObjectArray<btScalar> m_sideImpulse;
31 
32 	///backwards compatibility
33 	int m_userConstraintType;
34 	int m_userConstraintId;
35 
36 public:
37 	class btVehicleTuning
38 	{
39 	public:
btVehicleTuning()40 		btVehicleTuning()
41 			: m_suspensionStiffness(btScalar(5.88)),
42 			  m_suspensionCompression(btScalar(0.83)),
43 			  m_suspensionDamping(btScalar(0.88)),
44 			  m_maxSuspensionTravelCm(btScalar(500.)),
45 			  m_frictionSlip(btScalar(10.5)),
46 			  m_maxSuspensionForce(btScalar(6000.))
47 		{
48 		}
49 		btScalar m_suspensionStiffness;
50 		btScalar m_suspensionCompression;
51 		btScalar m_suspensionDamping;
52 		btScalar m_maxSuspensionTravelCm;
53 		btScalar m_frictionSlip;
54 		btScalar m_maxSuspensionForce;
55 	};
56 
57 private:
58 	btVehicleRaycaster* m_vehicleRaycaster;
59 	btScalar m_pitchControl;
60 	btScalar m_steeringValue;
61 	btScalar m_currentVehicleSpeedKmHour;
62 
63 	btRigidBody* m_chassisBody;
64 
65 	int m_indexRightAxis;
66 	int m_indexUpAxis;
67 	int m_indexForwardAxis;
68 
69 	void defaultInit(const btVehicleTuning& tuning);
70 
71 public:
72 	//constructor to create a car from an existing rigidbody
73 	btRaycastVehicle(const btVehicleTuning& tuning, btRigidBody* chassis, btVehicleRaycaster* raycaster);
74 
75 	virtual ~btRaycastVehicle();
76 
77 	///btActionInterface interface
updateAction(btCollisionWorld * collisionWorld,btScalar step)78 	virtual void updateAction(btCollisionWorld* collisionWorld, btScalar step)
79 	{
80 		(void)collisionWorld;
81 		updateVehicle(step);
82 	}
83 
84 	///btActionInterface interface
85 	void debugDraw(btIDebugDraw* debugDrawer);
86 
87 	const btTransform& getChassisWorldTransform() const;
88 
89 	btScalar rayCast(btWheelInfo& wheel);
90 
91 	virtual void updateVehicle(btScalar step);
92 
93 	void resetSuspension();
94 
95 	btScalar getSteeringValue(int wheel) const;
96 
97 	void setSteeringValue(btScalar steering, int wheel);
98 
99 	void applyEngineForce(btScalar force, int wheel);
100 
101 	const btTransform& getWheelTransformWS(int wheelIndex) const;
102 
103 	void updateWheelTransform(int wheelIndex, bool interpolatedTransform = true);
104 
105 	//	void	setRaycastWheelInfo( int wheelIndex , bool isInContact, const btVector3& hitPoint, const btVector3& hitNormal,btScalar depth);
106 
107 	btWheelInfo& addWheel(const btVector3& connectionPointCS0, const btVector3& wheelDirectionCS0, const btVector3& wheelAxleCS, btScalar suspensionRestLength, btScalar wheelRadius, const btVehicleTuning& tuning, bool isFrontWheel);
108 
getNumWheels()109 	inline int getNumWheels() const
110 	{
111 		return int(m_wheelInfo.size());
112 	}
113 
114 	btAlignedObjectArray<btWheelInfo> m_wheelInfo;
115 
116 	const btWheelInfo& getWheelInfo(int index) const;
117 
118 	btWheelInfo& getWheelInfo(int index);
119 
120 	void updateWheelTransformsWS(btWheelInfo& wheel, bool interpolatedTransform = true);
121 
122 	void setBrake(btScalar brake, int wheelIndex);
123 
setPitchControl(btScalar pitch)124 	void setPitchControl(btScalar pitch)
125 	{
126 		m_pitchControl = pitch;
127 	}
128 
129 	void updateSuspension(btScalar deltaTime);
130 
131 	virtual void updateFriction(btScalar timeStep);
132 
getRigidBody()133 	inline btRigidBody* getRigidBody()
134 	{
135 		return m_chassisBody;
136 	}
137 
getRigidBody()138 	const btRigidBody* getRigidBody() const
139 	{
140 		return m_chassisBody;
141 	}
142 
getRightAxis()143 	inline int getRightAxis() const
144 	{
145 		return m_indexRightAxis;
146 	}
getUpAxis()147 	inline int getUpAxis() const
148 	{
149 		return m_indexUpAxis;
150 	}
151 
getForwardAxis()152 	inline int getForwardAxis() const
153 	{
154 		return m_indexForwardAxis;
155 	}
156 
157 	///Worldspace forward vector
getForwardVector()158 	btVector3 getForwardVector() const
159 	{
160 		const btTransform& chassisTrans = getChassisWorldTransform();
161 
162 		btVector3 forwardW(
163 			chassisTrans.getBasis()[0][m_indexForwardAxis],
164 			chassisTrans.getBasis()[1][m_indexForwardAxis],
165 			chassisTrans.getBasis()[2][m_indexForwardAxis]);
166 
167 		return forwardW;
168 	}
169 
170 	///Velocity of vehicle (positive if velocity vector has same direction as foward vector)
getCurrentSpeedKmHour()171 	btScalar getCurrentSpeedKmHour() const
172 	{
173 		return m_currentVehicleSpeedKmHour;
174 	}
175 
setCoordinateSystem(int rightIndex,int upIndex,int forwardIndex)176 	virtual void setCoordinateSystem(int rightIndex, int upIndex, int forwardIndex)
177 	{
178 		m_indexRightAxis = rightIndex;
179 		m_indexUpAxis = upIndex;
180 		m_indexForwardAxis = forwardIndex;
181 	}
182 
183 	///backwards compatibility
getUserConstraintType()184 	int getUserConstraintType() const
185 	{
186 		return m_userConstraintType;
187 	}
188 
setUserConstraintType(int userConstraintType)189 	void setUserConstraintType(int userConstraintType)
190 	{
191 		m_userConstraintType = userConstraintType;
192 	};
193 
setUserConstraintId(int uid)194 	void setUserConstraintId(int uid)
195 	{
196 		m_userConstraintId = uid;
197 	}
198 
getUserConstraintId()199 	int getUserConstraintId() const
200 	{
201 		return m_userConstraintId;
202 	}
203 };
204 
205 class btDefaultVehicleRaycaster : public btVehicleRaycaster
206 {
207 	btDynamicsWorld* m_dynamicsWorld;
208 
209 public:
btDefaultVehicleRaycaster(btDynamicsWorld * world)210 	btDefaultVehicleRaycaster(btDynamicsWorld* world)
211 		: m_dynamicsWorld(world)
212 	{
213 	}
214 
215 	virtual void* castRay(const btVector3& from, const btVector3& to, btVehicleRaycasterResult& result);
216 };
217 
218 #endif  //BT_RAYCASTVEHICLE_H
219