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
5 #ifndef __C_SCENE_COLLISION_MANAGER_H_INCLUDED__
\r
6 #define __C_SCENE_COLLISION_MANAGER_H_INCLUDED__
\r
8 #include "ISceneCollisionManager.h"
\r
9 #include "ISceneManager.h"
\r
10 #include "IVideoDriver.h"
\r
17 //! The Scene Collision Manager provides methods for performing collision tests and picking on scene nodes.
\r
18 class CSceneCollisionManager : public ISceneCollisionManager
\r
23 CSceneCollisionManager(ISceneManager* smanager, video::IVideoDriver* driver);
\r
26 virtual ~CSceneCollisionManager();
\r
28 //! Returns the scene node, which is currently visible at the given
\r
29 //! screen coordinates, viewed from the currently active camera.
\r
30 virtual ISceneNode* getSceneNodeFromScreenCoordinatesBB(const core::position2d<s32>& pos,
\r
31 s32 idBitMask=0, bool bNoDebugObjects=false, ISceneNode* root=0) _IRR_OVERRIDE_;
\r
33 //! Returns the nearest scene node which collides with a 3d ray and
\r
34 //! whose id matches a bitmask.
\r
35 virtual ISceneNode* getSceneNodeFromRayBB(const core::line3d<f32>& ray,
\r
36 s32 idBitMask=0, bool bNoDebugObjects=false,
\r
37 ISceneNode* root=0) _IRR_OVERRIDE_;
\r
39 //! Returns the scene node, at which the given camera is looking at and
\r
40 //! which id matches the bitmask.
\r
41 virtual ISceneNode* getSceneNodeFromCameraBB(const ICameraSceneNode* camera,
\r
42 s32 idBitMask=0, bool bNoDebugObjects = false) _IRR_OVERRIDE_;
\r
44 //! Finds the nearest collision point of a line and lots of triangles, if there is one.
\r
45 virtual bool getCollisionPoint(SCollisionHit& hitResult, const core::line3d<f32>& ray,
\r
46 ITriangleSelector* selector) _IRR_OVERRIDE_;
\r
48 //! Collides a moving ellipsoid with a 3d world with gravity and returns
\r
49 //! the resulting new position of the ellipsoid.
\r
50 virtual core::vector3df getCollisionResultPosition(
\r
51 ITriangleSelector* selector,
\r
52 const core::vector3df &ellipsoidPosition,
\r
53 const core::vector3df& ellipsoidRadius,
\r
54 const core::vector3df& ellipsoidDirectionAndSpeed,
\r
55 core::triangle3df& triout,
\r
56 core::vector3df& hitPosition,
\r
58 ISceneNode*& outNode,
\r
60 const core::vector3df& gravityDirectionAndSpeed) _IRR_OVERRIDE_;
\r
62 //! Returns a 3d ray which would go through the 2d screen coordinates.
\r
63 virtual core::line3d<f32> getRayFromScreenCoordinates(
\r
64 const core::position2d<s32> & pos, const ICameraSceneNode* camera = 0) _IRR_OVERRIDE_;
\r
66 //! Calculates 2d screen position from a 3d position.
\r
67 virtual core::position2d<s32> getScreenCoordinatesFrom3DPosition(
\r
68 const core::vector3df & pos, const ICameraSceneNode* camera=0, bool useViewPort=false) _IRR_OVERRIDE_;
\r
70 //! Gets the scene node and nearest collision point for a ray based on
\r
71 //! the nodes' id bitmasks, bounding boxes and triangle selectors.
\r
72 virtual ISceneNode* getSceneNodeAndCollisionPointFromRay(
\r
73 SCollisionHit& hitResult,
\r
74 const core::line3df& ray,
\r
76 ISceneNode * collisionRootNode = 0,
\r
77 bool noDebugObjects = false) _IRR_OVERRIDE_;
\r
81 //! recursive method for going through all scene nodes
\r
82 void getPickedNodeBB(ISceneNode* root, core::line3df& ray, s32 bits,
\r
83 bool bNoDebugObjects,
\r
84 f32& outbestdistance, ISceneNode*& outbestnode);
\r
86 //! recursive method for going through all scene nodes
\r
87 void getPickedNodeFromBBAndSelector(
\r
88 SCollisionHit& hitResult,
\r
90 core::line3df & ray,
\r
92 bool noDebugObjects,
\r
93 f32 & outBestDistanceSquared);
\r
96 struct SCollisionData
\r
98 core::vector3df eRadius;
\r
100 core::vector3df R3Velocity;
\r
101 core::vector3df R3Position;
\r
103 core::vector3df velocity;
\r
104 core::vector3df normalizedVelocity;
\r
105 core::vector3df basePoint;
\r
107 bool foundCollision;
\r
108 f32 nearestDistance;
\r
109 core::vector3df intersectionPoint;
\r
111 core::triangle3df intersectionTriangle;
\r
112 irr::scene::ISceneNode* node;
\r
117 ITriangleSelector* selector;
\r
120 //! Tests the current collision data against an individual triangle.
\r
122 \param colData: the collision data.
\r
123 \param triangle: the triangle to test against.
\r
124 \return true if the triangle is hit (and is the closest hit), false otherwise */
\r
125 bool testTriangleIntersection(SCollisionData* colData,
\r
126 const core::triangle3df& triangle);
\r
128 //! recursive method for doing collision response
\r
129 core::vector3df collideEllipsoidWithWorld(ITriangleSelector* selector,
\r
130 const core::vector3df &position,
\r
131 const core::vector3df& radius, const core::vector3df& velocity,
\r
133 const core::vector3df& gravity, core::triangle3df& triout,
\r
134 core::vector3df& hitPosition,
\r
136 ISceneNode*& outNode);
\r
138 core::vector3df collideWithWorld(s32 recursionDepth, SCollisionData &colData,
\r
139 const core::vector3df& pos, const core::vector3df& vel);
\r
141 inline bool getLowestRoot(f32 a, f32 b, f32 c, f32 maxR, f32* root) const;
\r
143 ISceneManager* SceneManager;
\r
144 video::IVideoDriver* Driver;
\r
145 core::array<core::triangle3df> Triangles; // triangle buffer
\r
149 } // end namespace scene
\r
150 } // end namespace irr
\r