osg::ParticleBSPTree Class Reference

Particle BSP Tree. More...

#include <OSGParticleBSP.h>

List of all members.

Public Member Functions

Constructors


 ParticleBSPTree (void)
Destructors


virtual ~ParticleBSPTree (void)
Creation / Deletion


bool created (void)
void build (Particles *core)
void destroy (void)
Traversal


Int32traverse (const Pnt3f &refPoint, UInt32 &length, Int32 *order=NULL) const
Int32traverse (const Vec3f &refVec, UInt32 &length, Int32 *order=NULL) const
Input / Output


virtual void dump (UInt32 uiIndent=0, const BitVector bvFlags=0) const
void putToString (std::string &outVal) const
bool getFromString (const Char8 *&inVal)
UInt32 getBinSize (void) const
void copyToBin (BinaryDataHandler &pMem) const
void copyFromBin (BinaryDataHandler &pMem)

Protected Member Functions

Node Traversal


UInt32 doTraverse (const Pnt3f &refPoint, UInt32 index, UInt32 length, Int32 *order) const
UInt32 doTraverse (const Vec3f &refVec, UInt32 index, UInt32 length, Int32 *order) const
Creation Tools


UInt32 doBuild (std::vector< Int32 >::iterator begin, std::vector< Int32 >::iterator end, UInt32 nodeindex, GeoPositionsPtr pos)

Private Attributes

std::vector< ParticleBSPNode_tree


Detailed Description

A very simple BSP tree, optimized for particle sorting.

Definition at line 130 of file OSGParticleBSP.h.


Constructor & Destructor Documentation

ParticleBSPTree::ParticleBSPTree ( void   ) 

Definition at line 127 of file OSGParticleBSP.cpp.

00128 {
00129 }

ParticleBSPTree::~ParticleBSPTree ( void   )  [virtual]

Definition at line 131 of file OSGParticleBSP.cpp.

00132 {
00133 } 


Member Function Documentation

bool osg::ParticleBSPTree::created ( void   )  [inline]

Definition at line 87 of file OSGParticleBSP.inl.

References _tree.

00088 {
00089     return _tree.size() > 1;
00090 }

void ParticleBSPTree::build ( Particles core  ) 

Definition at line 362 of file OSGParticleBSP.cpp.

References _tree, doBuild(), FWARNING, osg::ParticlesBase::getMFIndices(), osg::ParticlesBase::getPositions(), osg::NullFC, osg::osgnextpower2(), osg::MField< FieldTypeT, fieldNameSpace >::reserve(), and osg::MField< FieldTypeT, fieldNameSpace >::size().

Referenced by osg::Particles::drawPrimitives().

00363 {
00364     _tree.clear();
00365     
00366     if(core == NULL)
00367     {
00368         FWARNING(("ParticleBSP::build: no core!!\n"));
00369         return;
00370     }
00371     
00372     const GeoPositionsPtr pos = core->getPositions();
00373     
00374     if(pos == NullFC)
00375         return;
00376 
00377     const MFInt32 *indices = core->getMFIndices();
00378         
00379     // 1. create list for particles
00380  
00381     std::vector<Int32> order;
00382     order.reserve(pos->getSize());
00383     
00384     for(UInt32 i = 0; i < pos->getSize(); ++i )
00385     {     
00386         if(indices->size() == pos->getSize())
00387         {        
00388             order.push_back((*indices)[i]);
00389         }
00390         else
00391         {
00392             order.push_back(i);            
00393         }
00394     }
00395     
00396     // reserve mem for tree
00397     
00398     _tree.resize(osgnextpower2(order.size()) * 2);
00399     
00400     // 2. recursively build the tree
00401     
00402     UInt32 nnodes = doBuild(order.begin(), order.end(), 1, pos);
00403     
00404     // 3. remove the unneeded elements from the end
00405     
00406     if(nnodes < _tree.size())
00407         _tree.erase( _tree.begin() + nnodes, _tree.end());
00408 
00409     // done
00410 }

