kick
/Users/morten/Programmering/cpp/kick/src/kick/math/kd_tree.h
00001 #pragma once
00002 
00003 #include "kick/math/aabb.h"
00004 #include "kick/math/ray.h"
00005 #include "glm/glm.hpp"
00006 #include <functional>
00007 #include <vector>
00008 
00009 namespace kick {
00010 
00011 
00012 
00013 
00014     struct KDTreeHitInfo;
00015 
00016     struct KDTreeNodeRef {
00017         KDTreeNodeRef();
00018         KDTreeNodeRef(const KDTreeNodeRef& other);
00019 
00020         glm::vec3 triangle[3];
00021         int id;
00022 
00023         bool intersectRay(const Ray &ray, KDTreeHitInfo& hit) const;
00024         AABB getAABB() const;
00025     };
00026     struct KDTreeHitInfo {
00027         float distance = std::numeric_limits<float>::max();
00028         KDTreeNodeRef const *hit;
00029         glm::vec3 collisionPoint;
00030     };
00031 
00032     class KDTreeNode {
00033     public:
00034         KDTreeNode *leftChild;
00035         KDTreeNode *rightChild;
00036         AABB aabb;
00037         float splittingPlane;
00038         int splittingAxis;
00039         std::vector<KDTreeNodeRef> objects;
00040 
00041         KDTreeNode(const AABB &aabb);
00042 
00043 
00044 
00045         bool isLeaf();
00046     };
00047 
00048 // Abstract KDTree
00049     class KDTree {
00050     public:
00051         /*
00052         *  treeDepth: The max depth of tree nodes
00053         *  minVoxelObjects: The minimum number of objects in a tree node (if less, node is not subdivided)
00054         */
00055         KDTree();
00056         ~KDTree(void);
00057         virtual void init(std::vector<KDTreeNodeRef> &objectList, AABB &aabb);
00058 
00059         virtual bool first_intersection(Ray &ray, KDTreeHitInfo& hit);
00060 
00061     protected:
00062         std::vector<KDTreeNodeRef> objectList;
00063         KDTreeNode *rootNode;
00064         AABB aabb;
00065         bool intersect(KDTreeNode *child, const Ray &ray, KDTreeHitInfo& hit, glm::vec3 startPoint);
00066         KDTreeNode *recursiveBuild(const std::vector<KDTreeNodeRef>& objectList, AABB &aabb, int currentDepth);
00067         virtual bool terminateBuild(const std::vector<KDTreeNodeRef>& objectList, AABB &aabb, int currentDepth) = 0;
00068         /***
00069          * Find optimal splitting plane
00070          */
00071         virtual void findPlane(const std::vector<KDTreeNodeRef>& objectList, AABB &aabb, int currentDepth, KDTreeNode *node) = 0;
00072 };
00073 
00074 
00075     // The Simple KD tree uses a näive spatial median as splitting plane
00076 class KDTreeNaive : public KDTree {
00077 public:
00078     /*
00079 *  treeDepth: The max depth of tree nodes
00080 *  minVoxelObjects: The minimum number of objects in a tree node (if less, node is not subdivided)
00081 */
00082         KDTreeNaive(int treeDepth = 12, int minVoxelObjects = 20);
00083 protected:
00084 
00085     bool terminateBuild(const std::vector<KDTreeNodeRef>& objectList, AABB &aabb, int currentDepth);
00086 
00087     /***
00088          * Find optimal splitting plane
00089          */
00090         void findPlane(const std::vector<KDTreeNodeRef>& objectList, AABB &aabb, int currentDepth, KDTreeNode *node);
00091         
00092 private:
00093         int treeDepth;
00094     int minVoxelObjects;
00095 };
00096 
00097 }
00098         
 All Classes Functions Variables