您的位置:首页 > 其它

OSG在同一视图中显示来自不同来源的多个模型节点文件

2017-05-26 11:39 453 查看
        在利用OSG节点文件导入两个不同类型的模型文件时,其在OSG中的世界坐标系不一定在一个地方,也就无法在同一视图中同时显示。需要进行位置变换和矩阵变换使多个模型在同一视图中显示。主要思路是通过利用包围盒来查看各模型所在世界坐标系中的位置,之后进行变换。当同时利用位置变换和矩阵变换时,需要按照root->矩阵变换->位置变换->模型节点的形式。先通过位置变换设置原点进行缩放,再通过矩阵变换进行平移和旋转。主要参考代码如下:

#include<osgViewer/Viewer>

#include<osg/Group>

#include<osgDB/ReadFile>

#include<osgUtil/Optimizer>

#include<osgDB/FileUtils>

#include<osgDB/ReadFile>

#include<osg/PositionAttitudeTransform>

#include<osg/Node>

#include<osg/ComputeBoundsVisitor>

#include<osg/MatrixTransform>

#include<iostream>

#include<osg/lightModel>

int main()

{

               osg::ref_ptr<osg::Node> topNode = osgDB::readNodeFile("模型1文件");

               osg::ref_ptr<osg::Node> bottomNode = osgDB::readNodeFile(“模型2文件");

                osg::ComputeBoundsVisitor cbvtop;

                topNode->accept(cbvtop);

                osg::BoundingBox topBox = cbvtop.getBoundingBox();
std::cout<<"模型1坐标:"<<topBox.xMin()<<","<<topBox.xMax()<<","<<topBox.yMin()<<","<<topBox.yMax()<<","<<topBox.zMin()<<","<<topBox.zMax()<<std::endl;
osg::ref_ptr<osg::PositionAttitudeTransform> topPat = new osg::PositionAttitudeTransform(); 
topPat->setPivotPoint(osg::Vec3(topBox.center().x(),topBox.center().y(),topBox.center().z()));

               //设置按照X坐标以0.0025的大小的结果进行等比缩放,可任意根据需要修改

topPat->setScale(osg::Vec3(0.00125/(topBox.xMax()-topBox.xMin()),0.00125/(topBox.xMax()-topBox.xMin()),0.00125/(topBox.xMax()-topBox.xMin()))); 
topPat->addChild(topNode);
osg::ComputeBoundsVisitor cbvtopPat;

                topPat->accept(cbvtopPat);

                osg::BoundingBox topPatBox = cbvtopPat.getBoundingBox();
std::cout<<"位置变换坐标:"<<topPatBox.xMin()<<","<<topPatBox.xMax()<<","<<topPatBox.yMin()<<","<<topPatBox.yMax()<<","<<topPatBox.zMin()<<","<<topPatBox.zMax()<<std::endl;
osg::ref_ptr<osg::MatrixTransform> topMt = new osg::MatrixTransform;
osg::Matrix m1;
m1.makeTranslate(osg::Vec3(-topPatBox.center().x(),-topPatBox.center().y(),-topPatBox.center().z()));
topMt->setMatrix(m1);
topMt->addChild(topPat);
osg::ComputeBoundsVisitor cbvtopMt;

                topMt->accept(cbvtopMt);

                osg::BoundingBox topMtBox = cbvtopMt.getBoundingBox();
std::cout<<"矩阵变换坐标:"<<topMtBox.xMin()<<","<<topMtBox.xMax()<<","<<topMtBox.yMin()<<","<<topMtBox.yMax()<<","<<topMtBox.zMin()<<","<<topMtBox.zMax()<<std::endl;

                osg::ComputeBoundsVisitor cbvbot;

                bottomNode->accept(cbvbot);

                osg::BoundingBox botBox = cbvbot.getBoundingBox();
std::cout<<"模型2坐标:"<<botBox.xMin()<<","<<botBox.xMax()<<","<<botBox.yMin()<<","<<botBox.yMax()<<","<<botBox.zMin()<<","<<botBox.zMax()<<std::endl;
osg::ref_ptr<osg::PositionAttitudeTransform> botPat = new osg::PositionAttitudeTransform(); 
botPat->setPivotPoint(osg::Vec3(botBox.center().x(),botBox.center().y(),botBox.center().z()));

                //设置按照X坐标以0.02的大小的结果进行等比缩放,可任意根据需要修改
botPat->setScale(osg::Vec3(0.01/(botBox.xMax()-botBox.xMin()),0.01/(botBox.xMax()-botBox.xMin()),0.01/(botBox.xMax()-botBox.xMin())));   
botPat->addChild(bottomNode);
osg::ComputeBoundsVisitor cbvbotPat;

                botPat->accept(cbvbotPat);

                osg::BoundingBox botPatBox = cbvbotPat.getBoundingBox();
std::cout<<"位置变换坐标:"<<botPatBox.xMin()<<","<<botPatBox.xMax()<<","<<botPatBox.yMin()<<","<<botPatBox.yMax()<<","<<botPatBox.zMin()<<","<<botPatBox.zMax()<<std::endl;
osg::ref_ptr<osg::MatrixTransform> botMt = new osg::MatrixTransform;
osg::Matrix m2;
m2.makeTranslate(osg::Vec3(-botPatBox.center().x(),-botPatBox.center().y(),-botPatBox.center().z()-(botPatBox.zMax() - topPatBox.zMin())));
botMt->setMatrix(m2);
botMt->addChild(botPat);
osg::ComputeBoundsVisitor cbvbotMt;

                botMt->accept(cbvbotMt);

                osg::BoundingBox botMtBox = cbvbotMt.getBoundingBox();
std::cout<<"矩阵变换坐标:"<<botMtBox.xMin()<<","<<botMtBox.xMax()<<","<<botMtBox.yMin()<<","<<botMtBox.yMax()<<","<<botMtBox.zMin()<<","<<botMtBox.zMax()<<std::endl;
osg::Group* root = new osg::Group;
root->addChild(topMt.get());
root->addChild(botMt.get());
osgViewer::Viewer viewer;
        osgUtil::Optimizer optimizer;
optimizer.optimize(root);

                viewer.setSceneData(root);

                viewer.setUpViewInWindow(100, 100, 800, 600);

                return viewer.run();

}

最后控制台输出的矩阵变换坐标和位置变换坐标是一样的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