OpenSceneGraph:通过矩阵变换实现在同一视图中显示来自不同来源的多个模型节点文件

        在利用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();
}

最后控制台输出的矩阵变换坐标和位置变换坐标是一样的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值