OSG节点更新与事件回调

osg 学习 2 UpdateCallback, EventHandler, 运动的相机 下午读了《osg开源教程》 ,对callback, EventHandler 理解更好了点。晚上回来试试这两个例子。      callback 是单纯的场景内节点附属功能, 当遍历到某个附带callback的节点,其中重载的operator()函数将被执行,比如修改该节点的坐标等等;     EventHandler 是窗口/视口事件(gui)响应,就是窗口内点下鼠标,或者按下某个键 阅读详情

OSG中的节点主要使用回调(CallBack)来完成用户临时、需要每帧执行的工作。根据回调功能被调用的时机划分为更新回调(Update CallBack)和人机交互事件回调(Event CallBack)。前者在每一帧中系统遍历到当前节点时调用,后者则由交互事件触发,如操作键盘、鼠标、关闭窗口、改变窗口大小等动作。回调类基类

是osg::NodeCallBack(),主要函数如下:

//虚函数,回调函数主要操作在此函数中,子类应当重写,已完成相应操作
void operator()(Node* node, NodeVisitor* nv);

//为当前更新回调添加(删除)一个后继的回调对象
void   addNestedCallback(NodeCallback* nc);
void   removeNestedCallback(NodeCallback* nc);

//直接设置/获取一个最近的回调
void   setNestedCallback(NodeCallback* nc);
NodeCallback*   getNestedCallback();

//调用临近中的下一个更新回调
void traverse(Node* node,NodeVisitor* nv);

节点类中完成回调函数设置和获取:


//设置/获取节点的更新回调
void  setUpdateCallback(NodeCallback* );
NodeCallback* getUpdateCallback();
//设置/获取节点的事件回调
void  setEventCallback(NodeCallback*);
NodeCallback*  getEventCallback();

对于addNestedCallback(……)函数,其源码如下:


inline void addNestedCallback(NodeCallback* nc)
        {
            if (nc)
            {
                if (_nestedCallback.valid())
                {
                    nc->addNestedCallback(_nestedCallback.get());
                    _nestedCallback = nc;
                }
                else
                {
                    _nestedCallback = nc;
                }
            }
        }

在NodeCallback类中用一个ref_ptr _nestedCallback; 来存储下一个回调对象,利用链表构成
一个回调对象序列,当要添加一个临近回调时,即调用addNestedCallback(NodeCallback* nc)时利用递归将两个
(分别以this,nc为连表头的)序列合并,例如:this->callback1->callback2->callback3->null, nc->callback4->callback5->null。合并后新的序列为this->nc->callback1->callback4->callback2->callback5->callback3->null。至于removeNestedCallback(...),比较简单,如下:


inline void addNestedCallback(NodeCallback* nc)
        {
            if (nc)
            {
                if (_nestedCallback.valid())
                {
                    nc->addNestedCallback(_nestedCallback.get());
                    _nestedCallback = nc;
                }
                else
                {
                    _nestedCallback = nc;
                }
            }
        }

在NodeCallback类中用一个ref_ptr _nestedCallback; 来存储下一个回调对象,利用链表构成
一个回调对象序列,当要添加一个临近回调时,即调用addNestedCallback(NodeCallback* nc)时利用递归将两个
(分别以this,nc为连表头的)序列合并,例如:this->callback1->callback2->callback3->null, nc->callback4->callback5->null。合并后新的序列为this->nc->callback1->callback4->callback2->callback5->callback3->null。至于removeNestedCallback(...),比较简单,如下:


inline void removeNestedCallback(NodeCallback* nc)
{
       if (nc)
       {
                if (_nestedCallback==nc)
                {
                    _nestedCallback = _nestedCallback->getNestedCallback();
                }
                else if (_nestedCallback.valid())
                {
                    _nestedCallback->removeNestedCallback(nc);
                }
        }
}

其中traverse()函数,其功能是对当前节点调用下一个临近回调函数,其代码如下:

