source: GTP/trunk/App/Games/Jungle_Rumble/src/physic/physics/include/NxContactStreamIterator.h @ 1378

Revision 1378, 13.4 KB checked in by giegl, 18 years ago (diff)

GTPD - Jungle Rumble - integrate into GTP SVN structure

Line 
1#ifndef NX_PHYSICS_NXCONTACTSTREAMITERATOR
2#define NX_PHYSICS_NXCONTACTSTREAMITERATOR
3/*----------------------------------------------------------------------------*\
4|
5|                                               Public Interface to NovodeX Technology
6|
7|                                                            www.novodex.com
8|
9\*----------------------------------------------------------------------------*/
10/** \addtogroup physics
11  @{
12*/
13
14#include "Nxp.h"
15
16class NxShape;
17
18typedef NxU32 * NxContactStream;
19typedef const NxU32 * NxConstContactStream;
20
21
22/**
23\brief Flags which describe a contact
24
25@see NxContactStreamIterator
26*/
27enum NxShapePairStreamFlags
28        {
29        NX_SF_HAS_MATS_PER_POINT                = (1<<0),       //!< used when we have materials per triangle in a mesh. In this case the extData field is used after the point separation value.
30        NX_SF_IS_INVALID                                = (1<<1),       //!< this pair was invalidated in the system after being generated. The user should ignore these pairs.
31        NX_SF_HAS_FEATURES_PER_POINT    = (1<<2),       //!< the stream includes per-point feature data
32        //note: bits 8-15 are reserved for internal use (static ccd pullback counter)
33        };
34
35/**
36\brief NxContactStreamIterator is for iterating through packed contact streams.
37
38<p>The user code to use this iterator looks like this:
39\code
40void MyUserContactInfo::onContactNotify(NxPair & pair, NxU32 events)
41        {
42        NxContactStreamIterator i(pair.stream);
43       
44        while(i.goNextPair()) // user can call getNumPairs() here
45                {
46                while(i.goNextPatch()) // user can also call getShape() and getNumPatches() here
47                        {
48                        while(i.goNextPoint()) //user can also call getPatchNormal() and getNumPoints() here
49                                {
50                                //user can also call getPoint() and getSeparation() here
51                                }
52                        }
53                }
54        }
55\endcode
56</p>
57
58\note It is NOT OK to skip any of the iteration calls. For example, you may NOT put a break or a continue
59statement in any of the above blocks, short of completely aborting the iteration and deleting the
60NxContactStreamIterator object.
61
62\note The user should not rely on the exact geometry or positioning of contact points. The SDK is free
63to re-organise, merge or move contact points as long as the overall physical simulation is not affected.</p>
64
65If the stream was received from a NxFluidContactPair then some iterator methods work slightly
66different (see comments to the methods below).
67
68<h3>Visulizations:</h3>
69\li #NX_VISUALIZE_CONTACT_POINT
70\li #NX_VISUALIZE_CONTACT_NORMAL
71\li #NX_VISUALIZE_CONTACT_ERROR
72\li #NX_VISUALIZE_CONTACT_FORCE
73
74<b>Platform:</b>
75        \li PC SW: Yes
76        \li PPU  : No (Hardware does not support contact stream readback)
77        \li PS3  : Yes
78        \li XB360: Yes
79
80@see NxConstContactStream NxUserContactReport
81*/
82
83class NxContactStreamIterator
84        {
85        public:
86        /**
87        \brief Starts the iteration, and returns the number of pairs.
88
89        \param[in] stream
90
91        @see NxConstContactStream
92        */
93        NX_INLINE NxContactStreamIterator(NxConstContactStream stream);
94
95//iteration:
96
97
98        /**
99        \brief Goes on to the next pair, silently skipping invalid pairs.
100       
101        Returns false if there are no more pairs. Note that getNumPairs() also includes invalid pairs in the count.
102       
103        Once goNextPoint() returns false, the user should not call it again.
104
105        \return True if there are more pairs.
106
107        @see getNumPairs() getShape()
108        */
109        NX_INLINE bool goNextPair();   
110
111        /**
112        \brief Goes on to the next patch (contacts with the same normal).
113       
114        Returns false if there are no more. Once goNextPatch() returns false, the user should
115        not call it again until they move to the next pair.
116
117        \return True if there are more patches.
118
119        @see getPatchNormal()
120        */
121        NX_INLINE bool goNextPatch();
122
123        /**
124        \brief Goes on to the next contact point.
125       
126        Returns false if there are no more. Once goNextPoint() returns false, the user should
127        not call it again unil they move to the next patch.
128
129        \return True if there are more contact points.
130
131        @see getPoint()
132        */
133        NX_INLINE bool goNextPoint();
134
135//accessors:
136
137        /**
138        \brief Returns the number of pairs in the structure.
139       
140        May be called at any time.
141       
142        \note Some of these pairs may be marked invalid using getShapeFlags() & NX_SF_IS_INVALID,
143        so the effective number may be lower. goNextPair() will automatically skip these!
144       
145        \return The number of pairs in the struct (including invalid pairs).
146
147        @see goNextPair()
148        */
149        NX_INLINE NxU32 getNumPairs();
150
151        /**
152        \brief Retrieves the shapes for the current pair.
153       
154        May be called after goNextPair() returned true. ShapeIndex is 0 or 1.
155
156        Fluid actor contact stream: getShape(1) always returns NULL.
157
158        \param[in] shapeIndex Used to choose which of the pair of shapes to retrieve(set to 0 or 1).
159        \return The shape specified by shapeIndex.
160
161        @see goNextPair() NxShape
162        */
163        NX_INLINE NxShape * getShape(NxU32 shapeIndex);
164
165        /**
166        \brief Retrieves the shape flags for the current pair.
167       
168        May be called after goNextPair() returned true
169
170        /return The shape flags for the current pair. See #NxShapeFlag.
171
172        @see NxShapeFlag NxShape goNextPair()
173        */
174        NX_INLINE NxU16 getShapeFlags();
175
176        /**
177        \brief Retrieves the number of patches for the current pair.
178       
179        May be called after goNextPair() returned true
180
181        /return The number of patches in this pair.
182
183        @see goNextPatch()
184        */
185        NX_INLINE NxU32 getNumPatches();
186
187        /**
188        \brief Retrieves the number of remaining patches.
189       
190        May be called after goNextPair() returned true
191
192        \return The number of patches remaining in this pair.
193
194        @see goNextPatch() getNumPatches()
195        */
196        NX_INLINE NxU32 getNumPatchesRemaining();
197
198        /**
199        \brief Retrieves the patch normal.
200       
201        May be called after goNextPatch() returned true
202
203        \return The patch normal.
204
205        @see goNextPatch()
206        */
207        NX_INLINE const NxVec3 & getPatchNormal();
208
209        /**
210        \brief Retrieves the number of points in the current patch.
211       
212        May be called after goNextPatch() returned true
213
214        \return The number of points in the current patch.
215
216        @see goNextPoint() getNumPointsRemaining()
217        */
218        NX_INLINE NxU32 getNumPoints();
219
220        /**
221        \brief Retrieves the number of points remaining in the current patch.
222       
223        May be called after goNextPatch() returned true
224
225        \return The number of points remaining in the current patch.
226
227        @see goNextPoint() getNumPoints()
228        */
229        NX_INLINE NxU32 getNumPointsRemaining();
230
231        /**
232        \brief Returns the contact point position.
233       
234        May be called after goNextPoint() returned true
235       
236        Fluid actor contact stream: If getShapeFlags()&NX_SF_HAS_FEATURES_PER_POINT is specified, this returns
237        the barycentric coordinates within the contact triangle. In this case the z coordinate is 0.0.
238
239        \return the current contact point (or in the case of fluids the barycentric coordinate)
240
241        @see getShapeFlags() goNextPoint() getNumPoints() getSeparation() getFeatureIndex0()
242        */
243        NX_INLINE const NxVec3 & getPoint();
244       
245        /**
246        \brief Return the separation for the contact point.
247
248        May be called after goNextPoint() returned true
249       
250        Fluid actor contact stream: always returns 0.0f.
251
252        \return the seperation distance for the current point.
253
254        @see goNextPoint() getPoint()
255        */
256        NX_INLINE NxReal getSeparation();
257
258        /**
259        \brief Retrieves the feature index.
260
261        May be called after goNextPoint() returned true
262        If getShapeFlags()&NX_SF_HAS_FEATURES_PER_POINT is specified, this method returns a feature belonging to shape 0,
263       
264        Fluid actor contact stream: returns the triangle index if shape 0 is a mesh shape.
265
266        \return The feature index on shape 0 for the current point.
267
268        @see NX_SF_FEATURE_INDICES goNextPoint() getPoint() getSeparation() getFeatureIndex1()
269        */
270        NX_INLINE NxU32 getFeatureIndex0();
271
272        /**
273        \brief Retrieves the feature index.
274
275        may be called after goNextPoint() returned true
276        If getShapeFlags()&NX_SF_HAS_FEATURES_PER_POINT is specified, this method returns a feature belonging to shape 1,
277       
278        Fluid actor contact stream: always returns 0.0f.
279
280        \return The feature index on shape1 for the current point.
281
282        @see NX_SF_FEATURE_INDICES goNextPoint() getPoint() getSeparation() getFeatureIndex0()
283        */
284        NX_INLINE NxU32 getFeatureIndex1();
285
286       
287        /**
288        \brief Internal.
289        */
290        NX_INLINE NxU32 getExtData();
291       
292        /**
293        \brief Retrieves the point normal force.
294
295        May be called after goNextPoint() returned true
296
297        If getShapeFlags()&NX_SF_POINT_CONTACT_FORCE is true (this is the case if this flag is raised for either shape in the pair),
298        this method returns the contact force at this contact point.
299        Returns 0 otherwise.
300
301        \return The contact force for the current point.
302
303        @see getShapeFlags goNextPoint() getPoint()
304        */
305        NX_INLINE NxReal getPointNormalForce();
306
307        private:
308        //iterator variables -- are only initialized by stream iterator calls:
309        //Note: structs are used so that we can leave the iterators vars on the stack as they were
310        //and the user's iteration code doesn't have to change when we add members.
311
312        NxU32 numPairs;
313        //current pair properties:
314        NxShape * shapes[2];
315        NxU16 shapeFlags;
316        NxU16 numPatches;
317        //current patch properties:
318        const NxVec3 * patchNormal;
319        NxU32  numPoints;
320        //current point properties:
321        const NxVec3 * point;
322        NxReal separation;
323        NxU32 featureIndex0;
324        NxU32 featureIndex1;
325        NxU32 extData;                                          //only exists if (shapeFlags & NX_SF_HAS_MATS_PER_POINT)
326
327        NxU32 numPairsRemaining, numPatchesRemaining, numPointsRemaining;
328        protected:
329        const NxReal * pointNormalForce;        //only exists if (shapeFlags & NX_SF_POINT_CONTACT_FORCE)
330        NxConstContactStream stream;
331        };
332
333NX_INLINE NxContactStreamIterator::NxContactStreamIterator(NxConstContactStream s)
334        {
335        stream = s;
336        numPairsRemaining = numPairs = stream ? *stream++ : 0;
337        }
338
339NX_INLINE NxU32 NxContactStreamIterator::getNumPairs()
340        {
341        return numPairs;
342        }
343
344NX_INLINE NxShape * NxContactStreamIterator::getShape(NxU32 shapeIndex)
345        {
346        NX_ASSERT(shapeIndex<=1);
347        return shapes[shapeIndex];
348        }
349
350NX_INLINE NxU16 NxContactStreamIterator::getShapeFlags()
351        {
352        return shapeFlags;
353        }
354
355NX_INLINE NxU32 NxContactStreamIterator::getNumPatches()
356        {
357        return numPatches;
358        }
359
360NX_INLINE NxU32 NxContactStreamIterator::getNumPatchesRemaining()
361        {
362        return numPatchesRemaining;
363        }
364
365NX_INLINE const NxVec3 & NxContactStreamIterator::getPatchNormal()
366        {
367        return *patchNormal;
368        }
369
370NX_INLINE NxU32 NxContactStreamIterator::getNumPoints()
371        {
372        return numPoints;
373        }
374
375NX_INLINE NxU32 NxContactStreamIterator::getNumPointsRemaining()
376        {
377        return numPointsRemaining;
378        }
379
380NX_INLINE const NxVec3 & NxContactStreamIterator::getPoint()
381        {
382        return *point;
383        }
384
385NX_INLINE NxReal NxContactStreamIterator::getSeparation()
386        {
387        return separation;
388        }
389
390NX_INLINE NxU32 NxContactStreamIterator::getFeatureIndex0()
391        {
392        return featureIndex0;
393        }
394NX_INLINE NxU32 NxContactStreamIterator::getFeatureIndex1()
395        {
396        return featureIndex1;
397        }
398
399NX_INLINE NxU32 NxContactStreamIterator::getExtData()
400        {
401        return extData;
402        }
403
404NX_INLINE NxReal NxContactStreamIterator::getPointNormalForce()
405        {
406        return pointNormalForce ? *pointNormalForce : 0;
407        }
408
409NX_INLINE bool NxContactStreamIterator::goNextPair()
410        {
411        while (numPairsRemaining--)
412                {
413#ifdef NX32
414                size_t bin0 = *stream++;
415                size_t bin1 = *stream++;
416                shapes[0] = (NxShape*)bin0;
417                shapes[1] = (NxShape*)bin1;
418//              shapes[0] = (NxShape*)*stream++;
419//              shapes[1] = (NxShape*)*stream++;
420#else
421                NxU64 low = (NxU64)*stream++;
422                NxU64 high = (NxU64)*stream++;
423                NxU64 bits = low|(high<<32);
424                shapes[0] = (NxShape*)bits;
425                low = (NxU64)*stream++;
426                high = (NxU64)*stream++;
427                bits = low|(high<<32);
428                shapes[1] = (NxShape*)bits;
429#endif
430                NxU32 t = *stream++;
431                numPatchesRemaining = numPatches = t & 0xffff;
432                shapeFlags = t >> 16;
433
434                if (!(shapeFlags & NX_SF_IS_INVALID))
435                        {
436                        return true;
437                        }
438                else
439                        {
440                        while(goNextPatch())
441                                {
442                                while(goNextPoint())
443                                        ;
444                                }
445                        }
446
447                }
448        return false;
449        }
450
451NX_INLINE bool NxContactStreamIterator::goNextPatch()
452        {
453        if (numPatchesRemaining--)
454                {
455                patchNormal = reinterpret_cast<const NxVec3 *>(stream);
456                stream += 3;
457                numPointsRemaining = numPoints = *stream++;
458                return true;
459                }
460        else
461                return false;
462        }
463
464NX_INLINE bool NxContactStreamIterator::goNextPoint()
465        {
466        if (numPointsRemaining--)
467                {
468                // Get contact point
469                point = reinterpret_cast<const NxVec3 *>(stream);
470                stream += 3;
471
472                // Get separation
473                NxU32 binary = *stream++;
474                NxU32 is32bits = binary & NX_SIGN_BITMASK;
475                binary |= NX_SIGN_BITMASK;      // PT: separation is always negative, but the sign bit is used
476                                                                        // for other purposes in the stream.
477                separation = NX_FR(binary);
478
479                // Get extra data
480                if (shapeFlags & NX_SF_HAS_MATS_PER_POINT)
481                        extData = *stream++;
482                else
483                        extData = 0xffffffff;   //means that there is no ext data.
484
485                if (shapeFlags & NX_SF_POINT_CONTACT_FORCE)
486                        pointNormalForce = reinterpret_cast<const NxReal *>(stream++);
487                else
488                        pointNormalForce = 0;   //there is no contact force.
489
490
491                if (shapeFlags & NX_SF_HAS_FEATURES_PER_POINT)
492                        {
493                        if(is32bits)
494                                {
495                                featureIndex0 = *stream++;
496                                featureIndex1 = *stream++;
497                                }
498                        else
499                                {
500                                featureIndex0 = *stream++;
501                                featureIndex1 = featureIndex0>>16;
502                                featureIndex0 &= 0xffff;
503                                }
504                        }
505                else
506                        {
507                        featureIndex0 = 0xffffffff;
508                        featureIndex1 = 0xffffffff;
509                        }
510
511                //bind = *stream++;
512                //materialIDs[0] = bind & 0xffff;
513                //materialIDs[1] = bind >> 16;
514
515                return true;
516                }
517        else
518                return false;
519        }
520
521/** @} */
522#endif
523
524
525//AGCOPYRIGHTBEGIN
526///////////////////////////////////////////////////////////////////////////
527// Copyright © 2005 AGEIA Technologies.
528// All rights reserved. www.ageia.com
529///////////////////////////////////////////////////////////////////////////
530//AGCOPYRIGHTEND
531
Note: See TracBrowser for help on using the repository browser.