X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2FMoof%2FOctree.hh;h=4dc0c5c7e460e801594585200e47d3a70bc34064;hb=3cba2347188d70f5ee6e401774b8f86acfd1a3b9;hp=78d3aa875706cd61f4558740c7b90a8cf4f82cd3;hpb=72d4af22710317acffab861421c4364b1780b6fe;p=chaz%2Fyoink diff --git a/src/Moof/Octree.hh b/src/Moof/Octree.hh index 78d3aa8..4dc0c5c 100644 --- a/src/Moof/Octree.hh +++ b/src/Moof/Octree.hh @@ -29,24 +29,36 @@ #ifndef _MOOF_OCTREE_HH_ #define _MOOF_OCTREE_HH_ +#include #include #include +#include + #include #include #include #include #include -#include namespace Mf { +class Camera; + + +struct OctreeNode; +typedef stlplus::ntree::iterator OctreeNodeP; + +class Octree; +typedef boost::shared_ptr OctreeP; + + struct OctreeNode : public Entity { - std::list objects; + std::list objects; OctreeNode() { @@ -64,24 +76,26 @@ struct OctreeNode : public Entity void draw(Scalar alpha) const { - std::list::const_iterator it; + std::list::const_iterator it; for (it = objects.begin(); it != objects.end(); ++it) { (*it)->draw(alpha); } + if (!objects.empty()) aabb_.draw(); // temporary } void drawIfVisible(Scalar alpha, const Camera& cam) const { - std::list::const_iterator it; + std::list::const_iterator it; for (it = objects.begin(); it != objects.end(); ++it) { (*it)->drawIfVisible(alpha, cam); } + if (!objects.empty()) aabb_.draw(); } @@ -96,245 +110,60 @@ struct OctreeNode : public Entity return false; } -}; - - -class Octree; -typedef boost::shared_ptr OctreePtr; - -class Octree : public Tree -{ - Octree() {} - explicit Octree(const OctreeNode& initNode) : - Tree(initNode) {} - -public: - - inline static OctreePtr createNewNode(const OctreeNode& item) + static bool compareZOrder(EntityP a, EntityP b) { - OctreePtr newNode = OctreePtr(new Octree(item)); - init(newNode); - return newNode; + return a->getSphere().point[2] < b->getSphere().point[2]; } - - static Tree::WeakPtr add(Ptr node, EntityPtr entity) + void sort() { - Plane::Halfspace halfspace; - int octantNum = -1; + //std::sort(objects.begin(), objects.end(), compareZOrder); + objects.sort(compareZOrder); + } +}; - Plane xy = node->node.getAabb().getPlaneXY(); - halfspace = xy.intersectsSphere(entity->getSphere()); - if (halfspace == Plane::POSITIVE) - { - Plane xz = node->node.getAabb().getPlaneXZ(); - halfspace = xz.intersectsSphere(entity->getSphere()); - - if (halfspace == Plane::POSITIVE) - { - Plane yz = node->node.getAabb().getPlaneYZ(); - halfspace = yz.intersectsSphere(entity->getSphere()); - - if (halfspace == Plane::POSITIVE) - { - octantNum = 2; - } - else if (halfspace == Plane::NEGATIVE) - { - octantNum = 3; - } - } - else if (halfspace == Plane::NEGATIVE) - { - Plane yz = node->node.getAabb().getPlaneYZ(); - halfspace = yz.intersectsSphere(entity->getSphere()); - - if (halfspace == Plane::POSITIVE) - { - octantNum = 1; - } - else if (halfspace == Plane::NEGATIVE) - { - octantNum = 0; - } - } - } - else if (halfspace == Plane::NEGATIVE) - { - Plane xz = node->node.getAabb().getPlaneXZ(); - halfspace = xz.intersectsSphere(entity->getSphere()); - - if (halfspace == Plane::POSITIVE) - { - Plane yz = node->node.getAabb().getPlaneYZ(); - halfspace = yz.intersectsSphere(entity->getSphere()); - - if (halfspace == Plane::POSITIVE) - { - octantNum = 6; - } - else if (halfspace == Plane::NEGATIVE) - { - octantNum = 7; - } - } - else if (halfspace == Plane::NEGATIVE) - { - Plane yz = node->node.getAabb().getPlaneYZ(); - halfspace = yz.intersectsSphere(entity->getSphere()); - - if (halfspace == Plane::POSITIVE) - { - octantNum = 5; - } - else if (halfspace == Plane::NEGATIVE) - { - octantNum = 4; - } - } - } +class Octree +{ + OctreeNodeP insert(EntityP entity, OctreeNodeP node); + + void addChild(OctreeNodeP node, int index); - if (octantNum == -1) - { - node->node.objects.push_front(entity); - return node; - } - else - { - if (node->isLeaf()) - { - addChildren(node); - } - - Ptr child = node->getChild(octantNum); - if (child) - { - return add(child, entity); - } - else - { - std::cerr << "no child at index " << octantNum << std::endl; - return Ptr(); - } - //return WeakPtr(); - } - } + void draw(Scalar alpha, OctreeNodeP node); + void drawIfVisible(Scalar alpha, const Camera& cam, OctreeNodeP node); - static void addChildren(Ptr node) - { - Aabb octant; + stlplus::ntree tree_; - for (int i = 0; i < 8; ++i) - { - node->node.getAabb().getOctant(octant, i); - //OctreeNode octantNode(octant); +public: - Ptr newChild = createNewNode(octant); - node->addChild(newChild); - } + inline static OctreeP alloc(const OctreeNode& rootNode) + { + return OctreeP(new Octree(rootNode)); } - void draw(Ptr node, Scalar alpha) + explicit Octree(const OctreeNode& rootNode) { - if (!node) - { - std::cerr << "null child :-(" << std::endl; - return; - } - - node->node.draw(alpha); - - if (!node->isLeaf()) - { - Ptr firstChild = node->getFirstChild(); - Ptr temp = firstChild; - - if (!firstChild) - { - std::cerr << "node is not a leaf, but has no first child :-(" << std::endl; - return; - } - - do - { - draw(temp, alpha); - temp = temp->getNextSibling(); - } - while (temp && temp != firstChild); - } + tree_.insert(rootNode); } - void drawIfVisible(Ptr node, Scalar alpha, const Camera& cam) + OctreeNodeP insert(EntityP entity) { - //node.drawIfVisible(alpha, cam); - - if (!node) - { - std::cerr << "null child :-(" << std::endl; - return; - } - - Frustum::Collision collision = - cam.getFrustum().containsSphere(node->node.getSphere()); - if (collision == Frustum::OUTSIDE) return; - - collision = cam.getFrustum().containsAabb(node->node.getAabb()); - if (collision == Frustum::OUTSIDE) return; - - - if (collision == Frustum::INSIDE) - { - node->node.draw(alpha); - } - else // collision == Frustum::INTERSECT - { - node->node.drawIfVisible(alpha, cam); - } - - if (!node->isLeaf()) - { - Ptr firstChild = node->getFirstChild(); - Ptr temp = firstChild; - - if (!firstChild) - { - std::cerr << "node is not a leaf, but has no first child :-(" << std::endl; - return; - } - - if (collision == Frustum::INSIDE) - { - do - { - draw(temp, alpha); - temp = temp->getNextSibling(); - } - while (temp && temp != firstChild); - } - else // collision == Frustum::INTERSECT - { - do - { - drawIfVisible(temp, alpha, cam); - temp = temp->getNextSibling(); - } - while (temp && temp != firstChild); - } - } + return insert(entity, tree_.root()); } + OctreeNodeP reinsert(EntityP entity, OctreeNodeP node); + void drawIfVisible(Scalar alpha, const Camera& cam) { - drawIfVisible(getThis(), alpha, cam); + drawIfVisible(alpha, cam, tree_.root()); } + void sort(); }; - } // namespace Mf #endif // _MOOF_OCTREE_HH_