simulationMaster/myNodeVisitor.cpp
2021-12-23 17:46:55 +08:00

148 lines
4.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "myNodeVisitor.h"
#include "mainwindow.h"
#include <osg/Texture2D>
#include <osg/ProxyNode>
#include <osg/PagedLOD>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
myNodeVisitor::myNodeVisitor()
{
opt->setOptionString("WriteImageHint=IncludeFile");
}
void myNodeVisitor::apply(osg::Geode &node)
{
// 遍历Geode里面的所有Geometry即形状点、线、面
for(uint i = 0; i<node.getNumDrawables(); i++){
osg::Geometry* pGeo = node.getDrawable(i)->asGeometry();
if(pGeo){
osg::Vec3Array* vertex = dynamic_cast<osg::Vec3Array*>(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; i<node.getNumChildren(); i++){
childAffected = false;
node.getChild(i)->accept(*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<osg::Node> 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<osg::Vec3Array> 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;
}