osg的NodeCallback回调使用方法
来源:互联网 发布:美女公寓小说txt淘宝 编辑:程序博客网 时间:2024/06/05 07:00
osg的NodeCallback回调使用方法
#include <Windows.h>
#include <osgViewer/Viewer>
#include <osg/Math>
#include <osgDB/ReadFile>
#include <osg/NodeCallback>
#include <osg/MatrixTransform>
//从osg::NodeCallBack继承一个新类,实现simpleCallBack的回调
class simpleCallBack:public osg::NodeCallback
{
public:
simpleCallBack():_angle(0)
{
}
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
//创建矩阵转换节点
osg::ref_ptr<osg::MatrixTransform> mt=dynamic_cast<osg::MatrixTransform*>(node);
//创建矩阵
osg::Matrix mx;
//绕着Z轴旋转
mx.makeRotate(_angle,osg::Vec3(0.0,0.0,1.0));
//设置矩阵
mt->setMatrix(mx);
_angle+=0.01;
//继续遍历
traverse(node,nv);
}
public:
//旋转角度
double _angle;
};
int main()
{
osg::ref_ptr<osgViewer::Viewer> viewer=new osgViewer::Viewer;
osg::ref_ptr<osg::Group> root=new osg::Group;
//读取模型
osg::ref_ptr<osg::Node> node=osgDB::readNodeFile("cow.osg");
//创建矩阵变换节点
osg::ref_ptr<osg::MatrixTransform> mt=new osg::MatrixTransform;
mt->addChild(node.get());
//设置更新回调函数
mt->setUpdateCallback(new simpleCallBack());
root->addChild(mt.get());
viewer->setSceneData(root.get());
viewer->realize();
viewer->run();
return 0;
}
所有继承自NodeCallback类的子类,可重载operator()方法,对于OSG结点指定更新毁掉为类实例,结点会自动调用类的operator方法进行回调更新。
---------------------------
OSG中的节点主要使用回调(CallBack)来完成用户临时、需要每帧执行的工作。根据回调功能被调用的时机
划分为更新回调(Update CallBack)和人机交互时间回调(Event CallBack)。前者在每一帧中系统遍历到
当前节点时调用,后者则由交互事件触发,如操作键盘、鼠标、关闭窗口、改变窗口大小等动作。回调类基类
是osg::NodeCallBack(),主要函数如下:
//虚函数,回调函数主要操作在此函数中,子类应当重写,已完成相应操作
void
operator()(Node* node, NodeVisitor* nv);
//为当前更新回调添加(删除)一个后继的回调对象
void
addNestedCallback(NodeCallback* nc);
void
removeNestedCallback(NodeCallback* nc);
//直接设置/获取一个最近的回调
void
(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<NodeCallback> _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<osg::PositionAttitudeTransform*>(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<osg::PositionAttitudeTransform*>(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<osg::PositionAttitudeTransform> pat = new osg::PositionAttitudeTransform(); pat->addChild(model); pat->setUpdateCallback(new RotateCallBack() ); pat->addUpdateCallback(new InfoCallBack() ); osgViewer::Viewer viewer; viewer.setSceneData(pat.get() );
viewer.setUpViewOnSingleScreen(0); viewer.setUpViewInWindow(0, 0, 600, 800,0);
return viewer.run();}
- osg的NodeCallback回调使用方法
- osg的NodeCallback回调使用方法
- OSG 裁剪回调
- OSG回调机制
- [osg]OSG的分格化
- 矩阵变换、osg的回调、动画路径和Geometry
- 初学OSG之节点回调的处理过程
- OSG-更新和回调
- osg::Sphere,osg::Texture2D,osg::StateSet,osg::TexEnv的使用
- OSG 更新回调(二种方法)
- OSG节点访问、更新和回调
- OSG学习笔记01:OSG的安装
- [OSG]OSG中字体的排版
- [osg]osg中回调机制的设计研究
- OSG的优点
- osg的一些理解
- OSG QWidgetImage 的使用
- osg的灯光使用
- Android webview 与js交互
- shell中的wait
- Tomcat启动报错A child container failed during start
- newScheduledThreadPool创建可间隔时间执行的线程池
- 如何通过JAVA发送邮件
- osg的NodeCallback回调使用方法
- Language Models
- csh shell编程入门
- 使用visualvm远程监控JVM LINUX tomcat服务器与客户端配置方法
- 对于唯一索引使用唯一条件搜索, InnoDB 只锁定找到的index record,不是它之前的区间
- 第6课:<body>标签
- codeforces 40A. Find Color
- HDU-1081-To The Max(二维最大子段和)
- boost 库 安装