void NodeCallback::traverse(Node* node,NodeVisitor* nv)
{
    //如果有后续回调对象,则调用, 重载操作符"()"来实现
    if (_nestedCallback.valid())
            (*_nestedCallback)(node,nv);
    //回调操作完成之后,访问该节点   
    else
            nv->traverse(*node);
} 

一个范例:使用回调实现旋转动画

代码

#include <osg/Quat>
#include <osg/PositionAttitudeTransform>
#include <osg/io_utils>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <iostream>

  class RotateCallBack: public osg::NodeCallback
{
 public:
    RotateCallBack():_rotateZ(0.0) {}

    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
    {
        osg::PositionAttitudeTransform* pat =
            dynamic_cast(node);
        if(pat)
        {
            osg::Vec3 vec(0, 0, 1);
            osg::Quat quat = osg::Quat(osg::DegreesToRadians(_rotateZ), osg::Z_AXIS);
            pat->setAttitude(quat);

            _rotateZ += 0.10;
        }

        traverse(node, nv);
    }

 private:
    double _rotateZ;
};


 class InfoCallBack: public osg::NodeCallback
{
 public:
    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
    {
        osg::PositionAttitudeTransform* pat =
            dynamic_cast(node);
       
        if(pat)
        {
            double angle = 0.0;
            osg::Vec3 axis;
            pat->getAttitude().getRotate(angle, axis);

            std::cout << "Node is rotate around the axis(" << axis << "), "
                <<osg::RadiansToDegrees(angle) << "degrees" << std::endl;
        }

        traverse(node, nv);
    }
};


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

    osg::ref_ptr pat =
            new osg::PositionAttitudeTransform();
    pat->addChild(model);

    pat->setUpdateCallback(new RotateCallBack() );
    pat->addUpdateCallback(new InfoCallBack() );

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

本文转自:https://www.cnblogs.com/hzhg/archive/2010/12/19/1910340.html

OSG学习笔记3-使用回调实现旋转动画 这是有关节点的更新与事件回调,OSG中的节点主要是使用回调Callback来完成用户临时定义的,需要每帧执行的工作。 回调时一种用户编写的功能模块,它可以作为一个参数传递给其他功能模块,从而实现一些底层系统事件的响应和处理。C++使用函数指针将回调函数的地址作为其他系统或用户函数的传入参数。 OSG节点回调分类: 1、更新回调 Update Callback:每一帧系统遍历到当前节点时都会被 阅读详情

相关推荐

初学OSG之节点回调的处理过程

