#define __I_SCENE_COLLISION_MANAGER_H_INCLUDED__\r
\r
#include "IReferenceCounted.h"\r
-#include "vector3d.h"\r
-#include "triangle3d.h"\r
#include "position2d.h"\r
#include "line3d.h"\r
\r
\r
namespace scene\r
{\r
- class ISceneNode;\r
class ICameraSceneNode;\r
- class ITriangleSelector;\r
- class IMeshBuffer;\r
\r
- struct SCollisionHit\r
- {\r
- //! Point of collision\r
- core::vector3df Intersection;\r
-\r
- //! Triangle with which we collided\r
- core::triangle3df Triangle;\r
-\r
- //! Triangle selector which contained the colliding triangle (useful when having MetaTriangleSelector)\r
- ITriangleSelector* TriangleSelector;\r
-\r
- //! Node which contained the triangle (is 0 when selector doesn't have that information)\r
- ISceneNode* Node;\r
-\r
- //! Meshbuffer which contained the triangle (is 0 when the selector doesn't have that information, only works when selectors are created per meshbuffer)\r
- const IMeshBuffer* MeshBuffer;\r
-\r
- //! Index of selected material of the triangle in the SceneNode. Usually only valid when MeshBuffer is also set, otherwise always 0\r
- irr::u32 MaterialIndex;\r
-\r
- SCollisionHit() : TriangleSelector(0), Node(0), MeshBuffer(0), MaterialIndex(0)\r
- {}\r
- };\r
-\r
- //! The Scene Collision Manager provides methods for performing collision tests and picking on scene nodes.\r
class ISceneCollisionManager : public virtual IReferenceCounted\r
{\r
public:\r
\r
- //! Finds the nearest collision point of a line and lots of triangles, if there is one.\r
- /** \param hitResult: Contains collision result when there was a collision detected.\r
- \param ray: Line with which collisions are tested.\r
- \param selector: TriangleSelector to be used for the collision check.\r
- \return true if a collision was detected and false if not. */\r
- virtual bool getCollisionPoint(SCollisionHit& hitResult, const core::line3d<f32>& ray,\r
- ITriangleSelector* selector) = 0;\r
-\r
- //! Finds the nearest collision point of a line and lots of triangles, if there is one.\r
- /** \param ray: Line with which collisions are tested.\r
- \param selector: TriangleSelector containing the triangles. It\r
- can be created for example using\r
- ISceneManager::createTriangleSelector() or\r
- ISceneManager::createTriangleOctreeSelector().\r
- \param outCollisionPoint: If a collision is detected, this will\r
- contain the position of the nearest collision to the line-start.\r
- \param outTriangle: If a collision is detected, this will\r
- contain the triangle with which the ray collided.\r
- \param outNode: If a collision is detected, this will contain\r
- the scene node associated with the triangle that was hit.\r
- \return True if a collision was detected and false if not. */\r
- virtual bool getCollisionPoint(const core::line3d<f32>& ray,\r
- ITriangleSelector* selector, core::vector3df& outCollisionPoint,\r
- core::triangle3df& outTriangle, ISceneNode*& outNode)\r
- {\r
- SCollisionHit hitResult;\r
- if ( getCollisionPoint(hitResult, ray, selector) )\r
- {\r
- outCollisionPoint = hitResult.Intersection;\r
- outTriangle = hitResult.Triangle;\r
- outNode = hitResult.Node;\r
- return true;\r
- }\r
- return false;\r
- }\r
-\r
- //! Collides a moving ellipsoid with a 3d world with gravity and returns the resulting new position of the ellipsoid.\r
- /** This can be used for moving a character in a 3d world: The\r
- character will slide at walls and is able to walk up stairs.\r
- The method used how to calculate the collision result position\r
- is based on the paper "Improved Collision detection and\r
- Response" by Kasper Fauerby.\r
- \param selector: TriangleSelector containing the triangles of\r
- the world. It can be created for example using\r
- ISceneManager::createTriangleSelector() or\r
- ISceneManager::createTriangleOctreeSelector().\r
- \param ellipsoidPosition: Position of the ellipsoid.\r
- \param ellipsoidRadius: Radius of the ellipsoid.\r
- \param ellipsoidDirectionAndSpeed: Direction and speed of the\r
- movement of the ellipsoid.\r
- \param triout: Optional parameter where the last triangle\r
- causing a collision is stored, if there is a collision.\r
- \param hitPosition: Return value for the position of the collision\r
- \param outFalling: Is set to true if the ellipsoid is falling\r
- down, caused by gravity.\r
- \param outNode: the node with which the ellipsoid collided (if any)\r
- \param slidingSpeed: DOCUMENTATION NEEDED.\r
- \param gravityDirectionAndSpeed: Direction and force of gravity.\r
- \return New position of the ellipsoid. */\r
- virtual core::vector3df getCollisionResultPosition(\r
- ITriangleSelector* selector,\r
- const core::vector3df &ellipsoidPosition,\r
- const core::vector3df& ellipsoidRadius,\r
- const core::vector3df& ellipsoidDirectionAndSpeed,\r
- core::triangle3df& triout,\r
- core::vector3df& hitPosition,\r
- bool& outFalling,\r
- ISceneNode*& outNode,\r
- f32 slidingSpeed = 0.0005f,\r
- const core::vector3df& gravityDirectionAndSpeed\r
- = core::vector3df(0.0f, 0.0f, 0.0f)) = 0;\r
-\r
//! Returns a 3d ray which would go through the 2d screen coordinates.\r
/** \param pos: Screen coordinates in pixels.\r
\param camera: Camera from which the ray starts. If null, the\r
virtual core::line3d<f32> getRayFromScreenCoordinates(\r
const core::position2d<s32>& pos, const ICameraSceneNode* camera = 0) = 0;\r
\r
- //! Calculates 2d screen position from a 3d position.\r
- /** \param pos: 3D position in world space to be transformed\r
- into 2d.\r
- \param camera: Camera to be used. If null, the currently active\r
- camera is used.\r
- \param useViewPort: Calculate screen coordinates relative to\r
- the current view port. Please note that unless the driver does\r
- not take care of the view port, it is usually best to get the\r
- result in absolute screen coordinates (flag=false).\r
- \return 2d screen coordinates which a object in the 3d world\r
- would have if it would be rendered to the screen. If the 3d\r
- position is behind the camera, it is set to (-1000,-1000). In\r
- most cases you can ignore this fact, because if you use this\r
- method for drawing a decorator over a 3d object, it will be\r
- clipped by the screen borders. */\r
- virtual core::position2d<s32> getScreenCoordinatesFrom3DPosition(\r
- const core::vector3df& pos, const ICameraSceneNode* camera=0, bool useViewPort=false) = 0;\r
-\r
- //! Gets the scene node, which is currently visible under the given screen coordinates, viewed from the currently active camera.\r
- /** The collision tests are done using a bounding box for each\r
- scene node. You can limit the recursive search so just all children of the specified root are tested.\r
- \param pos: Position in pixel screen coordinates, under which\r
- the returned scene node will be.\r
- \param idBitMask: Only scene nodes with an id with bits set\r
- like in this mask will be tested. If the BitMask is 0, this\r
- feature is disabled.\r
- Please note that the default node id of -1 will match with\r
- every bitmask != 0\r
- \param bNoDebugObjects: Doesn't take debug objects into account\r
- when true. These are scene nodes with IsDebugObject() = true.\r
- \param root If different from 0, the search is limited to the children of this node.\r
- \return Visible scene node under screen coordinates with\r
- matching bits in its id. If there is no scene node under this\r
- position, 0 is returned. */\r
- virtual ISceneNode* getSceneNodeFromScreenCoordinatesBB(const core::position2d<s32>& pos,\r
- s32 idBitMask=0, bool bNoDebugObjects=false, ISceneNode* root=0) =0;\r
-\r
- //! Returns the nearest scene node which collides with a 3d ray and whose id matches a bitmask.\r
- /** The collision tests are done using a bounding box for each\r
- scene node. The recursive search can be limited be specifying a scene node.\r
- \param ray Line with which collisions are tested.\r
- \param idBitMask Only scene nodes with an id which matches at\r
- least one of the bits contained in this mask will be tested.\r
- However, if this parameter is 0, then all nodes are checked.\r
- \param bNoDebugObjects: Doesn't take debug objects into account when true. These\r
- are scene nodes with IsDebugObject() = true.\r
- \param root If different from 0, the search is limited to the children of this node.\r
- \return Scene node nearest to ray.start, which collides with\r
- the ray and matches the idBitMask, if the mask is not null. If\r
- no scene node is found, 0 is returned. */\r
- virtual ISceneNode* getSceneNodeFromRayBB(const core::line3d<f32>& ray,\r
- s32 idBitMask=0, bool bNoDebugObjects=false, ISceneNode* root=0) =0;\r
-\r
- //! Get the scene node, which the given camera is looking at and whose id matches the bitmask.\r
- /** A ray is simply cast from the position of the camera to\r
- the view target position, and all scene nodes are tested\r
- against this ray. The collision tests are done using a bounding\r
- box for each scene node.\r
- \param camera: Camera from which the ray is cast.\r
- \param idBitMask: Only scene nodes with an id which matches at least one of the\r
- bits contained in this mask will be tested. However, if this parameter is 0, then\r
- all nodes are checked.\r
- feature is disabled.\r
- Please note that the default node id of -1 will match with\r
- every bitmask != 0\r
- \param bNoDebugObjects: Doesn't take debug objects into account\r
- when true. These are scene nodes with IsDebugObject() = true.\r
- \return Scene node nearest to the camera, which collides with\r
- the ray and matches the idBitMask, if the mask is not null. If\r
- no scene node is found, 0 is returned. */\r
- virtual ISceneNode* getSceneNodeFromCameraBB(const ICameraSceneNode* camera,\r
- s32 idBitMask=0, bool bNoDebugObjects = false) = 0;\r
-\r
-\r
- //! Perform a ray/box and ray/triangle collision check on a hierarchy of scene nodes.\r
- /** This checks all scene nodes under the specified one, first by ray/bounding\r
- box, and then by accurate ray/triangle collision, finding the nearest collision,\r
- and the scene node containing it. It returns the node hit, and (via output\r
- parameters) the position of the collision, and the triangle that was hit.\r
-\r
- All scene nodes in the hierarchy tree under the specified node are checked. Only\r
- nodes that are visible, with an ID that matches at least one bit in the supplied\r
- bitmask, and which have a triangle selector are considered as candidates for being hit.\r
- You do not have to build a meta triangle selector; the individual triangle selectors\r
- of each candidate scene node are used automatically.\r
-\r
- \param ray: Line with which collisions are tested.\r
- \param outCollisionPoint: If a collision is detected, this will contain the\r
- position of the nearest collision.\r
- \param outTriangle: If a collision is detected, this will contain the triangle\r
- with which the ray collided.\r
- \param idBitMask: Only scene nodes with an id which matches at least one of the\r
- bits contained in this mask will be tested. However, if this parameter is 0, then\r
- all nodes are checked.\r
- \param collisionRootNode: the scene node at which to begin checking. Only this\r
- node and its children will be checked. If you want to check the entire scene,\r
- pass 0, and the root scene node will be used (this is the default).\r
- \param noDebugObjects: when true, debug objects are not considered viable targets.\r
- Debug objects are scene nodes with IsDebugObject() = true.\r
- \return Returns the scene node containing the hit triangle nearest to ray.start.\r
- If no collision is detected, then 0 is returned. */\r
- virtual ISceneNode* getSceneNodeAndCollisionPointFromRay(\r
- SCollisionHit& hitResult, \r
- const core::line3df& ray,\r
- s32 idBitMask = 0,\r
- ISceneNode * collisionRootNode = 0,\r
- bool noDebugObjects = false) = 0;\r
-\r
- //! Perform a ray/box and ray/triangle collision check on a hierarchy of scene nodes.\r
- /** Works same as other getSceneNodeAndCollisionPointFromRay but returns less information.\r
- (was written before the other getSceneNodeAndCollisionPointFromRay implementation).\r
- \param ray: Line with which collisions are tested.\r
- \param outCollisionPoint: If a collision is detected, this will contain the\r
- position of the nearest collision.\r
- \param outTriangle: If a collision is detected, this will contain the triangle\r
- with which the ray collided.\r
- \param idBitMask: Only scene nodes with an id which matches at least one of the\r
- bits contained in this mask will be tested. However, if this parameter is 0, then\r
- all nodes are checked.\r
- \param collisionRootNode: the scene node at which to begin checking. Only this\r
- node and its children will be checked. If you want to check the entire scene,\r
- pass 0, and the root scene node will be used (this is the default).\r
- \param noDebugObjects: when true, debug objects are not considered viable targets.\r
- Debug objects are scene nodes with IsDebugObject() = true.\r
- \return Returns the scene node containing the hit triangle nearest to ray.start.\r
- If no collision is detected, then 0 is returned. */\r
- virtual ISceneNode* getSceneNodeAndCollisionPointFromRay(\r
- const core::line3df& ray,\r
- core::vector3df& outCollisionPoint,\r
- core::triangle3df& outTriangle,\r
- s32 idBitMask = 0,\r
- ISceneNode * collisionRootNode = 0,\r
- bool noDebugObjects = false)\r
- {\r
- SCollisionHit hitResult;\r
- ISceneNode* node = getSceneNodeAndCollisionPointFromRay(hitResult, ray, idBitMask, collisionRootNode, noDebugObjects);\r
- if ( node )\r
- {\r
- outCollisionPoint = hitResult.Intersection;\r
- outTriangle = hitResult.Triangle;\r
- }\r
- return node;\r
- }\r
-\r
};\r
\r
} // end namespace scene\r