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