UInt32 ParticleBSPTree::doBuild(std::vector<Int32>::iterator begin, std::vector<Int32>::iterator end, UInt32 nodeindex, GeoVectorProperty *pos) { // reached a leaf? if(begin + 1 == end) { _tree[nodeindex].setValue(*begin); return nodeindex + 1; } // find the bounding volume of the group BoxVolume b; Pnt3f p; b.setEmpty(); for(std::vector<Int32>::iterator i = begin; i != end; ++i) { pos->getValue(p,*i); b.extendBy(p); } // find the axis with the longest extension Vec3f d = b.getMax() - b.getMin(); UInt8 axis = ParticleBSPNode::X; Real32 maxval = d[0]; if(d[1] > maxval) { axis = ParticleBSPNode::Y; maxval = d[1]; } if(d[2] > maxval) { axis = ParticleBSPNode::Z; maxval = d[2]; } // sort in that axis ParticleCompare comp(pos, axis); std::sort(begin,end,comp); // find median value std::vector<Int32>::iterator mid = begin + (end - begin) / 2; Pnt3f p2; pos->getValue(p ,*mid); pos->getValue(p2,(*mid)-1); _tree[nodeindex].setSplit(axis, (p[axis] + p2[axis]) / 2.f); return osgMax( doBuild(begin, mid, nodeindex * 2 , pos), doBuild( mid, end, nodeindex * 2 + 1, pos) ); }
void Node::updateVolume(void) { // still valid or static, nothing to do if(_sfVolume.getValue().isValid () == true || _sfVolume.getValue().isStatic() == true || getTravMask() == 0x0000 ) { return; } // be careful to not change the real volume. If two threads // are updating the same aspect this will lead to chaos BoxVolume vol = _sfVolume.getValue(); MFUnrecChildNodePtr::const_iterator cIt = this->getMFChildren()->begin(); MFUnrecChildNodePtr::const_iterator cEnd = this->getMFChildren()->end(); vol.setEmpty(); for(; cIt != cEnd; ++cIt) { if(*cIt != NULL && (*cIt)->getTravMask()) { (*cIt)->updateVolume(); vol.extendBy((*cIt)->getVolume()); } } // test for null core. Shouldn't happen, but just in case... if(getCore() != NULL) { getCore()->adjustVolume(vol); } // don't propagate the static flag from children vol.setStatic(false); editSField(VolumeFieldMask); _sfVolume.setValue(vol); }