OpenSceneGraph几个重要功能节点练习

OpenSceneGraph几个重要功能节点练习

一. 空间变换节点

空间变换中最重要的是坐标系和矩阵运算了。OSG坐标系中使用右手系,Z轴垂直向上,X轴水平向右,Y轴垂直屏幕向里,与OpenGL和DirectX都不同。
相关缩放、旋转和平移主要由osg::Matrix, osg::Vec3, osg::Quat几个类来完成。
局部坐标系向世界坐标系转换规则是:设在局部坐标系下顶点 V 转换成世界坐标系坐标 V‘:
    V‘ = V * Mn* Mn-1*……* M3* M2* M1* M0

其中M0到Mn一次为各个矩阵变换。从世界坐标系坐标下顶点 V‘ 转换成局部坐标系 V:
    V  = V‘ * M0-1 * M1-1 * M2-1 * M3-1 *……* Mn-1-1 * Mn-1

对于空间变换而言,无论是OpenGL,DirectX还是OSG,一般都会遵守SRT(Scale/Rotate/Translate)的运算顺序来完成符合矩阵的构建:
其公式为:

    M =Ms * Mr * Mt

osg::Matrix mt = osg::Matrix::scale( osg::Vex3(sx, sy, sz) ) *
                       osg::Matrix::rotate( osg::Quat(angle, axis) ) *
                       osg::Matrix::translate( osg::Vec3(tx, ty, tz) ) ;

osg::MatrixTransform, osg::PositionAttitudeTransform, osg::AutoTransform 示例:

代码
#include <osg/Node>
#include <osg/AutoTransform>
#include <osg/MatrixTransform>
#include <osg/PositionAttitudeTransform>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>

 //library for OSG
 #pragma comment(lib, "osgd.lib")
 #pragma comment(lib, "osgDBd.lib")
 #pragma comment(lib, "osgViewerd.lib")

osg::Transform*  createAutoTransform(double posX, osg::Node* node)
{
    osg::ref_ptr<osg::AutoTransform> at = new osg::AutoTransform();
    at->setAutoRotateMode( osg::AutoTransform::ROTATE_TO_SCREEN );
    at->setPosition( osg::Vec3(posX, 0, 0) );
    at->addChild( node );

    return at.release();
}

osg::Transform*  createMatrixTransform(double posX, double rotateZ, osg::Node* node)
{
    osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform();
    mt->setMatrix( osg::Matrix::rotate( rotateZ, osg::Z_AXIS) *
                         osg::Matrix::translate( posX, 0, 0) );
    mt->addChild( node );

    return mt.release();
}

osg::Transform* createPositionAttitudeTransform(double posX, double rotateZ, osg::Node* node)
{
    osg::ref_ptr<osg::PositionAttitudeTransform> pat = new osg::PositionAttitudeTransform();
    pat->setAttitude( osg::Quat(rotateZ, osg::Z_AXIS) );
    pat->setPosition( osg::Vec3(posX, 0, 0) );
    pat->addChild(node);

    return pat.release();
}

int main(int argc, char** argv)
{
    osg::ArgumentParser argument(&argc, argv);
    osg::ref_ptr<osg::Node> node = osgDB::readNodeFiles(argument);
    if( !node.get() ) node = osgDB::readNodeFile( "cow.osg" );

    osg::ref_ptr<osg::Group> root = new osg::Group();
    root->addChild( createAutoTransform(0.0, node) );
    root->addChild( createMatrixTransform(-15.0, osg::PI_4, node) );
    root->addChild( createPositionAttitudeTransform(15.0, -osg::PI_4, node) );

    osgViewer::Viewer  viewer;
    viewer.setSceneData( root.get() );
    return viewer.run();
}

二. 开关节点(osg::Switch)
开关节点Switch的作用是,在场景中某时刻,它的某些子节点被隐藏和忽略,而列外一些节点正常显示并完成相应功能。示例中利用开关节点的更新回调实现子节点的切换:

代码
#include <osg/Switch>
#include <osg/NodeCallback>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgViewer/Viewer>

#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgDBd.lib")
#pragma comment(lib, "osgViewerd.lib")

class CessnaCallback: public osg::NodeCallback
{
public:
    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
    {
        osg::Switch* sw = dynamic_cast<osg::Switch*>(node);
        if(sw && nv)
        {
            const osg::FrameStamp* fs = nv->getFrameStamp();
            if( fs )
            {
                if( _fireStartFrame < fs->getFrameNumber() )
                {
                    sw->setValue(0, false);
                    sw->setValue(1, true);
                }
            }
        }
        traverse(node, nv);
    }

private:
    static const int _fireStartFrame = 900;
};

