1 | #ifndef NX_PHYSICS_NXACTORDESC
|
---|
2 | #define NX_PHYSICS_NXACTORDESC
|
---|
3 | /*----------------------------------------------------------------------------*\
|
---|
4 | |
|
---|
5 | | Public Interface to NovodeX Technology
|
---|
6 | |
|
---|
7 | | www.novodex.com
|
---|
8 | |
|
---|
9 | \*----------------------------------------------------------------------------*/
|
---|
10 | /** \addtogroup physics
|
---|
11 | @{
|
---|
12 | */
|
---|
13 |
|
---|
14 | #include "NxBodyDesc.h"
|
---|
15 | #include "NxShapeDesc.h"
|
---|
16 |
|
---|
17 | enum NxActorDescType
|
---|
18 | {
|
---|
19 | NX_ADT_SHAPELESS,
|
---|
20 | NX_ADT_DEFAULT,
|
---|
21 | NX_ADT_ALLOCATOR,
|
---|
22 | NX_ADT_LIST,
|
---|
23 | NX_ADT_POINTER
|
---|
24 | };
|
---|
25 |
|
---|
26 | /**
|
---|
27 | \brief Actor Descriptor. This structure is used to save and load the state of #NxActor objects.
|
---|
28 |
|
---|
29 | If the body descriptor contains a zero mass but the actor descriptor contains a non-zero density,
|
---|
30 | we compute a new mass automatically from the density and the shapes.
|
---|
31 |
|
---|
32 | Static or dynamic actors:
|
---|
33 |
|
---|
34 | \li To create a static actor, use a null body descriptor pointer(and not a body with zero mass). Shapes should
|
---|
35 | be specifyied for the static actor when it is created.
|
---|
36 | If you want to create a temporarily static actor that can be made dynamic at runtime, create your
|
---|
37 | dynamic actor as usual and use NX_BF_KINEMATIC flags in its body descriptor.
|
---|
38 |
|
---|
39 | \li To create a dynamic actor, provide a valid body descriptor with or without shape descriptors. The
|
---|
40 | shapes are not mandatory.
|
---|
41 |
|
---|
42 | Mass or density:
|
---|
43 |
|
---|
44 | To simulate a dynamic actor, the SDK needs a mass and an inertia tensor.
|
---|
45 | (The inertia tensor is the combination of bodyDesc.massLocalPose and bodyDesc.massSpaceInertia)
|
---|
46 |
|
---|
47 | These can be specified in several different ways:
|
---|
48 |
|
---|
49 | 1) actorDesc.density == 0, bodyDesc.mass > 0, bodyDesc.massSpaceInertia.magnitude() > 0
|
---|
50 |
|
---|
51 | Here the mass properties are specified explicitly, there is nothing to compute.
|
---|
52 |
|
---|
53 | 2) actorDesc.density > 0, actorDesc.shapes.size() > 0, bodyDesc.mass == 0, bodyDesc.massSpaceInertia.magnitude() == 0
|
---|
54 |
|
---|
55 | Here a density and the shapes are given. From this both the mass and the inertia tensor is computed.
|
---|
56 |
|
---|
57 | 3) actorDesc.density == 0, actorDesc.shapes.size() > 0, bodyDesc.mass > 0, bodyDesc.massSpaceInertia.magnitude() == 0
|
---|
58 |
|
---|
59 | Here a mass and shapes are given. From this the inertia tensor is computed.
|
---|
60 |
|
---|
61 | Other combinations of settings are illegal.
|
---|
62 |
|
---|
63 | When the SDK computes the inertia properties it uses the actor's shapes.
|
---|
64 | For each shape, the shape geometry, shape mass (or density), and shape positioning within the actor
|
---|
65 | are used to compute the body's mass and inertia properties.
|
---|
66 |
|
---|
67 | Setting the individual masses or densities of the shapes of an actor is the most intuitive method
|
---|
68 | to specify the mass, center of mass, and inertial properties of a multi shape actor in order to achieve
|
---|
69 | correct behavior.
|
---|
70 |
|
---|
71 | If the actor body has a mass, then the computed inertial properties of the actor are scaled to the specified body mass.
|
---|
72 | Even then, the individual shape masses are still useful since they specify how that mass is distributed within the object.
|
---|
73 | i.e. When specified, the actor/body mass properties have priority.
|
---|
74 |
|
---|
75 | If you specify a shape density and an actor density then the two are multiplied together to obtain the effective density
|
---|
76 | of the actor. So if you set the density of the actor to 2 and the density of the shape to 3 then the effective density
|
---|
77 | of that shape will be 6.
|
---|
78 |
|
---|
79 | When the sdk computes the inertial properties the default is to also compute the center of mass.
|
---|
80 | To specify an actor's center of mass exactly but still let the sdk compute and diagonalize the inertia
|
---|
81 | tensor raise NxActorDescBase::flags | NX_AF_LOCK_COM. In this case the center of mass (bodydesc.massLocalPose.t)
|
---|
82 | will not be overridden and the computed inertial tensor will be transformed correctly so that
|
---|
83 | it will be as if the volume integrals for the moments had been done from the specified point.
|
---|
84 |
|
---|
85 | The NX_AF_LOCK_COM is only considered when computing the mass properties during creation, it will
|
---|
86 | not be considered when calling NxActor::updateMassFromShapes().
|
---|
87 | */
|
---|
88 |
|
---|
89 | class NxActorDescBase
|
---|
90 | {
|
---|
91 | public:
|
---|
92 | /**
|
---|
93 | \brief The pose of the actor in the world.
|
---|
94 |
|
---|
95 | <b>Range:</b> rigid body transform<br>
|
---|
96 | <b>Default:</b> Identity Matrix
|
---|
97 |
|
---|
98 | <b>Platform:</b>
|
---|
99 | \li PC SW: Yes
|
---|
100 | \li PPU : Yes
|
---|
101 | \li PS3 : Yes
|
---|
102 | \li XB360: Yes
|
---|
103 |
|
---|
104 | @see NxActor::setGlobalPose()
|
---|
105 | */
|
---|
106 | NxMat34 globalPose;
|
---|
107 |
|
---|
108 | /**
|
---|
109 | \brief Body descriptor, null for static actors
|
---|
110 |
|
---|
111 | <b>Default:</b> NULL
|
---|
112 |
|
---|
113 | <b>Platform:</b>
|
---|
114 | \li PC SW: Yes
|
---|
115 | \li PPU : Yes
|
---|
116 | \li PS3 : Yes
|
---|
117 | \li XB360: Yes
|
---|
118 |
|
---|
119 | @see NxBodyDesc
|
---|
120 | */
|
---|
121 | const NxBodyDesc* body;
|
---|
122 |
|
---|
123 | /**
|
---|
124 | \brief Denisty used during mass/inertia computation.
|
---|
125 |
|
---|
126 | We can compute the mass from a density and the shapes mass/density.
|
---|
127 | See the notes for #NxActorDesc for more details.
|
---|
128 |
|
---|
129 | <b>Range:</b> (0,inf)<br>
|
---|
130 | <b>Default:</b> 0.0
|
---|
131 |
|
---|
132 | <b>Platform:</b>
|
---|
133 | \li PC SW: Yes
|
---|
134 | \li PPU : Yes
|
---|
135 | \li PS3 : Yes
|
---|
136 | \li XB360: Yes
|
---|
137 |
|
---|
138 | @see NxActorDesc
|
---|
139 | */
|
---|
140 | NxReal density;
|
---|
141 |
|
---|
142 | /**
|
---|
143 | \brief Combination of ::NxActorFlag flags
|
---|
144 |
|
---|
145 | <b>Default:</b> 0
|
---|
146 |
|
---|
147 | <b>Platform:</b>
|
---|
148 | \li PC SW: Yes
|
---|
149 | \li PPU : No
|
---|
150 | \li PS3 : Yes
|
---|
151 | \li XB360: Yes
|
---|
152 |
|
---|
153 | @see NxActor::raiseActorFlag()
|
---|
154 | */
|
---|
155 | NxU32 flags;
|
---|
156 |
|
---|
157 | /**
|
---|
158 | \brief The actors group.
|
---|
159 |
|
---|
160 | <b>Default:</b> 0
|
---|
161 |
|
---|
162 | <b>Platform:</b>
|
---|
163 | \li PC SW: Yes
|
---|
164 | \li PPU : No
|
---|
165 | \li PS3 : Yes
|
---|
166 | \li XB360: Yes
|
---|
167 |
|
---|
168 | @see NxActor::setGroup()
|
---|
169 | */
|
---|
170 | NxActorGroup group;
|
---|
171 |
|
---|
172 | /**
|
---|
173 | \brief Will be copied to NxActor::userData
|
---|
174 |
|
---|
175 | <b>Default:</b> NULL
|
---|
176 |
|
---|
177 | <b>Platform:</b>
|
---|
178 | \li PC SW: Yes
|
---|
179 | \li PPU : Yes
|
---|
180 | \li PS3 : Yes
|
---|
181 | \li XB360: Yes
|
---|
182 |
|
---|
183 | @see NxActor.userData
|
---|
184 | */
|
---|
185 | void* userData;
|
---|
186 |
|
---|
187 | /**
|
---|
188 | \brief Possible debug name. The string is not copied by the SDK, only the pointer is stored.
|
---|
189 |
|
---|
190 | <b>Platform:</b>
|
---|
191 | \li PC SW: Yes
|
---|
192 | \li PPU : Yes
|
---|
193 | \li PS3 : Yes
|
---|
194 | \li XB360: Yes
|
---|
195 |
|
---|
196 | <b>Default:</b> NULL
|
---|
197 | */
|
---|
198 | const char* name;
|
---|
199 |
|
---|
200 | /**
|
---|
201 | \brief constructor sets to default.
|
---|
202 | */
|
---|
203 | NX_INLINE NxActorDescBase();
|
---|
204 | /**
|
---|
205 | \brief (re)sets the structure to the default.
|
---|
206 | */
|
---|
207 | NX_INLINE void setToDefault();
|
---|
208 | /**
|
---|
209 | \brief Returns true if the descriptor is valid.
|
---|
210 |
|
---|
211 | \return True if the current settings are valid
|
---|
212 | */
|
---|
213 | NX_INLINE bool isValid() const;
|
---|
214 |
|
---|
215 | /**
|
---|
216 | \brief Retrieve the actor type.
|
---|
217 |
|
---|
218 | \return The actor desc type. See #NxActorDescType
|
---|
219 | */
|
---|
220 | NX_INLINE NxActorDescType getType() const;
|
---|
221 | protected:
|
---|
222 | NX_INLINE bool isValidInternal(bool hasShape) const;
|
---|
223 |
|
---|
224 | NxActorDescType type;
|
---|
225 | };
|
---|
226 |
|
---|
227 | /**
|
---|
228 | \brief Actor Descriptor. This structure is used to save and load the state of #NxActor objects.
|
---|
229 |
|
---|
230 | Legacy implementation that works with existing code but does not permit the user
|
---|
231 | to supply his own allocator for NxArray<NxShapeDesc*> shapes.
|
---|
232 | */
|
---|
233 | class NxActorDesc : public NxActorDescBase
|
---|
234 | {
|
---|
235 | public:
|
---|
236 |
|
---|
237 | /**
|
---|
238 | \brief Shapes composing the actor.
|
---|
239 |
|
---|
240 | Shapes should always be specified for static actors during creation. However it is optional for dynamic actors.
|
---|
241 |
|
---|
242 | <b>Default:</b> empty
|
---|
243 |
|
---|
244 | <b>Platform:</b>
|
---|
245 | \li PC SW: Yes
|
---|
246 | \li PPU : Yes
|
---|
247 | \li PS3 : Yes
|
---|
248 | \li XB360: Yes
|
---|
249 | */
|
---|
250 | NxArray<NxShapeDesc*> shapes;
|
---|
251 |
|
---|
252 | /**
|
---|
253 | \brief constructor sets to default.
|
---|
254 | */
|
---|
255 | NX_INLINE NxActorDesc();
|
---|
256 | /**
|
---|
257 | \brief (re)sets the structure to the default.
|
---|
258 | */
|
---|
259 | NX_INLINE void setToDefault();
|
---|
260 | /**
|
---|
261 | \brief Returns true if the descriptor is valid.
|
---|
262 |
|
---|
263 | \return True if the current settings are valid
|
---|
264 | */
|
---|
265 | NX_INLINE bool isValid() const;
|
---|
266 | };
|
---|
267 |
|
---|
268 | /**
|
---|
269 | \brief Implementation of an actor descriptor that permits the user to supply his own allocator
|
---|
270 | */
|
---|
271 | template<class AllocType = NxAllocatorDefault> class NxActorDesc_Template : public NxActorDescBase
|
---|
272 | {
|
---|
273 | public:
|
---|
274 |
|
---|
275 | /**
|
---|
276 | \brief Shapes composing the actor
|
---|
277 |
|
---|
278 | Shapes should always be specified for static actors during creation. However it is optional for dynamic actors.
|
---|
279 |
|
---|
280 | <b>Default:</b> empty
|
---|
281 | */
|
---|
282 | NxArray<NxShapeDesc*, AllocType> shapes;
|
---|
283 |
|
---|
284 |
|
---|
285 |
|
---|
286 | NX_INLINE NxActorDesc_Template()
|
---|
287 | {
|
---|
288 | setToDefault();
|
---|
289 | type = NX_ADT_ALLOCATOR;
|
---|
290 | }
|
---|
291 |
|
---|
292 | NX_INLINE void setToDefault()
|
---|
293 | {
|
---|
294 | NxActorDescBase::setToDefault();
|
---|
295 | shapes.clear();
|
---|
296 | }
|
---|
297 |
|
---|
298 | NX_INLINE bool isValid() const
|
---|
299 | {
|
---|
300 | if (!NxActorDescBase::isValid())
|
---|
301 | return false;
|
---|
302 | for (unsigned i = 0; i < shapes.size(); i++)
|
---|
303 | if (!shapes[i]->isValid())
|
---|
304 | return false;
|
---|
305 |
|
---|
306 | if (!NxActorDescBase::isValidInternal(shapes.size() > 0))
|
---|
307 | return false;
|
---|
308 |
|
---|
309 | return true;
|
---|
310 | }
|
---|
311 |
|
---|
312 |
|
---|
313 | };
|
---|
314 |
|
---|
315 |
|
---|
316 |
|
---|
317 | NX_INLINE NxActorDescBase::NxActorDescBase()
|
---|
318 | {
|
---|
319 | //nothing! Don't call setToDefault() here!
|
---|
320 | }
|
---|
321 |
|
---|
322 |
|
---|
323 | NX_INLINE void NxActorDescBase::setToDefault()
|
---|
324 | {
|
---|
325 | body = NULL;
|
---|
326 | density = 0.0f;
|
---|
327 | globalPose .id();
|
---|
328 | flags = 0;
|
---|
329 | userData = NULL;
|
---|
330 | name = NULL;
|
---|
331 | group = 0;
|
---|
332 | }
|
---|
333 |
|
---|
334 | NX_INLINE bool NxActorDescBase::isValid() const
|
---|
335 | {
|
---|
336 | if (density < 0)
|
---|
337 | return false;
|
---|
338 |
|
---|
339 | if (body && !body->isValid())
|
---|
340 | return false;
|
---|
341 | if(!globalPose.isFinite())
|
---|
342 | return false;
|
---|
343 |
|
---|
344 | return true;
|
---|
345 | }
|
---|
346 |
|
---|
347 | NX_INLINE NxActorDescType NxActorDescBase::getType() const
|
---|
348 | {
|
---|
349 | return type;
|
---|
350 | }
|
---|
351 |
|
---|
352 | NX_INLINE bool NxActorDescBase::isValidInternal(bool haveShape) const
|
---|
353 | {
|
---|
354 | bool haveDensity = density!=0.0f;
|
---|
355 | bool haveMass = body && body->mass != 0.0f;
|
---|
356 | bool haveTensor = body && !(body->massSpaceInertia.isZero() > 0.0f);
|
---|
357 |
|
---|
358 | if (haveShape && !body)
|
---|
359 | return true;
|
---|
360 | if (haveShape && haveDensity && !haveMass && !haveTensor) return true;
|
---|
361 | else if (haveShape && !haveDensity && haveMass && !haveTensor) return true;
|
---|
362 | else if (!haveDensity && haveMass && haveTensor) return true;
|
---|
363 | else return false;
|
---|
364 | }
|
---|
365 |
|
---|
366 |
|
---|
367 |
|
---|
368 |
|
---|
369 | NX_INLINE NxActorDesc::NxActorDesc()
|
---|
370 | {
|
---|
371 | memset(this,0,sizeof(NxActorDesc));
|
---|
372 | setToDefault();
|
---|
373 | type = NX_ADT_DEFAULT;
|
---|
374 | }
|
---|
375 |
|
---|
376 | NX_INLINE void NxActorDesc::setToDefault()
|
---|
377 | {
|
---|
378 | NxActorDescBase::setToDefault();
|
---|
379 | shapes .clear();
|
---|
380 | }
|
---|
381 |
|
---|
382 | NX_INLINE bool NxActorDesc::isValid() const
|
---|
383 | {
|
---|
384 | if (!NxActorDescBase::isValid())
|
---|
385 | return false;
|
---|
386 |
|
---|
387 | for (unsigned i = 0; i < shapes.size(); i++)
|
---|
388 | if (!shapes[i]->isValid())
|
---|
389 | return false;
|
---|
390 |
|
---|
391 |
|
---|
392 | if (!NxActorDescBase::isValidInternal(shapes.size() > 0))
|
---|
393 | return false;
|
---|
394 |
|
---|
395 | return true;
|
---|
396 | }
|
---|
397 | /** @} */
|
---|
398 | #endif
|
---|
399 |
|
---|
400 |
|
---|
401 | //AGCOPYRIGHTBEGIN
|
---|
402 | ///////////////////////////////////////////////////////////////////////////
|
---|
403 | // Copyright © 2005 AGEIA Technologies.
|
---|
404 | // All rights reserved. www.ageia.com
|
---|
405 | ///////////////////////////////////////////////////////////////////////////
|
---|
406 | //AGCOPYRIGHTEND
|
---|
407 |
|
---|