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);
}
示例#2
0
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;
}