void ParticleBSPTree::destroy ( void   ) 

Definition at line 495 of file OSGParticleBSP.cpp.

References _tree.

Referenced by osg::Particles::changed().

00496 {
00497     _tree.clear();
00498 }

Int32 * ParticleBSPTree::traverse ( const Pnt3f refPoint,
UInt32 length,
Int32 order = NULL 
) const

Definition at line 279 of file OSGParticleBSP.cpp.

References _tree, and doTraverse().

Referenced by osg::Particles::drawPrimitives().

00281 {
00282     if(_tree.empty())
00283         return NULL;
00284         
00285     if(order == NULL)
00286     {
00287         order = new Int32 [length];
00288     }
00289     
00290     length = doTraverse(refPoint,1,0,order);
00291     
00292     return order;
00293 }

Int32 * ParticleBSPTree::traverse ( const Vec3f refVec,
UInt32 length,
Int32 order = NULL 
) const

Definition at line 321 of file OSGParticleBSP.cpp.

References doTraverse().

00323 {
00324     if(order == NULL)
00325     {
00326         order = new Int32 [length];
00327     }
00328     
00329     length = doTraverse(refVec,1,0,order);
00330     
00331     return order;
00332 }

void ParticleBSPTree::dump ( UInt32  uiIndent = 0,
const BitVector  bvFlags = 0 
) const [virtual]

Definition at line 137 of file OSGParticleBSP.cpp.

References _tree, and PLOG.

00139 {
00140     PLOG << "ParticleBSPTree(";
00141 
00142     if(!_tree.empty())
00143     {
00144         for(std::vector<ParticleBSPNode>::const_iterator i = _tree.begin() + 1;
00145             i != _tree.end(); ++i )
00146         {
00147             i->dump();
00148         }
00149     }   
00150     
00151     PLOG << ")" << std::endl;
00152 }

void ParticleBSPTree::putToString ( std::string &  outVal  )  const

Definition at line 154 of file OSGParticleBSP.cpp.

References _tree.

Referenced by osg::osg::FieldDataTraits< ParticleBSPTree >::putToString().

00155 {
00156     outVal.assign(TypeTraits<UInt32>::putToString(_tree.size()));
00157     outVal.append(";");
00158     
00159     if(! _tree.empty())
00160     {
00161         for(std::vector<ParticleBSPNode>::const_iterator i = _tree.begin() + 1;
00162             i != _tree.end(); ++i )
00163         {
00164             outVal.append(TypeTraits<UInt8>::putToString(i->getAxis()));
00165             outVal.append(":");
00166             if(i->isLeaf())
00167             {
00168                 outVal.append(TypeTraits<Int32>::putToString(i->getValue()));
00169             }
00170             else
00171             {
00172                 outVal.append(TypeTraits<Real32>::putToString(
00173                     i->getSplitValue()));
00174             }
00175             outVal.append(";");
00176         }   
00177     }
00178 }

bool ParticleBSPTree::getFromString ( const Char8 *&  inVal  ) 

Definition at line 180 of file OSGParticleBSP.cpp.

References _tree, and osg::ParticleBSPNode::Leaf.

Referenced by osg::osg::FieldDataTraits< ParticleBSPTree >::getFromString().

00181 {
00182     UInt32 size = TypeTraits<UInt32>::getFromString(inVal);
00183  
00184     const Char8 *c = strchr(inVal, ';');
00185     
00186     if(!c)
00187         return false;
00188     c++;
00189     
00190     _tree.resize(size);
00191     
00192     for(UInt32 i = 1; i < size; ++i)
00193     {
00194         UInt8 axis = TypeTraits<UInt8>::getFromString(c);
00195         c = strchr(c, ':');
00196         if(!c)
00197             return false;
00198         c++;
00199         
00200         if(axis == ParticleBSPNode::Leaf)
00201         {
00202             Int32 value = TypeTraits<Int32>::getFromString(c);
00203             _tree[i].setValue(value);
00204         }
00205         else
00206         {
00207             Real32 value = TypeTraits<Real32>::getFromString(c);
00208             _tree[i].setSplit(axis, value);           
00209         }
00210         c = strchr(c, ';');
00211         if(!c)
00212             return false;
00213         c++;
00214     }
00215     
00216     return true;
00217 }

