#ifndef voxel_h #define voxel_h #include "flags.h" #include "object.h" class rtl_groupobj; class rtl_groupmem; class rtl_lclvoxel; class rtl_voxel { public: rtl_voxel(); ~rtl_voxel(); jFlt trace( rtl_ray& ray ) { return trace(ray,ray.origin()); } bool empty() const { return flags.on(Leaf) && !data.objects.olist; } const jBBox& volume() const { return box; } static bool naive() { return MaxDepth==0; } static jUInt MaxObjects; static jUInt MaxDepth; protected: static const jULng Subdivided; static const jULng Leaf; jFlt trace( rtl_ray&, const jVec3& ); jFlt naiveTrace( rtl_ray& ray ) { jFlt t,time = NOHIT; for(rtl_voxel::olink* o = data.objects.olist; o; o = o->next) { t = o->obj->intersect(ray,false); if(t>EPS && (t<time || time<EPS)) { // this may be casting a rtl_subobject* which is not an // rtl_object* ray.hit = (rtl_object*)o->obj; time = t; } } return time; } struct olink { olink( rtl_subobject*, bool, olink* ); ~olink(); rtl_subobject* obj; bool full; olink* next; }; union { struct { olink* olist; jUInt cnt; } objects; struct { rtl_voxel* vtable; jUInt subnx,subny,subnz; } voxels; } data; jUInt dep; jBBox box; rtl_flags flags; void subdivide(); jFlt traverse( rtl_ray&, const jVec3& ); bool intersection( rtl_ray&, rtl_voxel&, jFlt&, const jVec3& ); friend class rtl_world; friend class rtl_groupobj; friend class rtl_lclvoxel; void add( rtl_object* ); void add( rtl_subobject*, bool ); public: class objectiter { public: objectiter( rtl_voxel* v ) : o(v->data.objects.olist), cnt(v->data.objects.cnt) {} int count() { return cnt; } void operator ++ () { o = o->next; } operator bool () { return o!=0; } rtl_subobject* object() { return o->obj; } private: rtl_voxel::olink* o; int cnt; }; friend class rtl_voxel::objectiter; }; class rtl_lclvoxel : public rtl_voxel { public: rtl_groupobj* groupObject() { return obj; } void groupObject( rtl_groupobj* o ) { obj = o; } rtl_lclvoxel( rtl_groupobj* ); void add( rtl_groupmem* ); void add( rtl_groupmem*, jUInt, jUInt, jUInt ); void subdivide( const jBBox&, jUInt ); const jBBox& voxelBounds( jUInt, jUInt, jUInt ) const; void report() const; private: rtl_groupobj* obj; }; #endif