1 | /* |
2 | * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. |
3 | * |
4 | * NVIDIA CORPORATION and its licensors retain all intellectual property |
5 | * and proprietary rights in and to this software, related documentation |
6 | * and any modifications thereto. Any use, reproduction, disclosure or |
7 | * distribution of this software and related documentation without an express |
8 | * license agreement from NVIDIA CORPORATION is strictly prohibited. |
9 | */ |
10 | // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. |
11 | // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. |
12 | |
13 | |
14 | #ifndef PX_VEHICLE_WHEELS_H |
15 | #define PX_VEHICLE_WHEELS_H |
16 | /** \addtogroup vehicle |
17 | @{ |
18 | */ |
19 | |
20 | #include "PxFiltering.h" |
21 | #include "foundation/PxSimpleTypes.h" |
22 | #include "vehicle/PxVehicleShaders.h" |
23 | #include "vehicle/PxVehicleComponents.h" |
24 | #include "common/PxBase.h" |
25 | #include "PxRigidDynamic.h" |
26 | |
27 | #ifndef PX_DOXYGEN |
28 | namespace physx |
29 | { |
30 | #endif |
31 | |
32 | class PxVehicleWheels4SimData; |
33 | class PxVehicleWheels4DynData; |
34 | class PxVehicleTireForceCalculator; |
35 | class PxShape; |
36 | class PxPhysics; |
37 | class PxMaterial; |
38 | |
39 | /** |
40 | \brief Data structure describing configuration data of a vehicle with up to 20 wheels. |
41 | */ |
42 | |
43 | class PxVehicleWheelsSimData |
44 | { |
45 | //= ATTENTION! ===================================================================================== |
46 | // Changing the data layout of this class breaks the binary serialization format. See comments for |
47 | // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData |
48 | // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION |
49 | // accordingly. |
50 | //================================================================================================== |
51 | public: |
52 | |
53 | friend class PxVehicleWheels; |
54 | friend class PxVehicleNoDrive; |
55 | friend class PxVehicleDrive4W; |
56 | friend class PxVehicleDriveTank; |
57 | friend class PxVehicleUpdate; |
58 | |
59 | /** |
60 | \brief Allocate a PxVehicleWheelsSimData instance for with nbWheels. |
61 | @see free |
62 | */ |
63 | static PxVehicleWheelsSimData* allocate(const PxU32 nbWheels); |
64 | |
65 | /** |
66 | \brief Setup with mass information that can be applied to the default values of the suspensions, wheels, and tires |
67 | set in their respective constructors. |
68 | |
69 | \param chassisMass is the mass of the chassis. |
70 | |
71 | \note This function assumes that the suspensions equally share the load of the chassis mass. It also |
72 | assumes that the suspension will have a particular natural frequency and damping ratio that is typical |
73 | of a standard car. If either of these assumptions is broken then each suspension will need to |
74 | be individually configured with custom strength, damping rate, and sprung mass. |
75 | |
76 | @see allocate |
77 | */ |
78 | void setChassisMass(const PxF32 chassisMass); |
79 | |
80 | /** |
81 | \brief Free a PxVehicleWheelsSimData instance |
82 | @see allocate |
83 | */ |
84 | void free(); |
85 | |
86 | /** |
87 | \brief Copy wheel simulation data. |
88 | \note The number of wheels on both instances of PxVehicleWheelsSimData must match. |
89 | */ |
90 | PxVehicleWheelsSimData& operator=(const PxVehicleWheelsSimData& src); |
91 | |
92 | /** |
93 | \brief Copy the data of a single wheel unit (wheel, suspension, tire) from srcWheel of src to trgWheel. |
94 | \param[in] src is the data to be copied. |
95 | \param[in] srcWheel is the wheel whose data will be copied from src. |
96 | \param[in] trgWheel is the wheel that will be assigned the copied data. |
97 | */ |
98 | void copy(const PxVehicleWheelsSimData& src, const PxU32 srcWheel, const PxU32 trgWheel); |
99 | |
100 | /** |
101 | \brief Return the number of wheels |
102 | @see allocate |
103 | */ |
104 | PxU32 getNbWheels() const {return mNbActiveWheels;} |
105 | |
106 | /** |
107 | \brief Return the suspension data of the idth wheel |
108 | */ |
109 | const PxVehicleSuspensionData& getSuspensionData(const PxU32 id) const; |
110 | |
111 | /** |
112 | \brief Return the wheel data of the idth wheel |
113 | */ |
114 | const PxVehicleWheelData& getWheelData(const PxU32 id) const; |
115 | |
116 | /** |
117 | \brief Return the tire data of the idth wheel |
118 | */ |
119 | const PxVehicleTireData& getTireData(const PxU32 id) const; |
120 | |
121 | /** |
122 | \brief Return the direction of travel of the suspension of the idth wheel |
123 | */ |
124 | const PxVec3& getSuspTravelDirection(const PxU32 id) const; |
125 | |
126 | /** |
127 | \brief Return the application point of the suspension force of the suspension of the idth wheel as an offset from the rigid body center of mass. |
128 | \note Specified relative to the center of mass of the rigid body |
129 | */ |
130 | const PxVec3& getSuspForceAppPointOffset(const PxU32 id) const; |
131 | |
132 | /** |
133 | \brief Return the application point of the tire force of the tire of the idth wheel as an offset from the rigid body center of mass. |
134 | \note Specified relative to the centre of mass of the rigid body |
135 | */ |
136 | const PxVec3& getTireForceAppPointOffset(const PxU32 id) const; |
137 | |
138 | /** |
139 | \brief Return the offset from the rigid body centre of mass to the centre of the idth wheel. |
140 | */ |
141 | const PxVec3& getWheelCentreOffset(const PxU32 id) const; |
142 | |
143 | /** |
144 | \brief Return the wheel mapping for the ith wheel. |
145 | |
146 | \note The return value is the element in the array of |
147 | shapes of the vehicle's PxRigidDynamic that corresponds to the ith wheel. A return value of -1 means |
148 | that the wheel is not mapped to a PxShape. |
149 | |
150 | @see PxRigidActor.getShapes |
151 | */ |
152 | PxI32 getWheelShapeMapping(const PxU32 wheelId) const; |
153 | |
154 | /** |
155 | \brief Return the scene query filter data used by the specified suspension line |
156 | */ |
157 | const PxFilterData& getSceneQueryFilterData(const PxU32 suspId) const; |
158 | |
159 | /** |
160 | \brief Return the data that describes the filtering of the tire load to produce smoother handling at large time-steps. |
161 | */ |
162 | PX_FORCE_INLINE const PxVehicleTireLoadFilterData& getTireLoadFilterData() const |
163 | { |
164 | return mNormalisedLoadFilter; |
165 | } |
166 | |
167 | /** |
168 | \brief Set the suspension data of the idth wheel |
169 | \param[in] id is the wheel index. |
170 | \param[in] susp is the suspension data to be applied. |
171 | */ |
172 | void setSuspensionData(const PxU32 id, const PxVehicleSuspensionData& susp); |
173 | |
174 | /** |
175 | \brief Set the wheel data of the idth wheel |
176 | \param[in] id is the wheel index. |
177 | \param[in] wheel is the wheel data to be applied. |
178 | */ |
179 | void setWheelData(const PxU32 id, const PxVehicleWheelData& wheel); |
180 | |
181 | /** |
182 | \brief Set the tire data of the idth wheel |
183 | \param[in] id is the wheel index. |
184 | \param[in] tire is the tire data to be applied. |
185 | */ |
186 | void setTireData(const PxU32 id, const PxVehicleTireData& tire); |
187 | |
188 | /** |
189 | \brief Set the direction of travel of the suspension of the idth wheel |
190 | \param[in] id is the wheel index |
191 | \param[in] dir is the suspension travel direction to be applied. |
192 | */ |
193 | void setSuspTravelDirection(const PxU32 id, const PxVec3& dir); |
194 | |
195 | /** |
196 | \brief Set the application point of the suspension force of the suspension of the idth wheel. |
197 | \param[in] id is the wheel index |
198 | \param[in] offset is the offset from the rigid body center of mass to the application point of the suspension force. |
199 | \note Specified relative to the centre of mass of the rigid body |
200 | */ |
201 | void setSuspForceAppPointOffset(const PxU32 id, const PxVec3& offset); |
202 | |
203 | /** |
204 | \brief Set the application point of the tire force of the tire of the idth wheel. |
205 | \param[in] id is the wheel index |
206 | \param[in] offset is the offset from the rigid body center of mass to the application point of the tire force. |
207 | \note Specified relative to the centre of mass of the rigid body |
208 | */ |
209 | void setTireForceAppPointOffset(const PxU32 id, const PxVec3& offset); |
210 | |
211 | /** |
212 | \brief Set the offset from the rigid body centre of mass to the centre of the idth wheel. |
213 | \param[in] id is the wheel index |
214 | \param[in] offset is the offset from the rigid body center of mass to the center of the wheel at rest. |
215 | \note Specified relative to the centre of mass of the rigid body |
216 | */ |
217 | void setWheelCentreOffset(const PxU32 id, const PxVec3& offset); |
218 | |
219 | /** |
220 | \brief Set mapping between wheel id and position of corresponding wheel shape in the list of actor shapes. |
221 | |
222 | \note This mapping is used to pose the correct wheel shapes with the latest wheel rotation angle, steer angle, and suspension travel |
223 | while allowing arbitrary ordering of the wheel shapes in the actor's list of shapes. |
224 | |
225 | \note Use setWheelShapeMapping(i,-1) to register that there is no wheel shape corresponding to the ith wheel |
226 | |
227 | \note Set setWheelShapeMapping(i,k) to register that the ith wheel corresponds to the kth shape in the actor's list of shapes. |
228 | |
229 | \note The default values correspond to setWheelShapeMapping(i,i) for all wheels. |
230 | |
231 | \note Calling this function will also pose the relevant PxShape at the rest position of the wheel. |
232 | |
233 | \param wheelId is the wheel index |
234 | |
235 | \param shapeId is the shape index. |
236 | |
237 | @see PxVehicleUpdates, PxVehicleDrive4W::setup, PxVehicleDriveTank::setup, PxVehicleNoDrive::setup, setSceneQueryFilterData, PxRigidActor::getShapes |
238 | */ |
239 | void setWheelShapeMapping(const PxU32 wheelId, const PxI32 shapeId); |
240 | |
241 | /** |
242 | \brief Set the scene query filter data that will be used for raycasts along the travel |
243 | direction of the specified suspension. The default value is PxFilterData(0,0,0,0) |
244 | \param suspId is the wheel index |
245 | \param sqFilterData is the raycast filter data for the suspension raycast. |
246 | @see setWheelShapeMapping |
247 | */ |
248 | void setSceneQueryFilterData(const PxU32 suspId, const PxFilterData& sqFilterData); |
249 | |
250 | /** |
251 | \brief Set the data that describes the filtering of the tire load to produce smoother handling at large timesteps. |
252 | \param tireLoadFilter is the smoothing function data. |
253 | */ |
254 | void setTireLoadFilterData(const PxVehicleTireLoadFilterData& tireLoadFilter); |
255 | |
256 | /** |
257 | \brief Disable a wheel so that zero suspension forces and zero tire forces are applied to the rigid body from this wheel. |
258 | |
259 | \note If the vehicle has a differential (PxVehicleNW/PxVehicle4W) then the differential (PxVehicleDifferentialNWData/PxVehicleDifferential4WData) |
260 | needs to be configured so that no drive torque is delivered to the disabled wheel. |
261 | |
262 | \note If the vehicle is of type PxVehicleNoDrive then zero drive torque must be applied to the disabled wheel. |
263 | |
264 | \note For tanks (PxVehicleDriveTank) any drive torque that could be delivered to the wheel through the tank differential will be |
265 | re-directed to the remaining enabled wheels. |
266 | |
267 | @see enableWheel |
268 | @see PxVehicleDifferentialNWData::setDrivenWheel |
269 | @see PxVehicleDifferential4WData::mFrontLeftRightSplit, PxVehicleDifferential4WData::mRearLeftRightSplit, PxVehicleDifferential4WData::mType |
270 | @see PxVehicleNoDrive::setDriveTorque |
271 | @see PxVehicle4WEnable3WTadpoleMode, PxVehicle4WEnable3WDeltaMode |
272 | |
273 | \note If a PxShape is associated with the disabled wheel then the association must be broken by calling setWheelShapeMapping(wheelId, -1). |
274 | @see setWheelShapeMapping |
275 | |
276 | \note A wheel that is disabled must also simultaneously be given zero wheel rotation speed. |
277 | @see PxVehicleWheelsDynData::setWheelRotationSpeed |
278 | |
279 | \note Care must be taken with the sprung mass supported by the remaining enabled wheels. Depending on the desired effect, the mass of the rigid body |
280 | might need to be distributed among the remaining enabled wheels and suspensions. |
281 | |
282 | \param[in] wheel is the wheel index. |
283 | */ |
284 | void disableWheel(const PxU32 wheel); |
285 | |
286 | /** |
287 | \brief Enable a wheel so that suspension forces and tire forces are applied to the rigid body. |
288 | All wheels are enabled by default and remain enabled until they are disabled. |
289 | \param[in] wheel is the wheel index. |
290 | @see disableWheel |
291 | */ |
292 | void enableWheel(const PxU32 wheel); |
293 | |
294 | /** |
295 | \brief Test if a wheel has been disabled. |
296 | \param[in] wheel is the wheel index. |
297 | */ |
298 | bool getIsWheelDisabled(const PxU32 wheel) const; |
299 | |
300 | /** |
301 | \brief Set the number of vehicle sub-steps that will be performed when the vehicle's longitudinal |
302 | speed is below and above a threshold longitudinal speed. |
303 | |
304 | \note More sub-steps provides better stability but with greater computational cost. |
305 | |
306 | \note Typically, vehicles require more sub-steps at very low forward speeds. |
307 | |
308 | \note The threshold longitudinal speed has a default value of 5 metres per second. If metres are not the chosen scale |
309 | then setSubStepCount will need to be called with an equivalent or modified value in the adopted scale. |
310 | |
311 | \note The sub-step count below the threshold longitudinal speed has a default of 3. |
312 | |
313 | \note The sub-step count above the threshold longitudinal speed has a default of 1. |
314 | |
315 | \note Each sub-step has time advancement equal to the time-step passed to PxVhicleUpdates divided by the number of required sub-steps. |
316 | |
317 | \note The contact planes of the most recent suspension line raycast are reused across all sub-steps. |
318 | |
319 | \note Each sub-step computes tire and suspension forces and then advances a velocity, angular velocity and transform. |
320 | |
321 | \note At the end of all sub-steps the vehicle actor is given the velocity and angular velocity that would move the actor from its start transform prior |
322 | to the first sub-step to the transform computed at the end of the last substep, assuming it doesn't collide with anything along the way in the next PhysX SDK update. |
323 | |
324 | \note The global pose of the actor is left unchanged throughout the sub-steps. |
325 | |
326 | \param[in] thresholdLongitudinalSpeed is a threshold speed that is used to categorize vehicle speed as low speed or high speed. |
327 | \param[in] lowForwardSpeedSubStepCount is the number of sub-steps performed in PxVehicleUpates for vehicles that have longitudinal speed lower than thresholdLongitudinalSpeed. |
328 | \param[in] highForwardSpeedSubStepCount is the number of sub-steps performed in PxVehicleUpdates for vehicles that have longitudinal speed graeter than thresholdLongitudinalSpeed. |
329 | */ |
330 | void setSubStepCount(const PxReal thresholdLongitudinalSpeed, const PxU32 lowForwardSpeedSubStepCount, const PxU32 highForwardSpeedSubStepCount); |
331 | |
332 | /** |
333 | \brief Set the minimum denominator used in the longitudinal slip calculation. |
334 | |
335 | \note The longitudinal slip has a theoretical value of (w*r - vz)/|vz|, where w is the angular speed of the wheel; r is the radius of the wheel; |
336 | and vz is the component of rigid body velocity (computed at the wheel base) that lies along the longitudinal wheel direction. The term |vz| |
337 | normalizes the slip, while preserving the sign of the longitudinal tire slip. The difficulty here is that when |vz| approaches zero the |
338 | longitudinal slip approaches infinity. A solution to this problem is to replace the denominator (|vz|) with a value that never falls below a chosen threshold. |
339 | The longitudinal slip is then calculated with (w*r - vz)/PxMax(|vz|, minLongSlipDenominator). |
340 | |
341 | \note The default value is 4 metres per second. If metres are not the chosen scale then setSubStepCount will need to be called with an equivalent or |
342 | modified value in the adopted scale. |
343 | |
344 | \note Adjust this value upwards if a vehicle has difficulty coming to rest. |
345 | |
346 | \note Decreasing the timestep (or increasing the number of sub-steps at low longitudinal speed with setSubStepCount) should allow stable stable |
347 | behavior with smaller values of minLongSlipDenominator. |
348 | */ |
349 | void setMinLongSlipDenominator(const PxReal minLongSlipDenominator); |
350 | |
351 | private: |
352 | |
353 | /** |
354 | \brief Graph to filter normalised load |
355 | @see setTireLoadFilterData, getTireLoadFilterData |
356 | */ |
357 | PxVehicleTireLoadFilterData mNormalisedLoadFilter; |
358 | |
359 | /** |
360 | \brief Wheels data organised in blocks of 4 wheels. |
361 | */ |
362 | PxVehicleWheels4SimData* mWheels4SimData; |
363 | |
364 | /** |
365 | \brief Number of blocks of 4 wheels. |
366 | */ |
367 | PxU32 mNbWheels4; |
368 | |
369 | /** |
370 | \brief Number of actual wheels (<=(mNbWheels4*4)) |
371 | */ |
372 | PxU32 mNbActiveWheels; |
373 | |
374 | /** |
375 | \brief Which of the mNbActiveWheels are active or disabled? |
376 | The default is that all mNbActiveWheels wheels are active. |
377 | */ |
378 | PxU32 mActiveWheelsBitmapBuffer[((PX_MAX_NB_WHEELS + 31) & ~31) >> 5]; |
379 | |
380 | /** |
381 | \brief Threshold longitudinal speed used to decide whether to use |
382 | mLowForwardSpeedSubStepCount or mHighForwardSpeedSubStepCount as the |
383 | number of sub-steps that will be peformed. |
384 | */ |
385 | PxF32 mThresholdLongitudinalSpeed; |
386 | |
387 | /** |
388 | \brief Number of sub-steps that will be performed if the longitudinal speed |
389 | of the vehicle is smaller than mThresholdLongitudinalSpeed. |
390 | */ |
391 | PxU32 mLowForwardSpeedSubStepCount; |
392 | |
393 | /** |
394 | \brief Number of sub-steps that will be performed if the longitudinal speed |
395 | of the vehicle is greater than or equal to mThresholdLongitudinalSpeed. |
396 | */ |
397 | PxU32 mHighForwardSpeedSubStepCount; |
398 | |
399 | /** |
400 | \brief Minimum long slip denominator |
401 | */ |
402 | PxF32 mMinLongSlipDenominator; |
403 | |
404 | #if defined(PX_P64) |
405 | PxU32 mPad[3]; |
406 | #endif |
407 | |
408 | |
409 | /** |
410 | \brief Test if wheel simulation data has been setup with legal values. |
411 | */ |
412 | bool isValid() const; |
413 | |
414 | |
415 | //serialization |
416 | public: |
417 | PxVehicleWheelsSimData(const PxEMPTY&) : mNormalisedLoadFilter(PxEmpty) {} |
418 | static void getBinaryMetaData(PxOutputStream& stream); |
419 | PxU32 getNbWheels4() const { return mNbWheels4; } |
420 | PxU32 getNbSuspensionData() const { return mNbActiveWheels; } |
421 | PxU32 getNbWheelData() const { return mNbActiveWheels; } |
422 | PxU32 getNbSuspTravelDirection() const { return mNbActiveWheels; } |
423 | PxU32 getNbTireData() const { return mNbActiveWheels; } |
424 | PxU32 getNbSuspForceAppPointOffset() const { return mNbActiveWheels; } |
425 | PxU32 getNbTireForceAppPointOffset() const { return mNbActiveWheels; } |
426 | PxU32 getNbWheelCentreOffset() const { return mNbActiveWheels; } |
427 | PxU32 getNbWheelShapeMapping() const { return mNbActiveWheels; } |
428 | PxU32 getNbSceneQueryFilterData() const { return mNbActiveWheels; } |
429 | PxF32 getMinLongSlipDenominator() const {return mMinLongSlipDenominator;} |
430 | void setThresholdLongSpeed(const PxF32 f) {mThresholdLongitudinalSpeed = f;} |
431 | PxF32 getThresholdLongSpeed() const {return mThresholdLongitudinalSpeed;} |
432 | void setLowForwardSpeedSubStepCount(const PxU32 f) {mLowForwardSpeedSubStepCount = f;} |
433 | PxU32 getLowForwardSpeedSubStepCount() const {return mLowForwardSpeedSubStepCount;} |
434 | void setHighForwardSpeedSubStepCount(const PxU32 f) {mHighForwardSpeedSubStepCount = f;} |
435 | PxU32 getHighForwardSpeedSubStepCount() const {return mHighForwardSpeedSubStepCount;} |
436 | void setWheelEnabledState(const PxU32 wheel, const bool state) {if(state) {enableWheel(wheel);} else {disableWheel(wheel);}} |
437 | bool getWheelEnabledState(const PxU32 wheel) const {return !getIsWheelDisabled(wheel);} |
438 | PxU32 getNbWheelEnabledState() const {return mNbActiveWheels;} |
439 | PxVehicleWheelsSimData(){} |
440 | ~PxVehicleWheelsSimData(){} |
441 | //~serialization |
442 | }; |
443 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleWheelsSimData) & 15)); |
444 | |
445 | /** |
446 | \brief Data structure with instanced dynamics data for wheels |
447 | */ |
448 | class PxVehicleWheelsDynData |
449 | { |
450 | //= ATTENTION! ===================================================================================== |
451 | // Changing the data layout of this class breaks the binary serialization format. See comments for |
452 | // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData |
453 | // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION |
454 | // accordingly. |
455 | //================================================================================================== |
456 | public: |
457 | |
458 | friend class PxVehicleWheels; |
459 | friend class PxVehicleDrive4W; |
460 | friend class PxVehicleDriveTank; |
461 | friend class PxVehicleUpdate; |
462 | |
463 | PxVehicleWheelsDynData(){} |
464 | ~PxVehicleWheelsDynData(){} |
465 | |
466 | /** |
467 | \brief Set all wheels to their rest state. |
468 | @see setup |
469 | */ |
470 | void setToRestState(); |
471 | |
472 | /** |
473 | \brief Set the tire force shader function |
474 | \param[in] tireForceShaderFn is the shader function that will be used to compute tire forces. |
475 | */ |
476 | void setTireForceShaderFunction(PxVehicleComputeTireForce tireForceShaderFn); |
477 | |
478 | /** |
479 | \brief Set the tire force shader data for a specific tire |
480 | \param[in] tireId is the wheel index |
481 | \param[in] tireForceShaderData is the data describing the tire. |
482 | */ |
483 | void setTireForceShaderData(const PxU32 tireId, const void* tireForceShaderData); |
484 | |
485 | /** |
486 | \brief Get the tire force shader data for a specific tire |
487 | */ |
488 | const void* getTireForceShaderData(const PxU32 tireId) const; |
489 | |
490 | /** |
491 | \brief Set the wheel rotation speed (radians per second) about the rolling axis for the specified wheel. |
492 | \param[in] wheelIdx is the wheel index |
493 | \param[in] speed is the rotation speed to be applied to the wheel. |
494 | */ |
495 | void setWheelRotationSpeed(const PxU32 wheelIdx, const PxReal speed); |
496 | |
497 | /** |
498 | \brief Return the rotation speed about the rolling axis of a specified wheel . |
499 | */ |
500 | PxReal getWheelRotationSpeed(const PxU32 wheelIdx) const; |
501 | |
502 | /** |
503 | \brief Set the wheel rotation angle (radians) about the rolling axis of the specified wheel. |
504 | \param[in] wheelIdx is the wheel index |
505 | \param[in] angle is the rotation angle to be applied to the wheel. |
506 | */ |
507 | void setWheelRotationAngle(const PxU32 wheelIdx, const PxReal angle); |
508 | |
509 | /** |
510 | \brief Return the rotation angle about the rolling axis for the the specified wheel. |
511 | */ |
512 | PxReal getWheelRotationAngle(const PxU32 wheelIdx) const; |
513 | |
514 | /** |
515 | \brief Set the user data pointer for the specified wheel |
516 | It has a default value of NULL. |
517 | \param[in] tireIdx is the wheel index |
518 | \param[in] userData is the data to be associated with the wheel. |
519 | */ |
520 | void setUserData(const PxU32 tireIdx, void* userData); |
521 | |
522 | /** |
523 | \brief Get the user data pointer that was set for the specified wheel |
524 | */ |
525 | void* getUserData(const PxU32 tireIdx) const; |
526 | |
527 | /** |
528 | \brief Copy the dynamics data of a single wheel unit (wheel, suspension, tire) from srcWheel of src to trgWheel. |
529 | \param[in] src is the data to be copied. |
530 | \param[in] srcWheel is the wheel whose data will be copied from src. |
531 | \param[in] trgWheel is the wheel that will be assigned the copied data. |
532 | */ |
533 | void copy(const PxVehicleWheelsDynData& src, const PxU32 srcWheel, const PxU32 trgWheel); |
534 | |
535 | private: |
536 | |
537 | /** |
538 | \brief Dynamics data arranged in blocks of 4 wheels. |
539 | */ |
540 | PxVehicleWheels4DynData* mWheels4DynData; |
541 | |
542 | /** |
543 | \brief Test if wheel dynamics data have legal values. |
544 | */ |
545 | bool isValid() const; |
546 | |
547 | /** |
548 | \brief Shader data and function for tire force calculations. |
549 | */ |
550 | PxVehicleTireForceCalculator* mTireForceCalculators; |
551 | |
552 | /** |
553 | \brief A userData pointer can be stored for each wheel. |
554 | @see setUserData, getUserData |
555 | */ |
556 | void** mUserDatas; |
557 | |
558 | /** |
559 | \brief Number of blocks of 4 wheels. |
560 | */ |
561 | PxU32 mNbWheels4; |
562 | |
563 | /** |
564 | \brief Number of wheels (mNbActiveWheels <= (mNbWheels4*4)) |
565 | */ |
566 | PxU32 mNbActiveWheels; |
567 | |
568 | PxU32 mPad[3]; |
569 | |
570 | |
571 | //serialization |
572 | public: |
573 | static void getBinaryMetaData(PxOutputStream& stream); |
574 | PxU32 getNbWheelRotationSpeed() const { return mNbActiveWheels; } |
575 | PxU32 getNbWheelRotationAngle() const { return mNbActiveWheels; } |
576 | PxVehicleWheels4DynData* getWheel4DynData() const { return mWheels4DynData; } |
577 | //~serialization |
578 | }; |
579 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleWheelsDynData) & 15)); |
580 | |
581 | /** |
582 | \brief Data structure with instanced dynamics data and configuration data of a vehicle with just wheels |
583 | @see PxVehicleDrive, PxVehicleDrive4W, PxVehicleDriveTank |
584 | */ |
585 | class PxVehicleWheels : public PxBase |
586 | { |
587 | //= ATTENTION! ===================================================================================== |
588 | // Changing the data layout of this class breaks the binary serialization format. See comments for |
589 | // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData |
590 | // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION |
591 | // accordingly. |
592 | //================================================================================================== |
593 | public: |
594 | |
595 | friend class PxVehicleUpdate; |
596 | friend class PxVehicleConstraintShader; |
597 | |
598 | /** |
599 | \brief Return the type of vehicle |
600 | @see PxVehicleTypes |
601 | */ |
602 | PX_FORCE_INLINE PxU32 getVehicleType() const {return mType;} |
603 | |
604 | /** |
605 | \brief Get non-const ptr to PxRigidDynamic instance that is the vehicle's physx representation |
606 | */ |
607 | PX_FORCE_INLINE PxRigidDynamic* getRigidDynamicActor() {return mActor;} |
608 | |
609 | /** |
610 | \brief Get const ptr to PxRigidDynamic instance that is the vehicle's physx representation |
611 | */ |
612 | PX_FORCE_INLINE const PxRigidDynamic* getRigidDynamicActor() const {return mActor;} |
613 | |
614 | /** |
615 | \brief Compute the rigid body velocity component along the forward vector of the rigid body transform. |
616 | @see PxVehicleSetBasisVectors |
617 | */ |
618 | PxReal computeForwardSpeed() const; |
619 | |
620 | /** |
621 | \brief Compute the rigid body velocity component along the right vector of the rigid body transform. |
622 | @see PxVehicleSetBasisVectors |
623 | */ |
624 | PxReal computeSidewaysSpeed() const; |
625 | |
626 | /** |
627 | \brief Data describing the setup of all the wheels/suspensions/tires. |
628 | */ |
629 | PxVehicleWheelsSimData mWheelsSimData; |
630 | |
631 | /** |
632 | \brief Data describing the dynamic state of all wheels/suspension/tires. |
633 | */ |
634 | PxVehicleWheelsDynData mWheelsDynData; |
635 | |
636 | protected: |
637 | |
638 | /** |
639 | \brief Set all wheels to their rest state |
640 | */ |
641 | void setToRestState(); |
642 | |
643 | /** |
644 | \brief Test that all configuration and instanced dynamics data is valid. |
645 | */ |
646 | bool isValid() const; |
647 | |
648 | /** |
649 | @see PxVehicleDrive4W::allocate, PxVehicleDriveTank::allocate |
650 | */ |
651 | static PxU32 computeByteSize(const PxU32 nbWheels4); |
652 | |
653 | /** |
654 | @see PxVehicleDrive4W::allocate, PxVehicleDriveTank::allocate |
655 | */ |
656 | static PxU8* patchupPointers(PxVehicleWheels* veh, PxU8* ptr, const PxU32 nbWheels4, const PxU32 nbWheels, bool renew = true); |
657 | |
658 | /** |
659 | \brief Deallocate a PxVehicleWheels instance. |
660 | @see PxVehicleDrive4W::free, PxVehicleDriveTank::free |
661 | */ |
662 | void free(); |
663 | |
664 | /** |
665 | @see PxVehicleDrive4W::setup, PxVehicleDriveTank::setup |
666 | */ |
667 | void setup |
668 | (PxPhysics* physics, PxRigidDynamic* vehActor, |
669 | const PxVehicleWheelsSimData& wheelsData, |
670 | const PxU32 nbDrivenWheels, const PxU32 nbNonDrivenWheels); |
671 | |
672 | /** |
673 | \brief The rigid body actor that represents the vehicle in the PhysX SDK. |
674 | */ |
675 | PxRigidDynamic* mActor; |
676 | |
677 | private: |
678 | |
679 | /** |
680 | \brief Count the number of constraint connectors that have hit their callback when deleting a vehicle. |
681 | Can only delete the vehicle's memory when all constraint connectors have hit their callback. |
682 | */ |
683 | PxU32 mNbNonDrivenWheels; |
684 | |
685 | PxU8 mOnConstraintReleaseCounter; |
686 | |
687 | protected: |
688 | |
689 | /** |
690 | \brief Vehicle type (eVehicleDriveTypes) |
691 | */ |
692 | PxU8 mType; |
693 | |
694 | #if defined(PX_P64) |
695 | PxU8 mPad[14]; |
696 | #else |
697 | PxU8 mPad[14]; |
698 | #endif |
699 | |
700 | //serialization |
701 | public: |
702 | virtual void requires(PxProcessPxBaseCallback& c); |
703 | virtual const char* getConcreteTypeName() const { return "PxVehicleWheels" ; } |
704 | virtual bool isKindOf(const char* name) const { return !strcmp("PxVehicleWheels" , name) || PxBase::isKindOf(name); } |
705 | virtual void (PxSerializationContext&); |
706 | void (PxDeserializationContext&); |
707 | void resolveReferences(PxDeserializationContext&); |
708 | static void getBinaryMetaData(PxOutputStream& stream); |
709 | PX_FORCE_INLINE PxU32 getNbNonDrivenWheels() const { return mNbNonDrivenWheels; } |
710 | PxVehicleWheels(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} |
711 | PxVehicleWheels(PxBaseFlags baseFlags) : PxBase(baseFlags), mWheelsSimData(PxEmpty) {} |
712 | virtual ~PxVehicleWheels() {} |
713 | virtual void release() { free(); } |
714 | //~serialization |
715 | }; |
716 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleWheels) & 15)); |
717 | |
718 | #ifndef PX_DOXYGEN |
719 | } // namespace physx |
720 | #endif |
721 | |
722 | /** @} */ |
723 | #endif //PX_VEHICLE_WHEELS_H |
724 | |