Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Extras / CDTestFramework / Opcode / OPC_RayCollider.h
1 /*
2  *      OPCODE - Optimized Collision Detection
3  * http://www.codercorner.com/Opcode.htm
4  * 
5  * Copyright (c) 2001-2008 Pierre Terdiman,  pierre@codercorner.com
6
7 This software is provided 'as-is', without any express or implied warranty.
8 In no event will the authors be held liable for any damages arising from the use of this software.
9 Permission is granted to anyone to use this software for any purpose, 
10 including commercial applications, and to alter it and redistribute it freely, 
11 subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
14 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
15 3. This notice may not be removed or altered from any source distribution.
16 */
17
18 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
19 /**
20  *      Contains code for a ray collider.
21  *      \file           OPC_RayCollider.h
22  *      \author         Pierre Terdiman
23  *      \date           June, 2, 2001
24  */
25 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
26
27 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
28 // Include Guard
29 #ifndef __OPC_RAYCOLLIDER_H__
30 #define __OPC_RAYCOLLIDER_H__
31
32         class OPCODE_API CollisionFace
33         {
34                 public:
35                 //! Constructor
36                 inline_                         CollisionFace()                 {}
37                 //! Destructor
38                 inline_                         ~CollisionFace()                {}
39
40                                 udword          mFaceID;                                //!< Index of touched face
41                                 float           mDistance;                              //!< Distance from collider to hitpoint
42                                 float           mU, mV;                                 //!< Impact barycentric coordinates
43         };
44
45         class OPCODE_API CollisionFaces : private Container
46         {
47                 public:
48                 //! Constructor
49                                                                                 CollisionFaces()                                                {}
50                 //! Destructor
51                                                                                 ~CollisionFaces()                                               {}
52
53                 inline_ udword                                  GetNbFaces()                                    const   { return GetNbEntries()>>2;                                             }
54                 inline_ const CollisionFace*    GetFaces()                                              const   { return (const CollisionFace*)GetEntries();    }
55
56                 inline_ void                                    Reset()                                                                 { Container::Reset();                                                   }
57
58                 inline_ void                                    AddFace(const CollisionFace& face)              { Add(face.mFaceID).Add(face.mDistance).Add(face.mU).Add(face.mV);      }
59         };
60
61 #ifdef OPC_RAYHIT_CALLBACK
62         ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
63         /**
64          *      User-callback, called by OPCODE to record a hit.
65          *      \param          hit                     [in] current hit
66          *      \param          user_data       [in] user-defined data from SetCallback()
67          */
68         ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
69         typedef void    (*HitCallback)  (const CollisionFace& hit, void* user_data);
70 #endif
71
72         class OPCODE_API RayCollider : public Collider
73         {
74                 public:
75                 // Constructor / Destructor
76                                                                                         RayCollider();
77                 virtual                                                         ~RayCollider();
78
79                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
80                 /**
81                  *      Generic stabbing query for generic OPCODE models. After the call, access the results:
82                  *      - with GetContactStatus()
83                  *      - in the user-provided destination array
84                  *
85                  *      \param          world_ray               [in] stabbing ray in world space
86                  *      \param          model                   [in] Opcode model to collide with
87                  *      \param          world                   [in] model's world matrix, or null
88                  *      \param          cache                   [in] a possibly cached face index, or null
89                  *      \return         true if success
90                  *      \warning        SCALE NOT SUPPORTED. The matrices must contain rotation & translation parts only.
91                  */
92                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
93                                                         bool                    Collide(const Ray& world_ray, const Model& model, const Matrix4x4* world=null, udword* cache=null);
94                 //
95                                                         bool                    Collide(const Ray& world_ray, const AABBTree* tree, Container& box_indices);
96                 // Settings
97
98 #ifndef OPC_RAYHIT_CALLBACK
99                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
100                 /**
101                  *      Settings: enable or disable "closest hit" mode.
102                  *      \param          flag            [in] true to report closest hit only
103                  *      \see            SetCulling(bool flag)
104                  *      \see            SetMaxDist(float max_dist)
105                  *      \see            SetDestination(StabbedFaces* sf)
106                  */
107                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
108                 inline_                         void                    SetClosestHit(bool flag)                                { mClosestHit   = flag;         }
109 #endif
110                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
111                 /**
112                  *      Settings: enable or disable backface culling.
113                  *      \param          flag            [in] true to enable backface culling
114                  *      \see            SetClosestHit(bool flag)
115                  *      \see            SetMaxDist(float max_dist)
116                  *      \see            SetDestination(StabbedFaces* sf)
117                  */
118                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
119                 inline_                         void                    SetCulling(bool flag)                                   { mCulling              = flag;         }
120
121                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
122                 /**
123                  *      Settings: sets the higher distance bound.
124                  *      \param          max_dist        [in] higher distance bound. Default = maximal value, for ray queries (else segment)
125                  *      \see            SetClosestHit(bool flag)
126                  *      \see            SetCulling(bool flag)
127                  *      \see            SetDestination(StabbedFaces* sf)
128                  */
129                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
130                 inline_                         void                    SetMaxDist(float max_dist=MAX_FLOAT)    { mMaxDist              = max_dist;     }
131
132 #ifdef OPC_RAYHIT_CALLBACK
133                 inline_                         void                    SetHitCallback(HitCallback cb)                  { mHitCallback  = cb;                   }
134                 inline_                         void                    SetUserData(void* user_data)                    { mUserData             = user_data;    }
135 #else
136                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
137                 /**
138                  *      Settings: sets the destination array for stabbed faces.
139                  *      \param          cf                      [in] destination array, filled during queries
140                  *      \see            SetClosestHit(bool flag)
141                  *      \see            SetCulling(bool flag)
142                  *      \see            SetMaxDist(float max_dist)
143                  */
144                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
145                 inline_                         void                    SetDestination(CollisionFaces* cf)              { mStabbedFaces = cf;           }
146 #endif
147                 // Stats
148                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
149                 /**
150                  *      Stats: gets the number of Ray-BV overlap tests after a collision query.
151                  *      \see            GetNbRayPrimTests()
152                  *      \see            GetNbIntersections()
153                  *      \return         the number of Ray-BV tests performed during last query
154                  */
155                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
156                 inline_                         udword                  GetNbRayBVTests()                               const   { return mNbRayBVTests;         }
157
158                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
159                 /**
160                  *      Stats: gets the number of Ray-Triangle overlap tests after a collision query.
161                  *      \see            GetNbRayBVTests()
162                  *      \see            GetNbIntersections()
163                  *      \return         the number of Ray-Triangle tests performed during last query
164                  */
165                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
166                 inline_                         udword                  GetNbRayPrimTests()                             const   { return mNbRayPrimTests;       }
167
168                 // In-out test
169                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
170                 /**
171                  *      Stats: gets the number of intersection found after a collision query. Can be used for in/out tests.
172                  *      \see            GetNbRayBVTests()
173                  *      \see            GetNbRayPrimTests()
174                  *      \return         the number of valid intersections during last query
175                  */
176                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
177                 inline_                         udword                  GetNbIntersections()                    const   { return mNbIntersections;      }
178
179                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
180                 /**
181                  *      Validates current settings. You should call this method after all the settings and callbacks have been defined for a collider.
182                  *      \return         null if everything is ok, else a string describing the problem
183                  */
184                 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
185                 override(Collider)      const char*             ValidateSettings();
186
187                 protected:
188                 // Ray in local space
189                                                         Point                   mOrigin;                        //!< Ray origin
190                                                         Point                   mDir;                           //!< Ray direction (normalized)
191                                                         Point                   mFDir;                          //!< fabsf(mDir)
192                                                         Point                   mData, mData2;
193                 // Stabbed faces
194                                                         CollisionFace   mStabbedFace;           //!< Current stabbed face
195 #ifdef OPC_RAYHIT_CALLBACK
196                                                         HitCallback             mHitCallback;           //!< Callback used to record a hit
197                                                         void*                   mUserData;                      //!< User-defined data
198 #else
199                                                         CollisionFaces* mStabbedFaces;          //!< List of stabbed faces
200 #endif
201                 // Stats
202                                                         udword                  mNbRayBVTests;          //!< Number of Ray-BV tests
203                                                         udword                  mNbRayPrimTests;        //!< Number of Ray-Primitive tests
204                 // In-out test
205                                                         udword                  mNbIntersections;       //!< Number of valid intersections
206                 // Dequantization coeffs
207                                                         Point                   mCenterCoeff;
208                                                         Point                   mExtentsCoeff;
209                 // Settings
210                                                         float                   mMaxDist;                       //!< Valid segment on the ray
211 #ifndef OPC_RAYHIT_CALLBACK
212                                                         bool                    mClosestHit;            //!< Report closest hit only
213 #endif
214                                                         bool                    mCulling;                       //!< Stab culled faces or not
215                 // Internal methods
216                                                         void                    _SegmentStab(const AABBCollisionNode* node);
217                                                         void                    _SegmentStab(const AABBNoLeafNode* node);
218                                                         void                    _SegmentStab(const AABBQuantizedNode* node);
219                                                         void                    _SegmentStab(const AABBQuantizedNoLeafNode* node);
220                                                         void                    _SegmentStab(const AABBTreeNode* node, Container& box_indices);
221                                                         void                    _RayStab(const AABBCollisionNode* node);
222                                                         void                    _RayStab(const AABBNoLeafNode* node);
223                                                         void                    _RayStab(const AABBQuantizedNode* node);
224                                                         void                    _RayStab(const AABBQuantizedNoLeafNode* node);
225                                                         void                    _RayStab(const AABBTreeNode* node, Container& box_indices);
226                         // Overlap tests
227                 inline_                         BOOL                    RayAABBOverlap(const Point& center, const Point& extents);
228                 inline_                         BOOL                    SegmentAABBOverlap(const Point& center, const Point& extents);
229                 inline_                         BOOL                    RayTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2);
230                         // Init methods
231                                                         BOOL                    InitQuery(const Ray& world_ray, const Matrix4x4* world=null, udword* face_id=null);
232         };
233
234 #endif // __OPC_RAYCOLLIDER_H__