// HBV.h // // (c) Rich Cross, 2000 #ifndef __HBV_H #define __HBV_H #include #include #include "HBVNode.h" #include "Aggregate.h" class Point3; class Vector3; template class HBV { public: HBV(); ~HBV(); Geometry* clone() const; void open(); void add(const T& element); void addMany(const std::vector& v); void close(); bool vectorIntersect(const Point3& origin,const Vector3& dir,float& dist) const; void getBounds(BoundingBox& result) const; void getNormal(const Point3& pt,Vector3& result) const; void getUV(const Point3& pt,float& u,float& v) const; const T& getIntersectedElement() const; private: mutable T _cachedElement; HBVNode* _root; std::vector* _elementList; }; #include "common.h" #include "HBVLeaf.h" template HBV::HBV() : _root(0), _elementList(0), _cachedElement(0) { } template HBV::~HBV() { assert(_elementList==0); delete _root; } template Geometry* HBV::clone() const { assert(0); return 0; } template void HBV::open() { _elementList=new std::vector(); } template void HBV::add(const T& element) { assert(_elementList!=0); _elementList->push_back(element); } template void HBV::addMany(const std::vector& v) { assert(_elementList!=0); for (int i=0;ipush_back(v.at(i)); } template void HBV::close() { std::random_shuffle(_elementList->begin(),_elementList->end()); for (int i=0;i<_elementList->size();i++) { T element=_elementList->at(i); HBVLeaf *leaf=new HBVLeaf(element); if (_root) { _root->addLeaf(leaf); while (_root->getParent()) _root=_root->getParent(); } else _root=leaf; } _elementList->clear(); delete _elementList; _elementList=0; } template bool HBV::vectorIntersect(const Point3& origin,const Vector3& dir,float& dist) const { T element; _cachedElement=0; int result=_root->vectorIntersect(origin,dir,dist,element); if (result) { _cachedElement=element; return true; } return false; } template void HBV::getBounds(BoundingBox& result) const { result=_root->getBounds(); } template void HBV::getNormal(const Point3& pt,Vector3& result) const { assert(_cachedElement!=0); _cachedElement->getNormal(pt,result); } template void HBV::getUV(const Point3& pt,float& u,float& v) const { assert(_cachedElement!=0); _cachedElement->getUV(pt,u,v); } template const T& HBV::getIntersectedElement() const { assert(_cachedElement!=0); return _cachedElement; } #endif