UInt32 ParticleBSPTree::getBinSize ( void   )  const

Definition at line 219 of file OSGParticleBSP.cpp.

References _tree.

Referenced by osg::osg::FieldDataTraits< ParticleBSPTree >::getBinSize().

00220 {
00221     return sizeof(UInt32) // num elements
00222         + (sizeof(UInt8)+sizeof(UInt32)) * _tree.size();
00223 }

void ParticleBSPTree::copyToBin ( BinaryDataHandler pMem  )  const

Definition at line 225 of file OSGParticleBSP.cpp.

References _tree, osg::ParticleBSPNode::Leaf, and osg::BinaryDataHandler::putValue().

Referenced by osg::osg::FieldDataTraits< ParticleBSPTree >::copyToBin().

00226 {
00227     UInt8  axis;
00228     Int32  value;
00229     Real32 splitvalue;
00230     UInt32 i;
00231     UInt32 size = _tree.size();
00232     pMem.putValue(size);
00233 
00234     for(i=0;i<size;++i)
00235     {
00236         axis=_tree[i].getAxis();
00237         pMem.putValue(axis);
00238         if(axis==ParticleBSPNode::Leaf)
00239         {
00240             value=_tree[i].getValue();
00241             pMem.putValue(value);
00242         }
00243         else
00244         {
00245             splitvalue=_tree[i].getSplitValue();
00246             pMem.putValue(splitvalue);
00247         }
00248     }
00249 }

void ParticleBSPTree::copyFromBin ( BinaryDataHandler pMem  ) 

Definition at line 251 of file OSGParticleBSP.cpp.

References _tree, osg::BinaryDataHandler::getValue(), and osg::ParticleBSPNode::Leaf.

Referenced by osg::osg::FieldDataTraits< ParticleBSPTree >::copyFromBin().

00252 {
00253     UInt8  axis;
00254     Int32  value;
00255     Real32 splitvalue;
00256     UInt32 i;
00257     UInt32 size;
00258     pMem.getValue(size);
00259     _tree.resize(size);
00260 
00261     for(i=0;i<size;++i)
00262     {
00263         pMem.getValue(axis);
00264         if(axis==ParticleBSPNode::Leaf)
00265         {
00266             pMem.getValue(value);
00267             _tree[i].setValue(value);
00268         }
00269         else
00270         {
00271             pMem.getValue(splitvalue);
00272             _tree[i].setSplit(axis, Real32(value));
00273         }
00274     }
00275 }

UInt32 ParticleBSPTree::doTraverse ( const Pnt3f refPoint,
UInt32  index,
UInt32  length,
Int32 order 
) const [protected]

Definition at line 295 of file OSGParticleBSP.cpp.

References _tree, osg::ParticleBSPNode::getAxis(), osg::ParticleBSPNode::getSplitValue(), osg::ParticleBSPNode::getValue(), and osg::ParticleBSPNode::isLeaf().

Referenced by doTraverse(), and traverse().

00297 {
00298     const ParticleBSPNode *n = &_tree[index];
00299     
00300     if(n->isLeaf())
00301     {
00302         order[length] = n->getValue();
00303         return ++length;
00304     }
00305     else
00306     {
00307         if(refPoint[n->getAxis()] > n->getSplitValue())
00308         {
00309             length = doTraverse(refPoint, index * 2    , length, order);
00310             length = doTraverse(refPoint, index * 2 + 1, length, order);
00311         }
00312         else
00313         {
00314             length = doTraverse(refPoint, index * 2 + 1, length, order);
00315             length = doTraverse(refPoint, index * 2    , length, order);
00316         }
00317     }
00318     return length;
00319 }

