/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #ifndef __NBIH__ #define __NBIH__ #include "geometry/bounding_box.h" #include "container/narray.h" #include "memory/nauto_ptr.h" namespace GS { namespace BIH { // Bounding interval hierarchy node. struct Node { char axis; ///< @TODO: Packed bitfield! void *p; ///< Pointer to child nodes or index array. union { uint count; ///< Index count in leaf. float split[2]; ///< Split planes. }; Node() : axis(3), p(0) {} ~Node(); }; struct StackEntry { Node *node; float tmin, tmax; }; // struct Trace { StackEntry stack[65]; uint stack_pos; bool want_closest; bool has_i; ///< Do we have an intersection. float i_t; ///< Distance to intersection from ray's origin. Vector4 s; ///< Ray origin. Vector4 d; ///< Ray direction. uint node_visited; ///< Number of nodes visited. Trace(bool closest = true) : want_closest(closest), has_i(false) {} }; /*! @short Bounding interval hierarchy. This is a fully generic bounding interval hierarchy implementation. In order to use this structure on a custom set of data you need to derive from this class and provide the implementation for the TraceLeaf method. In order to build the structure you simply provide a list of volumes to the build() methods. @author Emmanuel Julien (ejulien@gsworks.fr) */ class Tree { protected: /// Minimum leaf volume count. uint min_leaf_vcount; MinMax minmax; ///< Hierarchy bounding box. AutoPtr root; ///< Hierarchy root node. Array sarray; ///< Index array. uint node_count; uint leaf_count; uint depth; /*! @name Trace functions. @{ */ /// Trace a leaf. virtual void TraceLeaf(Node *leaf, float tmin, float tmax, Trace &trace, void *parm = 0) = 0; /// Trace a node. void TraceNode(Node *node, float tmin, float tmax, Trace &trace); /// @} /*! @name Intersection functions. @{ */ /// Intersect a node. uint IntersectNode(Node *node, MinMax &sub_mm, uint *index_array, uint max_index); /// @} /*! @name Build functions. @{ */ /// Create a leaf. void MakeNodeLeaf(Node *node, uint count, uint *sarray, MinMax *varray); /// Perform a node split. void DoNodeSplit(MinMax &minmax, uint count, uint *sarray, MinMax *varray, uint &pivot, Node *node, uint &split_axis); /// Split an index list of volumes. bool Split(MinMax &minmax, uint count, uint *sarray, MinMax *varray, Node *node, uint depth); /// Build hierarchy from a set of input volumes. virtual bool Build(uint volume_count, MinMax *varray); /// @} public: /// Intersect tree with an axis aligned bounding box. uint Intersect(MinMax &minmax, uint *index_array, uint max_index); /* @short Raytrace hierarchy. @note Ray direction must be normalized. */ virtual void Raytrace(Trace &trace, const Vector4 &s, const Vector4 &d, float l = -1.f, void *parm = 0); /// Delete hierarchy. virtual void Free(); Tree(); virtual ~Tree(); }; } // BIH } // GS #endif // __NBIH__