浅谈在操控器类中,为何要通过osgGA::CameraManipulator的逆矩阵改变视点位置

六、osg操作器实现 osgGA::CameraManipulator是一个支持自定义相机操作的操作器,支持用户自己定义鼠标、键盘操作来操作相机。常见的自定义鼠标键盘操作需求,比如: 使用键盘控制相机旋转、平移 使用鼠标操作相机旋转、平移 控制场景绕某个视点旋转 第一人称视角的的相机操作 等等 阅读详情

        在osg代码目录下的include\osgGA目录存放了很多osg自带的操控器类,这些操控器类都派生自osgGA::CameraManipulator,而这个CameraManipulator又派生自osgGA::GUIEventHandler,可见其本质上是个事件处理类。因此它首先会接收事件,比如鼠标一拖,场景就动。场景动与不动是受视点的位置、朝向来决定的,也就是观察矩阵,因此CameraManipulator必有处理事件的接口和输出矩阵的接口,处理事件的接口是函数bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter &aa);所以每个操作器类必须要对这个函数大书特书来达到按自己的操作目的。这个handle的被调用的地方是在一帧绘制的事件遍历阶段,是在void Viewer::eventTraversal()中,viewer.cpp的第1125行(以osg 3.6.2为例,下同):

_cameraManipulator->handle( event, 0, _eventVisitor.get());

虽然入参不一样,但是跟踪一下会发现会调用过去的。事件处理之后,就要根据处理的事件改变视点位置来达到操作场景的目的。这个是通过osgGA::CameraManipulator的如下函数:

virtual osg::Matrixd getInverseMatrix()

来实现的,它的调用时机是在更新阶段void Viewer::updateTraversal()中,viewer.cpp的第1212行:

_cameraManipulator->updateCamera(*_camera);

它会调用至:

camera.setViewMatrix(getInverseMatrix());

这个时候就有人不明白了,为什么要使用逆矩阵呢?原因这里有点绕,大家认真理解一下,世界坐标下,一个盒子在A点(xa,ya,za),视点在B点(xb,yb,zb),先不管朝向不朝向的。我们要输出此时在B点的人看到A点的图像,做法有很多,实际上图形学界是这么做的:把A点先转换为以B点为局部坐标的坐标系下,然后再进行一系列操作。这个变换的过程其实相当于需要求出把B点移回世界坐标原点的矩阵,A点再乘以这个矩阵就可以,这个移回的矩阵是这样计算的,把人从世界坐标原点移到B点的变换是Matrix,而把B点移回世界坐标原点的变换就是InverseMatrix,现在我们要把A点放在以B点为局部坐标下,则需要变换的就是InverseMatrix。下图是以二维坐标来讲解:(三维不好画出第三个轴,其实原理都一样)

假设在世界坐标系XOY下,A点、B点的变换矩阵分别为MatrixA、MatrixB。如果以B点为原点的坐标系为基准,则原来的世界坐标系原点O的变换矩形则为 MatrixB的逆矩阵,记为InverseMatrixB。因为如果在以B点为原点的坐标系下,A点不能直接转到B坐标系下,必须通过世界坐标系转到B为原点的坐标系才行,即如果以B点为原点的坐标系为基准,则必须按B->O->A来算出A在B坐标系下的坐标。而A点在世界坐标下的变换矩阵为MatrixA(即对应O->A), 世界坐标系的原点O在以B点为原点的坐标系下的变换矩阵为InverseMatrixB(即对应B->O),那么这反应到数学上,就是矩阵的级联相乘,即为如下:

InverseMatrixB * MatrixA

OSG 关于MVPW变换 阅读详情

相关推荐

RTC 实时时钟实验

如果在 RTC_CR 寄存器中设置了相应的允许位,则在每个TR_CLK 周期中 RTC 产生一个中断(秒中断)。void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data) // 往备份区域写用户数据的函数 (这个函数的第一个参数就是寄存器的标号了,这个是通过宏定义定义的)存储在 RTC_ALR 寄存器中的可编程时间相比较,如果 RTC_CR 控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。寄存器操作完成,并同步之后,设置秒钟中断。

m0_55996456的博客 1205

osg中漫游器的原理——osgGA::CameraManipulator(二)

osgGA库中所有漫游器的基类是CameraManipulator,本文就对这个类进行一个完整的解析。通过之前的分析(详细请参考这一些列的第一篇),可以知道为了实现一个自定义的漫游器,我们至少需要实现以下几个纯虚函数: virtual void setByMatrix(const osg::Matrixd& matrix) = 0; //设置相机的位置姿态矩阵 virtual void setByInverseMatrix(const osg::Matrixd& matri...

