2013-03-28 10:04:07 -07:00
// Copyright (C) 2002-2012 Nikolaus Gebhardt
2007-05-20 11:03:49 -07:00
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
2021-08-30 14:06:51 -07:00
# ifndef IRR_I_SCENE_COLLISION_MANAGER_H_INCLUDED
# define IRR_I_SCENE_COLLISION_MANAGER_H_INCLUDED
2007-05-20 11:03:49 -07:00
2007-09-06 23:11:47 -07:00
# include "IReferenceCounted.h"
2007-05-20 11:03:49 -07:00
# include "vector3d.h"
# include "triangle3d.h"
# include "position2d.h"
# include "line3d.h"
namespace irr
{
namespace scene
{
class ISceneNode ;
class ICameraSceneNode ;
class ITriangleSelector ;
2017-04-12 08:33:31 -07:00
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)
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 )
{ }
} ;
2007-05-20 11:03:49 -07:00
2008-05-22 04:51:37 -07:00
//! The Scene Collision Manager provides methods for performing collision tests and picking on scene nodes.
2007-09-06 23:11:47 -07:00
class ISceneCollisionManager : public virtual IReferenceCounted
2007-05-20 11:03:49 -07:00
{
public :
2017-04-12 08:33:31 -07:00
//! 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 ;
2010-01-23 12:13:43 -08:00
//! Finds the nearest collision point of a line and lots of triangles, if there is one.
2009-11-02 09:20:21 -08:00
/** \param ray: Line with which collisions are tested.
2008-05-22 04:51:37 -07:00
\ param selector : TriangleSelector containing the triangles . It
can be created for example using
ISceneManager : : createTriangleSelector ( ) or
2010-01-23 12:13:43 -08:00
ISceneManager : : createTriangleOctreeSelector ( ) .
2008-05-22 04:51:37 -07:00
\ param outCollisionPoint : If a collision is detected , this will
2010-01-23 12:13:43 -08:00
contain the position of the nearest collision to the line - start .
2008-05-22 04:51:37 -07:00
\ param outTriangle : If a collision is detected , this will
contain the triangle with which the ray collided .
2009-01-27 05:23:36 -08:00
\ param outNode : If a collision is detected , this will contain
the scene node associated with the triangle that was hit .
2008-05-22 04:51:37 -07:00
\ return True if a collision was detected and false if not . */
2007-05-20 11:03:49 -07:00
virtual bool getCollisionPoint ( const core : : line3d < f32 > & ray ,
2009-05-04 17:09:53 -07:00
ITriangleSelector * selector , core : : vector3df & outCollisionPoint ,
2017-04-12 08:33:31 -07:00
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 ;
}
2007-05-20 11:03:49 -07:00
2008-05-22 04:51:37 -07:00
//! 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
2010-01-23 12:13:43 -08:00
ISceneManager : : createTriangleOctreeSelector ( ) .
2008-05-22 04:51:37 -07:00
\ 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 .
2009-11-02 09:20:21 -08:00
\ param hitPosition : Return value for the position of the collision
2008-05-22 04:51:37 -07:00
\ param outFalling : Is set to true if the ellipsoid is falling
down , caused by gravity .
2017-03-13 07:54:20 -07:00
\ param outNode : the node with which the ellipsoid collided ( if any )
2008-05-22 04:51:37 -07:00
\ param slidingSpeed : DOCUMENTATION NEEDED .
\ param gravityDirectionAndSpeed : Direction and force of gravity .
\ return New position of the ellipsoid . */
2007-05-20 11:03:49 -07:00
virtual core : : vector3df getCollisionResultPosition (
ITriangleSelector * selector ,
const core : : vector3df & ellipsoidPosition ,
2008-05-22 04:51:37 -07:00
const core : : vector3df & ellipsoidRadius ,
2007-05-20 11:03:49 -07:00
const core : : vector3df & ellipsoidDirectionAndSpeed ,
core : : triangle3df & triout ,
2008-12-19 01:56:25 -08:00
core : : vector3df & hitPosition ,
2007-05-20 11:03:49 -07:00
bool & outFalling ,
2011-01-14 07:36:50 -08:00
ISceneNode * & outNode ,
2007-05-20 11:03:49 -07:00
f32 slidingSpeed = 0.0005f ,
2008-05-22 04:51:37 -07:00
const core : : vector3df & gravityDirectionAndSpeed
2007-05-20 11:03:49 -07:00
= core : : vector3df ( 0.0f , 0.0f , 0.0f ) ) = 0 ;
2017-03-13 07:54:20 -07:00
//! Returns a 3d ray which would go through the 2d screen coordinates.
2008-05-22 04:51:37 -07:00
/** \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
2017-03-13 07:54:20 -07:00
would be behind the 2 d screen coordinates . */
2007-05-20 11:03:49 -07:00
virtual core : : line3d < f32 > getRayFromScreenCoordinates (
2017-03-13 07:54:20 -07:00
const core : : position2d < s32 > & pos , const ICameraSceneNode * camera = 0 ) = 0 ;
2007-05-20 11:03:49 -07:00
//! Calculates 2d screen position from a 3d position.
2008-05-22 04:51:37 -07:00
/** \param pos: 3D position in world space to be transformed
into 2 d .
\ param camera : Camera to be used . If null , the currently active
camera is used .
2011-01-14 07:36:50 -08:00
\ 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 ) .
2008-05-22 04:51:37 -07:00
\ return 2 d screen coordinates which a object in the 3 d world
would have if it would be rendered to the screen . If the 3 d
2011-01-14 07:36:50 -08:00
position is behind the camera , it is set to ( - 1000 , - 1000 ) . In
2008-05-22 04:51:37 -07:00
most cases you can ignore this fact , because if you use this
method for drawing a decorator over a 3 d object , it will be
clipped by the screen borders . */
2007-05-20 11:03:49 -07:00
virtual core : : position2d < s32 > getScreenCoordinatesFrom3DPosition (
2017-03-13 07:54:20 -07:00
const core : : vector3df & pos , const ICameraSceneNode * camera = 0 , bool useViewPort = false ) = 0 ;
2007-05-20 11:03:49 -07:00
2017-03-13 07:54:20 -07:00
//! Gets the scene node, which is currently visible under the given screen coordinates, viewed from the currently active camera.
2008-05-22 04:51:37 -07:00
/** The collision tests are done using a bounding box for each
2009-05-04 17:09:53 -07:00
scene node . You can limit the recursive search so just all children of the specified root are tested .
2008-05-22 04:51:37 -07:00
\ 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 .
2009-07-03 02:11:53 -07:00
Please note that the default node id of - 1 will match with
every bitmask ! = 0
2008-05-22 04:51:37 -07:00
\ param bNoDebugObjects : Doesn ' t take debug objects into account
when true . These are scene nodes with IsDebugObject ( ) = true .
2009-05-04 17:09:53 -07:00
\ param root If different from 0 , the search is limited to the children of this node .
2008-05-22 04:51:37 -07:00
\ 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 . */
2009-05-04 17:09:53 -07:00
virtual ISceneNode * getSceneNodeFromScreenCoordinatesBB ( const core : : position2d < s32 > & pos ,
s32 idBitMask = 0 , bool bNoDebugObjects = false , ISceneNode * root = 0 ) = 0 ;
2007-05-20 11:03:49 -07:00
2009-05-04 17:09:53 -07:00
//! Returns the nearest scene node which collides with a 3d ray and whose id matches a bitmask.
2008-05-22 04:51:37 -07:00
/** The collision tests are done using a bounding box for each
2009-05-04 17:09:53 -07:00
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 .
2008-05-22 04:51:37 -07:00
\ 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 . */
2009-05-04 17:09:53 -07:00
virtual ISceneNode * getSceneNodeFromRayBB ( const core : : line3d < f32 > & ray ,
s32 idBitMask = 0 , bool bNoDebugObjects = false , ISceneNode * root = 0 ) = 0 ;
2007-05-20 11:03:49 -07:00
2009-05-04 17:09:53 -07:00
//! Get the scene node, which the given camera is looking at and whose id matches the bitmask.
2017-03-13 07:54:20 -07:00
/** A ray is simply cast from the position of the camera to
2008-05-22 04:51:37 -07:00
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 .
2017-03-13 07:54:20 -07:00
\ param camera : Camera from which the ray is cast .
2010-01-23 12:13:43 -08:00
\ 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
2009-05-04 17:09:53 -07:00
all nodes are checked .
2008-05-22 04:51:37 -07:00
feature is disabled .
2009-07-03 02:11:53 -07:00
Please note that the default node id of - 1 will match with
every bitmask ! = 0
2008-05-22 04:51:37 -07:00
\ 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 . */
2017-03-13 07:54:20 -07:00
virtual ISceneNode * getSceneNodeFromCameraBB ( const ICameraSceneNode * camera ,
2007-05-20 11:03:49 -07:00
s32 idBitMask = 0 , bool bNoDebugObjects = false ) = 0 ;
2009-05-04 17:09:53 -07:00
2017-04-12 08:33:31 -07:00
2017-03-13 07:54:20 -07:00
//! Perform a ray/box and ray/triangle collision check on a hierarchy of scene nodes.
2010-01-23 12:13:43 -08:00
/** This checks all scene nodes under the specified one, first by ray/bounding
2009-05-04 17:09:53 -07:00
box , and then by accurate ray / triangle collision , finding the nearest collision ,
2017-03-13 07:54:20 -07:00
and the scene node containing it . It returns the node hit , and ( via output
2009-05-04 17:09:53 -07:00
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
2010-07-18 14:25:27 -07:00
nodes that are visible , with an ID that matches at least one bit in the supplied
2009-05-04 17:09:53 -07:00
bitmask , and which have a triangle selector are considered as candidates for being hit .
2010-01-23 12:13:43 -08:00
You do not have to build a meta triangle selector ; the individual triangle selectors
2009-05-04 17:09:53 -07:00
of each candidate scene node are used automatically .
2010-01-23 12:13:43 -08:00
2017-04-12 08:33:31 -07:00
\ 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 ) .
2009-05-04 17:09:53 -07:00
\ 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 .
2010-01-23 12:13:43 -08:00
\ 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
2009-05-04 17:09:53 -07:00
all nodes are checked .
\ param collisionRootNode : the scene node at which to begin checking . Only this
2010-01-23 12:13:43 -08:00
node and its children will be checked . If you want to check the entire scene ,
2009-05-04 17:09:53 -07:00
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 . */
2010-01-23 12:13:43 -08:00
virtual ISceneNode * getSceneNodeAndCollisionPointFromRay (
2014-05-08 07:01:54 -07:00
const core : : line3df & ray ,
core : : vector3df & outCollisionPoint ,
core : : triangle3df & outTriangle ,
2009-05-04 17:09:53 -07:00
s32 idBitMask = 0 ,
ISceneNode * collisionRootNode = 0 ,
2017-04-12 08:33:31 -07:00
bool noDebugObjects = false )
{
SCollisionHit hitResult ;
ISceneNode * node = getSceneNodeAndCollisionPointFromRay ( hitResult , ray , idBitMask , collisionRootNode , noDebugObjects ) ;
if ( node )
{
outCollisionPoint = hitResult . Intersection ;
outTriangle = hitResult . Triangle ;
}
return node ;
}
2007-05-20 11:03:49 -07:00
2017-04-12 08:33:31 -07:00
} ;
2007-05-20 11:03:49 -07:00
} // end namespace scene
} // end namespace irr
# endif