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();
}
最后控制台输出的矩阵变换坐标和位置变换坐标是一样的。
#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();
}
最后控制台输出的矩阵变换坐标和位置变换坐标是一样的。
相关文章推荐
- vc工程中打开的时候类视图无法完全显示类解决方案——删除工程所在文件夹中的后缀为ncb的文件,重新打开即可
- 用一个页面显示来自不同页面处理结果
- linux下文件和目录权限的不同 ----来自《鸟哥的linux私房菜》
- Microsoft Visual Studio 如何设置双击ASPX显示设计视图而不是源文件视图?
- [转载]iPhone中OpenGL ES显示3DS MAX模型之一:OBJ文件格式分析
- 在程序中加载解析3DS文件,显示三维模型(c# MDX),
- 将eclipse中的表视图导出成为sql文件。可执行sql建表建视图语句。进度条显示
- 如何在MVC3 razor视图下的ViewsStart文件中设置使用两套不同的Layout布局视图
- 观察osg格式文件中如何处理多个节点共享一个子节点
- 使用rails高效开发之快速创建控制器 视图 模型和数据库文件
- linux od命令: 按不同进制显示文件
- Jxls导出excel的若干方式总结(十一)-- 同一个sheet中显示来自不同数据表的对象记录
- [Unix/Linux] catsrc.sh: 此脚本用于在写报告时把项目的多个源代码文件方便的 `cat` 到一个文件上, 并把来自不同的文件之间加上一个标识头以区分输出文件里的不同文件
- vc workspace不能显示类视图/工程文件视图/资源视图
- 使用rails高效开发之快速创建控制器 视图 模型和数据库文件
- 比较两个文件或两个文件集并显示它们之间的不同
- JPanel作为容器,显示不同的视图
- 读取数据库中xml类型文件,并把每个节点名当做列名用gridview显示出来
- CodeIgniter框架模型(model),视图(view)和控制器(controller)中的文件操作
- 织梦dede搜索结果页按频道模型显示不同模板