whl0071的专栏 2189

百度贴吧爬虫实战:完整实现与使用指南

使用 csv 模块创建写入器,首先写入表头("标题" 和 "链接"),然后遍历帖子字典,将每个标题和链接作为一行写入文件。首先检查内容是否为空,然后通过查找 JSON 结构的起始({)和结束(})位置,提取有效的 JSON 片段。接着遍历帖子列表中的每个条目,提取标题文本和对应的链接,对于相对路径的链接会自动补全为完整的 URL。从 JSON 提取标题和链接此方法专门用于从解析后的 JSON 数据中提取帖子标题和对应的链接。提取到的标题和链接以字典形式返回,键为标题,值为对应的完整链接。

qq_63736560的博客 2016

osgGA::CameraManipulator类computeHomePosition函数分析

osgGA::CameraManipulator类computeHomePosition函数分析

danshiming的博客 1210

GD32F103程序烧录全攻略:从SWD到串口的实战指南

本文提供了GD32F103微控制器程序烧录的全面实战指南,详细介绍了SWD、JTAG和串口(ISP)三种主流下载方式。文章重点解析了在Keil MDK中使用ST-Link进行SWD下载的完整步骤,包括硬件连接、软件配置和Flash算法设置,并针对烧录过程中的常见问题提供了实用的排坑解决方案,帮助开发者高效完成程序部署。

weixin_29191669的博客 436

链路聚合Eth-trunk以及华为交换机配置实例

链路聚合简介 以太网链路聚合Eth-Trunk简称链路聚合,它通过将多条以太网物理链路捆绑在一起成为一条逻辑链路,从而实现增加链路带宽的目的。同时,这些捆绑在一起的链路通过相互间的动态备份,可以有效地提高链路的可靠性。 目的: 随着网络规模不断扩大,用户对骨干链路的带宽和可靠性提出越来越高的要求。在传统技术中,常用更换高速率的接口板或更换支持高速率接口板的设备的方式来增加带宽,但这种方案需要付出高额的费用,而且不够灵活。 采用链路聚合技术可以在不进行硬件升级的条件下,通过将多个物理接口捆绑为一个逻辑接口

ChaseAug的博客 2万+

osg操纵器解析

转载自:http://lzchenheng.blog.163.com/blog/static/8383353620106710534514/  osg操纵器是我们实现场景漫游的主要手段,osg提供了驾驶操纵器、飞行操纵器、轨迹球操纵器等,这些操纵器的基类为osgGA::MatrixManipulator,有时为了漫游的需要,我们需要编写自己的操纵器,要想编写好自己的操纵器,必须对osg操

luffv的专栏 4111

解决Android UVCCamera stopPreview 报错 崩溃 闪退 问题

