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 | |
31 | #ifndef PX_VEHICLE_WHEELS_H |
32 | #define PX_VEHICLE_WHEELS_H |
33 | /** \addtogroup vehicle |
34 | @{ |
35 | */ |
36 | |
37 | #include "foundation/PxSimpleTypes.h" |
38 | #include "vehicle/PxVehicleShaders.h" |
39 | #include "vehicle/PxVehicleComponents.h" |
40 | #include "common/PxBase.h" |
41 | #include "PxRigidDynamic.h" |
42 | |
43 | #if !PX_DOXYGEN |
44 | namespace physx |
45 | { |
46 | #endif |
47 | |
48 | class PxVehicleWheels4SimData; |
49 | class PxVehicleWheels4DynData; |
50 | class PxVehicleTireForceCalculator; |
51 | class PxShape; |
52 | class PxPhysics; |
53 | class PxMaterial; |
54 | |
55 | /** |
56 | \brief Flags to configure the vehicle wheel simulation. |
57 | |
58 | @see PxVehicleWheelsSimData::setFlags(), PxVehicleWheelsSimData::getFlags() |
59 | */ |
60 | struct PxVehicleWheelsSimFlag |
61 | { |
62 | enum Enum |
63 | { |
64 | /** |
65 | \brief Limit the suspension expansion velocity. |
66 | |
67 | For extreme damping ratios, large damping forces might result in the vehicle sticking to the ground where |
68 | one would rather expect to see the vehicle lift off. While it is highly recommended to use somewhat realistic |
69 | damping ratios, this flag can be used to limit the velocity of the suspension. In more detail, the simulation |
70 | will check whether the suspension can extend to the target length in the given simulation time step. If that |
71 | is the case, the suspension force will be computed as usual, else the force will be set to zero. Enabling |
72 | this feature gives a slightly more realisitic behavior at the potential cost of more easily losing control |
73 | when steering the vehicle. |
74 | */ |
75 | eLIMIT_SUSPENSION_EXPANSION_VELOCITY = (1 << 0), |
76 | |
77 | /** |
78 | \brief Disable internal cylinder-plane intersection test. |
79 | |
80 | By default the internal code runs a post-process on sweep results, approximating the wheel shape with a |
81 | cylinder and tweaking the sweep hit results accordingly. This can produce artefacts in certain cases, in |
82 | particular when the swept shape is very different from a cylinder - e.g. with swept spheres. This flag |
83 | tells the system to disable this internal test, and reuse the direct user-provided sweep results. |
84 | |
85 | The default code refines the sweep results in each substep. Enabling this flag makes the system partially |
86 | reuse the same sweep results over each substep, which could potentially create other artefacts. |
87 | */ |
88 | eDISABLE_INTERNAL_CYLINDER_PLANE_INTERSECTION_TEST = (1 << 1), |
89 | |
90 | /** |
91 | \brief Disable suspension force projection. |
92 | |
93 | By default the internal code modulates the suspension force with the contact normal, i.e. the more the contact |
94 | normal is aligned with the suspension direction, the bigger the force. This can create issues when using a |
95 | single blocking hit, whose unique contact normal sometimes does not accurately capture the reality of the |
96 | surrounding geometry. For example it can weaken the suspension force too much, which visually makes the wheel |
97 | move up and down against e.g. a kerb. Enabling this flag tells the system to disable the modulation of the |
98 | suspension force by the contact normal. |
99 | |
100 | The rationale is that a real tire has a deformed contact patch containing multiple normals, and even if some |
101 | of these normals are bent when colliding against a kerb, there would still be a large area of the contact patch |
102 | touching the ground, and getting normals aligned with the suspension. This is difficult to capture with simple |
103 | sweep results, especially with a single sweep hit whose normal is computed by a less than accurate algorithm |
104 | like GJK. Using this flag shortcuts these issues, which can improves the behavior when driving over kerbs or |
105 | small obstacles. |
106 | */ |
107 | eDISABLE_SUSPENSION_FORCE_PROJECTION = (1 << 2) |
108 | }; |
109 | }; |
110 | |
111 | /** |
112 | \brief Collection of set bits defined in #PxVehicleWheelsSimFlag. |
113 | |
114 | @see PxVehicleWheelsSimFlag |
115 | */ |
116 | typedef PxFlags<PxVehicleWheelsSimFlag::Enum, PxU32> PxVehicleWheelsSimFlags; |
117 | PX_FLAGS_OPERATORS(PxVehicleWheelsSimFlag::Enum, PxU32) |
118 | |
119 | /** |
120 | \brief Data structure describing configuration data of a vehicle with up to 20 wheels. |
121 | */ |
122 | |
123 | class PxVehicleWheelsSimData |
124 | { |
125 | //= ATTENTION! ===================================================================================== |
126 | // Changing the data layout of this class breaks the binary serialization format. See comments for |
127 | // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData |
128 | // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION |
129 | // accordingly. |
130 | //================================================================================================== |
131 | public: |
132 | |
133 | friend class PxVehicleWheels; |
134 | friend class PxVehicleNoDrive; |
135 | friend class PxVehicleDrive4W; |
136 | friend class PxVehicleDriveTank; |
137 | friend class PxVehicleUpdate; |
138 | |
139 | /** |
140 | \brief Allocate a PxVehicleWheelsSimData instance for with nbWheels. |
141 | @see free |
142 | */ |
143 | static PxVehicleWheelsSimData* allocate(const PxU32 nbWheels); |
144 | |
145 | /** |
146 | \brief Setup with mass information that can be applied to the default values of the suspensions, wheels, and tires |
147 | set in their respective constructors. |
148 | |
149 | \param chassisMass is the mass of the chassis. |
150 | |
151 | \note This function assumes that the suspensions equally share the load of the chassis mass. It also |
152 | assumes that the suspension will have a particular natural frequency and damping ratio that is typical |
153 | of a standard car. If either of these assumptions is broken then each suspension will need to |
154 | be individually configured with custom strength, damping rate, and sprung mass. |
155 | |
156 | @see allocate |
157 | */ |
158 | void setChassisMass(const PxF32 chassisMass); |
159 | |
160 | /** |
161 | \brief Free a PxVehicleWheelsSimData instance |
162 | @see allocate |
163 | */ |
164 | void free(); |
165 | |
166 | /** |
167 | \brief Copy wheel simulation data. |
168 | \note The number of wheels on both instances of PxVehicleWheelsSimData must match. |
169 | */ |
170 | PxVehicleWheelsSimData& operator=(const PxVehicleWheelsSimData& src); |
171 | |
172 | /** |
173 | \brief Copy the data of a single wheel unit (wheel, suspension, tire) from srcWheel of src to trgWheel. |
174 | \param[in] src is the data to be copied. |
175 | \param[in] srcWheel is the wheel whose data will be copied from src. |
176 | \param[in] trgWheel is the wheel that will be assigned the copied data. |
177 | */ |
178 | void copy(const PxVehicleWheelsSimData& src, const PxU32 srcWheel, const PxU32 trgWheel); |
179 | |
180 | /** |
181 | \brief Return the number of wheels |
182 | @see allocate |
183 | */ |
184 | PxU32 getNbWheels() const {return mNbActiveWheels;} |
185 | |
186 | /** |
187 | \brief Return the suspension data of the idth wheel |
188 | */ |
189 | const PxVehicleSuspensionData& getSuspensionData(const PxU32 id) const; |
190 | |
191 | /** |
192 | \brief Return the wheel data of the idth wheel |
193 | */ |
194 | const PxVehicleWheelData& getWheelData(const PxU32 id) const; |
195 | |
196 | /** |
197 | \brief Return the tire data of the idth wheel |
198 | */ |
199 | const PxVehicleTireData& getTireData(const PxU32 id) const; |
200 | |
201 | /** |
202 | \brief Return the direction of travel of the suspension of the idth wheel |
203 | */ |
204 | const PxVec3& getSuspTravelDirection(const PxU32 id) const; |
205 | |
206 | /** |
207 | \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. |
208 | \note Specified relative to the center of mass of the rigid body |
209 | */ |
210 | const PxVec3& getSuspForceAppPointOffset(const PxU32 id) const; |
211 | |
212 | /** |
213 | \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. |
214 | \note Specified relative to the centre of mass of the rigid body |
215 | */ |
216 | const PxVec3& getTireForceAppPointOffset(const PxU32 id) const; |
217 | |
218 | /** |
219 | \brief Return the offset from the rigid body centre of mass to the centre of the idth wheel. |
220 | */ |
221 | const PxVec3& getWheelCentreOffset(const PxU32 id) const; |
222 | |
223 | /** |
224 | \brief Return the wheel mapping for the ith wheel. |
225 | |
226 | \note The return value is the element in the array of |
227 | shapes of the vehicle's PxRigidDynamic that corresponds to the ith wheel. A return value of -1 means |
228 | that the wheel is not mapped to a PxShape. |
229 | |
230 | @see PxRigidActor.getShapes |
231 | */ |
232 | PxI32 getWheelShapeMapping(const PxU32 wheelId) const; |
233 | |
234 | /** |
235 | \brief Return the scene query filter data used by the specified suspension line |
236 | */ |
237 | const PxFilterData& getSceneQueryFilterData(const PxU32 suspId) const; |
238 | |
239 | /** |
240 | \brief Return the number of unique anti-roll bars that have been added with addAntiRollBarData |
241 | @see PxVehicleWheelsSimData::addAntiRollBarData |
242 | */ |
243 | PxU32 getNbAntiRollBars() const |
244 | { |
245 | return mNbActiveAntiRollBars; |
246 | } |
247 | |
248 | /** |
249 | \brief Return a specific anti-roll bar. |
250 | \param antiRollId is the unique id of the anti-roll bar |
251 | \note The return value of addAntiRollBarData is a unique id for that specific anti-roll bar |
252 | and can be used as input parameter for getAntiRollBarData in order to query the same anti-roll bar. |
253 | Alternatively, it is possible to iterate over all anti-roll bars by choosing antiRollId |
254 | in range (0, getNbAntiRollBars()). |
255 | */ |
256 | const PxVehicleAntiRollBarData& getAntiRollBarData(const PxU32 antiRollId) const; |
257 | |
258 | /** |
259 | \brief Return the data that describes the filtering of the tire load to produce smoother handling at large time-steps. |
260 | */ |
261 | PX_FORCE_INLINE const PxVehicleTireLoadFilterData& getTireLoadFilterData() const |
262 | { |
263 | return mNormalisedLoadFilter; |
264 | } |
265 | |
266 | /** |
267 | \brief Set the suspension data of the idth wheel |
268 | \param[in] id is the wheel index. |
269 | \param[in] susp is the suspension data to be applied. |
270 | */ |
271 | void setSuspensionData(const PxU32 id, const PxVehicleSuspensionData& susp); |
272 | |
273 | /** |
274 | \brief Set the wheel data of the idth wheel |
275 | \param[in] id is the wheel index. |
276 | \param[in] wheel is the wheel data to be applied. |
277 | */ |
278 | void setWheelData(const PxU32 id, const PxVehicleWheelData& wheel); |
279 | |
280 | /** |
281 | \brief Set the tire data of the idth wheel |
282 | \param[in] id is the wheel index. |
283 | \param[in] tire is the tire data to be applied. |
284 | */ |
285 | void setTireData(const PxU32 id, const PxVehicleTireData& tire); |
286 | |
287 | /** |
288 | \brief Set the direction of travel of the suspension of the idth wheel |
289 | \param[in] id is the wheel index |
290 | \param[in] dir is the suspension travel direction to be applied. |
291 | */ |
292 | void setSuspTravelDirection(const PxU32 id, const PxVec3& dir); |
293 | |
294 | /** |
295 | \brief Set the application point of the suspension force of the suspension of the idth wheel. |
296 | \param[in] id is the wheel index |
297 | \param[in] offset is the offset from the rigid body center of mass to the application point of the suspension force. |
298 | \note Specified relative to the centre of mass of the rigid body |
299 | */ |
300 | void setSuspForceAppPointOffset(const PxU32 id, const PxVec3& offset); |
301 | |
302 | /** |
303 | \brief Set the application point of the tire force of the tire of the idth wheel. |
304 | \param[in] id is the wheel index |
305 | \param[in] offset is the offset from the rigid body center of mass to the application point of the tire force. |
306 | \note Specified relative to the centre of mass of the rigid body |
307 | */ |
308 | void setTireForceAppPointOffset(const PxU32 id, const PxVec3& offset); |
309 | |
310 | /** |
311 | \brief Set the offset from the rigid body centre of mass to the centre of the idth wheel. |
312 | \param[in] id is the wheel index |
313 | \param[in] offset is the offset from the rigid body center of mass to the center of the wheel at rest. |
314 | \note Specified relative to the centre of mass of the rigid body |
315 | */ |
316 | void setWheelCentreOffset(const PxU32 id, const PxVec3& offset); |
317 | |
318 | /** |
319 | \brief Set mapping between wheel id and position of corresponding wheel shape in the list of actor shapes. |
320 | |
321 | \note This mapping is used to pose the correct wheel shapes with the latest wheel rotation angle, steer angle, and suspension travel |
322 | while allowing arbitrary ordering of the wheel shapes in the actor's list of shapes. |
323 | |
324 | \note Use setWheelShapeMapping(i,-1) to register that there is no wheel shape corresponding to the ith wheel |
325 | |
326 | \note Set setWheelShapeMapping(i,k) to register that the ith wheel corresponds to the kth shape in the actor's list of shapes. |
327 | |
328 | \note The default values correspond to setWheelShapeMapping(i,i) for all wheels. |
329 | |
330 | \note Calling this function will also pose the relevant PxShape at the rest position of the wheel. |
331 | |
332 | \param wheelId is the wheel index |
333 | |
334 | \param shapeId is the shape index. |
335 | |
336 | @see PxVehicleUpdates, PxVehicleDrive4W::setup, PxVehicleDriveTank::setup, PxVehicleNoDrive::setup, setSceneQueryFilterData, PxRigidActor::getShapes |
337 | */ |
338 | void setWheelShapeMapping(const PxU32 wheelId, const PxI32 shapeId); |
339 | |
340 | /** |
341 | \brief Set the scene query filter data that will be used for raycasts along the travel |
342 | direction of the specified suspension. The default value is PxFilterData(0,0,0,0) |
343 | \param suspId is the wheel index |
344 | \param sqFilterData is the raycast filter data for the suspension raycast. |
345 | @see setWheelShapeMapping |
346 | */ |
347 | void setSceneQueryFilterData(const PxU32 suspId, const PxFilterData& sqFilterData); |
348 | |
349 | /** |
350 | \brief Set the data that describes the filtering of the tire load to produce smoother handling at large timesteps. |
351 | \param tireLoadFilter is the smoothing function data. |
352 | */ |
353 | void setTireLoadFilterData(const PxVehicleTireLoadFilterData& tireLoadFilter); |
354 | |
355 | /** |
356 | \brief Set the anti-roll suspension for a pair of wheels. |
357 | |
358 | \param antiRoll is the anti-roll suspension. |
359 | |
360 | \note If an anti-roll bar has already been set for the same logical wheel pair |
361 | (independent of wheel index order specified by PxVehicleAntiRollBar.mWheel0 and PxVehicleAntiRollBar.mWheel0) |
362 | then the existing anti-roll bar is updated with a new stiffness parameter antiRoll.mStiffness. |
363 | |
364 | \note If the wheel pair specified by antiRoll does not yet have an anti-roll bar then antiRoll is added to |
365 | a list of anti-roll bars for the vehicle. |
366 | |
367 | \return If antiRoll represents a new wheel pair then a unique id is assigned to the anti-roll bar and returned. |
368 | If antiRoll represents an existing wheel pair then the unique id of the existing anti-roll bar is returned. |
369 | The return value is always in range (0, getNbAntiRollBars()). |
370 | |
371 | \note The return value can be used to query the anti-roll bar with getAntiRollBarData(id). |
372 | |
373 | \note The number of possible anti-roll bars is limited to half the wheel count. |
374 | |
375 | \note An existing anti-roll bar can be disabled by calling antiRoll.mStiffness to zero. |
376 | |
377 | @see PxVehicleWheelsSimData::getAntiRollBarData, PxVehicleAntiRollBarData |
378 | */ |
379 | PxU32 addAntiRollBarData(const PxVehicleAntiRollBarData& antiRoll); |
380 | |
381 | /** |
382 | \brief Disable a wheel so that zero suspension forces and zero tire forces are applied to the rigid body from this wheel. |
383 | |
384 | \note If the vehicle has a differential (PxVehicleNW/PxVehicle4W) then the differential (PxVehicleDifferentialNWData/PxVehicleDifferential4WData) |
385 | needs to be configured so that no drive torque is delivered to the disabled wheel. |
386 | |
387 | \note If the vehicle is of type PxVehicleNoDrive then zero drive torque must be applied to the disabled wheel. |
388 | |
389 | \note For tanks (PxVehicleDriveTank) any drive torque that could be delivered to the wheel through the tank differential will be |
390 | re-directed to the remaining enabled wheels. |
391 | |
392 | @see enableWheel |
393 | @see PxVehicleDifferentialNWData::setDrivenWheel |
394 | @see PxVehicleDifferential4WData::mFrontLeftRightSplit, PxVehicleDifferential4WData::mRearLeftRightSplit, PxVehicleDifferential4WData::mType |
395 | @see PxVehicleNoDrive::setDriveTorque |
396 | @see PxVehicle4WEnable3WTadpoleMode, PxVehicle4WEnable3WDeltaMode |
397 | |
398 | \note If a PxShape is associated with the disabled wheel then the association must be broken by calling setWheelShapeMapping(wheelId, -1). |
399 | @see setWheelShapeMapping |
400 | |
401 | \note A wheel that is disabled must also simultaneously be given zero wheel rotation speed. |
402 | @see PxVehicleWheelsDynData::setWheelRotationSpeed |
403 | |
404 | \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 |
405 | might need to be distributed among the remaining enabled wheels and suspensions. |
406 | |
407 | \param[in] wheel is the wheel index. |
408 | */ |
409 | void disableWheel(const PxU32 wheel); |
410 | |
411 | /** |
412 | \brief Enable a wheel so that suspension forces and tire forces are applied to the rigid body. |
413 | All wheels are enabled by default and remain enabled until they are disabled. |
414 | \param[in] wheel is the wheel index. |
415 | @see disableWheel |
416 | */ |
417 | void enableWheel(const PxU32 wheel); |
418 | |
419 | /** |
420 | \brief Test if a wheel has been disabled. |
421 | \param[in] wheel is the wheel index. |
422 | */ |
423 | bool getIsWheelDisabled(const PxU32 wheel) const; |
424 | |
425 | /** |
426 | \brief Set the number of vehicle sub-steps that will be performed when the vehicle's longitudinal |
427 | speed is below and above a threshold longitudinal speed. |
428 | |
429 | \note More sub-steps provides better stability but with greater computational cost. |
430 | |
431 | \note Typically, vehicles require more sub-steps at very low forward speeds. |
432 | |
433 | \note The threshold longitudinal speed has a default value that is the equivalent of 5 metres per second after accounting for |
434 | the length scale set in PxTolerancesScale. |
435 | |
436 | \note The sub-step count below the threshold longitudinal speed has a default of 3. |
437 | |
438 | \note The sub-step count above the threshold longitudinal speed has a default of 1. |
439 | |
440 | \note Each sub-step has time advancement equal to the time-step passed to PxVehicleUpdates divided by the number of required sub-steps. |
441 | |
442 | \note The contact planes of the most recent suspension line raycast are reused across all sub-steps. |
443 | |
444 | \note Each sub-step computes tire and suspension forces and then advances a velocity, angular velocity and transform. |
445 | |
446 | \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 |
447 | 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. |
448 | |
449 | \note The global pose of the actor is left unchanged throughout the sub-steps. |
450 | |
451 | \param[in] thresholdLongitudinalSpeed is a threshold speed that is used to categorize vehicle speed as low speed or high speed. |
452 | \param[in] lowForwardSpeedSubStepCount is the number of sub-steps performed in PxVehicleUpates for vehicles that have longitudinal speed lower than thresholdLongitudinalSpeed. |
453 | \param[in] highForwardSpeedSubStepCount is the number of sub-steps performed in PxVehicleUpdates for vehicles that have longitudinal speed graeter than thresholdLongitudinalSpeed. |
454 | */ |
455 | void setSubStepCount(const PxReal thresholdLongitudinalSpeed, const PxU32 lowForwardSpeedSubStepCount, const PxU32 highForwardSpeedSubStepCount); |
456 | |
457 | /** |
458 | \brief Set the minimum denominator used in the longitudinal slip calculation. |
459 | |
460 | \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; |
461 | and vz is the component of rigid body velocity (computed at the wheel base) that lies along the longitudinal wheel direction. The term |vz| |
462 | normalizes the slip, while preserving the sign of the longitudinal tire slip. The difficulty here is that when |vz| approaches zero the |
463 | 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. |
464 | The longitudinal slip is then calculated with (w*r - vz)/PxMax(|vz|, minLongSlipDenominator). |
465 | |
466 | \note The default value is the equivalent of 4 metres per second after accounting for the length scale set in PxTolerancesScale. |
467 | |
468 | \note Adjust this value upwards if a vehicle has difficulty coming to rest. |
469 | |
470 | \note Decreasing the timestep (or increasing the number of sub-steps at low longitudinal speed with setSubStepCount) should allow stable stable |
471 | behavior with smaller values of minLongSlipDenominator. |
472 | */ |
473 | void setMinLongSlipDenominator(const PxReal minLongSlipDenominator); |
474 | |
475 | /** |
476 | \brief Set the vehicle wheel simulation flags. |
477 | |
478 | \param[in] flags The flags to set (see #PxVehicleWheelsSimFlags). |
479 | |
480 | <b>Default:</b> no flag set |
481 | |
482 | @see PxVehicleWheelsSimFlag |
483 | */ |
484 | void setFlags(PxVehicleWheelsSimFlags flags); |
485 | |
486 | /** |
487 | \brief Return the vehicle wheel simulation flags. |
488 | |
489 | \return The values of the flags. |
490 | |
491 | @see PxVehicleWheelsSimFlag |
492 | */ |
493 | PxVehicleWheelsSimFlags getFlags() const; |
494 | |
495 | private: |
496 | |
497 | /** |
498 | \brief Graph to filter normalised load |
499 | @see setTireLoadFilterData, getTireLoadFilterData |
500 | */ |
501 | PxVehicleTireLoadFilterData mNormalisedLoadFilter; |
502 | |
503 | /** |
504 | \brief Wheels data organised in blocks of 4 wheels. |
505 | */ |
506 | PxVehicleWheels4SimData* mWheels4SimData; |
507 | |
508 | /** |
509 | \brief Number of blocks of 4 wheels. |
510 | */ |
511 | PxU32 mNbWheels4; |
512 | |
513 | /** |
514 | \brief Number of actual wheels (<=(mNbWheels4*4)) |
515 | */ |
516 | PxU32 mNbActiveWheels; |
517 | |
518 | /** |
519 | \brief Anti-roll bars |
520 | */ |
521 | PxVehicleAntiRollBarData* mAntiRollBars; |
522 | |
523 | /** |
524 | \brief 2 anti-rollbars allocated for each block of 4 wheels. |
525 | */ |
526 | PxU32 mNbAntiRollBars4; |
527 | |
528 | /** |
529 | \brief Number of active anti-roll bars. |
530 | */ |
531 | PxU32 mNbActiveAntiRollBars; |
532 | |
533 | /** |
534 | \brief Which of the mNbActiveWheels are active or disabled? |
535 | The default is that all mNbActiveWheels wheels are active. |
536 | */ |
537 | PxU32 mActiveWheelsBitmapBuffer[((PX_MAX_NB_WHEELS + 31) & ~31) >> 5]; |
538 | |
539 | /** |
540 | \brief Threshold longitudinal speed used to decide whether to use |
541 | mLowForwardSpeedSubStepCount or mHighForwardSpeedSubStepCount as the |
542 | number of sub-steps that will be peformed. |
543 | */ |
544 | PxF32 mThresholdLongitudinalSpeed; |
545 | |
546 | /** |
547 | \brief Number of sub-steps that will be performed if the longitudinal speed |
548 | of the vehicle is smaller than mThresholdLongitudinalSpeed. |
549 | */ |
550 | PxU32 mLowForwardSpeedSubStepCount; |
551 | |
552 | /** |
553 | \brief Number of sub-steps that will be performed if the longitudinal speed |
554 | of the vehicle is greater than or equal to mThresholdLongitudinalSpeed. |
555 | */ |
556 | PxU32 mHighForwardSpeedSubStepCount; |
557 | |
558 | /** |
559 | \brief Minimum long slip denominator |
560 | */ |
561 | PxF32 mMinLongSlipDenominator; |
562 | |
563 | /** |
564 | \brief The vehicle wheel simulation flags. |
565 | |
566 | @see PxVehicleWheelsSimFlags |
567 | */ |
568 | PxU32 mFlags; |
569 | |
570 | #if PX_P64_FAMILY |
571 | PxU32 mPad[1]; |
572 | #endif |
573 | |
574 | /** |
575 | \brief Test if wheel simulation data has been setup with legal values. |
576 | */ |
577 | bool isValid() const; |
578 | |
579 | /** |
580 | \brief see PxVehicleWheels::allocate |
581 | */ |
582 | static PxU32 computeByteSize(const PxU32 numWheels); |
583 | static PxU8* patchUpPointers(const PxU32 numWheels, PxVehicleWheelsSimData* simData, PxU8* ptrIn); |
584 | PxVehicleWheelsSimData(const PxU32 numWheels); |
585 | |
586 | //serialization |
587 | public: |
588 | PxVehicleWheelsSimData(const PxEMPTY) : mNormalisedLoadFilter(PxEmpty) {} |
589 | static void getBinaryMetaData(PxOutputStream& stream); |
590 | PxU32 getNbWheels4() const { return mNbWheels4; } |
591 | PxU32 getNbSuspensionData() const { return mNbActiveWheels; } |
592 | PxU32 getNbWheelData() const { return mNbActiveWheels; } |
593 | PxU32 getNbSuspTravelDirection() const { return mNbActiveWheels; } |
594 | PxU32 getNbTireData() const { return mNbActiveWheels; } |
595 | PxU32 getNbSuspForceAppPointOffset() const { return mNbActiveWheels; } |
596 | PxU32 getNbTireForceAppPointOffset() const { return mNbActiveWheels; } |
597 | PxU32 getNbWheelCentreOffset() const { return mNbActiveWheels; } |
598 | PxU32 getNbWheelShapeMapping() const { return mNbActiveWheels; } |
599 | PxU32 getNbSceneQueryFilterData() const { return mNbActiveWheels; } |
600 | PxF32 getMinLongSlipDenominator() const {return mMinLongSlipDenominator;} |
601 | void setThresholdLongSpeed(const PxF32 f) {mThresholdLongitudinalSpeed = f;} |
602 | PxF32 getThresholdLongSpeed() const {return mThresholdLongitudinalSpeed;} |
603 | void setLowForwardSpeedSubStepCount(const PxU32 f) {mLowForwardSpeedSubStepCount = f;} |
604 | PxU32 getLowForwardSpeedSubStepCount() const {return mLowForwardSpeedSubStepCount;} |
605 | void setHighForwardSpeedSubStepCount(const PxU32 f) {mHighForwardSpeedSubStepCount = f;} |
606 | PxU32 getHighForwardSpeedSubStepCount() const {return mHighForwardSpeedSubStepCount;} |
607 | void setWheelEnabledState(const PxU32 wheel, const bool state) {if(state) {enableWheel(wheel);} else {disableWheel(wheel);}} |
608 | bool getWheelEnabledState(const PxU32 wheel) const {return !getIsWheelDisabled(wheel);} |
609 | PxU32 getNbWheelEnabledState() const {return mNbActiveWheels;} |
610 | PxU32 getNbAntiRollBars4() const { return mNbAntiRollBars4; } |
611 | PxU32 getNbAntiRollBarData() const {return mNbActiveAntiRollBars;} |
612 | void setAntiRollBarData(const PxU32 id, const PxVehicleAntiRollBarData& antiRoll); |
613 | PxVehicleWheelsSimData(){} |
614 | ~PxVehicleWheelsSimData(){} |
615 | //~serialization |
616 | }; |
617 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleWheelsSimData) & 15)); |
618 | |
619 | /** |
620 | \brief Data structure with instanced dynamics data for wheels |
621 | */ |
622 | class PxVehicleWheelsDynData |
623 | { |
624 | //= ATTENTION! ===================================================================================== |
625 | // Changing the data layout of this class breaks the binary serialization format. See comments for |
626 | // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData |
627 | // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION |
628 | // accordingly. |
629 | //================================================================================================== |
630 | public: |
631 | |
632 | friend class PxVehicleWheels; |
633 | friend class PxVehicleDrive4W; |
634 | friend class PxVehicleDriveTank; |
635 | friend class PxVehicleUpdate; |
636 | |
637 | PxVehicleWheelsDynData(){} |
638 | ~PxVehicleWheelsDynData(){} |
639 | |
640 | /** |
641 | \brief Set all wheels to their rest state. |
642 | @see setup |
643 | */ |
644 | void setToRestState(); |
645 | |
646 | /** |
647 | \brief Set the tire force shader function |
648 | \param[in] tireForceShaderFn is the shader function that will be used to compute tire forces. |
649 | */ |
650 | void setTireForceShaderFunction(PxVehicleComputeTireForce tireForceShaderFn); |
651 | |
652 | /** |
653 | \brief Set the tire force shader data for a specific tire |
654 | \param[in] tireId is the wheel index |
655 | \param[in] tireForceShaderData is the data describing the tire. |
656 | */ |
657 | void setTireForceShaderData(const PxU32 tireId, const void* tireForceShaderData); |
658 | |
659 | /** |
660 | \brief Get the tire force shader data for a specific tire |
661 | */ |
662 | const void* getTireForceShaderData(const PxU32 tireId) const; |
663 | |
664 | /** |
665 | \brief Set the wheel rotation speed (radians per second) about the rolling axis for the specified wheel. |
666 | \param[in] wheelIdx is the wheel index |
667 | \param[in] speed is the rotation speed to be applied to the wheel. |
668 | */ |
669 | void setWheelRotationSpeed(const PxU32 wheelIdx, const PxReal speed); |
670 | |
671 | /** |
672 | \brief Return the rotation speed about the rolling axis of a specified wheel . |
673 | */ |
674 | PxReal getWheelRotationSpeed(const PxU32 wheelIdx) const; |
675 | |
676 | /** |
677 | \brief Set the wheel rotation angle (radians) about the rolling axis of the specified wheel. |
678 | \param[in] wheelIdx is the wheel index |
679 | \param[in] angle is the rotation angle to be applied to the wheel. |
680 | */ |
681 | void setWheelRotationAngle(const PxU32 wheelIdx, const PxReal angle); |
682 | |
683 | /** |
684 | \brief Return the rotation angle about the rolling axis for the specified wheel. |
685 | */ |
686 | PxReal getWheelRotationAngle(const PxU32 wheelIdx) const; |
687 | |
688 | /** |
689 | \brief Set the user data pointer for the specified wheel |
690 | It has a default value of NULL. |
691 | \param[in] tireIdx is the wheel index |
692 | \param[in] userData is the data to be associated with the wheel. |
693 | */ |
694 | void setUserData(const PxU32 tireIdx, void* userData); |
695 | |
696 | /** |
697 | \brief Get the user data pointer that was set for the specified wheel |
698 | */ |
699 | void* getUserData(const PxU32 tireIdx) const; |
700 | |
701 | /** |
702 | \brief Copy the dynamics data of a single wheel unit (wheel, suspension, tire) from srcWheel of src to trgWheel. |
703 | \param[in] src is the data to be copied. |
704 | \param[in] srcWheel is the wheel whose data will be copied from src. |
705 | \param[in] trgWheel is the wheel that will be assigned the copied data. |
706 | */ |
707 | void copy(const PxVehicleWheelsDynData& src, const PxU32 srcWheel, const PxU32 trgWheel); |
708 | |
709 | private: |
710 | |
711 | /** |
712 | \brief Dynamics data arranged in blocks of 4 wheels. |
713 | */ |
714 | PxVehicleWheels4DynData* mWheels4DynData; |
715 | |
716 | /** |
717 | \brief Test if wheel dynamics data have legal values. |
718 | */ |
719 | bool isValid() const; |
720 | |
721 | /** |
722 | \brief Shader data and function for tire force calculations. |
723 | */ |
724 | PxVehicleTireForceCalculator* mTireForceCalculators; |
725 | |
726 | /** |
727 | \brief A userData pointer can be stored for each wheel. |
728 | @see setUserData, getUserData |
729 | */ |
730 | void** mUserDatas; |
731 | |
732 | /** |
733 | \brief Number of blocks of 4 wheels. |
734 | */ |
735 | PxU32 mNbWheels4; |
736 | |
737 | /** |
738 | \brief Number of wheels (mNbActiveWheels <= (mNbWheels4*4)) |
739 | */ |
740 | PxU32 mNbActiveWheels; |
741 | |
742 | PxU32 mPad[3]; |
743 | |
744 | /** |
745 | \brief see PxVehicleWheels::allocate |
746 | */ |
747 | static PxU32 computeByteSize(const PxU32 numWheels); |
748 | static PxU8* patchUpPointers(const PxU32 numWheels, PxVehicleWheelsDynData* dynData, PxU8* ptr); |
749 | PxVehicleWheelsDynData(const PxU32 numWheels); |
750 | |
751 | //serialization |
752 | public: |
753 | static void getBinaryMetaData(PxOutputStream& stream); |
754 | PxU32 getNbWheelRotationSpeed() const { return mNbActiveWheels; } |
755 | PxU32 getNbWheelRotationAngle() const { return mNbActiveWheels; } |
756 | PxVehicleWheels4DynData* getWheel4DynData() const { return mWheels4DynData; } |
757 | //~serialization |
758 | |
759 | /** |
760 | \brief Retrieve the number of PxConstraint objects associated with the vehicle. |
761 | |
762 | You can use #getConstraints() to retrieve the constraint pointers. |
763 | |
764 | \return Number of constraints associated with this vehicle. |
765 | |
766 | @see PxConstraint getConstraints() |
767 | */ |
768 | PxU32 getNbConstraints() const { return mNbWheels4; } |
769 | |
770 | /** |
771 | \brief Retrieve all the PxConstraint objects associated with the vehicle. |
772 | |
773 | There is one PxConstraint per block of 4 wheels. The count can be extracted through #getNbConstraints() |
774 | |
775 | \param[out] userBuffer The buffer to store the constraint pointers. |
776 | \param[in] bufferSize Size of provided user buffer. |
777 | \param[in] startIndex Index of first constraint pointer to be retrieved |
778 | \return Number of constraint pointers written to the buffer. |
779 | |
780 | @see PxConstraint getNbConstraints() |
781 | */ |
782 | PxU32 getConstraints(PxConstraint** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const; |
783 | }; |
784 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleWheelsDynData) & 15)); |
785 | |
786 | /** |
787 | \brief Data structure with instanced dynamics data and configuration data of a vehicle with just wheels |
788 | @see PxVehicleDrive, PxVehicleDrive4W, PxVehicleDriveTank |
789 | */ |
790 | class PxVehicleWheels : public PxBase |
791 | { |
792 | //= ATTENTION! ===================================================================================== |
793 | // Changing the data layout of this class breaks the binary serialization format. See comments for |
794 | // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData |
795 | // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION |
796 | // accordingly. |
797 | //================================================================================================== |
798 | public: |
799 | |
800 | friend class PxVehicleUpdate; |
801 | friend class PxVehicleConstraintShader; |
802 | |
803 | /** |
804 | \brief Return the type of vehicle |
805 | @see PxVehicleTypes |
806 | */ |
807 | PX_FORCE_INLINE PxU32 getVehicleType() const {return mType;} |
808 | |
809 | /** |
810 | \brief Get non-const ptr to PxRigidDynamic instance that is the vehicle's physx representation |
811 | */ |
812 | PX_FORCE_INLINE PxRigidDynamic* getRigidDynamicActor() {return mActor;} |
813 | |
814 | /** |
815 | \brief Get const ptr to PxRigidDynamic instance that is the vehicle's physx representation |
816 | */ |
817 | PX_FORCE_INLINE const PxRigidDynamic* getRigidDynamicActor() const {return mActor;} |
818 | |
819 | /** |
820 | \brief Compute the rigid body velocity component along the forward vector of the rigid body transform. |
821 | @see PxVehicleSetBasisVectors |
822 | */ |
823 | PxReal computeForwardSpeed() const; |
824 | |
825 | /** |
826 | \brief Compute the rigid body velocity component along the right vector of the rigid body transform. |
827 | @see PxVehicleSetBasisVectors |
828 | */ |
829 | PxReal computeSidewaysSpeed() const; |
830 | |
831 | /** |
832 | \brief Data describing the setup of all the wheels/suspensions/tires. |
833 | */ |
834 | PxVehicleWheelsSimData mWheelsSimData; |
835 | |
836 | /** |
837 | \brief Data describing the dynamic state of all wheels/suspension/tires. |
838 | */ |
839 | PxVehicleWheelsDynData mWheelsDynData; |
840 | |
841 | protected: |
842 | |
843 | /** |
844 | \brief Set all wheels to their rest state |
845 | */ |
846 | void setToRestState(); |
847 | |
848 | /** |
849 | \brief Test that all configuration and instanced dynamics data is valid. |
850 | */ |
851 | bool isValid() const; |
852 | |
853 | /** |
854 | @see PxVehicleDrive4W::allocate, PxVehicleDriveTank::allocate |
855 | */ |
856 | static PxU32 computeByteSize(const PxU32 nbWheels); |
857 | static PxU8* patchupPointers(const PxU32 nbWheels, PxVehicleWheels* vehWheels, PxU8* ptr); |
858 | virtual void init(const PxU32 numWheels); |
859 | |
860 | /** |
861 | \brief Deallocate a PxVehicleWheels instance. |
862 | @see PxVehicleDrive4W::free, PxVehicleDriveTank::free |
863 | */ |
864 | void free(); |
865 | |
866 | /* |
867 | \brief Deferred deletion. |
868 | */ |
869 | void onConstraintRelease(); |
870 | |
871 | /** |
872 | @see PxVehicleDrive4W::setup, PxVehicleDriveTank::setup |
873 | */ |
874 | void setup |
875 | (PxPhysics* physics, PxRigidDynamic* vehActor, |
876 | const PxVehicleWheelsSimData& wheelsData, |
877 | const PxU32 nbDrivenWheels, const PxU32 nbNonDrivenWheels); |
878 | |
879 | /** |
880 | \brief The rigid body actor that represents the vehicle in the PhysX SDK. |
881 | */ |
882 | PxRigidDynamic* mActor; |
883 | |
884 | private: |
885 | |
886 | /** |
887 | \brief Count the number of constraint connectors that have hit their callback when deleting a vehicle. |
888 | Can only delete the vehicle's memory when all constraint connectors have hit their callback. |
889 | */ |
890 | PxU32 mNbNonDrivenWheels; |
891 | |
892 | PxU8 mOnConstraintReleaseCounter; |
893 | |
894 | protected: |
895 | |
896 | /** |
897 | \brief Vehicle type (eVehicleDriveTypes) |
898 | */ |
899 | PxU8 mType; |
900 | |
901 | #if PX_P64_FAMILY |
902 | PxU8 mPad0[14]; |
903 | #else |
904 | PxU8 mPad0[14]; |
905 | #endif |
906 | |
907 | //serialization |
908 | public: |
909 | virtual void requiresObjects(PxProcessPxBaseCallback& c); |
910 | virtual const char* getConcreteTypeName() const { return "PxVehicleWheels" ; } |
911 | virtual bool isKindOf(const char* name) const { return !::strcmp(s1: "PxVehicleWheels" , s2: name) || PxBase::isKindOf(superClass: name); } |
912 | virtual void preExportDataReset() {} |
913 | virtual void (PxSerializationContext&); |
914 | void (PxDeserializationContext&); |
915 | void resolveReferences(PxDeserializationContext&); |
916 | static void getBinaryMetaData(PxOutputStream& stream); |
917 | PX_FORCE_INLINE PxU32 getNbNonDrivenWheels() const { return mNbNonDrivenWheels; } |
918 | PxVehicleWheels(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} |
919 | PxVehicleWheels(PxBaseFlags baseFlags) : PxBase(baseFlags), mWheelsSimData(PxEmpty) {} |
920 | virtual ~PxVehicleWheels() {} |
921 | virtual void release() { free(); } |
922 | //~serialization |
923 | }; |
924 | PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleWheels) & 15)); |
925 | |
926 | #if !PX_DOXYGEN |
927 | } // namespace physx |
928 | #endif |
929 | |
930 | /** @} */ |
931 | #endif //PX_VEHICLE_WHEELS_H |
932 | |