CSceneCollisionManager.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. // Copyright (C) 2002-2012 Nikolaus Gebhardt
  2. // This file is part of the "Irrlicht Engine".
  3. // For conditions of distribution and use, see copyright notice in irrlicht.h
  4. #ifndef __C_SCENE_COLLISION_MANAGER_H_INCLUDED__
  5. #define __C_SCENE_COLLISION_MANAGER_H_INCLUDED__
  6. #include "ISceneCollisionManager.h"
  7. #include "ISceneManager.h"
  8. #include "IVideoDriver.h"
  9. namespace irr
  10. {
  11. namespace scene
  12. {
  13. //! The Scene Collision Manager provides methods for performing collision tests and picking on scene nodes.
  14. class CSceneCollisionManager : public ISceneCollisionManager
  15. {
  16. public:
  17. //! constructor
  18. CSceneCollisionManager(ISceneManager* smanager, video::IVideoDriver* driver);
  19. //! destructor
  20. virtual ~CSceneCollisionManager();
  21. //! Returns the scene node, which is currently visible at the given
  22. //! screen coordinates, viewed from the currently active camera.
  23. virtual ISceneNode* getSceneNodeFromScreenCoordinatesBB(const core::position2d<s32>& pos,
  24. s32 idBitMask=0, bool bNoDebugObjects=false, ISceneNode* root=0);
  25. //! Returns the nearest scene node which collides with a 3d ray and
  26. //! whose id matches a bitmask.
  27. virtual ISceneNode* getSceneNodeFromRayBB(const core::line3d<f32>& ray,
  28. s32 idBitMask=0, bool bNoDebugObjects=false,
  29. ISceneNode* root=0);
  30. //! Returns the scene node, at which the overgiven camera is looking at and
  31. //! which id matches the bitmask.
  32. virtual ISceneNode* getSceneNodeFromCameraBB(ICameraSceneNode* camera,
  33. s32 idBitMask=0, bool bNoDebugObjects = false);
  34. //! Finds the collision point of a line and lots of triangles, if there is one.
  35. virtual bool getCollisionPoint(const core::line3d<f32>& ray,
  36. ITriangleSelector* selector, core::vector3df& outCollisionPoint,
  37. core::triangle3df& outTriangle,
  38. ISceneNode* & outNode);
  39. //! Collides a moving ellipsoid with a 3d world with gravity and returns
  40. //! the resulting new position of the ellipsoid.
  41. virtual core::vector3df getCollisionResultPosition(
  42. ITriangleSelector* selector,
  43. const core::vector3df &ellipsoidPosition,
  44. const core::vector3df& ellipsoidRadius,
  45. const core::vector3df& ellipsoidDirectionAndSpeed,
  46. core::triangle3df& triout,
  47. core::vector3df& hitPosition,
  48. bool& outFalling,
  49. ISceneNode*& outNode,
  50. f32 slidingSpeed,
  51. const core::vector3df& gravityDirectionAndSpeed);
  52. //! Returns a 3d ray which would go through the 2d screen coodinates.
  53. virtual core::line3d<f32> getRayFromScreenCoordinates(
  54. const core::position2d<s32> & pos, ICameraSceneNode* camera = 0);
  55. //! Calculates 2d screen position from a 3d position.
  56. virtual core::position2d<s32> getScreenCoordinatesFrom3DPosition(
  57. const core::vector3df & pos, ICameraSceneNode* camera=0, bool useViewPort=false);
  58. //! Gets the scene node and nearest collision point for a ray based on
  59. //! the nodes' id bitmasks, bounding boxes and triangle selectors.
  60. virtual ISceneNode* getSceneNodeAndCollisionPointFromRay(
  61. core::line3df ray,
  62. core::vector3df & outCollisionPoint,
  63. core::triangle3df & outTriangle,
  64. s32 idBitMask = 0,
  65. ISceneNode * collisionRootNode = 0,
  66. bool noDebugObjects = false);
  67. private:
  68. //! recursive method for going through all scene nodes
  69. void getPickedNodeBB(ISceneNode* root, core::line3df& ray, s32 bits,
  70. bool bNoDebugObjects,
  71. f32& outbestdistance, ISceneNode*& outbestnode);
  72. //! recursive method for going through all scene nodes
  73. void getPickedNodeFromBBAndSelector(ISceneNode * root,
  74. core::line3df & ray,
  75. s32 bits,
  76. bool noDebugObjects,
  77. f32 & outBestDistanceSquared,
  78. ISceneNode * & outBestNode,
  79. core::vector3df & outBestCollisionPoint,
  80. core::triangle3df & outBestTriangle);
  81. struct SCollisionData
  82. {
  83. core::vector3df eRadius;
  84. core::vector3df R3Velocity;
  85. core::vector3df R3Position;
  86. core::vector3df velocity;
  87. core::vector3df normalizedVelocity;
  88. core::vector3df basePoint;
  89. bool foundCollision;
  90. f32 nearestDistance;
  91. core::vector3df intersectionPoint;
  92. core::triangle3df intersectionTriangle;
  93. s32 triangleIndex;
  94. s32 triangleHits;
  95. f32 slidingSpeed;
  96. ITriangleSelector* selector;
  97. };
  98. //! Tests the current collision data against an individual triangle.
  99. /**
  100. \param colData: the collision data.
  101. \param triangle: the triangle to test against.
  102. \return true if the triangle is hit (and is the closest hit), false otherwise */
  103. bool testTriangleIntersection(SCollisionData* colData,
  104. const core::triangle3df& triangle);
  105. //! recursive method for doing collision response
  106. core::vector3df collideEllipsoidWithWorld(ITriangleSelector* selector,
  107. const core::vector3df &position,
  108. const core::vector3df& radius, const core::vector3df& velocity,
  109. f32 slidingSpeed,
  110. const core::vector3df& gravity, core::triangle3df& triout,
  111. core::vector3df& hitPosition,
  112. bool& outFalling,
  113. ISceneNode*& outNode);
  114. core::vector3df collideWithWorld(s32 recursionDepth, SCollisionData &colData,
  115. core::vector3df pos, core::vector3df vel);
  116. inline bool getLowestRoot(f32 a, f32 b, f32 c, f32 maxR, f32* root);
  117. ISceneManager* SceneManager;
  118. video::IVideoDriver* Driver;
  119. core::array<core::triangle3df> Triangles; // triangle buffer
  120. };
  121. } // end namespace scene
  122. } // end namespace irr
  123. #endif