在使用libuvccamera库的UVCCamera时,经常在调用stopPreview关闭预览的时候,app直接崩溃闪退了,经过综合各种修改源码的方案,已解决这个问题,以下请参考: 首先找到android_usbfs.c,linux_usbfs.c两个原文件,在两个文件中都可以找到这段代码,按如下示例修改: 修改前: for (i = 0; i < num_urbs; i++) { if (urb == tpriv->iso_urbs[i]) { urb_idx = i + 1;

hanye2020的博客 3576

自定义一个简单的操控器类

osg已经自己实现了很多操控器类,这些操控器类存放在osg源码目录下的src\osgGA目录。感兴趣的童鞋,可以自己去研究源码。虽然说osg实现了很多常用的操控器类,但现实中的业务需求是各种各样的,当osg自己实现的操控器不能满足平时的业务需求时,就需要自己开发操控器,本博文通过实现一个简单的操控器,来说明如何定制开发自己的操控器类。

danshiming的博客 557

大模型训练和推理

大模型训练moe是指混合专家(Mixture-of-experts,简称MoE)的,这是一种用于提高大型神经网络性能的技术,它可以将模型的一部分替换为多个专家,每个专家只负责处理一部分输入数据,从而增加模型的参数量和表达能力,同时减少计算量和训练时间。指令可以作为模型的输入的一部分,也可以作为模型的输出的一部分,具体取决于任务的类型。上下文扩展技术的,这是一种用于提高大型语言模型(LLM)对长文本的处理能力的技术,它可以让模型在不增加参数量的情况下,扩展其注意力范围,从而提高模型的语言理解和生成能力。

weixin_45325331的博客 6020

别再硬编码了!Flowable工作流动态审批人配置全解析(Spring Boot集成版)

本文深入解析Flowable工作流在Spring Boot中的动态审批人配置技术,通过角色、部门等变量实现审批流程的灵活设计。文章详细介绍了架构原理、前端配置映射、动态候选组解析及查询优化方案,帮助企业提升审批流程的适应性和维护效率。

weixin_30919571的博客 135

osg中漫游器的原理(一)

对osg中漫游器的解析,从中可以了解到漫游器的添加、更新、处理和自定义自己漫游器的方式

Frank的专栏 1万+

华为OD统一考试 - 模拟消息队列(Java & Python& JS & C++ & C )

让我们来模拟一个消息队列的运作,有一个发布者和若干消费者,发布者会在给定的时刻向消息队列发送消息,

算法大师! 3518

osg漫游器的原理和执行流程

关键词:manipulator; 漫游器; 第一人称漫游器; osg; osg漫游器的原理; osg漫游器的流程 从CameraManipulator讲起吧,CameraManipulator是漫游器的基类,它继承于GUIEventHandler class OSGGA_EXPORT CameraManipulator : public GUIEventHandler { ... }; ...

三维小糊涂,泽云,三维开发技术分享 1万+

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

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

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

osgGA::CameraManipulator

上述的fabs(right - left) / 2 / zNear 就是代码中的vertical2;而fab(top - bottom) / 2.0 / zNear就是代码中的horizontal2。沟通连接为:Should naming be exchanged?

hanfenkui的博客 294

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

OSG中获取任一时刻相机的位置

就是在有漫游器的程序中获取相机任一时刻的位置,有时使用漫游器漫游时需要

7344

OSG 视景器、漫游器、摄像机与场景的关系

视景器包括几个最主要的组件:漫游器_cameraManipulator,用于实现交互式的场景漫 游;事件处理器组_eventHandlers,负责处理视景器的事件队列_eventQueue,主要是键盘/ 鼠标等事件的处理;场景_scene,它包括视景器所对应的场景图形根节点,以及用于提高节 点和图像数据处理速度的两个分页数据库;摄像机_camera 和_slaves,前者为场景的主摄像 机

ZhangXL的专栏 3825

OSG学习之示例遇到的问题二图形不能显示网格模式

代码中加了 viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));   但是不能显示成网格模式 解决方法: W键切换显示模式,如果不行,注意自己是否有输入法错误。

wuwangrun的专栏 2875

osgGA的CameraManipulator类

操作器基类,用于实现各种操作器接口。本身也是一个操作器的管理类,里面可以压入多个操作器,根据用户按键选择使用哪一个操作器。 virtual const char * className() const 说明:获取当前类的名称 void addMatrixManipulator(int key , std::string nam , CameraManipulator *cm) 说明:添加一个操作器...

Jeacean的博客 1115

osg拖拽器

#include <osgViewer/Viewer> #include <osg/Node> #include <osg/Geometry> #include <osg/Geode> #include <osg/Group> #include <osg/AutoTransform> #include <osg/ProxyNode> #include <osgDB/ReadFile> #include <.

danshiming的博客 1099

OSG学习——漫游操作器

在进行制作漫游操作器时,遇到了几个问题。 一:在新的版本下,:MatrixManipulator 已经改名为CameraManipulator。 二:在继承CameraManipulator的类中,四个虚函数 第1个和第2个为设置矩阵及设置逆矩阵,可以不进行设置。 第3个和第4个为得到矩阵和逆矩阵,其中得到逆矩阵和响应函数handle会每一帧都会进行渲染。 三:在响应函数handle...

城南花已开 887

osg shader 相机观察矩阵逆矩阵 求顶点世界坐标

uniform mat4 osg_ViewMatrixInverse;//osg内置uniform void main() { vec4 posWorld = osg_ViewMatrixInverse*gl_ModelViewMatrix*gl_Vertex; ..... } 转载于:https://www.cnblogs.com/coolbear/p/10717756....

weixin_30776273的博客 554

osg_操作器、碰撞检测、上楼梯篇

一.  操作器 OSG经常用到的自带操作器为TrackBall, osgEarth经常用到的自带操作器为EarthManipulator 自己要写操作器应继承于osgGA::CameraManipulator 流程:1. 设置自定义操作器  2. viewer在帧绘制时候取操作器控制的矩阵,(矩阵控制一般重载getMatrix()和getInverseMatrix()函数),然后更新came

Scarlett_OHara的博客 3140

osg操控器之键盘切换操控器osgGA::KeySwitchMatrixManipulator

osg操控器之键盘切换操控器osgGA::KeySwitchMatrixManipulator

danshiming的博客 1612
上一篇: osg实现自定义插件读取自定义格式的模型文件到场景
下一篇: osg的 realize()函数剖析
荆楚闲人
博客等级 码龄20年 3万+粉丝 473原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值