| 1 | // | 
| 2 | // Redistribution and use in source and binary forms, with or without | 
| 3 | // modification, are permitted provided that the following conditions | 
| 4 | // are met: | 
| 5 | //  * Redistributions of source code must retain the above copyright | 
| 6 | //    notice, this list of conditions and the following disclaimer. | 
| 7 | //  * Redistributions in binary form must reproduce the above copyright | 
| 8 | //    notice, this list of conditions and the following disclaimer in the | 
| 9 | //    documentation and/or other materials provided with the distribution. | 
| 10 | //  * Neither the name of NVIDIA CORPORATION nor the names of its | 
| 11 | //    contributors may be used to endorse or promote products derived | 
| 12 | //    from this software without specific prior written permission. | 
| 13 | // | 
| 14 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY | 
| 15 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
| 16 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 
| 17 | // PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR | 
| 18 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 
| 19 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 
| 20 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 
| 21 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 
| 22 | // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
| 23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
| 24 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
| 25 | // | 
| 26 | // Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved. | 
| 27 | // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. | 
| 28 | // Copyright (c) 2001-2004 NovodeX AG. All rights reserved.   | 
| 29 |  | 
| 30 | #ifndef PX_VEHICLE_CORE_COMPONENTS_H | 
| 31 | #define PX_VEHICLE_CORE_COMPONENTS_H | 
| 32 | /** \addtogroup vehicle | 
| 33 |   @{ | 
| 34 | */ | 
| 35 |  | 
| 36 | #include "foundation/PxMemory.h" | 
| 37 | #include "foundation/PxVec3.h" | 
| 38 | #include "common/PxCoreUtilityTypes.h" | 
| 39 | #include "vehicle/PxVehicleSDK.h" | 
| 40 | #include "common/PxTypeInfo.h" | 
| 41 |  | 
| 42 | #if !PX_DOXYGEN | 
| 43 | namespace physx | 
| 44 | { | 
| 45 | #endif | 
| 46 |  | 
| 47 | class PxVehicleChassisData | 
| 48 | { | 
| 49 | public: | 
| 50 |  | 
| 51 | 	friend class PxVehicleDriveSimData4W; | 
| 52 |  | 
| 53 | 	PxVehicleChassisData() | 
| 54 | 		:	mMOI(PxVec3(0,0,0)), | 
| 55 | 			mMass(1500), | 
| 56 | 			mCMOffset(PxVec3(0,0,0)) | 
| 57 | 	{ | 
| 58 | 	} | 
| 59 |  | 
| 60 | 	/** | 
| 61 | 	\brief Moment of inertia of vehicle rigid body actor. | 
| 62 | 	 | 
| 63 | 	\note Specified in kilograms metres-squared (kg m^2). | 
| 64 | 	*/ | 
| 65 | 	PxVec3 mMOI; | 
| 66 |  | 
| 67 | 	/** | 
| 68 | 	\brief Mass of vehicle rigid body actor. | 
| 69 | 	 | 
| 70 | 	\note Specified in kilograms (kg). | 
| 71 | 	*/ | 
| 72 | 	PxReal mMass; | 
| 73 |  | 
| 74 | 	/** | 
| 75 | 	\brief Center of mass offset of vehicle rigid body actor. | 
| 76 |  | 
| 77 | 	\note Specified in metres (m). | 
| 78 | 	*/ | 
| 79 | 	PxVec3 mCMOffset; | 
| 80 |  | 
| 81 | private: | 
| 82 |  | 
| 83 | 	PxReal pad; | 
| 84 |  | 
| 85 | 	bool isValid() const; | 
| 86 | }; | 
| 87 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleChassisData)& 0x0f)); | 
| 88 |  | 
| 89 | class PxVehicleEngineData | 
| 90 | { | 
| 91 | public: | 
| 92 |  | 
| 93 | 	friend class PxVehicleDriveSimData; | 
| 94 | 	 | 
| 95 | 	enum | 
| 96 | 	{ | 
| 97 | 		eMAX_NB_ENGINE_TORQUE_CURVE_ENTRIES = 8 | 
| 98 | 	}; | 
| 99 |  | 
| 100 | 	PxVehicleEngineData() | 
| 101 | 		: 	mMOI(1.0f), | 
| 102 | 			mPeakTorque(500.0f), | 
| 103 | 			mMaxOmega(600.0f), | 
| 104 | 			mDampingRateFullThrottle(0.15f), | 
| 105 | 			mDampingRateZeroThrottleClutchEngaged(2.0f), | 
| 106 | 			mDampingRateZeroThrottleClutchDisengaged(0.35f) | 
| 107 | 	{ | 
| 108 | 		mTorqueCurve.addPair(x: 0.0f, y: 0.8f); | 
| 109 | 		mTorqueCurve.addPair(x: 0.33f, y: 1.0f); | 
| 110 | 		mTorqueCurve.addPair(x: 1.0f, y: 0.8f); | 
| 111 |  | 
| 112 | 		mRecipMOI=1.0f/mMOI; | 
| 113 | 		mRecipMaxOmega=1.0f/mMaxOmega; | 
| 114 | 	} | 
| 115 |  | 
| 116 | 	/** | 
| 117 | 	\brief Graph of normalized torque (torque/mPeakTorque) against normalized engine speed ( engineRotationSpeed / mMaxOmega ). | 
| 118 | 	 | 
| 119 | 	\note The normalized engine speed is the x-axis of the graph, while the normalized torque is the y-axis of the graph. | 
| 120 | 	*/ | 
| 121 | 	PxFixedSizeLookupTable<eMAX_NB_ENGINE_TORQUE_CURVE_ENTRIES> mTorqueCurve; | 
| 122 |  | 
| 123 | 	/** | 
| 124 | 	\brief Moment of inertia of the engine around the axis of rotation. | 
| 125 | 	 | 
| 126 | 	\note Specified in kilograms metres-squared (kg m^2) | 
| 127 | 	*/ | 
| 128 | 	PxReal mMOI; | 
| 129 |  | 
| 130 | 	/** | 
| 131 | 	\brief Maximum torque available to apply to the engine when the accelerator pedal is at maximum. | 
| 132 | 	 | 
| 133 | 	\note The torque available is the value of the accelerator pedal (in range [0, 1]) multiplied by the normalized torque as computed from mTorqueCurve multiplied by mPeakTorque. | 
| 134 | 	 | 
| 135 | 	\note Specified in kilograms metres-squared per second-squared (kg m^2 s^-2). | 
| 136 |  | 
| 137 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 138 | 	*/ | 
| 139 | 	PxReal mPeakTorque; | 
| 140 |  | 
| 141 | 	/** | 
| 142 | 	\brief Maximum rotation speed of the engine. | 
| 143 |  | 
| 144 | 	\note Specified in radians per second (s^-1). | 
| 145 |  | 
| 146 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 147 | 	*/ | 
| 148 | 	PxReal mMaxOmega; | 
| 149 |  | 
| 150 | 	/** | 
| 151 | 	\brief Damping rate of engine when full throttle is applied. | 
| 152 | 	 | 
| 153 | 	\note If the clutch is engaged (any gear except neutral) then the damping rate applied at run-time is an interpolation  | 
| 154 | 	between mDampingRateZeroThrottleClutchEngaged and mDampingRateFullThrottle: | 
| 155 | 	mDampingRateZeroThrottleClutchEngaged + (mDampingRateFullThrottle-mDampingRateZeroThrottleClutchEngaged)*acceleratorPedal; | 
| 156 | 	 | 
| 157 | 	\note If the clutch is disengaged (in neutral gear) the damping rate applied at run-time is an interpolation | 
| 158 | 	between mDampingRateZeroThrottleClutchDisengaged and mDampingRateFullThrottle: | 
| 159 | 	mDampingRateZeroThrottleClutchDisengaged + (mDampingRateFullThrottle-mDampingRateZeroThrottleClutchDisengaged)*acceleratorPedal; | 
| 160 | 	 | 
| 161 | 	\note Specified in kilograms metres-squared per second (kg m^2 s^-1). | 
| 162 |  | 
| 163 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 164 | 	*/ | 
| 165 | 	PxReal mDampingRateFullThrottle; | 
| 166 |  | 
| 167 |  | 
| 168 | 	/** | 
| 169 | 	\brief Damping rate of engine when full throttle is applied. | 
| 170 | 	 | 
| 171 | 	\note If the clutch is engaged (any gear except neutral) then the damping rate applied at run-time is an interpolation  | 
| 172 | 	between mDampingRateZeroThrottleClutchEngaged and mDampingRateFullThrottle: | 
| 173 | 	mDampingRateZeroThrottleClutchEngaged + (mDampingRateFullThrottle-mDampingRateZeroThrottleClutchEngaged)*acceleratorPedal; | 
| 174 | 	 | 
| 175 | 	\note If the clutch is disengaged (in neutral gear) the damping rate applied at run-time is an interpolation | 
| 176 | 	between mDampingRateZeroThrottleClutchDisengaged and mDampingRateFullThrottle: | 
| 177 | 	mDampingRateZeroThrottleClutchDisengaged + (mDampingRateFullThrottle-mDampingRateZeroThrottleClutchDisengaged)*acceleratorPedal; | 
| 178 | 	 | 
| 179 | 	\note Specified in kilograms metres-squared per second (kg m^2 s^-1). | 
| 180 |  | 
| 181 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 182 | 	*/ | 
| 183 | 	PxReal mDampingRateZeroThrottleClutchEngaged; | 
| 184 |  | 
| 185 | 	/** | 
| 186 | 	\brief Damping rate of engine when full throttle is applied. | 
| 187 | 	 | 
| 188 | 	\note If the clutch is engaged (any gear except neutral) then the damping rate applied at run-time is an interpolation  | 
| 189 | 	between mDampingRateZeroThrottleClutchEngaged and mDampingRateFullThrottle: | 
| 190 | 	mDampingRateZeroThrottleClutchEngaged + (mDampingRateFullThrottle-mDampingRateZeroThrottleClutchEngaged)*acceleratorPedal; | 
| 191 | 	 | 
| 192 | 	\note If the clutch is disengaged (in neutral gear) the damping rate applied at run-time is an interpolation | 
| 193 | 	between mDampingRateZeroThrottleClutchDisengaged and mDampingRateFullThrottle: | 
| 194 | 	mDampingRateZeroThrottleClutchDisengaged + (mDampingRateFullThrottle-mDampingRateZeroThrottleClutchDisengaged)*acceleratorPedal; | 
| 195 | 	 | 
| 196 | 	\note Specified in kilograms metres-squared per second (kg m^2 s^-1). | 
| 197 |  | 
| 198 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 199 | 	*/ | 
| 200 | 	PxReal mDampingRateZeroThrottleClutchDisengaged; | 
| 201 |  | 
| 202 | 	/** | 
| 203 | 	\brief Return value of mRecipMOI(=1.0f/mMOI) that is automatically set by PxVehicleDriveSimData::setEngineData | 
| 204 | 	*/ | 
| 205 | 	PX_FORCE_INLINE PxReal getRecipMOI() const {return mRecipMOI;} | 
| 206 |  | 
| 207 | 	/** | 
| 208 | 	\brief Return value of mRecipMaxOmega( = 1.0f / mMaxOmega ) that is automatically set by PxVehicleDriveSimData::setEngineData | 
| 209 | 	*/ | 
| 210 | 	PX_FORCE_INLINE PxReal getRecipMaxOmega() const {return mRecipMaxOmega;} | 
| 211 |  | 
| 212 | private: | 
| 213 |  | 
| 214 | 	/** | 
| 215 | 	\brief Reciprocal of the engine moment of inertia. | 
| 216 | 	 | 
| 217 | 	\note Not necessary to set this value because it is set by PxVehicleDriveSimData::setEngineData | 
| 218 |  | 
| 219 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 220 | 	*/ | 
| 221 | 	PxReal mRecipMOI; | 
| 222 |  | 
| 223 | 	/** | 
| 224 | 	\brief Reciprocal of the maximum rotation speed of the engine. | 
| 225 | 	 | 
| 226 | 	\note Not necessary to set this value because it is set by PxVehicleDriveSimData::setEngineData | 
| 227 |  | 
| 228 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 229 | 	*/ | 
| 230 | 	PxReal mRecipMaxOmega; | 
| 231 |  | 
| 232 | 	bool isValid() const; | 
| 233 |  | 
| 234 |  | 
| 235 | //serialization | 
| 236 | public: | 
| 237 | 	PxVehicleEngineData(const PxEMPTY) : mTorqueCurve(PxEmpty) {} | 
| 238 | //~serialization | 
| 239 | }; | 
| 240 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleEngineData)& 0x0f)); | 
| 241 |  | 
| 242 | class PxVehicleGearsData | 
| 243 | { | 
| 244 | public: | 
| 245 |  | 
| 246 | 	friend class PxVehicleDriveSimData; | 
| 247 |  | 
| 248 | 	enum Enum | 
| 249 | 	{ | 
| 250 | 		eREVERSE=0, | 
| 251 | 		eNEUTRAL, | 
| 252 | 		eFIRST, | 
| 253 | 		eSECOND, | 
| 254 | 		eTHIRD, | 
| 255 | 		eFOURTH, | 
| 256 | 		eFIFTH, | 
| 257 | 		eSIXTH, | 
| 258 | 		eSEVENTH, | 
| 259 | 		eEIGHTH, | 
| 260 | 		eNINTH, | 
| 261 | 		eTENTH, | 
| 262 | 		eELEVENTH, | 
| 263 | 		eTWELFTH, | 
| 264 | 		eTHIRTEENTH, | 
| 265 | 		eFOURTEENTH, | 
| 266 | 		eFIFTEENTH, | 
| 267 | 		eSIXTEENTH, | 
| 268 | 		eSEVENTEENTH, | 
| 269 | 		eEIGHTEENTH, | 
| 270 | 		eNINETEENTH, | 
| 271 | 		eTWENTIETH, | 
| 272 | 		eTWENTYFIRST, | 
| 273 | 		eTWENTYSECOND, | 
| 274 | 		eTWENTYTHIRD, | 
| 275 | 		eTWENTYFOURTH, | 
| 276 | 		eTWENTYFIFTH, | 
| 277 | 		eTWENTYSIXTH, | 
| 278 | 		eTWENTYSEVENTH, | 
| 279 | 		eTWENTYEIGHTH, | 
| 280 | 		eTWENTYNINTH, | 
| 281 | 		eTHIRTIETH, | 
| 282 | 		eGEARSRATIO_COUNT | 
| 283 | 	}; | 
| 284 |  | 
| 285 | 	PxVehicleGearsData() | 
| 286 | 		: 	mFinalRatio(4.0f), | 
| 287 | 			mNbRatios(7), | 
| 288 | 			mSwitchTime(0.5f) | 
| 289 | 	{ | 
| 290 | 		mRatios[PxVehicleGearsData::eREVERSE]=-4.0f; | 
| 291 | 		mRatios[PxVehicleGearsData::eNEUTRAL]=0.0f; | 
| 292 | 		mRatios[PxVehicleGearsData::eFIRST]=4.0f; | 
| 293 | 		mRatios[PxVehicleGearsData::eSECOND]=2.0f; | 
| 294 | 		mRatios[PxVehicleGearsData::eTHIRD]=1.5f; | 
| 295 | 		mRatios[PxVehicleGearsData::eFOURTH]=1.1f; | 
| 296 | 		mRatios[PxVehicleGearsData::eFIFTH]=1.0f; | 
| 297 | 		 | 
| 298 | 		for(PxU32 i = PxVehicleGearsData::eSIXTH; i < PxVehicleGearsData::eGEARSRATIO_COUNT; ++i) | 
| 299 | 			mRatios[i]=0.f; | 
| 300 | 	} | 
| 301 | 	 | 
| 302 | 	/** | 
| 303 | 	\brief Gear ratios  | 
| 304 |  | 
| 305 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 306 | 	*/ | 
| 307 | 	PxReal mRatios[PxVehicleGearsData::eGEARSRATIO_COUNT]; | 
| 308 |  | 
| 309 | 	/** | 
| 310 | 	\brief Gear ratio applied is mRatios[currentGear]*finalRatio | 
| 311 |  | 
| 312 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 313 | 	*/ | 
| 314 | 	PxReal mFinalRatio; | 
| 315 |  | 
| 316 | 	/** | 
| 317 | 	\brief Number of gears (including reverse and neutral). | 
| 318 |  | 
| 319 | 	<b>Range:</b> (0, MAX_NB_GEAR_RATIOS)<br> | 
| 320 | 	*/ | 
| 321 | 	PxU32 mNbRatios; | 
| 322 | 	 | 
| 323 | 	/** | 
| 324 | 	\brief Time it takes to switch gear. | 
| 325 | 	 | 
| 326 | 	\note Specified in seconds (s). | 
| 327 |  | 
| 328 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 329 | 	*/ | 
| 330 | 	PxReal mSwitchTime; | 
| 331 | 	 | 
| 332 | private: | 
| 333 |  | 
| 334 | 	PxReal mPad; | 
| 335 |  | 
| 336 | 	bool isValid() const; | 
| 337 |  | 
| 338 | //serialization | 
| 339 | public: | 
| 340 | 	PxVehicleGearsData(const PxEMPTY) {} | 
| 341 | 	PxReal getGearRatio(PxVehicleGearsData::Enum a)  const {return mRatios[a];} | 
| 342 | 	void setGearRatio(PxVehicleGearsData::Enum a, PxReal ratio)   { mRatios[a] = ratio;} | 
| 343 | //~serialization | 
| 344 | }; | 
| 345 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleGearsData)& 0x0f)); | 
| 346 |  | 
| 347 | class PxVehicleAutoBoxData | 
| 348 | { | 
| 349 | public: | 
| 350 |  | 
| 351 | 	friend class PxVehicleDriveSimData; | 
| 352 |  | 
| 353 | 	PxVehicleAutoBoxData() | 
| 354 | 	{ | 
| 355 | 		for(PxU32 i=0;i<PxVehicleGearsData::eGEARSRATIO_COUNT;i++) | 
| 356 | 		{ | 
| 357 | 			mUpRatios[i]=0.65f; | 
| 358 | 			mDownRatios[i]=0.50f; | 
| 359 | 		} | 
| 360 | 		//Not sure how important this is but we want to kick out of neutral very quickly. | 
| 361 | 		mUpRatios[PxVehicleGearsData::eNEUTRAL]=0.15f; | 
| 362 | 		//Set the latency time in an unused element of one of the arrays. | 
| 363 | 		mDownRatios[PxVehicleGearsData::eREVERSE]=2.0f;	 | 
| 364 | 	} | 
| 365 | 	 | 
| 366 | 	/** | 
| 367 | 	\brief Value of ( engineRotationSpeed / PxVehicleEngineData::mMaxOmega ) that is high enough to increment gear. | 
| 368 | 	 | 
| 369 | 	\note When ( engineRotationSpeed / PxVehicleEngineData::mMaxOmega ) > mUpRatios[currentGear] the autobox will begin  | 
| 370 | 	a transition to currentGear+1 unless currentGear is the highest possible gear or neutral or reverse. | 
| 371 |  | 
| 372 | 	<b>Range:</b> [0, 1]<br> | 
| 373 | 	*/ | 
| 374 | 	PxReal mUpRatios[PxVehicleGearsData::eGEARSRATIO_COUNT]; | 
| 375 |  | 
| 376 | 	/** | 
| 377 | 	\brief Value of engineRevs/maxEngineRevs that is low enough to decrement gear. | 
| 378 | 	 | 
| 379 | 	\note When ( engineRotationSpeed / PxVehicleEngineData::mMaxOmega ) < mDownRatios[currentGear] the autobox will begin  | 
| 380 | 	a transition to currentGear-1 unless currentGear is first gear or neutral or reverse. | 
| 381 |  | 
| 382 | 	<b>Range:</b> [0, 1]<br> | 
| 383 | 	*/ | 
| 384 | 	PxReal mDownRatios[PxVehicleGearsData::eGEARSRATIO_COUNT]; | 
| 385 |  | 
| 386 | 	/** | 
| 387 | 	\brief Set the latency time of the autobox. | 
| 388 | 	 | 
| 389 | 	\note Latency time is the minimum time that must pass between each gear change that is initiated by the autobox. | 
| 390 | 	The auto-box will only attempt to initiate another gear change up or down if the simulation time that has passed since the most recent | 
| 391 | 	automated gear change is greater than the specified latency. | 
| 392 | 	 | 
| 393 | 	\note Specified in seconds (s). | 
| 394 |  | 
| 395 | 	@see getLatency | 
| 396 | 	*/ | 
| 397 | 	void setLatency(const PxReal latency)  | 
| 398 | 	{  | 
| 399 | 		mDownRatios[PxVehicleGearsData::eREVERSE]=latency; | 
| 400 | 	} | 
| 401 |  | 
| 402 | 	/** | 
| 403 | 	\brief Get the latency time of the autobox. | 
| 404 | 	 | 
| 405 | 	\note Specified in seconds (s). | 
| 406 |  | 
| 407 | 	@see setLatency | 
| 408 | 	*/ | 
| 409 | 	PxReal getLatency() const  | 
| 410 | 	{  | 
| 411 | 		return mDownRatios[PxVehicleGearsData::eREVERSE]; | 
| 412 | 	} | 
| 413 |  | 
| 414 | private: | 
| 415 | 	bool isValid() const; | 
| 416 |  | 
| 417 | //serialization | 
| 418 | public: | 
| 419 | 	PxVehicleAutoBoxData(const PxEMPTY) {} | 
| 420 | 	 | 
| 421 | 	PxReal getUpRatios(PxVehicleGearsData::Enum a)  const {return mUpRatios[a];} | 
| 422 | 	void setUpRatios(PxVehicleGearsData::Enum a, PxReal ratio)   { mUpRatios[a] = ratio;} | 
| 423 |  | 
| 424 | 	PxReal getDownRatios(PxVehicleGearsData::Enum a)  const {return mDownRatios[a];} | 
| 425 | 	void setDownRatios(PxVehicleGearsData::Enum a, PxReal ratio)   { mDownRatios[a] = ratio;} | 
| 426 | //~serialization | 
| 427 | }; | 
| 428 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleAutoBoxData)& 0x0f)); | 
| 429 |  | 
| 430 | class PxVehicleDifferential4WData | 
| 431 | { | 
| 432 | public: | 
| 433 |  | 
| 434 | 	friend class PxVehicleDriveSimData4W; | 
| 435 |  | 
| 436 | 	enum Enum | 
| 437 | 	{ | 
| 438 | 		eDIFF_TYPE_LS_4WD,			//limited slip differential for car with 4 driven wheels | 
| 439 | 		eDIFF_TYPE_LS_FRONTWD,		//limited slip differential for car with front-wheel drive | 
| 440 | 		eDIFF_TYPE_LS_REARWD,		//limited slip differential for car with rear-wheel drive | 
| 441 | 		eDIFF_TYPE_OPEN_4WD,		//open differential for car with 4 driven wheels  | 
| 442 | 		eDIFF_TYPE_OPEN_FRONTWD,	//open differential for car with front-wheel drive | 
| 443 | 		eDIFF_TYPE_OPEN_REARWD,		//open differential for car with rear-wheel drive | 
| 444 | 		eMAX_NB_DIFF_TYPES | 
| 445 | 	}; | 
| 446 |  | 
| 447 | 	PxVehicleDifferential4WData() | 
| 448 | 		:	mFrontRearSplit(0.45f), | 
| 449 | 			mFrontLeftRightSplit(0.5f), | 
| 450 | 			mRearLeftRightSplit(0.5f), | 
| 451 | 			mCentreBias(1.3f), | 
| 452 | 			mFrontBias(1.3f), | 
| 453 | 			mRearBias(1.3f), | 
| 454 | 			mType(PxVehicleDifferential4WData::eDIFF_TYPE_LS_4WD) | 
| 455 | 	{ | 
| 456 | 	} | 
| 457 |  | 
| 458 | 	/** | 
| 459 | 	\brief Ratio of torque split between front and rear (>0.5 means more to front, <0.5 means more to rear). | 
| 460 | 	 | 
| 461 | 	\note Only applied to DIFF_TYPE_LS_4WD and eDIFF_TYPE_OPEN_4WD | 
| 462 |  | 
| 463 | 	<b>Range:</b> [0, 1]<br> | 
| 464 | 	*/ | 
| 465 | 	PxReal mFrontRearSplit; | 
| 466 |  | 
| 467 | 	/** | 
| 468 | 	\brief Ratio of torque split between front-left and front-right (>0.5 means more to front-left, <0.5 means more to front-right). | 
| 469 | 	 | 
| 470 | 	\note Only applied to DIFF_TYPE_LS_4WD and eDIFF_TYPE_OPEN_4WD and eDIFF_TYPE_LS_FRONTWD | 
| 471 |  | 
| 472 | 	<b>Range:</b> [0, 1]<br> | 
| 473 | 	*/ | 
| 474 | 	PxReal mFrontLeftRightSplit; | 
| 475 |  | 
| 476 | 	/** | 
| 477 | 	\brief Ratio of torque split between rear-left and rear-right (>0.5 means more to rear-left, <0.5 means more to rear-right). | 
| 478 | 	 | 
| 479 | 	\note Only applied to DIFF_TYPE_LS_4WD and eDIFF_TYPE_OPEN_4WD and eDIFF_TYPE_LS_REARWD | 
| 480 |  | 
| 481 | 	<b>Range:</b> [0, 1]<br> | 
| 482 | 	*/ | 
| 483 | 	PxReal mRearLeftRightSplit; | 
| 484 |  | 
| 485 | 	/** | 
| 486 | 	\brief Maximum allowed ratio of average front wheel rotation speed and rear wheel rotation speeds  | 
| 487 | 	The differential will divert more torque to the slower wheels when the bias is exceeded. | 
| 488 | 	 | 
| 489 | 	\note Only applied to DIFF_TYPE_LS_4WD | 
| 490 |  | 
| 491 | 	<b>Range:</b> [1, PX_MAX_F32)<br> | 
| 492 | 	*/ | 
| 493 | 	PxReal mCentreBias; | 
| 494 |  | 
| 495 | 	/** | 
| 496 | 	\brief Maximum allowed ratio of front-left and front-right wheel rotation speeds. | 
| 497 | 	The differential will divert more torque to the slower wheel when the bias is exceeded. | 
| 498 | 	 | 
| 499 | 	\note Only applied to DIFF_TYPE_LS_4WD and DIFF_TYPE_LS_FRONTWD | 
| 500 |  | 
| 501 | 	<b>Range:</b> [1, PX_MAX_F32)<br> | 
| 502 | 	*/ | 
| 503 | 	PxReal mFrontBias; | 
| 504 |  | 
| 505 | 	/** | 
| 506 | 	\brief Maximum allowed ratio of rear-left and rear-right wheel rotation speeds. | 
| 507 | 	The differential will divert more torque to the slower wheel when the bias is exceeded. | 
| 508 | 	 | 
| 509 | 	\note Only applied to DIFF_TYPE_LS_4WD and DIFF_TYPE_LS_REARWD | 
| 510 |  | 
| 511 | 	<b>Range:</b> [1, PX_MAX_F32)<br> | 
| 512 | 	*/ | 
| 513 | 	PxReal mRearBias; | 
| 514 |  | 
| 515 | 	/** | 
| 516 | 	\brief Type of differential. | 
| 517 |  | 
| 518 | 	<b>Range:</b> [DIFF_TYPE_LS_4WD, DIFF_TYPE_OPEN_FRONTWD]<br> | 
| 519 | 	*/ | 
| 520 | 	PxVehicleDifferential4WData::Enum mType; | 
| 521 |  | 
| 522 | private: | 
| 523 |  | 
| 524 | 	PxReal mPad[1]; | 
| 525 |  | 
| 526 | 	bool isValid() const; | 
| 527 |  | 
| 528 | //serialization | 
| 529 | public: | 
| 530 | 	PxVehicleDifferential4WData(const PxEMPTY) {} | 
| 531 | //~serialization | 
| 532 | }; | 
| 533 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleDifferential4WData)& 0x0f)); | 
| 534 |  | 
| 535 | class PxVehicleDifferentialNWData | 
| 536 | { | 
| 537 | public: | 
| 538 |  | 
| 539 | 	friend class PxVehicleDriveSimDataNW; | 
| 540 | 	friend class PxVehicleUpdate; | 
| 541 |  | 
| 542 | 	PxVehicleDifferentialNWData() | 
| 543 | 	{ | 
| 544 | 		PxMemSet(dest: mBitmapBuffer, c: 0, count: sizeof(PxU32) * (((PX_MAX_NB_WHEELS + 31) & ~31) >> 5)); | 
| 545 | 		mNbDrivenWheels=0; | 
| 546 | 		mInvNbDrivenWheels=0.0f; | 
| 547 | 	} | 
| 548 |  | 
| 549 | 	/** | 
| 550 | 	\brief Set a specific wheel to be driven or non-driven by the differential. | 
| 551 | 	 | 
| 552 | 	\note The available drive torque will be split equally between all driven wheels. | 
| 553 | 	Zero torque will be applied to non-driven wheels. | 
| 554 | 	The default state of each wheel is to be uncoupled to the differential. | 
| 555 | 	*/ | 
| 556 | 	void setDrivenWheel(const PxU32 wheelId, const bool drivenState); | 
| 557 |  | 
| 558 | 	/** | 
| 559 | 	\brief Test if a specific wheel has been configured as a driven or non-driven wheel. | 
| 560 | 	*/ | 
| 561 | 	bool getIsDrivenWheel(const PxU32 wheelId) const; | 
| 562 |  | 
| 563 | private: | 
| 564 |  | 
| 565 | 	PxU32 mBitmapBuffer[((PX_MAX_NB_WHEELS + 31) & ~31) >> 5]; | 
| 566 | 	PxU32 mNbDrivenWheels; | 
| 567 | 	PxReal mInvNbDrivenWheels; | 
| 568 | 	PxU32 mPad; | 
| 569 |  | 
| 570 | 	bool isValid() const; | 
| 571 |  | 
| 572 | //serialization | 
| 573 | public: | 
| 574 | 	PxVehicleDifferentialNWData(const PxEMPTY) {} | 
| 575 | 	PxU32 getDrivenWheelStatus() const; | 
| 576 | 	void setDrivenWheelStatus(PxU32 status); | 
| 577 | //~serialization | 
| 578 | }; | 
| 579 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleDifferentialNWData)& 0x0f)); | 
| 580 |  | 
| 581 |  | 
| 582 | class PxVehicleAckermannGeometryData | 
| 583 | { | 
| 584 | public: | 
| 585 |  | 
| 586 | 	friend class PxVehicleDriveSimData4W; | 
| 587 |  | 
| 588 | 	PxVehicleAckermannGeometryData() | 
| 589 | 		: 	mAccuracy(1.0f), | 
| 590 | 			mFrontWidth(0.0f),		//Must be filled out  | 
| 591 | 			mRearWidth(0.0f),		//Must be filled out | 
| 592 | 			mAxleSeparation(0.0f)	//Must be filled out | 
| 593 | 	{ | 
| 594 | 	} | 
| 595 |  | 
| 596 | 	/** | 
| 597 | 	\brief Accuracy of Ackermann steer calculation. | 
| 598 | 	 | 
| 599 | 	\note Accuracy with value 0.0 results in no Ackermann steer-correction, while | 
| 600 | 	accuracy with value 1.0 results in perfect Ackermann steer-correction. | 
| 601 | 	 | 
| 602 | 	\note Perfect Ackermann steer correction modifies the steer angles applied to the front-left and  | 
| 603 | 	front-right wheels so that the perpendiculars to the wheels' longitudinal directions cross the  | 
| 604 | 	extended vector of the rear axle at the same point.  It is also applied to any steer angle applied  | 
| 605 | 	to the rear wheels but instead using the extended vector of the front axle. | 
| 606 | 	 | 
| 607 | 	\note In general, more steer correction produces better cornering behavior. | 
| 608 |  | 
| 609 | 	<b>Range:</b> [0, 1]<br> | 
| 610 | 	*/		 | 
| 611 | 	PxReal mAccuracy; | 
| 612 |  | 
| 613 | 	/** | 
| 614 | 	\brief Distance between center-point of the two front wheels. | 
| 615 | 	 | 
| 616 | 	\note Specified in metres (m). | 
| 617 |  | 
| 618 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 619 | 	*/ | 
| 620 | 	PxReal mFrontWidth;		 | 
| 621 |  | 
| 622 | 	/** | 
| 623 | 	\brief Distance between center-point of the two rear wheels. | 
| 624 | 	 | 
| 625 | 	\note Specified in metres (m). | 
| 626 |  | 
| 627 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 628 | 	*/ | 
| 629 | 	PxReal mRearWidth;		 | 
| 630 |  | 
| 631 | 	/** | 
| 632 | 	\brief Distance between center of front axle and center of rear axle. | 
| 633 |  | 
| 634 | 	\note Specified in metres (m). | 
| 635 |  | 
| 636 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 637 | 	*/ | 
| 638 | 	PxReal mAxleSeparation;	 | 
| 639 |  | 
| 640 | private: | 
| 641 |  | 
| 642 | 	bool isValid() const; | 
| 643 |  | 
| 644 | //serialization | 
| 645 | public: | 
| 646 | 	PxVehicleAckermannGeometryData(const PxEMPTY) {} | 
| 647 | //~serialization | 
| 648 | }; | 
| 649 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleAckermannGeometryData)& 0x0f)); | 
| 650 |  | 
| 651 | /** | 
| 652 | \brief Choose between a potentially more expensive but more accurate solution to the clutch model or a potentially cheaper but less accurate solution. | 
| 653 | @see PxVehicleClutchData | 
| 654 | */ | 
| 655 | struct PxVehicleClutchAccuracyMode | 
| 656 | { | 
| 657 | 	enum Enum | 
| 658 | 	{ | 
| 659 | 		eESTIMATE = 0, | 
| 660 | 		eBEST_POSSIBLE | 
| 661 | 	}; | 
| 662 | }; | 
| 663 |  | 
| 664 | class PxVehicleClutchData | 
| 665 | { | 
| 666 | public: | 
| 667 |  | 
| 668 | 	friend class PxVehicleDriveSimData; | 
| 669 |  | 
| 670 | 	PxVehicleClutchData() | 
| 671 | 		: 	mStrength(10.0f), | 
| 672 | 		    mAccuracyMode(PxVehicleClutchAccuracyMode::eBEST_POSSIBLE), | 
| 673 | 			mEstimateIterations(5) | 
| 674 | 	{ | 
| 675 | 	} | 
| 676 |  | 
| 677 | 	/** | 
| 678 | 	\brief Strength of clutch. | 
| 679 | 	 | 
| 680 | 	\note The clutch is the mechanism that couples the engine to the wheels. | 
| 681 | 	A stronger clutch more strongly couples the engine to the wheels, while a | 
| 682 | 	clutch of strength zero completely decouples the engine from the wheels. | 
| 683 | 	Stronger clutches more quickly bring the wheels and engine into equilibrium, while weaker | 
| 684 | 	clutches take longer, resulting in periods of clutch slip and delays in power transmission | 
| 685 | 	from the engine to the wheels. | 
| 686 | 	The torque generated by the clutch is proportional to the clutch strength and  | 
| 687 | 	the velocity difference between the engine's rotational speed and the rotational speed of the  | 
| 688 | 	driven wheels after accounting for the gear ratio.   | 
| 689 | 	The torque at the clutch is applied negatively to the engine and positively to the driven wheels. | 
| 690 | 	 | 
| 691 | 	\note Specified in kilograms metres-squared per second (kg m^2 s^-1) | 
| 692 |  | 
| 693 | 	<b>Range:</b> [0,PX_MAX_F32)<br> | 
| 694 | 	*/ | 
| 695 | 	PxReal mStrength; | 
| 696 |  | 
| 697 | 	/** | 
| 698 | 	\brief The engine and wheel rotation speeds that are coupled through the clutch can be updated by choosing | 
| 699 | 	one of two modes: eESTIMATE and eBEST_POSSIBLE. | 
| 700 |  | 
| 701 | 	\note If eESTIMATE is chosen the vehicle sdk will update the wheel and engine rotation speeds  | 
| 702 | 	with estimated values to the implemented clutch model.   | 
| 703 |  | 
| 704 | 	\note If eBEST_POSSIBLE is chosen the vehicle sdk will compute the best possible  | 
| 705 | 	solution (within floating point tolerance) to the implemented clutch model.  | 
| 706 | 	This is the recommended mode. | 
| 707 |  | 
| 708 | 	\note The clutch model remains the same if either eESTIMATE or eBEST_POSSIBLE is chosen but the accuracy and  | 
| 709 | 	computational cost of the solution to the model can be tuned as required. | 
| 710 | 	*/ | 
| 711 | 	PxVehicleClutchAccuracyMode::Enum mAccuracyMode; | 
| 712 |  | 
| 713 | 	/** | 
| 714 | 	\brief Tune the mathematical accuracy and computational cost of the computed estimate to the wheel and  | 
| 715 | 	engine rotation speeds if eESTIMATE is chosen. | 
| 716 |  | 
| 717 | 	\note As mEstimateIterations increases the computational cost of the clutch also increases and the solution  | 
| 718 | 	approaches the solution that would be computed if eBEST_POSSIBLE was chosen instead. | 
| 719 |  | 
| 720 | 	\note This has no effect if eBEST_POSSIBLE is chosen as the accuracy mode. | 
| 721 |  | 
| 722 | 	\note A value of zero is not allowed if eESTIMATE is chosen as the accuracy mode. | 
| 723 | 	*/ | 
| 724 | 	PxU32 mEstimateIterations; | 
| 725 |  | 
| 726 | private: | 
| 727 |  | 
| 728 | 	PxU8 mPad[4]; | 
| 729 |  | 
| 730 | 	bool isValid() const; | 
| 731 |  | 
| 732 | //serialization | 
| 733 | public: | 
| 734 | 	PxVehicleClutchData(const PxEMPTY) {} | 
| 735 | //~serialization | 
| 736 | }; | 
| 737 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleClutchData)& 0x0f)); | 
| 738 |  | 
| 739 |  | 
| 740 | /** | 
| 741 | \brief Tire load variation can be strongly dependent on the time-step so it is a good idea to filter it  | 
| 742 | to give less jerky handling behavior.  | 
| 743 |  | 
| 744 | \note The x-axis of the graph is normalized tire load, while the y-axis is the filtered normalized tire load. | 
| 745 |  | 
| 746 | \note The normalized load is the force acting downwards on the tire divided by the force experienced by the tire when the car is at rest on the ground. | 
| 747 |  | 
| 748 | \note The rest load is approximately the product of the value of gravitational acceleration and PxVehicleSuspensionData::mSprungMass. | 
| 749 |  | 
| 750 | \note The minimum possible normalized load is zero. | 
| 751 |  | 
| 752 | \note There are two points on the graph: (mMinNormalisedLoad, mMinNormalisedFilteredLoad) and (mMaxNormalisedLoad, mMaxFilteredNormalisedLoad). | 
| 753 |  | 
| 754 | \note Normalized loads less than mMinNormalisedLoad have filtered normalized load = mMinNormalisedFilteredLoad. | 
| 755 |  | 
| 756 | \note Normalized loads greater than mMaxNormalisedLoad have filtered normalized load = mMaxFilteredNormalisedLoad. | 
| 757 |  | 
| 758 | \note Normalized loads in-between are linearly interpolated between mMinNormalisedFilteredLoad and mMaxFilteredNormalisedLoad. | 
| 759 |  | 
| 760 | \note The tire load applied as input to the tire force computation is the filtered normalized load multiplied by the rest load. | 
| 761 | */ | 
| 762 | class PxVehicleTireLoadFilterData | 
| 763 | { | 
| 764 | public: | 
| 765 |  | 
| 766 | 	friend class PxVehicleWheelsSimData; | 
| 767 |  | 
| 768 | 	PxVehicleTireLoadFilterData() | 
| 769 | 		: 	mMinNormalisedLoad(0), | 
| 770 | 			mMinFilteredNormalisedLoad(0.2308f), | 
| 771 | 			mMaxNormalisedLoad(3.0f), | 
| 772 | 			mMaxFilteredNormalisedLoad(3.0f) | 
| 773 | 	{ | 
| 774 | 		mDenominator=1.0f/(mMaxNormalisedLoad - mMinNormalisedLoad); | 
| 775 | 	} | 
| 776 |  | 
| 777 | 	/** | 
| 778 | 	\brief Graph point (mMinNormalisedLoad,mMinFilteredNormalisedLoad) | 
| 779 | 	*/ | 
| 780 | 	PxReal mMinNormalisedLoad;  | 
| 781 |  | 
| 782 | 	/** | 
| 783 | 	\brief Graph point (mMinNormalisedLoad,mMinFilteredNormalisedLoad) | 
| 784 | 	*/ | 
| 785 | 	PxReal mMinFilteredNormalisedLoad;  | 
| 786 |  | 
| 787 | 	/** | 
| 788 | 	\brief Graph point (mMaxNormalisedLoad,mMaxFilteredNormalisedLoad) | 
| 789 | 	*/ | 
| 790 | 	PxReal mMaxNormalisedLoad; | 
| 791 | 		 | 
| 792 | 	/** | 
| 793 | 	\brief Graph point (mMaxNormalisedLoad,mMaxFilteredNormalisedLoad) | 
| 794 | 	*/ | 
| 795 | 	PxReal mMaxFilteredNormalisedLoad; | 
| 796 |  | 
| 797 | 	PX_FORCE_INLINE PxReal getDenominator() const {return mDenominator;} | 
| 798 |  | 
| 799 | private: | 
| 800 |  | 
| 801 | 	/** | 
| 802 | 	\brief Not necessary to set this value. | 
| 803 | 	*/ | 
| 804 | 	//1.0f/(mMaxNormalisedLoad-mMinNormalisedLoad) for quick calculations | 
| 805 | 	PxReal mDenominator; | 
| 806 |  | 
| 807 | 	PxU32 mPad[3]; | 
| 808 |  | 
| 809 | 	bool isValid() const; | 
| 810 |  | 
| 811 | //serialization | 
| 812 | public: | 
| 813 | 	PxVehicleTireLoadFilterData(const PxEMPTY) {} | 
| 814 | //~serialization | 
| 815 | }; | 
| 816 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleTireLoadFilterData)& 0x0f)); | 
| 817 |  | 
| 818 | class PxVehicleWheelData | 
| 819 | { | 
| 820 | public: | 
| 821 |  | 
| 822 | 	friend class PxVehicleWheels4SimData; | 
| 823 |  | 
| 824 | 	PxVehicleWheelData() | 
| 825 | 		: 	mRadius(0.0f),				//Must be filled out | 
| 826 | 			mWidth(0.0f), | 
| 827 | 			mMass(20.0f), | 
| 828 | 			mMOI(0.0f),					//Must be filled out | 
| 829 | 			mDampingRate(0.25f), | 
| 830 | 			mMaxBrakeTorque(1500.0f), | 
| 831 | 			mMaxHandBrakeTorque(0.0f),	 | 
| 832 | 			mMaxSteer(0.0f),			 | 
| 833 | 			mToeAngle(0.0f), | 
| 834 | 			mRecipRadius(0.0f),			//Must be filled out | 
| 835 | 			mRecipMOI(0.0f)				//Must be filled out | 
| 836 | 	{ | 
| 837 | 	} | 
| 838 |  | 
| 839 | 	/** | 
| 840 | 	\brief Radius of unit that includes metal wheel plus rubber tire. | 
| 841 | 	 | 
| 842 | 	\note Specified in metres (m). | 
| 843 |  | 
| 844 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 845 | 	*/ | 
| 846 | 	PxReal mRadius; | 
| 847 |  | 
| 848 | 	/** | 
| 849 | 	\brief Maximum width of unit that includes wheel plus tire. | 
| 850 |  | 
| 851 | 	\note Specified in metres (m). | 
| 852 |  | 
| 853 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 854 | 	*/ | 
| 855 | 	PxReal mWidth; | 
| 856 |  | 
| 857 | 	/** | 
| 858 | 	\brief Mass of unit that includes wheel plus tire. | 
| 859 | 	 | 
| 860 | 	\note Specified in kilograms (kg). | 
| 861 |  | 
| 862 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 863 | 	*/ | 
| 864 | 	PxReal mMass; | 
| 865 |  | 
| 866 | 	/** | 
| 867 | 	\brief Moment of inertia of unit that includes wheel plus tire about the rolling axis. | 
| 868 | 	 | 
| 869 | 	\note Specified in kilograms metres-squared (kg m^2). | 
| 870 |  | 
| 871 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 872 | 	*/ | 
| 873 | 	PxReal mMOI; | 
| 874 |  | 
| 875 | 	/** | 
| 876 | 	\brief Damping rate applied to wheel. | 
| 877 | 	 | 
| 878 | 	\note Specified in kilograms metres-squared per second (kg m^2 s^-1). | 
| 879 |  | 
| 880 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 881 | 	*/ | 
| 882 | 	PxReal mDampingRate; | 
| 883 |  | 
| 884 | 	/** | 
| 885 | 	\brief Max brake torque that can be applied to wheel. | 
| 886 | 	 | 
| 887 | 	\note Specified in kilograms metres-squared per second-squared (kg m^2 s^-2) | 
| 888 |  | 
| 889 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 890 | 	*/ | 
| 891 | 	PxReal mMaxBrakeTorque; | 
| 892 |  | 
| 893 | 	/** | 
| 894 | 	\brief Max handbrake torque that can be applied to wheel. | 
| 895 | 	 | 
| 896 | 	\note Specified in kilograms metres-squared per second-squared (kg m^2 s^-2) | 
| 897 |  | 
| 898 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 899 | 	*/ | 
| 900 | 	PxReal mMaxHandBrakeTorque; | 
| 901 |  | 
| 902 | 	/** | 
| 903 | 	\brief Max steer angle that can be achieved by the wheel. | 
| 904 | 	 | 
| 905 | 	\note Specified in radians. | 
| 906 |  | 
| 907 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 908 | 	*/ | 
| 909 | 	PxReal mMaxSteer; | 
| 910 |  | 
| 911 | 	/** | 
| 912 | 	\brief Wheel toe angle.  This value is ignored by PxVehicleDriveTank and PxVehicleNoDrive. | 
| 913 | 	 | 
| 914 | 	\note Specified in radians. | 
| 915 |  | 
| 916 | 	<b>Range:</b> [0, Pi/2]<br> | 
| 917 | 	*/ | 
| 918 | 	PxReal mToeAngle;//in radians | 
| 919 |  | 
| 920 | 	/** | 
| 921 | 	\brief Return value equal to 1.0f/mRadius | 
| 922 | 	 | 
| 923 | 	@see PxVehicleWheelsSimData::setWheelData | 
| 924 | 	*/ | 
| 925 | 	PX_FORCE_INLINE PxReal getRecipRadius() const {return mRecipRadius;} | 
| 926 |  | 
| 927 | 	/** | 
| 928 | 	\brief Return value equal to 1.0f/mRecipMOI | 
| 929 | 	 | 
| 930 | 	@see PxVehicleWheelsSimData::setWheelData | 
| 931 | 	*/ | 
| 932 | 	PX_FORCE_INLINE PxReal getRecipMOI() const {return mRecipMOI;} | 
| 933 |  | 
| 934 | private: | 
| 935 |  | 
| 936 | 	/** | 
| 937 | 	\brief Reciprocal of radius of unit that includes metal wheel plus rubber tire. | 
| 938 | 	 | 
| 939 | 	\note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setWheelData | 
| 940 |  | 
| 941 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 942 | 	*/ | 
| 943 | 	PxReal mRecipRadius; | 
| 944 |  | 
| 945 | 	/** | 
| 946 | 	\brief Reciprocal of moment of inertia of unit that includes wheel plus tire about single allowed axis of rotation. | 
| 947 | 	 | 
| 948 | 	\note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setWheelData | 
| 949 |  | 
| 950 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 951 | 	*/ | 
| 952 | 	PxReal mRecipMOI; | 
| 953 |  | 
| 954 | 	PxReal mPad[1]; | 
| 955 |  | 
| 956 | 	bool isValid() const; | 
| 957 | }; | 
| 958 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleWheelData)& 0x0f)); | 
| 959 |  | 
| 960 | class PxVehicleSuspensionData | 
| 961 | { | 
| 962 | public: | 
| 963 |  | 
| 964 | 	friend class PxVehicleWheels4SimData; | 
| 965 |  | 
| 966 | 	PxVehicleSuspensionData() | 
| 967 | 		: 	mSpringStrength(0.0f), | 
| 968 | 			mSpringDamperRate(0.0f), | 
| 969 | 			mMaxCompression(0.3f), | 
| 970 | 			mMaxDroop(0.1f), | 
| 971 | 			mSprungMass(0.0f), | 
| 972 | 			mCamberAtRest(0.0f), | 
| 973 | 			mCamberAtMaxCompression(0.0f), | 
| 974 | 			mCamberAtMaxDroop(0.0f), | 
| 975 | 			mRecipMaxCompression(1.0f), | 
| 976 | 			mRecipMaxDroop(1.0f) | 
| 977 | 	{ | 
| 978 | 	} | 
| 979 | 	 | 
| 980 | 	/** | 
| 981 | 	\brief Spring strength of suspension unit. | 
| 982 | 	 | 
| 983 | 	\note Specified in kilograms per second-squared (kg s^-2). | 
| 984 |  | 
| 985 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 986 | 	*/ | 
| 987 | 	PxReal mSpringStrength; | 
| 988 |  | 
| 989 | 	/** | 
| 990 | 	\brief Spring damper rate of suspension unit. | 
| 991 | 	 | 
| 992 | 	\note Specified in kilograms per second (kg s^-1). | 
| 993 |  | 
| 994 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 995 | 	*/ | 
| 996 | 	PxReal mSpringDamperRate; | 
| 997 |  | 
| 998 | 	/** | 
| 999 | 	\brief Maximum compression allowed by suspension spring. | 
| 1000 | 	 | 
| 1001 | 	\note Specified in metres (m). | 
| 1002 |  | 
| 1003 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 1004 | 	*/ | 
| 1005 | 	PxReal mMaxCompression; | 
| 1006 |  | 
| 1007 | 	/** | 
| 1008 | 	\brief Maximum elongation allowed by suspension spring. | 
| 1009 | 	 | 
| 1010 | 	\note Specified in metres (m). | 
| 1011 |  | 
| 1012 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 1013 | 	*/ | 
| 1014 | 	PxReal mMaxDroop; | 
| 1015 |  | 
| 1016 | 	/** | 
| 1017 | 	\brief Mass of vehicle that is supported by suspension spring. | 
| 1018 | 	 | 
| 1019 | 	\note Specified in kilograms (kg). | 
| 1020 |  | 
| 1021 | 	\note Each suspension is guaranteed to generate an upwards force of |gravity|*mSprungMass along the suspension direction when the wheel is perfectly  | 
| 1022 | 	at rest and sitting at the rest pose defined by the wheel centre offset.   | 
| 1023 |  | 
| 1024 | 	\note The sum of the sprung masses of all suspensions of a vehicle should match the mass of the PxRigidDynamic associated with the vehicle.   | 
| 1025 | 	When this condition is satisfied for a vehicle on a horizontal plane the wheels of the vehicle are guaranteed to sit at the rest pose  | 
| 1026 | 	defined by the wheel centre offset.  The mass matching condition is not enforced. | 
| 1027 |  | 
| 1028 | 	\note As the wheel compresses or elongates along the suspension direction the force generated by the spring is  | 
| 1029 | 	F = |gravity|*mSprungMass + deltaX*mSpringStrength + deltaXDot*mSpringDamperRate | 
| 1030 | 	where deltaX is the deviation from the defined rest pose and deltaXDot is the velocity of the sprung mass along the suspension direction. | 
| 1031 | 	In practice, deltaXDot is computed by comparing the current and previous deviation from the rest pose and dividing the difference  | 
| 1032 | 	by the simulation timestep. | 
| 1033 |  | 
| 1034 | 	\note If a single suspension spring is hanging in the air and generates zero force the remaining springs of the vehicle will necessarily  | 
| 1035 | 	sit in a compressed configuration.  In summary, the sum of the remaining suspension forces cannot balance the downwards gravitational force  | 
| 1036 | 	acting on the vehicle without extra force arising from the deltaX*mSpringStrength force term. | 
| 1037 |  | 
| 1038 | 	\note Theoretically, a suspension spring should generate zero force at maximum elongation and increase linearly as the suspension approaches the rest pose. | 
| 1039 | 	PxVehicleSuspensionData will only enforce this physical law if the spring is configured so that |gravity|*mSprungMass == mMaxDroop*mSpringStrength.   | 
| 1040 | 	To help decouple vehicle handling from visual wheel positioning this condition is not enforced.   | 
| 1041 | 	In practice, the value of |gravity|*mSprungMass + deltaX*mSpringStrength is clamped at zero to ensure it never falls negative. | 
| 1042 |  | 
| 1043 | 	@see PxVehicleComputeSprungMasses, PxVehicleWheelsSimData::setWheelCentreOffset, PxVehicleSuspensionData::mSpringStrength, PxVehicleSuspensionData::mSpringDamperRate, PxVehicleSuspensionData::mMaxDroop | 
| 1044 |  | 
| 1045 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 1046 | 	*/ | 
| 1047 | 	PxReal mSprungMass; | 
| 1048 |  | 
| 1049 | 	/** | 
| 1050 | 	\brief Camber angle (in radians) of wheel when the suspension is at its rest position. | 
| 1051 | 	 | 
| 1052 | 	\note Specified in radians. | 
| 1053 |  | 
| 1054 | 	<b>Range:</b> [-pi/2, pi/2]<br> | 
| 1055 |  | 
| 1056 | 	*/ | 
| 1057 | 	PxReal mCamberAtRest; | 
| 1058 |  | 
| 1059 | 	/** | 
| 1060 | 	\brief Camber angle (in radians) of wheel when the suspension is at maximum compression. | 
| 1061 |  | 
| 1062 | 	\note For compressed suspensions the camber angle is a linear interpolation of  | 
| 1063 | 	mCamberAngleAtRest and mCamberAtMaxCompression | 
| 1064 |  | 
| 1065 | 	\note Specified in radians. | 
| 1066 |  | 
| 1067 | 	<b>Range:</b> [-pi/2, pi/2]<br> | 
| 1068 | 	*/ | 
| 1069 | 	PxReal mCamberAtMaxCompression;  | 
| 1070 |  | 
| 1071 | 	/** | 
| 1072 | 	\brief Camber angle (in radians) of wheel when the suspension is at maximum droop. | 
| 1073 |  | 
| 1074 | 	\note For extended suspensions the camber angle is linearly interpolation of  | 
| 1075 | 	mCamberAngleAtRest and mCamberAtMaxDroop | 
| 1076 |  | 
| 1077 | 	\note Specified in radians. | 
| 1078 |  | 
| 1079 | 	<b>Range:</b> [-pi/2, pi/2]<br> | 
| 1080 | 	*/ | 
| 1081 | 	PxReal mCamberAtMaxDroop;  | 
| 1082 |  | 
| 1083 | 	/** | 
| 1084 | 	\brief Reciprocal of maximum compression. | 
| 1085 | 	 | 
| 1086 | 	\note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setSuspensionData | 
| 1087 |  | 
| 1088 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 1089 | 	*/ | 
| 1090 | 	PX_FORCE_INLINE PxReal getRecipMaxCompression() const {return mRecipMaxCompression;} | 
| 1091 |  | 
| 1092 | 	/** | 
| 1093 | 	\brief Reciprocal of maximum droop. | 
| 1094 | 	 | 
| 1095 | 	\note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setSuspensionData | 
| 1096 |  | 
| 1097 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 1098 | 	*/ | 
| 1099 | 	PX_FORCE_INLINE PxReal getRecipMaxDroop() const {return mRecipMaxDroop;} | 
| 1100 |  | 
| 1101 | 	/** | 
| 1102 | 	\brief Set a new sprung mass for the suspension and modify the spring strength so that the natural frequency | 
| 1103 | 	of the spring is preserved. | 
| 1104 | 	\param[in] newSprungMass is the new mass that the suspension spring will support. | 
| 1105 | 	*/ | 
| 1106 | 	void setMassAndPreserveNaturalFrequency(const PxReal newSprungMass) | 
| 1107 | 	{ | 
| 1108 | 		const PxF32 oldStrength = mSpringStrength; | 
| 1109 | 		const PxF32 oldSprungMass = mSprungMass; | 
| 1110 | 		const PxF32 newStrength = oldStrength * (newSprungMass / oldSprungMass); | 
| 1111 | 		mSpringStrength = newStrength; | 
| 1112 | 		mSprungMass = newSprungMass; | 
| 1113 | 	} | 
| 1114 |  | 
| 1115 | private: | 
| 1116 |  | 
| 1117 | 	/** | 
| 1118 | 	\brief Cached value of 1.0f/mMaxCompression | 
| 1119 | 	 | 
| 1120 | 	\note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setSuspensionData | 
| 1121 | 	*/ | 
| 1122 | 	PxReal mRecipMaxCompression; | 
| 1123 |  | 
| 1124 | 	/** | 
| 1125 | 	\brief Cached value of 1.0f/mMaxDroop | 
| 1126 | 	 | 
| 1127 | 	\note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setSuspensionData | 
| 1128 | 	*/ | 
| 1129 | 	PxReal mRecipMaxDroop; | 
| 1130 |  | 
| 1131 | 	//padding | 
| 1132 | 	PxReal mPad[2]; | 
| 1133 |  | 
| 1134 | 	bool isValid() const; | 
| 1135 | }; | 
| 1136 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleSuspensionData)& 0x0f)); | 
| 1137 |  | 
| 1138 | class PxVehicleAntiRollBarData | 
| 1139 | { | 
| 1140 | public: | 
| 1141 |  | 
| 1142 | 	friend class PxVehicleWheelsSimData; | 
| 1143 |  | 
| 1144 | 	PxVehicleAntiRollBarData() | 
| 1145 | 		: mWheel0(0xffffffff), | 
| 1146 | 		  mWheel1(0xffffffff), | 
| 1147 | 		  mStiffness(0.0f) | 
| 1148 | 	{ | 
| 1149 | 	} | 
| 1150 |  | 
| 1151 | 	/* | 
| 1152 | 	\brief The anti-roll bar connects two wheels with indices mWheel0 and mWheel1 | 
| 1153 | 	*/ | 
| 1154 | 	PxU32 mWheel0; | 
| 1155 |  | 
| 1156 | 	/* | 
| 1157 | 	\brief The anti-roll bar connects two wheels with indices mWheel0 and mWheel1 | 
| 1158 | 	*/ | 
| 1159 | 	PxU32 mWheel1; | 
| 1160 |  | 
| 1161 | 	/* | 
| 1162 | 	\brief The stiffness of the anti-roll bar. | 
| 1163 |  | 
| 1164 | 	\note Specified in kilograms per second-squared (kg s^-2). | 
| 1165 |  | 
| 1166 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 1167 | 	*/ | 
| 1168 | 	PxF32 mStiffness; | 
| 1169 |  | 
| 1170 | private: | 
| 1171 |  | 
| 1172 | 	PxF32 mPad[1]; | 
| 1173 |  | 
| 1174 | 	bool isValid() const; | 
| 1175 | }; | 
| 1176 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleAntiRollBarData)& 0x0f)); | 
| 1177 |  | 
| 1178 | class PxVehicleTireData | 
| 1179 | { | 
| 1180 | public: | 
| 1181 | 	friend class PxVehicleWheels4SimData; | 
| 1182 |  | 
| 1183 | 	PxVehicleTireData() | 
| 1184 | 		: 	mLatStiffX(2.0f), | 
| 1185 | 			mLatStiffY(0.3125f*(180.0f / PxPi)), | 
| 1186 | 			mLongitudinalStiffnessPerUnitGravity(1000.0f), | 
| 1187 | 			mCamberStiffnessPerUnitGravity(0.1f*(180.0f / PxPi)), | 
| 1188 | 			mType(0) | 
| 1189 | 	{ | 
| 1190 | 		mFrictionVsSlipGraph[0][0]=0.0f; | 
| 1191 | 		mFrictionVsSlipGraph[0][1]=1.0f; | 
| 1192 | 		mFrictionVsSlipGraph[1][0]=0.1f; | 
| 1193 | 		mFrictionVsSlipGraph[1][1]=1.0f; | 
| 1194 | 		mFrictionVsSlipGraph[2][0]=1.0f; | 
| 1195 | 		mFrictionVsSlipGraph[2][1]=1.0f; | 
| 1196 |  | 
| 1197 | 		mRecipLongitudinalStiffnessPerUnitGravity=1.0f/mLongitudinalStiffnessPerUnitGravity; | 
| 1198 |  | 
| 1199 | 		mFrictionVsSlipGraphRecipx1Minusx0=1.0f/(mFrictionVsSlipGraph[1][0]-mFrictionVsSlipGraph[0][0]); | 
| 1200 | 		mFrictionVsSlipGraphRecipx2Minusx1=1.0f/(mFrictionVsSlipGraph[2][0]-mFrictionVsSlipGraph[1][0]); | 
| 1201 | 	} | 
| 1202 |  | 
| 1203 | 	/** | 
| 1204 | 	\brief Tire lateral stiffness is a graph of tire load that has linear behavior near zero load and  | 
| 1205 | 	flattens at large loads.  mLatStiffX describes the minimum normalized load (load/restLoad) that gives a  | 
| 1206 | 	flat lateral stiffness response to load. | 
| 1207 |  | 
| 1208 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 1209 | 	*/ | 
| 1210 | 	PxReal mLatStiffX; | 
| 1211 |  | 
| 1212 | 	/** | 
| 1213 | 	\brief Tire lateral stiffness is a graph of tire load that has linear behavior near zero load and  | 
| 1214 | 	flattens at large loads. mLatStiffY describes the maximum possible value of lateralStiffness/restLoad that occurs  | 
| 1215 | 	when (load/restLoad)>= mLatStiffX. | 
| 1216 | 	 | 
| 1217 | 	\note If load/restLoad is greater than mLatStiffX then the lateral stiffness is mLatStiffY*restLoad. | 
| 1218 | 	 | 
| 1219 | 	\note If load/restLoad is less than mLatStiffX then the lateral stiffness is mLastStiffY*(load/mLatStiffX) | 
| 1220 | 	 | 
| 1221 | 	\note Lateral force can be approximated as lateralStiffness * lateralSlip. | 
| 1222 | 	 | 
| 1223 | 	\note Specified in per radian. | 
| 1224 | 	 | 
| 1225 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 1226 | 	*/ | 
| 1227 | 	PxReal mLatStiffY; | 
| 1228 |  | 
| 1229 | 	/** | 
| 1230 | 	\brief Tire Longitudinal stiffness per unit gravitational acceleration. | 
| 1231 |  | 
| 1232 | 	\note Longitudinal stiffness of the tire is calculated as gravitationalAcceleration*mLongitudinalStiffnessPerUnitGravity. | 
| 1233 |  | 
| 1234 | 	\note Longitudinal force can be approximated as gravitationalAcceleration*mLongitudinalStiffnessPerUnitGravity*longitudinalSlip. | 
| 1235 |  | 
| 1236 | 	\note Specified in kilograms per radian. | 
| 1237 | 	 | 
| 1238 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 1239 | 	*/ | 
| 1240 | 	PxReal mLongitudinalStiffnessPerUnitGravity; | 
| 1241 |  | 
| 1242 | 	/** | 
| 1243 | 	\brief tire Tire camber stiffness per unity gravitational acceleration. | 
| 1244 |  | 
| 1245 | 	\note Camber stiffness of the tire is calculated as gravitationalAcceleration*mCamberStiffnessPerUnitGravity | 
| 1246 | 	 | 
| 1247 | 	\note Camber force can be approximated as gravitationalAcceleration*mCamberStiffnessPerUnitGravity*camberAngle. | 
| 1248 |  | 
| 1249 | 	\note Specified in kilograms per radian. | 
| 1250 | 	 | 
| 1251 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 1252 | 	*/ | 
| 1253 | 	PxReal mCamberStiffnessPerUnitGravity; | 
| 1254 |  | 
| 1255 | 	/** | 
| 1256 | 	\brief Graph of friction vs longitudinal slip with 3 points.  | 
| 1257 | 	 | 
| 1258 | 	\note mFrictionVsSlipGraph[0][0] is always zero. | 
| 1259 |  | 
| 1260 | 	\note mFrictionVsSlipGraph[0][1] is the friction available at zero longitudinal slip. | 
| 1261 | 	 | 
| 1262 | 	\note mFrictionVsSlipGraph[1][0] is the value of longitudinal slip with maximum friction. | 
| 1263 | 	 | 
| 1264 | 	\note mFrictionVsSlipGraph[1][1] is the maximum friction. | 
| 1265 | 	 | 
| 1266 | 	\note mFrictionVsSlipGraph[2][0] is the end point of the graph. | 
| 1267 | 	 | 
| 1268 | 	\note mFrictionVsSlipGraph[2][1] is the value of friction for slips greater than mFrictionVsSlipGraph[2][0]. | 
| 1269 | 	 | 
| 1270 | 	\note The friction value computed from the friction vs longitudinal slip graph is used to scale the friction | 
| 1271 | 	value for the combination of material and tire type (PxVehicleDrivableSurfaceToTireFrictionPairs). | 
| 1272 |  | 
| 1273 | 	\note mFrictionVsSlipGraph[2][0] > mFrictionVsSlipGraph[1][0] > mFrictionVsSlipGraph[0][0] | 
| 1274 |  | 
| 1275 | 	\note mFrictionVsSlipGraph[1][1] is typically greater than  mFrictionVsSlipGraph[0][1] | 
| 1276 |  | 
| 1277 | 	\note mFrictionVsSlipGraph[2][1] is typically smaller than mFrictionVsSlipGraph[1][1] | 
| 1278 |  | 
| 1279 | 	\note longitudinal slips > mFrictionVsSlipGraph[2][0] use friction multiplier mFrictionVsSlipGraph[2][1] | 
| 1280 |  | 
| 1281 | 	\note The final friction value used by the tire model is the value returned by PxVehicleDrivableSurfaceToTireFrictionPairs  | 
| 1282 | 	multiplied by the value computed from mFrictionVsSlipGraph. | 
| 1283 |  | 
| 1284 | 	@see PxVehicleDrivableSurfaceToTireFrictionPairs, PxVehicleComputeTireForce | 
| 1285 | 	 | 
| 1286 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 1287 | 	*/ | 
| 1288 | 	PxReal mFrictionVsSlipGraph[3][2]; | 
| 1289 |  | 
| 1290 | 	/** | 
| 1291 | 	\brief Tire type denoting slicks, wets, snow, winter, summer, all-terrain, mud etc. | 
| 1292 | 	 | 
| 1293 | 	@see PxVehicleDrivableSurfaceToTireFrictionPairs | 
| 1294 | 	 | 
| 1295 | 	<b>Range:</b> [0, PX_MAX_F32)<br> | 
| 1296 | 	*/ | 
| 1297 | 	PxU32 mType; | 
| 1298 |  | 
| 1299 | 	/** | 
| 1300 | 	\brief Return Cached value of 1.0/mLongitudinalStiffnessPerUnitGravity | 
| 1301 | 	 | 
| 1302 | 	@see PxVehicleWheelsSimData::setTireData | 
| 1303 | 	*/ | 
| 1304 | 	PX_FORCE_INLINE PxReal getRecipLongitudinalStiffnessPerUnitGravity() const {return mRecipLongitudinalStiffnessPerUnitGravity;} | 
| 1305 |  | 
| 1306 | 	/** | 
| 1307 | 	\brief Return Cached value of 1.0f/(mFrictionVsSlipGraph[1][0]-mFrictionVsSlipGraph[0][0]) | 
| 1308 | 	 | 
| 1309 | 	@see PxVehicleWheelsSimData::setTireData | 
| 1310 | 	*/ | 
| 1311 | 	PX_FORCE_INLINE PxReal getFrictionVsSlipGraphRecipx1Minusx0() const {return mFrictionVsSlipGraphRecipx1Minusx0;} | 
| 1312 |  | 
| 1313 | 	/** | 
| 1314 | 	\brief Return Cached value of 1.0f/(mFrictionVsSlipGraph[2][0]-mFrictionVsSlipGraph[1][0]) | 
| 1315 | 	 | 
| 1316 | 	@see PxVehicleWheelsSimData::setTireData | 
| 1317 | 	*/ | 
| 1318 | 	PX_FORCE_INLINE PxReal getFrictionVsSlipGraphRecipx2Minusx1() const {return mFrictionVsSlipGraphRecipx2Minusx1;} | 
| 1319 |  | 
| 1320 | private: | 
| 1321 |  | 
| 1322 | 	/** | 
| 1323 | 	\brief Cached value of 1.0/mLongitudinalStiffnessPerUnitGravity. | 
| 1324 | 	 | 
| 1325 | 	\note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setTireData | 
| 1326 |  | 
| 1327 | 	@see PxVehicleWheelsSimData::setTireData | 
| 1328 | 	*/ | 
| 1329 | 	PxReal mRecipLongitudinalStiffnessPerUnitGravity; | 
| 1330 |  | 
| 1331 | 	/** | 
| 1332 | 	\brief Cached value of 1.0f/(mFrictionVsSlipGraph[1][0]-mFrictionVsSlipGraph[0][0]) | 
| 1333 | 	 | 
| 1334 | 	\note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setTireData | 
| 1335 | 	 | 
| 1336 | 	@see PxVehicleWheelsSimData::setTireData | 
| 1337 | 	*/ | 
| 1338 | 	PxReal mFrictionVsSlipGraphRecipx1Minusx0; | 
| 1339 |  | 
| 1340 | 	/** | 
| 1341 | 	\brief Cached value of 1.0f/(mFrictionVsSlipGraph[2][0]-mFrictionVsSlipGraph[1][0]) | 
| 1342 | 	 | 
| 1343 | 	\note Not necessary to set this value because it is set by PxVehicleWheelsSimData::setTireData | 
| 1344 |  | 
| 1345 | 	@see PxVehicleWheelsSimData::setTireData | 
| 1346 | 	*/ | 
| 1347 | 	PxReal mFrictionVsSlipGraphRecipx2Minusx1; | 
| 1348 |  | 
| 1349 | 	PxReal mPad[2]; | 
| 1350 |  | 
| 1351 | 	bool isValid() const; | 
| 1352 | }; | 
| 1353 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleTireData)& 0x0f)); | 
| 1354 | #if !PX_DOXYGEN | 
| 1355 | } // namespace physx | 
| 1356 | #endif | 
| 1357 |  | 
| 1358 | /** @} */ | 
| 1359 | #endif //PX_VEHICLE_CORE_COMPONENTS_H | 
| 1360 |  |