NodeTransitPtr OctreeVisualization::createNodeDistanceLOD(OctreePtr, const Octree::OTNodePtr node, Material* GeoMaterial, const Node* BaseGeo, Real32 Range ) { NodeRecPtr box = deepCloneTree(BaseGeo); dynamic_cast<Geometry*>(box->getCore())->setMaterial(GeoMaterial); //DistanceLOD node DistanceLODRecPtr LOD = DistanceLOD::create(); LOD->editMFRange()->push_back(10.0); NodeRecPtr LODNode = makeNodeFor(LOD); LODNode->addChild(box); LODNode->addChild(makeCoredNode<Group>()); Matrix m; TransformRecPtr box_trans; NodeRecPtr trans_node = makeCoredNode<Transform>(&box_trans); Pnt3f Center; node->getVolume().getCenter(Center); m.setTranslate(Center.x(), Center.y(), Center.z()); const Real32 Offset(0.0f); Vec3f Size; node->getVolume().getSize(Size); m.setScale(Size.x()-(Size.x()*Offset), Size.y()-(Size.y()*Offset), Size.z()-(Size.z()*Offset)); box_trans->setMatrix(m); trans_node->addChild(LODNode); return NodeTransitPtr(trans_node); }
Action::ResultE LODSetupGraphOp::traverseEnter(Node * const node) { if(node->getCore()->getType().isDerivedFrom(DistanceLOD::getClassType())) { return Action::Skip; } // clear out the old sets _mSets.clear(); UInt32 numChildren = node->getNChildren(); // check node's children for LOD name tags. UInt32 i = 0; UInt32 j = 0; for(i = 0; i < numChildren; ++i) { const Char8 *namePtr = OSG::getName(node->getChild(i)); if(namePtr != NULL) { std::string curNodeName(namePtr ); size_t nameSize (curNodeName.size()); for(j = 0; j < _mLODs.size(); ++j) { // we only check for the tags at the end of the strings size_t searchLoc = (nameSize > _mLODs[j].mTag.size()) ? (nameSize - _mLODs[j].mTag.size()) : 0; size_t loc = curNodeName.find(_mLODs[j].mTag, searchLoc); if(loc != std::string::npos) { std::string baseName(curNodeName); baseName.erase(loc, _mLODs[j].mTag.size()); bool createNewSet = true; for(UInt32 k = 0; k < _mSets.size(); ++k) { if(baseName.compare(_mSets[k].mBaseName) == 0) { _mSets[k].addLODPair(_mLODs[j].mLOD, node->getChild(i)); createNewSet = false; break; } } if(createNewSet == true) { LODSet newSet; newSet.mBaseName = baseName; newSet.addLODPair(_mLODs[j].mLOD, node->getChild(i)); _mSets.push_back(newSet); break; } } }// end for(_mLODs.size()) } //end if(namePtr != NULL) } // end for(numChildren) // now we add as many LODs as we can int madeNow = 0; if(_mSets.size() > 0) { for(i = 0; i < _mSets.size(); ++i) { if(_mSets[i].mLODPairs.size() > 1) { DistanceLODRecPtr TheLODCore = DistanceLOD::create(); MFReal32 *ranges = TheLODCore->editMFRange(); NodeRecPtr newLODNode = Node::create(); newLODNode->setCore(TheLODCore); // also set the name of the node now OSG::setName(newLODNode, _mSets[i].mBaseName + "_LODNode"); node->addChild(newLODNode); bool centerIsSet = false; for(j = 0; j < _mSets[i].mLODPairs.size(); ++j) { LODPair cur = _mSets[i].mLODPairs[j]; if((cur.first != -1 ) && (cur.second != NULL) && (getRange(cur.first) > 0.0f) ) { ranges ->push_back(getRange(cur.first)); newLODNode->addChild (cur.second ); if(!centerIsSet) { Pnt3f volCenter; cur.second->getVolume().getCenter(volCenter); TheLODCore->setCenter(volCenter); centerIsSet = true; } madeNow++; } } } } if(madeNow > 0) { _totalNumMade += madeNow; return Action::Skip; } } return Action::Continue; }