int main(int argc, char** argv)
{
    osg::ref_ptr<osg::Switch> root = new osg::Switch();
    root->addChild( osgDB::readNodeFile("cessna.osg"), true );
    root->addChild( osgDB::readNodeFile("cessnafire.osg"), false );
    root->addUpdateCallback(new CessnaCallback() );

    osgDB::writeNodeFile( *(root.get()), "Switch.osg" );
    osgViewer::Viewer viewer;
    viewer.setSceneData( root.get() );
    return viewer.run();
}

三. 细节层次节点(osg::LOD)

LOD节点,其基本实现功能是在不影响渲染效果的条件下 ,根据场景对象与观察者的距离,从多个预置方案中选择一种合适的来表达要渲染的物体,从而减轻系统的负担,模型越靠近观察者越精细,而远处只需要较少的多边形类表达。示例如下:

代码
#include <osg/LOD>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Notify>

#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgDBd.lib")
#pragma comment(lib, "osgViewerd.lib")

int main(int argc, char** argv)
{
    osg::ref_ptr<osg::Node> node = osgDB::readNodeFile( "bunny-high.ive" );

    if(!node)
    {
        osg::notify(osg::NotifySeverity::ALWAYS) << "Cannot open the model bunny!\n" ;
        return 0;
    }

    float r = node->getBound().radius();

    osg::ref_ptr<osg::LOD> lod = new osg::LOD();
    lod->addChild(node.get(), 0.0f, r*3 );
    lod->addChild( osgDB::readNodeFile("bunny-mid.ive"), r*3, r*7 );
    lod->addChild( osgDB::readNodeFile("bunny-low.ive"), r*7, FLT_MAX );

    osgViewer::Viewer viewer;
    viewer.setSceneData( lod.get() );
    viewer.run();
}

四. 代理节点(ProxyNode)
ProxyNode代理节点是一种用于动态加载其他模型节点的节点类型。这些节点不会立即被解析和加入场景,而是在场景运行过程中逐步载入。示例:

代码
#include <osg/ProxyNode>
#include <osgDB/ReadFile>
#include <osg/ArgumentParser>
#include <osgViewer/Viewer>
#include <osg/Notify>
#include <iostream>

#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgDBd.lib")
#pragma comment(lib, "osgViewerd.lib")

int main(int argc, char** argv)
{
    osg::ArgumentParser argument(&argc, argv);
    osg::ref_ptr<osg::ProxyNode> pn = new osg::ProxyNode();
    unsigned int num = 0;

    for(int i = 1; i < argument.argc(); i++)
    {
        if( argument.isString(i) )
        {
            std::cout << num << ":  " << argument[i] << "\n" ;
            pn->setFileName( num++, argument[i] );
        }
    }
    if( !pn->getNumFileNames() )
        pn->setFileName(0, "cow.osg" );

    osgViewer::Viewer viewer;
    viewer.setSceneData( pn.get() );
    return viewer.run();
}
时间: 2024-10-18 14:39:35

OpenSceneGraph几个重要功能节点练习的相关文章

多功能节点连线绘图控件Nevron Diagram for .NET使用方法及下载地址

Nevron Diagram for .NET是一个功能强大,世界上顶级的.NET图表控件.可扩展的图形报表构架,可以帮您创建功能丰富的Winforms及Webforms图表解决方案.这个产品构建于Nevron表述层框架之上,能为您提供令人激动的视觉冲击,您无法通过其它产品体验到 - 独一无二的商业图表应用程序.Nevron Diagram for .NET专门根据广泛的自定义需求而设计,它提供了高扩展性的对象模型,其API更加细化本地化及直观性.产品本身大量利用现代的设计模式,使其具有更高的可

更换zigbee设备导致节点地址冲突的流程解析

目前公司商用的协议栈程序是支持分节点地址可配置的,与zigbee2007pro有很大的不同,因此也产生了一些问题,特别严重的就是本篇所讲述的更换设备导致的现象.本篇将深入代码分析冲突检测及处理的流程,并给出修改方法. 测试使用两个设备模拟冲突场景,A设备先行入网,之后断电,B设备与A设备配置相同的短地址0x0140.当B设备上电后,便产生如下的冲突情景,会影响到正常通讯. A设备的MAC地址为:E3909602004B1200 B设备的MAC地址为:CB909602004B1200 一.冲突情况

