You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
3.6 KiB
C++
119 lines
3.6 KiB
C++
#ifndef OPENMW_COMPONENTS_TERRAIN_QUADTREENODE_H
|
|
#define OPENMW_COMPONENTS_TERRAIN_QUADTREENODE_H
|
|
|
|
#include <osg/Group>
|
|
#include <osgUtil/LineSegmentIntersector>
|
|
|
|
#include "defs.hpp"
|
|
|
|
namespace Terrain
|
|
{
|
|
|
|
class TerrainLineIntersector : public osgUtil::LineSegmentIntersector
|
|
{
|
|
public:
|
|
TerrainLineIntersector(osgUtil::LineSegmentIntersector* intersector, osg::Matrix& matrix) :
|
|
osgUtil::LineSegmentIntersector(intersector->getStart() * matrix, intersector->getEnd() * matrix)
|
|
{
|
|
setPrecisionHint(intersector->getPrecisionHint());
|
|
_intersectionLimit = intersector->getIntersectionLimit();
|
|
_parent = intersector;
|
|
}
|
|
|
|
bool intersectAndClip(const osg::BoundingBox& bbInput)
|
|
{
|
|
osg::Vec3d s(_start), e(_end);
|
|
return osgUtil::LineSegmentIntersector::intersectAndClip(s, e, bbInput);
|
|
}
|
|
};
|
|
|
|
enum ChildDirection
|
|
{
|
|
NW = 0,
|
|
NE = 1,
|
|
SW = 2,
|
|
SE = 3,
|
|
Root
|
|
};
|
|
|
|
class QuadTreeNode;
|
|
class LodCallback : public osg::Referenced
|
|
{
|
|
public:
|
|
virtual ~LodCallback() {}
|
|
|
|
virtual bool isSufficientDetail(QuadTreeNode *node, float dist) = 0;
|
|
};
|
|
|
|
class ViewDataMap;
|
|
class ViewData;
|
|
|
|
class QuadTreeNode : public osg::Group
|
|
{
|
|
public:
|
|
QuadTreeNode(QuadTreeNode* parent, ChildDirection dir, float size, const osg::Vec2f& center);
|
|
virtual ~QuadTreeNode();
|
|
|
|
inline QuadTreeNode* getParent() { return mParent; }
|
|
inline QuadTreeNode* getChild(unsigned int i) { return static_cast<QuadTreeNode*>(Group::getChild(i)); }
|
|
inline unsigned int getNumChildren() const { return _children.size(); }
|
|
|
|
// osg::Group::addChild() does a lot of unrelated stuff, but we just really want to add a child node.
|
|
void addChildNode(QuadTreeNode* child)
|
|
{
|
|
// QuadTree node should not contain more than 4 child nodes.
|
|
// Reserve enough space if this node is supposed to have child nodes.
|
|
_children.reserve(4);
|
|
_children.push_back(child);
|
|
child->addParent(this);
|
|
};
|
|
|
|
float distance(const osg::Vec3f& v) const;
|
|
|
|
/// Returns our direction relative to the parent node, or Root if we are the root node.
|
|
ChildDirection getDirection() { return mDirection; }
|
|
|
|
/// Get neighbour node in this direction
|
|
QuadTreeNode* getNeighbour (Direction dir);
|
|
|
|
/// Initialize neighbours - do this after the quadtree is built
|
|
void initNeighbours();
|
|
|
|
void setBoundingBox(const osg::BoundingBox& boundingBox);
|
|
const osg::BoundingBox& getBoundingBox() const;
|
|
bool hasValidBounds() const { return mValidBounds; }
|
|
|
|
virtual osg::BoundingSphere computeBound() const;
|
|
|
|
/// size in cell coordinates
|
|
float getSize() const;
|
|
|
|
/// center in cell coordinates
|
|
const osg::Vec2f& getCenter() const;
|
|
|
|
/// Traverse nodes according to LOD selection.
|
|
void traverse(ViewData* vd, const osg::Vec3f& viewPoint, LodCallback* lodCallback, float maxDist);
|
|
|
|
/// Traverse to a specific node and add only that node.
|
|
void traverseTo(ViewData* vd, float size, const osg::Vec2f& center);
|
|
|
|
/// Adds all leaf nodes which intersect the line from start to end
|
|
void intersect(ViewData* vd, TerrainLineIntersector* intersector);
|
|
|
|
private:
|
|
QuadTreeNode* mParent;
|
|
|
|
QuadTreeNode* mNeighbours[4];
|
|
|
|
ChildDirection mDirection;
|
|
|
|
osg::BoundingBox mBoundingBox;
|
|
bool mValidBounds;
|
|
float mSize;
|
|
osg::Vec2f mCenter;
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|