141 lines
3.2 KiB
C++
141 lines
3.2 KiB
C++
/* -----------------------------------------------------------------------------
|
|
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 <Node> root; ///< Hierarchy root node.
|
|
|
|
Array <uint> 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__
|