节点Node可以在场景运行期间,利用节点回调来动态处理数据。 节点Node添加更新回调函数为 void Node::setUpdateCallback(Callback* nc) { // if no changes just return. if (_updateCallback==nc) return; // updated callback has be

bestHulk的博客 1126

osg::Drawable类通过setDrawCallback函数设置回调函数的说明

osg::Drawable类通过setDrawCallback函数设置回调函数的说明

danshiming的博客 1716

osgEarth通过更新模型位置使模型运动

一、背景 在osgEarth中,使模型运动有两种方案: 使用回调函数setUpdateCallback(Path)让模型按预设路径飞行,这种方法飞行过程很流畅 使用csn->getEllipsoidModel()->computeLocalToWorldTransformFromLatLongHeight(osg::DegreesToRadians(lat), osg::DegreesToRadians(log), 100.0, matrix)更新模型的位置,但是测试后发现有卡顿,并且不能

ljjjjjjjjjjj的博客 3588

osg::PositionAttitudeTransform旋转物体

osg::PositionAttiruteTransform类没有像osg::MatrixTransform那样的rotate方法,只有setAttitude方法,该方法的参数是一个四元组对象,四元组的第一个参数是旋转的角度(弧度为单位),第二个参数是个向量,表示绕哪个轴旋转的向量。例如,将一个物体旋转180°的代码如下: // 绕着osg::Vec3(0.0f,0.0f,1.0f)把物体旋转osg::PI个弧度 pat->setAttitude(osg::Quat(osg::PI, osg.

danshiming的博客 1485

OpenSceneGraph 中的 osg::Transform详解

是 OpenSceneGraph 中用于实现空间变换的基类,它提供了一种在场景图中应用各种变换(平移、旋转、缩放等)的机制。

深之JohnChen的专栏 893

Windows 必看!OpenClaw 一键安装教程|告别报错,一次成功不踩坑

OpenClaw 完整安装与配置的全流程教程

m0_70389289的博客 1085

<7> 场景图形的工作机制 - 2

osg::NodcCallback、 节点回调(NodeCallback) 事件回调(EventCallback) 文件读取回调(ReadFileCallback) 数据变量

liangfei868的博客 1171

OLLAMA_HOST环境变量设置全攻略:从127.0.0.1到局域网共享的完整配置

本文详细解析了OLLAMA_HOST环境变量的核心作用与配置方法,指导用户如何将Ollama服务从仅限本机访问(127.0.0.1)扩展到局域网共享。文章涵盖了macOS、Linux、Windows三大平台的实战配置步骤,并提供了安全加固、性能优化及常见故障排查方案,是解决多设备协作访问本地AI模型的完整指南。

weixin_28455801的博客 1898

OSG事件回调

OSG中的节点主要使用回调(CallBack)来完成用户临时、需要每帧执行的工作。根据回调功能被调用的时机划分为更新回调(UpdateCallBack)和人机交互时间回调(Event CallBack)。前者在每一帧中系统遍历到当前节点时调用,后者则由交互事件触发,如操作键盘、鼠标、关闭窗口、改变窗口大小等动作。回调类基类是osg::NodeCallBack(),主要函数如下: ...

ajacn40402的专栏 508

海康VisionMaster表面缺陷滤波实战:从参数调优到工业检测避坑指南

本文深入探讨海康VisionMaster表面缺陷滤波技术在工业检测中的应用,从参数调优到ROI绘制与Blob分析的协同策略,提供金属外壳、锂电池铝壳等复杂表面的缺陷检测实战指南。通过多级滤波架构和动态ROI生成法,显著提升检出率至98.7%,误检率低于0.5%,为工业质检提供智能化解决方案。

ujm5678901的博客 328

OpenFOAM收敛问题排查指南:从参数设置到网格优化

本文系统性地介绍了OpenFOAM计算中收敛问题的排查方法。从理解收敛本质出发,详细讲解了如何通过调优求解控制参数(如松弛因子、离散格式)、合理设置时间步长与耦合算法,以及优化网格质量来解决发散难题。文章提供了从软件设置到硬件网格的完整排查路径,帮助用户实现稳定高效的计算流体力学模拟。

fern8的博客 792

osgcallback

该示例程序主要展示了osg回调的用法,osg提供的回调功能主要使节点能够完成用户临时定义的功能,这些功能由回调函数完成,在每帧更新时(不同回调类型执行回调函数的时机不一样)执行回调函数完成用户定义的功能。 能执行回调函数的对象包括:节点、叶结点、相机、几何体(Drawable),osg提供的回调类型包括: 更新回调(UpdateCallback)每帧遍历时执行,自动执行回调函数。

shui_zhi_lian的专栏 1074

Python脚本自动化芯片设计?PyAether实战教程带你玩转EDA

本文通过PyAether实战教程,详细介绍了如何利用Python脚本实现芯片设计自动化。内容涵盖环境搭建、核心对象模型解析,并重点演示了原理图自动生成、参数化单元创建及设计验证流程集成,帮助EDA工程师从重复性手动操作中解放,显著提升设计效率与一致性。

e4f5g6h的博客 1316

C++学习(三二三)osg的事件访问器EventVisitor

作用:对场景图节点Node进行更新。需要场景图节点定义回调函数osg::Callback。 创建时机: 调用时机: osgGA/EventVisitor inline void handle_callbacks_and_traverse(osg::Node& node) { handle_callbacks(node.getStateSet()); osg::Callback* cal.

hankern的专栏 416

【科研】Michaelis–Menten 曲线(米氏曲线)中反应速率的计算

Michaelis–Menten 曲线 米氏曲线 纵坐标 反应速率求值 朗伯比尔定律

weixin_42809675的博客 2万+

基于计算机视觉的无人便利店技术:从算法到部署的系统化实战指南

摘要:本文系统介绍了基于计算机视觉的无人便利店技术方案,提出"商品检测-跟踪-动作识别-防损-结算"五段式流水线架构。详细阐述了YOLOv8-Seg商品检测、OC-Sort多目标跟踪、3D-CNN+ST-GCN动作识别等核心算法实现,并完成NVIDIA Jetson Xavier NX边缘端的优化部署。通过TensorRT量化、DeepStream加速等技术手段,系统在保持94.7%动作识别准确率的同时,将漏单率降至0.8%,单店云端算力成本较行业平均降低84%。所有代码已开源,可直接应

博客 625

探索未知种族之osg类生物---呼吸分解之更新循环一

上节总结 前几天我们大体上介绍完成了osg的事件循环的介绍,总结一下osg的时间循环主要就是得到平台(windows)的所有消息,并遍历所有的node的eventCallback,并对他们进行处理。接下来我们就要进入osg的另一个维持生命的循环---更新循环。 更新循环 OSG 更新循环的作用与事件回调有类似之处:由专门的访问器对象_updateVisitor 的负 责场景图形更新遍历;...

weixin_30408309的博客 82

SQL面试题——抖音SQL面试题 股票波峰波谷

这个题目的难度比较低,我们是用lead 和 lag 两个函数就可以搞定,也就是在一个SQL 里面同时使用多个函数,问题的考查点在于对边界的考虑。

2万+

osg 场景节点(事件,更新,裁剪)遍历状态开启机制

OSG 显示引擎为优化其显示效率,节点的更新遍历,事件处理遍历默认情况下是关闭的,内部通过更新计数来控制是否将事件处理,节点更新应用到子场景中。void Node::setUpdateCallback(Callback* nc);void Node::setEventCallback(Callback* nc);void Node::setCullingActive(bool active);下面...

fatcat123的博客 5432

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

OSG 场景树

OSG(2):OSG 场景树一、概述二、场景树三、节点访问四、节点方法 以下内容转载自 https://blog.youkuaiyun.com/u013719339/article/details/80340849 一、概述 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OSG采用包围体层次(Bounding Volume Hierarchy, HVH)来实现场景图形

ayww的博客 1369

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

用OpenSceneGraph实现的NeHe OpenGL教程 - 第十八课

简介 这节课在第七课的基础上修改了部分代码,用来在场景中显示圆球、圆柱、圆锥等二次几何体。在osg中定义了一些基本的几何体,主要有如下几种: Fig1. osg内置定义的几何体类型 实现 在本课中通过切换空格键实现几何体的切换,在osg中开关节点osg::Switch用在这里再合适不过了,它可以切换不同的子节点进行显示 我们定义如下: /////////////

Frank的专栏 1655

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

OSG使用更新回调来更改模型

OSG使用更新回调来更改模型

fguihbfg的博客 1201

OSG程序设计之更新回调

  更新回调(Update Callback)涉及到一个类:osg::NodeCallback。这个类重载了函数调用操作符。当回调动作发生时,将会执行这一操作符的内容。   如果节点绑定了更新回调函数,那么在每一帧系统遍历到此节点时,回调函数都会被调用。   下面给出一个例子: #include <osg/io_utils> #include <osg/Positio...

weixin_34234721的博客 659

OSG:幼儿园篇 第四章 节点回调类

一.简介 osg::NodeCallback类继承自osg::Object类 osg::Node可以在执行更新和拣选遍历时进行回调 osg::Drawable可以在拣选和绘制遍历时进行回调 osg::Camera可以在更新遍历时进行回调 //第一个参数关联节点地址 第二个参数是节点访问器 virtual void operator() (Node* node, N...

weixin_30716141的博客 290
上一篇: 如何编译生成OSG帮助文档
下一篇: linux下利用图形化工具合并分区
荆楚闲人
博客等级 码龄20年 3万+粉丝 473原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值