]> git.lizzy.rs Git - irrlicht.git/blob - include/ISceneCollisionManager.h
Merging r6122 through r6127 from trunk to ogl-es branch
[irrlicht.git] / include / ISceneCollisionManager.h
1 // Copyright (C) 2002-2012 Nikolaus Gebhardt\r
2 // This file is part of the "Irrlicht Engine".\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h\r
4 \r
5 #ifndef __I_SCENE_COLLISION_MANAGER_H_INCLUDED__\r
6 #define __I_SCENE_COLLISION_MANAGER_H_INCLUDED__\r
7 \r
8 #include "IReferenceCounted.h"\r
9 #include "vector3d.h"\r
10 #include "triangle3d.h"\r
11 #include "position2d.h"\r
12 #include "line3d.h"\r
13 \r
14 namespace irr\r
15 {\r
16 \r
17 namespace scene\r
18 {\r
19         class ISceneNode;\r
20         class ICameraSceneNode;\r
21         class ITriangleSelector;\r
22         class IMeshBuffer;\r
23 \r
24         struct SCollisionHit\r
25         {\r
26                 //! Point of collision\r
27                 core::vector3df Intersection;\r
28 \r
29                 //! Triangle with which we collided\r
30                 core::triangle3df Triangle;\r
31 \r
32                 //! Triangle selector which contained the colliding triangle (useful when having MetaTriangleSelector)\r
33                 ITriangleSelector* TriangleSelector;\r
34 \r
35                 //! Node which contained the triangle (is 0 when selector doesn't have that information)\r
36                 ISceneNode* Node;\r
37 \r
38                 //! Meshbuffer which contained the triangle (is 0 when the selector doesn't have that information, only works when selectors are created per meshbuffer)\r
39                 const IMeshBuffer* MeshBuffer;\r
40 \r
41                 //! Index of selected material of the triangle in the SceneNode. Usually only valid when MeshBuffer is also set, otherwise always 0\r
42                 irr::u32 MaterialIndex;\r
43 \r
44                 SCollisionHit() : TriangleSelector(0), Node(0), MeshBuffer(0), MaterialIndex(0)\r
45                 {}\r
46         };\r
47 \r
48         //! The Scene Collision Manager provides methods for performing collision tests and picking on scene nodes.\r
49         class ISceneCollisionManager : public virtual IReferenceCounted\r
50         {\r
51         public:\r
52 \r
53                 //! Finds the nearest collision point of a line and lots of triangles, if there is one.\r
54                 /** \param hitResult: Contains collision result when there was a collision detected.\r
55                 \param ray: Line with which collisions are tested.\r
56                 \param selector: TriangleSelector to be used for the collision check.\r
57                 \return true if a collision was detected and false if not.      */\r
58                 virtual bool getCollisionPoint(SCollisionHit& hitResult, const core::line3d<f32>& ray,\r
59                                 ITriangleSelector* selector) = 0;\r
60 \r
61                 //! Finds the nearest collision point of a line and lots of triangles, if there is one.\r
62                 /** \param ray: Line with which collisions are tested.\r
63                 \param selector: TriangleSelector containing the triangles. It\r
64                 can be created for example using\r
65                 ISceneManager::createTriangleSelector() or\r
66                 ISceneManager::createTriangleOctreeSelector().\r
67                 \param outCollisionPoint: If a collision is detected, this will\r
68                 contain the position of the nearest collision to the line-start.\r
69                 \param outTriangle: If a collision is detected, this will\r
70                 contain the triangle with which the ray collided.\r
71                 \param outNode: If a collision is detected, this will contain\r
72                 the scene node associated with the triangle that was hit.\r
73                 \return True if a collision was detected and false if not. */\r
74                 virtual bool getCollisionPoint(const core::line3d<f32>& ray,\r
75                                 ITriangleSelector* selector, core::vector3df& outCollisionPoint,\r
76                                 core::triangle3df& outTriangle, ISceneNode*& outNode)\r
77                 {\r
78                         SCollisionHit hitResult;\r
79                         if ( getCollisionPoint(hitResult, ray, selector) )\r
80                         {\r
81                                 outCollisionPoint = hitResult.Intersection;\r
82                                 outTriangle = hitResult.Triangle;\r
83                                 outNode = hitResult.Node;\r
84                                 return true;\r
85                         }\r
86                         return false;\r
87                 }\r
88 \r
89                 //! Collides a moving ellipsoid with a 3d world with gravity and returns the resulting new position of the ellipsoid.\r
90                 /** This can be used for moving a character in a 3d world: The\r
91                 character will slide at walls and is able to walk up stairs.\r
92                 The method used how to calculate the collision result position\r
93                 is based on the paper "Improved Collision detection and\r
94                 Response" by Kasper Fauerby.\r
95                 \param selector: TriangleSelector containing the triangles of\r
96                 the world. It can be created for example using\r
97                 ISceneManager::createTriangleSelector() or\r
98                 ISceneManager::createTriangleOctreeSelector().\r
99                 \param ellipsoidPosition: Position of the ellipsoid.\r
100                 \param ellipsoidRadius: Radius of the ellipsoid.\r
101                 \param ellipsoidDirectionAndSpeed: Direction and speed of the\r
102                 movement of the ellipsoid.\r
103                 \param triout: Optional parameter where the last triangle\r
104                 causing a collision is stored, if there is a collision.\r
105                 \param hitPosition: Return value for the position of the collision\r
106                 \param outFalling: Is set to true if the ellipsoid is falling\r
107                 down, caused by gravity.\r
108                 \param outNode: the node with which the ellipsoid collided (if any)\r
109                 \param slidingSpeed: DOCUMENTATION NEEDED.\r
110                 \param gravityDirectionAndSpeed: Direction and force of gravity.\r
111                 \return New position of the ellipsoid. */\r
112                 virtual core::vector3df getCollisionResultPosition(\r
113                         ITriangleSelector* selector,\r
114                         const core::vector3df &ellipsoidPosition,\r
115                         const core::vector3df& ellipsoidRadius,\r
116                         const core::vector3df& ellipsoidDirectionAndSpeed,\r
117                         core::triangle3df& triout,\r
118                         core::vector3df& hitPosition,\r
119                         bool& outFalling,\r
120                         ISceneNode*& outNode,\r
121                         f32 slidingSpeed = 0.0005f,\r
122                         const core::vector3df& gravityDirectionAndSpeed\r
123                         = core::vector3df(0.0f, 0.0f, 0.0f)) = 0;\r
124 \r
125                 //! Returns a 3d ray which would go through the 2d screen coordinates.\r
126                 /** \param pos: Screen coordinates in pixels.\r
127                 \param camera: Camera from which the ray starts. If null, the\r
128                 active camera is used.\r
129                 \return Ray starting from the position of the camera and ending\r
130                 at a length of the far value of the camera at a position which\r
131                 would be behind the 2d screen coordinates. */\r
132                 virtual core::line3d<f32> getRayFromScreenCoordinates(\r
133                         const core::position2d<s32>& pos, const ICameraSceneNode* camera = 0) = 0;\r
134 \r
135                 //! Calculates 2d screen position from a 3d position.\r
136                 /** \param pos: 3D position in world space to be transformed\r
137                 into 2d.\r
138                 \param camera: Camera to be used. If null, the currently active\r
139                 camera is used.\r
140                 \param useViewPort: Calculate screen coordinates relative to\r
141                 the current view port. Please note that unless the driver does\r
142                 not take care of the view port, it is usually best to get the\r
143                 result in absolute screen coordinates (flag=false).\r
144                 \return 2d screen coordinates which a object in the 3d world\r
145                 would have if it would be rendered to the screen. If the 3d\r
146                 position is behind the camera, it is set to (-1000,-1000). In\r
147                 most cases you can ignore this fact, because if you use this\r
148                 method for drawing a decorator over a 3d object, it will be\r
149                 clipped by the screen borders. */\r
150                 virtual core::position2d<s32> getScreenCoordinatesFrom3DPosition(\r
151                         const core::vector3df& pos, const ICameraSceneNode* camera=0, bool useViewPort=false) = 0;\r
152 \r
153                 //! Gets the scene node, which is currently visible under the given screen coordinates, viewed from the currently active camera.\r
154                 /** The collision tests are done using a bounding box for each\r
155                 scene node. You can limit the recursive search so just all children of the specified root are tested.\r
156                 \param pos: Position in pixel screen coordinates, under which\r
157                 the returned scene node will be.\r
158                 \param idBitMask: Only scene nodes with an id with bits set\r
159                 like in this mask will be tested. If the BitMask is 0, this\r
160                 feature is disabled.\r
161                 Please note that the default node id of -1 will match with\r
162                 every bitmask != 0\r
163                 \param bNoDebugObjects: Doesn't take debug objects into account\r
164                 when true. These are scene nodes with IsDebugObject() = true.\r
165                 \param root If different from 0, the search is limited to the children of this node.\r
166                 \return Visible scene node under screen coordinates with\r
167                 matching bits in its id. If there is no scene node under this\r
168                 position, 0 is returned. */\r
169                 virtual ISceneNode* getSceneNodeFromScreenCoordinatesBB(const core::position2d<s32>& pos,\r
170                                 s32 idBitMask=0, bool bNoDebugObjects=false, ISceneNode* root=0) =0;\r
171 \r
172                 //! Returns the nearest scene node which collides with a 3d ray and whose id matches a bitmask.\r
173                 /** The collision tests are done using a bounding box for each\r
174                 scene node. The recursive search can be limited be specifying a scene node.\r
175                 \param ray Line with which collisions are tested.\r
176                 \param idBitMask Only scene nodes with an id which matches at\r
177                 least one of the bits contained in this mask will be tested.\r
178                 However, if this parameter is 0, then all nodes are checked.\r
179                 \param bNoDebugObjects: Doesn't take debug objects into account when true. These\r
180                 are scene nodes with IsDebugObject() = true.\r
181                 \param root If different from 0, the search is limited to the children of this node.\r
182                 \return Scene node nearest to ray.start, which collides with\r
183                 the ray and matches the idBitMask, if the mask is not null. If\r
184                 no scene node is found, 0 is returned. */\r
185                 virtual ISceneNode* getSceneNodeFromRayBB(const core::line3d<f32>& ray,\r
186                                                         s32 idBitMask=0, bool bNoDebugObjects=false, ISceneNode* root=0) =0;\r
187 \r
188                 //! Get the scene node, which the given camera is looking at and whose id matches the bitmask.\r
189                 /** A ray is simply cast from the position of the camera to\r
190                 the view target position, and all scene nodes are tested\r
191                 against this ray. The collision tests are done using a bounding\r
192                 box for each scene node.\r
193                 \param camera: Camera from which the ray is cast.\r
194                 \param idBitMask: Only scene nodes with an id which matches at least one of the\r
195                 bits contained in this mask will be tested. However, if this parameter is 0, then\r
196                 all nodes are checked.\r
197                 feature is disabled.\r
198                 Please note that the default node id of -1 will match with\r
199                 every bitmask != 0\r
200                 \param bNoDebugObjects: Doesn't take debug objects into account\r
201                 when true. These are scene nodes with IsDebugObject() = true.\r
202                 \return Scene node nearest to the camera, which collides with\r
203                 the ray and matches the idBitMask, if the mask is not null. If\r
204                 no scene node is found, 0 is returned. */\r
205                 virtual ISceneNode* getSceneNodeFromCameraBB(const ICameraSceneNode* camera,\r
206                         s32 idBitMask=0, bool bNoDebugObjects = false) = 0;\r
207 \r
208 \r
209                 //! Perform a ray/box and ray/triangle collision check on a hierarchy of scene nodes.\r
210                 /** This checks all scene nodes under the specified one, first by ray/bounding\r
211                 box, and then by accurate ray/triangle collision, finding the nearest collision,\r
212                 and the scene node containing it.  It returns the node hit, and (via output\r
213                 parameters) the position of the collision, and the triangle that was hit.\r
214 \r
215                 All scene nodes in the hierarchy tree under the specified node are checked. Only\r
216                 nodes that are visible, with an ID that matches at least one bit in the supplied\r
217                 bitmask, and which have a triangle selector are considered as candidates for being hit.\r
218                 You do not have to build a meta triangle selector; the individual triangle selectors\r
219                 of each candidate scene node are used automatically.\r
220 \r
221                 \param ray: Line with which collisions are tested.\r
222                 \param outCollisionPoint: If a collision is detected, this will contain the\r
223                 position of the nearest collision.\r
224                 \param outTriangle: If a collision is detected, this will contain the triangle\r
225                 with which the ray collided.\r
226                 \param idBitMask: Only scene nodes with an id which matches at least one of the\r
227                 bits contained in this mask will be tested. However, if this parameter is 0, then\r
228                 all nodes are checked.\r
229                 \param collisionRootNode: the scene node at which to begin checking. Only this\r
230                 node and its children will be checked. If you want to check the entire scene,\r
231                 pass 0, and the root scene node will be used (this is the default).\r
232                 \param noDebugObjects: when true, debug objects are not considered viable targets.\r
233                 Debug objects are scene nodes with IsDebugObject() = true.\r
234                 \return Returns the scene node containing the hit triangle nearest to ray.start.\r
235                 If no collision is detected, then 0 is returned. */\r
236                 virtual ISceneNode* getSceneNodeAndCollisionPointFromRay(\r
237                                                                 SCollisionHit& hitResult, \r
238                                                                 const core::line3df& ray,\r
239                                                                 s32 idBitMask = 0,\r
240                                                                 ISceneNode * collisionRootNode = 0,\r
241                                                                 bool noDebugObjects = false) = 0;\r
242 \r
243                 //! Perform a ray/box and ray/triangle collision check on a hierarchy of scene nodes.\r
244                 /** Works same as other getSceneNodeAndCollisionPointFromRay but returns less information.\r
245                 (was written before the other getSceneNodeAndCollisionPointFromRay implementation).\r
246                 \param ray: Line with which collisions are tested.\r
247                 \param outCollisionPoint: If a collision is detected, this will contain the\r
248                 position of the nearest collision.\r
249                 \param outTriangle: If a collision is detected, this will contain the triangle\r
250                 with which the ray collided.\r
251                 \param idBitMask: Only scene nodes with an id which matches at least one of the\r
252                 bits contained in this mask will be tested. However, if this parameter is 0, then\r
253                 all nodes are checked.\r
254                 \param collisionRootNode: the scene node at which to begin checking. Only this\r
255                 node and its children will be checked. If you want to check the entire scene,\r
256                 pass 0, and the root scene node will be used (this is the default).\r
257                 \param noDebugObjects: when true, debug objects are not considered viable targets.\r
258                 Debug objects are scene nodes with IsDebugObject() = true.\r
259                 \return Returns the scene node containing the hit triangle nearest to ray.start.\r
260                 If no collision is detected, then 0 is returned. */\r
261                 virtual ISceneNode* getSceneNodeAndCollisionPointFromRay(\r
262                                                                 const core::line3df& ray,\r
263                                                                 core::vector3df& outCollisionPoint,\r
264                                                                 core::triangle3df& outTriangle,\r
265                                                                 s32 idBitMask = 0,\r
266                                                                 ISceneNode * collisionRootNode = 0,\r
267                                                                 bool noDebugObjects = false)\r
268                 {\r
269                         SCollisionHit hitResult;\r
270                         ISceneNode* node = getSceneNodeAndCollisionPointFromRay(hitResult, ray, idBitMask, collisionRootNode, noDebugObjects);\r
271                         if ( node )\r
272                         {\r
273                                 outCollisionPoint = hitResult.Intersection;\r
274                                 outTriangle  = hitResult.Triangle;\r
275                         }\r
276                         return node;\r
277                 }\r
278 \r
279         };\r
280 \r
281 } // end namespace scene\r
282 } // end namespace irr\r
283 \r
284 #endif\r