git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@6404 dfc29bdd-3216-0410-991c-e03cc46cb475
		
			
				
	
	
		
			285 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			285 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // 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
 |