14.2 添加群集功能

14.2 添加群集功能 14.2.1 打开服务器管理器 默认情况下,Windows Server 2008 及后续的服务器产品在登录成功后都会自动打开服务器管理器的界面. 对于 Windows Server 2008,可以在左侧树状列表中右键单击"功能"节点,然后在右键菜单中选择"添加功能":或者在主菜单中选择"操作",然后选择"添加功能":或者在左侧树状列表中选择根节点,然后在右侧详细窗格的"功能摘要"中

Lua BehaviourTree 各节点说明

项目说明 本行为树的代码使用Lua编写,所有的内容也建立的Lua的基础语法之上 因为公司项目需求,需要一套Lua的行为树代码,所以尝试从饥荒中抽离了行为树相关的代码.绝大多数节点行为与饥荒中相同,不过部分节点因为也许需求也有部分变动 通用说明 行为树状态基本分为4种 READY:准备状态,节点还没有被调用过.或者已经调用结束被Reset之后的状态 RUNNING:正在运行的状态,通常父节点会等待子节点Runing结束才会将自己的状态标示为结束,当然部分节点不会理会子节点的Runing状态 SUC

考勤模块功能的介绍

1. 可自定义班次,灵活处理倒班的情况 ·能够设置浮动班次,最好可以自动跟据员工下班时间核算加班工时,但是不要有加班费用计算 ·设有自动抓班功能,某些部门可不用给员工排班,根据员工打卡数据自动识别班次: ·与企业现有考勤结合,支持请假.加班.调休等相关考勤业务管理,通过汇总计算等功能,在薪酬管理中直接引用相关结果进行计算.部门未对当月人员考勤情况进行确认.签发的,应有提醒功能. ·迟到.早退和加班可以分部门设定规则. ·具备识别跨夜打卡和通宵上班的功能. ·具备单独按部门设定上连班识别时间跨度的

Windows Azure 管理入口网站功能再扩充 - SQL Reporting

本文将介绍如何在 Windows Azure 管理入口网站建立 SQL Reporting. [情境描述] 在过去 SQL Reporting 只能在旧版由 Silverlight 所开发的 Windows Azure 管理入口网站中使用,现在 SQL Reporting 也已经搬到新版入口管理网站了. 除此之外还有一些更新像是管理入口网站开始支持繁体中文,以及 Mobile Services 支持 Android 平台等,还有新的 Service Bus Notification Hub (P

轻松构建复杂数据集,永洪自服务数据查询功能详解

现在的报告样式多种多样,越来越炫酷以至于让人应接不暇.如果想从数据结果上进行溯源,由于数据处理过程盘根错节且技术性过强,让业务人员捉襟见肘.如何让业务人员清晰可视化的看到数据从来源.加工到展示的一步步操作,永洪科技为您排忧解难. 今天这篇文章,主要介绍永洪自服务数据查询,这种方式提供强大.便捷的数据准备和整合方式,用户可以通过在图形化界面上只需要进行简单的拖拽和可视化的操作,便可以构建复杂的数据集. 数据准备过程主要涉及三类功能节点:输入节点(用于实现数据库表连接.导入EXCEL数据.创建内嵌数

WordPress版微信小程序2.2.0版发布

2017年8月12日WordPress版微信小程序2.2.0版通过了微信的审核正式发布,此版本的更新以完善功能为主.主要更新的功能是:站内链接,猜你喜欢,热点文章. WordPress版微信小程序开放源码地址:https://github.com/iamxjb/winxin-app-watch-life.net 了解程序的开发历程及开发技术,建议看看相关版本的更新文章: 1.用微信小程序连接WordPress网站 2.WordPress版微信小程序1.5版本发布 3.WordPress版微信小程

淘宝技术发展

转载 http://blog.csdn.net/kobejayandy/article/details/8685271 目录 一.引言 二.个人网站 三.Oracle/支付宝/旺旺 四.淘宝技术发展(Java时代:脱胎换骨) 五.淘宝技术发展(Java时代:坚若磐石) 六.淘宝技术发展(Java时代:创造技术-TFS) 七.淘宝技术发展(分布式时代:服务化) 作者:赵超 一.引言 光棍节的狂欢 “时间到,开抢!”坐在电脑前早已等待多时的小美一看时间已到 2011 年 11 月 11 日零时,便迫