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