The Simplest RT
Data Structure:
Code
class e_RayTriangle {
public:
e_RayGPIndex source_inst; // 2
e_RayGPIndex source_prim; // 2
ushort no_use_1[2]; // 4
Vector3f v1, v2, v3; // 36
Vector3f n1, n2, n3; // 36
Vector3f t1, t2, t3; // 36
ushort no_use_2; // 2
// 128
};
class e_RayMotionTriangle {
public:
e_RayGPIndex source_inst; // 2
e_RayGPIndex source_prim; // 2
Vector3f v1, v2, v3; // 36
Vector3f n1, n2, n3; // 36
Vector3f t1, t2, t3; // 36
Vector3f mv1, mv2, mv3; // 36
ushort no_use[6]; // 12
// 160
};
class e_RayAccelTriangle {
public:
union {
struct {
Vector4f normal; // 16
Vector3f la, lb; // 24
ushort projX, projY, projZ; // 6
ushort no_used; // 2
};
byte pad[48]; // 48
};
};
class e_RayAccelMotionTriangle {
public:
union {
struct {
float xmin, xmax,
m_xmin, m_xmax,
ymin, ymax,
m_ymin, m_ymax,
zmin, zmax,
m_zmin, m_zmax;
};
byte pad[48]; // 48
};
};
class e_RayBSPNode {
public:
union {
float splitter; // interior: division plane position
e_RayGPIndex *prims; // leaf: list of primitives
};
int flags; // 2bits: is_leaf, axis;
// 30bits: interior: number of primitives
// leaf: index of right child
};
class e_RayInterface {
public:
void buildTree();
void buildSubTree();
BOOL intersect( const e_RayGPIndex index );
void getBound( Bound6f & box, const e_RayGPIndex index );
void splitBound( Bound6f & left_box, Bound6f & right_box, const Bound6f & box, const int axis, const float plane );
private:
BOOL isStatic( const e_RayGPIndex index );
BOOL intersectStatic( e_RayState *state, const e_RayGPIndex index );
BOOL intersectMotion( e_RayState *state, const e_RayGPIndex index );
void getBoundStatic( Bound6f & box, const e_RayGPIndex index );
void getBoundMotion( Bound6f & box, const e_RayGPIndex index );
void splitBoundStatic( Bound6f & left_box, Bound6f & right_box, const Bound6f & box, const int axis, const float plane );
void splitBoundMotion( Bound6f & left_box, Bound6f & right_box, const Bound6f & box, const int axis, const float plane );
public:
e_RayGPIndex num_triangles;
e_RayGPIndex num_motion_triangles;
e_FileReader trilist[ MAX_NUM_THREADS ];
e_FileReader motion_trilist[ MAX_NUM_THREADS ];
e_FileReader accel_trilist[ MAX_NUM_THREADS ];
e_FileReader accel_motion_trilist[ MAX_NUM_THREADS ];
e_RayBSPNode *nodes;
};
void e_RayInterface::buildTree()
{
}
void e_RayInterface::buildSubTree()
{
}
BOOL e_RayInterface::intersect( e_RayState *state, const e_RayGPIndex index )
{
if( isStatic( index ) )
{
return intersectStatic( state, index );
}
else
{
return intersectMotion( state, index );
}
}
void e_RayInterface::getBound( Bound6f & box, const e_RayGPIndex index )
{
if( isStatic( index ) )
{
getBoundStatic( box, index );
}
else
{
getBoundMotion( box, index );
}
}
void e_RayInterface::splitBound( Bound6f & left_box, Bound6f & right_box, const Bound6f & box, const int axis, const float plane )
{
if( isStatic( index ) )
{
splitBoundStatic( left_box, right_box, box, axis, plane );
}
else
{
splitBoundMotion( left_box, right_box, box, axis, plane );
}
}
BOOL e_RayInterface::isStatic( const e_RayGPIndex index )
{
if( index < num_triangles )
{
return TRUE;
}
else
{
return FALSE;
}
}
class e_RayTriangle {
public:
e_RayGPIndex source_inst; // 2
e_RayGPIndex source_prim; // 2
ushort no_use_1[2]; // 4
Vector3f v1, v2, v3; // 36
Vector3f n1, n2, n3; // 36
Vector3f t1, t2, t3; // 36
ushort no_use_2; // 2
// 128
};
class e_RayMotionTriangle {
public:
e_RayGPIndex source_inst; // 2
e_RayGPIndex source_prim; // 2
Vector3f v1, v2, v3; // 36
Vector3f n1, n2, n3; // 36
Vector3f t1, t2, t3; // 36
Vector3f mv1, mv2, mv3; // 36
ushort no_use[6]; // 12
// 160
};
class e_RayAccelTriangle {
public:
union {
struct {
Vector4f normal; // 16
Vector3f la, lb; // 24
ushort projX, projY, projZ; // 6
ushort no_used; // 2
};
byte pad[48]; // 48
};
};
class e_RayAccelMotionTriangle {
public:
union {
struct {
float xmin, xmax,
m_xmin, m_xmax,
ymin, ymax,
m_ymin, m_ymax,
zmin, zmax,
m_zmin, m_zmax;
};
byte pad[48]; // 48
};
};
class e_RayBSPNode {
public:
union {
float splitter; // interior: division plane position
e_RayGPIndex *prims; // leaf: list of primitives
};
int flags; // 2bits: is_leaf, axis;
// 30bits: interior: number of primitives
// leaf: index of right child
};
class e_RayInterface {
public:
void buildTree();
void buildSubTree();
BOOL intersect( const e_RayGPIndex index );
void getBound( Bound6f & box, const e_RayGPIndex index );
void splitBound( Bound6f & left_box, Bound6f & right_box, const Bound6f & box, const int axis, const float plane );
private:
BOOL isStatic( const e_RayGPIndex index );
BOOL intersectStatic( e_RayState *state, const e_RayGPIndex index );
BOOL intersectMotion( e_RayState *state, const e_RayGPIndex index );
void getBoundStatic( Bound6f & box, const e_RayGPIndex index );
void getBoundMotion( Bound6f & box, const e_RayGPIndex index );
void splitBoundStatic( Bound6f & left_box, Bound6f & right_box, const Bound6f & box, const int axis, const float plane );
void splitBoundMotion( Bound6f & left_box, Bound6f & right_box, const Bound6f & box, const int axis, const float plane );
public:
e_RayGPIndex num_triangles;
e_RayGPIndex num_motion_triangles;
e_FileReader trilist[ MAX_NUM_THREADS ];
e_FileReader motion_trilist[ MAX_NUM_THREADS ];
e_FileReader accel_trilist[ MAX_NUM_THREADS ];
e_FileReader accel_motion_trilist[ MAX_NUM_THREADS ];
e_RayBSPNode *nodes;
};
void e_RayInterface::buildTree()
{
}
void e_RayInterface::buildSubTree()
{
}
BOOL e_RayInterface::intersect( e_RayState *state, const e_RayGPIndex index )
{
if( isStatic( index ) )
{
return intersectStatic( state, index );
}
else
{
return intersectMotion( state, index );
}
}
void e_RayInterface::getBound( Bound6f & box, const e_RayGPIndex index )
{
if( isStatic( index ) )
{
getBoundStatic( box, index );
}
else
{
getBoundMotion( box, index );
}
}
void e_RayInterface::splitBound( Bound6f & left_box, Bound6f & right_box, const Bound6f & box, const int axis, const float plane )
{
if( isStatic( index ) )
{
splitBoundStatic( left_box, right_box, box, axis, plane );
}
else
{
splitBoundMotion( left_box, right_box, box, axis, plane );
}
}
BOOL e_RayInterface::isStatic( const e_RayGPIndex index )
{
if( index < num_triangles )
{
return TRUE;
}
else
{
return FALSE;
}
}
We don't need dynamic tessellations, geometry instancing, it's the most straightforward but rapid implementation.
A Design based on Array-styled File Reader is the King.