UInt32 ParticleBSPTree::doTraverse ( const Vec3f refVec,
UInt32  index,
UInt32  length,
Int32 order 
) const [protected]

Definition at line 334 of file OSGParticleBSP.cpp.

References _tree, doTraverse(), osg::ParticleBSPNode::getAxis(), osg::ParticleBSPNode::getValue(), and osg::ParticleBSPNode::isLeaf().

00336 {
00337     const ParticleBSPNode *n = &_tree[index];
00338     
00339     if(n->isLeaf())
00340     {
00341         order[length] = n->getValue();
00342         return ++length;
00343     }
00344     else
00345     {
00346         if(refVec[n->getAxis()] > 0.f)
00347         {
00348             length = doTraverse(refVec, index * 2    , length, order);
00349             length = doTraverse(refVec, index * 2 + 1, length, order);
00350         }
00351         else
00352         {
00353             length = doTraverse(refVec, index * 2 + 1, length, order);
00354             length = doTraverse(refVec, index * 2    , length, order);
00355         }
00356     }
00357     return length;
00358 }

UInt32 ParticleBSPTree::doBuild ( std::vector< Int32 >::iterator  begin,
std::vector< Int32 >::iterator  end,
UInt32  nodeindex,
GeoPositionsPtr  pos 
) [protected]

Definition at line 433 of file OSGParticleBSP.cpp.

References _tree, osg::BoxVolume::extendBy(), osg::BoxVolume::getMax(), osg::BoxVolume::getMin(), osg::osgMax(), p, osg::Volume::setEmpty(), osg::ParticleBSPNode::X, osg::ParticleBSPNode::Y, and osg::ParticleBSPNode::Z.

Referenced by build().

00437 {
00438     // reached a leaf?
00439     
00440     if(begin + 1 == end)
00441     {
00442         _tree[nodeindex].setValue(*begin);
00443         return nodeindex + 1;
00444     }
00445     
00446     // find the bounding volume of the group
00447     
00448     BoxVolume b;
00449     Pnt3f p;
00450     
00451     b.setEmpty();
00452     
00453     for(std::vector<Int32>::iterator i = begin; i != end; ++i)
00454     {
00455         pos->getValue(p,*i);     
00456         b.extendBy(p);
00457     }
00458     
00459     // find the axis with the longest extension
00460     
00461     Vec3f d = b.getMax() - b.getMin();
00462     
00463     UInt8 axis = ParticleBSPNode::X;
00464     Real32 maxval = d[0];
00465     
00466     if(d[1] > maxval)
00467     {
00468         axis = ParticleBSPNode::Y;
00469         maxval = d[1];
00470     }
00471     if(d[2] > maxval)
00472     {
00473         axis = ParticleBSPNode::Z;
00474         maxval = d[2];
00475     }
00476 
00477     // sort in that axis
00478     ParticleCompare comp(pos, axis);
00479     
00480     std::sort(begin,end,comp);
00481     
00482     // find median value
00483     std::vector<Int32>::iterator mid = begin + (end - begin) / 2;
00484     
00485     Pnt3f p2;
00486     pos->getValue(p ,*mid);
00487     pos->getValue(p2,(*mid)-1);
00488     _tree[nodeindex].setSplit(axis, (p[axis] + p2[axis]) / 2.f);
00489     
00490     return osgMax( doBuild(begin, mid, nodeindex * 2    , pos),
00491                    doBuild(  mid, end, nodeindex * 2 + 1, pos) );   
00492 }   


Member Data Documentation


The documentation for this class was generated from the following files:

Generated on Mon Mar 17 12:07:26 2008 for OpenSG by  doxygen 1.5.5