RavEngine
Loading...
Searching...
No Matches
PxVehicleComponentSequence.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2008-2022 NVIDIA Corporation. All rights reserved.
26// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
27// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
28
29#pragma once
33#include "foundation/PxAssert.h"
34#include "foundation/PxErrors.h"
35#include "foundation/PxFoundation.h"
36#include "PxVehicleComponent.h"
37
38#if !PX_DOXYGEN
39namespace physx
40{
41namespace vehicle2
42{
43#endif
44
45
47{
48 enum Enum
49 {
50 eMAX_NB_SUBGROUPS = 16,
51 eMAX_NB_COMPONENTS = 64,
52 eMAX_NB_SUBGROUPELEMENTS = eMAX_NB_SUBGROUPS + eMAX_NB_COMPONENTS
53 };
54};
55
57{
58 enum
59 {
60 eINVALID_SUBSTEP_GROUP = 0xff
61 };
62
64 : mNbComponents(0), mNbSubgroups(1), mNbSubGroupElements(0), mActiveSubgroup(0)
65 {
66 }
67
74 PX_FORCE_INLINE bool add(PxVehicleComponent* component);
75
88 PX_FORCE_INLINE PxU8 beginSubstepGroup(const PxU8 nbSubSteps = 1);
89
97 {
98 mActiveSubgroup = mSubGroups[mActiveSubgroup].parentGroup;
99 }
100
108 void setSubsteps(const PxU8 subGroupHandle, const PxU8 nbSteps)
109 {
110 PX_ASSERT(subGroupHandle < mNbSubgroups);
111 mSubGroups[subGroupHandle].nbSteps = nbSteps;
112 }
113
122 void update(const PxReal dt, const PxVehicleSimulationContext& context)
123 {
124 PX_ASSERT(0 == mActiveSubgroup);
125
126 if (dt > 0.0f)
127 {
128 updateSubGroup(dt, context, 0, 1);
129 }
130 else
131 {
132 PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__,
133 "PxVehicleComponentSequence::update: The timestep must be positive!");
134 }
135 }
136
137private:
138 enum
139 {
140 eINVALID_COMPONENT = 0xff,
141 eINVALID_SUB_GROUP_ELEMENT = 0xff
142 };
143
144 //Elements have the form of a linked list to allow traversal over a list of elements.
145 //Each element is either a single component or a subgroup.
146 struct SubGroupElement
147 {
148 SubGroupElement()
149 : childGroup(eINVALID_SUBSTEP_GROUP),
150 component(eINVALID_COMPONENT),
151 nextElement(eINVALID_SUB_GROUP_ELEMENT)
152 {
153 }
154
155 PxU8 childGroup;
156 PxU8 component;
157 PxU8 nextElement;
158 };
159
160 //A group is a linked list of elements to be processed in sequence.
161 //Each group stores the first element in the sequence.
162 //Each element in the sequence stores the next element in the sequence
163 //to allow traversal over the list of elements in the group.
164 struct Group
165 {
166 Group()
167 : parentGroup(eINVALID_SUBSTEP_GROUP),
168 firstElement(eINVALID_SUB_GROUP_ELEMENT),
169 nbSteps(1)
170 {
171 }
172 PxU8 parentGroup;
173 PxU8 firstElement;
174 PxU8 nbSteps;
175 };
176
177 PxVehicleComponent* mComponents[PxVehicleComponentSequenceLimits::eMAX_NB_COMPONENTS];
178 PxU8 mNbComponents;
179
180 Group mSubGroups[PxVehicleComponentSequenceLimits::eMAX_NB_SUBGROUPS];
181 PxU8 mNbSubgroups;
182
183 SubGroupElement mSubGroupElements[PxVehicleComponentSequenceLimits::eMAX_NB_SUBGROUPELEMENTS];
184 PxU8 mNbSubGroupElements;
185
186 PxU8 mActiveSubgroup;
187
188 bool updateSubGroup(const PxReal dt, const PxVehicleSimulationContext& context, const PxU8 groupId, const PxU8 parentSepMultiplier)
189 {
190 const PxU8 nbSteps = mSubGroups[groupId].nbSteps;
191 const PxU8 stepMultiplier = parentSepMultiplier * nbSteps;
192 const PxReal timestepForGroup = dt / PxReal(stepMultiplier);
193 for (PxU8 k = 0; k < nbSteps; k++)
194 {
195 PxU8 nextElement = mSubGroups[groupId].firstElement;
196 while (eINVALID_SUB_GROUP_ELEMENT != nextElement)
197 {
198 const SubGroupElement& e = mSubGroupElements[nextElement];
199 PX_ASSERT(e.component != eINVALID_COMPONENT || e.childGroup != eINVALID_SUBSTEP_GROUP);
200 if (eINVALID_COMPONENT != e.component)
201 {
202 PxVehicleComponent* c = mComponents[e.component];
203 if (!c->update(timestepForGroup, context))
204 return false;
205 }
206 else
207 {
208 PX_ASSERT(eINVALID_SUBSTEP_GROUP != e.childGroup);
209 if (!updateSubGroup(dt, context, e.childGroup, stepMultiplier))
210 return false;
211 }
212 nextElement = e.nextElement;
213 }
214 }
215
216 return true;
217 }
218
219 PxU8 getLastKnownElementInGroup(const PxU8 groupId) const
220 {
221 PxU8 currElement = mSubGroups[groupId].firstElement;
222 PxU8 nextElement = mSubGroups[groupId].firstElement;
223 while (nextElement != eINVALID_SUB_GROUP_ELEMENT)
224 {
225 currElement = nextElement;
226 nextElement = mSubGroupElements[nextElement].nextElement;
227 }
228 return currElement;
229 }
230};
231
232
234{
235 if (PxVehicleComponentSequenceLimits::eMAX_NB_COMPONENTS == mNbComponents)
236 return false;
237 if (PxVehicleComponentSequenceLimits::eMAX_NB_SUBGROUPELEMENTS == mNbSubGroupElements)
238 return false;
239
240 //Create a new element and point it at the component.
241 SubGroupElement& nextElementInGroup = mSubGroupElements[mNbSubGroupElements];
242 nextElementInGroup.childGroup = eINVALID_SUBSTEP_GROUP;
243 nextElementInGroup.component = mNbComponents;
244 nextElementInGroup.nextElement = eINVALID_SUB_GROUP_ELEMENT;
245
246 if (eINVALID_SUB_GROUP_ELEMENT == mSubGroups[mActiveSubgroup].firstElement)
247 {
248 //The group is empty so add the first element to it.
249 //Point the group at the new element because this will
250 //be the first element in the group.
251 mSubGroups[mActiveSubgroup].firstElement = mNbSubGroupElements;
252 }
253 else
254 {
255 //We are extending the sequence of element of the group.
256 //Add the new element to the end of the group's sequence.
257 mSubGroupElements[getLastKnownElementInGroup(mActiveSubgroup)].nextElement = mNbSubGroupElements;
258 }
259
260 //Increment the number of elements.
261 mNbSubGroupElements++;
262
263 //Record the component and increment the number of components.
264 mComponents[mNbComponents] = c;
265 mNbComponents++;
266
267 return true;
268}
269
271{
272 if (mNbSubgroups == PxVehicleComponentSequenceLimits::eMAX_NB_SUBGROUPS)
273 return eINVALID_SUBSTEP_GROUP;
274 if (mNbSubGroupElements == PxVehicleComponentSequenceLimits::eMAX_NB_SUBGROUPELEMENTS)
275 return eINVALID_SUBSTEP_GROUP;
276
277 //We have a parent and child group relationship.
278 const PxU8 parentGroup = mActiveSubgroup;
279 const PxU8 childGroup = mNbSubgroups;
280
281 //Set up the child group.
282 mSubGroups[childGroup].parentGroup = parentGroup;
283 mSubGroups[childGroup].firstElement = eINVALID_SUB_GROUP_ELEMENT;
284 mSubGroups[childGroup].nbSteps = nbSubSteps;
285
286 //Create a new element to add to the parent group and point it at the child group.
287 SubGroupElement& nextElementIInGroup = mSubGroupElements[mNbSubGroupElements];
288 nextElementIInGroup.childGroup = childGroup;
289 nextElementIInGroup.nextElement = eINVALID_SUB_GROUP_ELEMENT;
290 nextElementIInGroup.component = eINVALID_COMPONENT;
291
292 //Add the new element to the parent group.
293 if (eINVALID_SUB_GROUP_ELEMENT == mSubGroups[parentGroup].firstElement)
294 {
295 //The parent group is empty so add the first element to it.
296 //Point the parent group at the new element because this will
297 //be the first element in the group.
298 mSubGroups[parentGroup].firstElement = mNbSubGroupElements;
299 }
300 else
301 {
302 //We are extending the sequence of elements of the parent group.
303 //Add the new element to the end of the group's sequence.
304 mSubGroupElements[getLastKnownElementInGroup(parentGroup)].nextElement = mNbSubGroupElements;
305 }
306
307 //Push the active group.
308 //All subsequent operations will now address the child group and we push or pop the group.
309 mActiveSubgroup = childGroup;
310
311 //Increment the number of elements.
312 mNbSubGroupElements++;
313
314 //Increment the number of groups.
315 mNbSubgroups++;
316
317 //Return the group id.
318 return mActiveSubgroup;
319}
320
321#if !PX_DOXYGEN
322} // namespace vehicle2
323} // namespace physx
324#endif
325
Definition base.h:1940
Definition PxVehicleComponent.h:45
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
PX_C_EXPORT PX_FOUNDATION_API physx::PxFoundation &PX_CALL_CONV PxGetFoundation()
Retrieves the Foundation SDK after it has been created.
Definition FdFoundation.cpp:279
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
@ eINVALID_PARAMETER
method called with invalid parameter(s)
Definition PxErrors.h:62
Definition PxVehicleComponentSequence.h:47
Definition PxVehicleComponentSequence.h:57
PX_FORCE_INLINE bool add(PxVehicleComponent *component)
Add a component to the sequence.
Definition PxVehicleComponentSequence.h:233
PX_FORCE_INLINE PxU8 beginSubstepGroup(const PxU8 nbSubSteps=1)
Start a substepping group.
Definition PxVehicleComponentSequence.h:270
void update(const PxReal dt, const PxVehicleSimulationContext &context)
Update each component in the sequence.
Definition PxVehicleComponentSequence.h:122
void setSubsteps(const PxU8 subGroupHandle, const PxU8 nbSteps)
Set the number of substeps to perform for a specific substepping group.
Definition PxVehicleComponentSequence.h:108
PX_FORCE_INLINE void endSubstepGroup()
End a substepping group.
Definition PxVehicleComponentSequence.h:96
Definition PxVehicleParams.h:672