#include "myNodeVisitor.h" #include "mainwindow.h" #include #include #include #include #include myNodeVisitor::myNodeVisitor() { opt->setOptionString("WriteImageHint=IncludeFile"); } void myNodeVisitor::apply(osg::Geode &node) { // 遍历Geode里面的所有Geometry,即形状(点、线、面) for(uint i = 0; iasGeometry(); if(pGeo){ osg::Vec3Array* vertex = dynamic_cast(pGeo->getVertexArray()); if (!vertex){ continue; } for (int i = 0; i < vertex->size(); i++){ // 对于满足条件的点 int index = pointsNearVertex((*vertex)[i]); if (index != -1) { (*vertex)[i].z() = vertexArray->at(index).z(); affected = true; } } } } if (affected && !node.getName().empty()){ // 和PagedLOD的处理方式一致 newFileName = QString::fromStdString(node.getName()).split('.').first() + "~.osgb"; node.accept(*tv); node.setName(newFileName.toStdString()); // 写文件 osgDB::writeNodeFile(node, (workingDir + '/' + newFileName).toStdString(), opt); childAffected = true; } } void myNodeVisitor::apply(osg::Group &node) { bool groupAffected = false; for(uint i = 0; iaccept(*this); if(childAffected){ groupAffected = true; } } if(groupAffected && !node.getName().empty()){ // 和PagedLOD的处理方式一致 newFileName = QString::fromStdString(node.getName()).split('.').first() + "~.osgb"; node.accept(*tv); node.setName(newFileName.toStdString()); // 写文件 osgDB::writeNodeFile(node, (workingDir + '/' + newFileName).toStdString(), opt); childAffected = true; } } void myNodeVisitor::apply(osg::PagedLOD &node) { affected = false; childAffected = false; for(uint i = 0; i < node.getNumChildren(); i++){ // 这个遍历过程可能会修改文件 node.getChild(i)->accept(*this); } // // 使用affected作为初步判断,以尽可能地减少计算量, 非affected文件都不会被修改 // if(!affected && ! childAffected){ // return; // } // 如果真的被修改了文件,那么, workingDir = QString::fromStdString(node.getDatabasePath()); // for(uint i = 0; i < node.getNumFileNames(); i++){ for(uint i = 1; i < node.getNumFileNames(); i++){ // 遍历这个LOD文件中的所有子文件,即金字塔中更精细的那一层,他们也要改 childAffected = false; // 读文件以继续遍历 osg::ref_ptr fileNode = osgDB::readNodeFile(workingDir.toStdString() + '/' + node.getFileName(i)); if(!fileNode.valid()){ continue; } // 将fileNode和文件名链接在一起,这样当节点被修改时,可以及时更新对应的文件 fileNode->setName(node.getFileName(i)); // 两个遍历器都要遍历 fileNode->accept(*tv); fileNode->accept(*this); if(childAffected){ //更改文件名链接 node.setFileName(i, newFileName.toStdString()); // 此时也应该相应地修改pLOD对应的文件 } } if(!node.getName().empty()){ newFileName = QString::fromStdString(node.getName()).split('.').first() + "~.osgb"; node.accept(*tv); node.setName(newFileName.toStdString()); // 写文件 osgDB::writeNodeFile(node, (workingDir + '/' + newFileName).toStdString(), opt); } // 作为别人的儿子,文件被修改了 childAffected = true; } bool myNodeVisitor::pointInPolygon(osg::Vec3 &point) { for(osg::ref_ptr boundary: boundaryList){ int i, j, nvert = boundary->size(); bool c = false; // 射线法 for (i = 0, j = nvert - 1; i < nvert; j = i++) { if (((boundary->at(i).y() >= point.y()) != (boundary->at(j).y() >= point.y())) && (point.x() <= (boundary->at(j).x() - boundary->at(i).x()) * (point.y() - boundary->at(i).y()) / (boundary->at(j).y() - boundary->at(i).y()) + boundary->at(i).x()) ) c = !c; } if(c && point.z() > boundary->at(0).z()){ return true; } } return false; } int myNodeVisitor::pointsNearVertex(osg::Vec3 &point) { for(int i = 0; i < vertexArray->size(); i++){ if(pow(point.x() - vertexArray->at(i).x(), 2) + pow(point.y() - vertexArray->at(i).y(), 2) < 4 && point.z() > vertexArray->at(i).z()){ return i; } } return -1; }