【Overload游戏引擎分析】从视图投影矩阵提取视锥体及overload对视锥体的封装
overoad代码中包含一段有意思的代码,可以从视图投影矩阵逆推出摄像机的视锥体,本文来分析一下原理
一、平面的方程
视锥体是用平面来表示的,所以先看看平面的数学表达。
平面方程可以由其法线N=(A, B, C)和一个点Q=(x0,y0,z0)定义,其形式为:
A ( x − x 0 ) + B ( y − y 0 ) + C ( z − z 0 ) = 0 A(x-x_{0})+B(y-y_{0})+C(z-z_{0})=0 A(x−x0)+B(y−y0)+C(z−z0)=0 整理变为: A x + B y + C z + D = 0 Ax+By+Cz+D=0 Ax+By+Cz+D=0, 其中 D = − A x 0 − B y 0 − C z 0 D=−Ax_{0}−By_{0}−Cz_{0} D=−Ax0−By0−Cz0
方程进一步可以将方程归一化:
A A 2 + B 2 + C 2 x + B A 2 + B 2 + C 2 y + C A 2 + B 2 + C 2 z + D A 2 + B 2 + C 2 = 0 \frac{A}{\sqrt{A^{2}+B^{2}+C^{2} } } x + \frac{B}{\sqrt{A^{2}+B^{2}+C^{2} } }y+\frac{C}{\sqrt{A^{2}+B^{2}+C^{2} } }z+\frac{D}{\sqrt{A^{2}+B^{2}+C^{2} } } = 0 A2+B2+C2Ax+A2+B2+C2By+A2+B2+C2Cz+A2+B2+C2D=0 写成通用格式 a x + b y + c z + d = 0 ax+by+cz+d=0 ax+by+cz+d=0
那么点 p = ( x 1 , y 1 , z 1 ) p=(x_{1}, y_{1}, z_{1}) p=(x1,y1,z1)到平面的距离为:
D = a x 1 + b y 1 + c z 1 + d D=ax_{1}+by_{1}+cz_{1}+d D=ax1+by1+cz1+d
一个平面会将空间分成两个半空间(halfspace),进一步法线的朝向的空间称为正半空间(positive halfspace),法线背离的空间称为反半空间(negative halfspace)。根据D的符号可以判断点的相对位置:
- D < 0, 点位于反半空间
- D = 0, 点位于平面上
- D > 0, 点位于正半空间
这种特性可用于判断点是否在视锥体内部。
二、OpenGL视锥体
视锥体是摄像机能看到的区域,只有在视锥体内的物体才能被看到。其由近平面、远平面与周围四个面组成,形成一个平截头体区域。

三、Overload对视锥体的封装
Overload对视锥体的封装在文件Frustum.h、Frustum.cpp中。先看其定义:
class Frustum
{
public:/*** 根据视图投影矩阵提取视锥体* @param p_viewProjection*/ void CalculateFrustum(const OvMaths::FMatrix4& _viewProjection);/*** 判断点是不是在视锥体内* @param p_x* @param p_y* @param p_z*/bool PointInFrustum(float p_x, float p_y, float _z) const;/*** 判断球是不是在视锥体内* @param p_x* @param p_y* @param p_z* @param p_radius*/bool SphereInFrustum(float p_x, float p_y, loat p_z, float p_radius) const;/*** 判断立方体是不是在视锥体内* @param p_x* @param p_y* @param p_z* @param p_size*/bool CubeInFrustum(float p_x, float p_y, float _z, float p_size) const;/*** 判断包围球是不是在视锥体内* @param p_boundingSphere* @param p_transform*/bool BoundingSphereInFrustum(const vRendering::Geometry::BoundingSphere& _boundingSphere, const OvMaths::FTransform& _transform) const;/*** 返回近平面*/std::array<float, 4> GetNearPlane() const;/*** 返回远平面*/std::array<float, 4> GetFarPlane() const;
private:float m_frustum[6][4]; // 6个平面的方程参数
};
m_frustum保存着6个平面的方程参数,为了提升操作便利性,其定义了两个枚举作为索引:
enum FrustumSide
{RIGHT = 0, // The RIGHT side of the frustumLEFT = 1, // The LEFT side of the frustumBOTTOM = 2, // The BOTTOM side of the frustumTOP = 3, // The TOP side of the frustumBACK = 4, // The BACK side of the frustumFRONT = 5 // The FRONT side of the frustum
};// 平面方程的参数索引
enum PlaneData
{A = 0, // The X value of the plane's normalB = 1, // The Y value of the plane's normalC = 2, // The Z value of the plane's normalD = 3 // The distance the plane is from the origin
};
函数的具体实现在文件Frustum.cpp中,我们先看最基础的判断点是否在视锥体内:
bool OvRendering::Data::Frustum::PointInFrustum(float x, float y, float z) const
{for (int i = 0; i < 6; i++){if (m_frustum[i][A] * x + m_frustum[i][B] * y + m_frustum[i][C] * z + m_frustum[i][D] <= 0){return false;}}return true;
}
定义视锥体的面法线都是朝外的,如果点在视锥体内,点到6个面的距离必须全部小于0。进一步判断球体是否完全在视锥体内,距离必须小于半径的负数。
最后分析一下CalculateFrustum,它是根据一个视图投影矩阵反向构建一个视锥体,具体公式怎么来的可以参考这篇文章,里面将的特别详细:
Fast Extraction of Viewing Frustum Planes from the World View-Projection Matrix
其本身的代码没啥好说的,无非就是公式的翻译。
相关文章:
【Overload游戏引擎分析】从视图投影矩阵提取视锥体及overload对视锥体的封装
overoad代码中包含一段有意思的代码,可以从视图投影矩阵逆推出摄像机的视锥体,本文来分析一下原理 一、平面的方程 视锥体是用平面来表示的,所以先看看平面的数学表达。 平面方程可以由其法线N(A, B, C)和一个点Q(x0,…...
vue全局事件总线是什么?有什么用?解决了什么问题,与pinia有什么区别?
全局事件总线快速入门 概念基本概念(是什么?)核心概念 核心特性和优势(有什么用?)解决了什么问题?主要优势是什么? 案例演示?传递数据-案例演示传递事件-案例演示 与pinia有什么区别?…...
【debian 12】:debian系统切换中文界面
目录 目录 项目场景 基础参数 原因分析 解决方案 1.ctrlaltT 打开终端 2.查询当前语言环境(我的已经设置成了中文 zh_CN.UTF-8) 3.打开语言配置界面 4.最后一步:重启 不要放弃任何一个机会! 项目场景: 这两…...
es官方为我们提供的堆内存保护机制-熔断器( breaker )
总熔断器(相当于似乎总闸) 参数: indices.breaker.total.use_real_memory 默认值:true 在 elasticsearch.yml中配置。 参数: indices.breaker.total.limit 如果 indices.breaker.total.use_real_memory : true, in…...
靶场通关记录
OSCP系列靶场-Esay-CyberSploit1 总结 getwebshell → 源码注释发现用户名 → robots.txt发现base64密码 → SSH登录 提 权 思 路 → 内网信息收集 → 发现发行版本有点老 → 内核overlayfs提权 准备工作 启动VPN 获取攻击机IP > 192.168.45.220 启动靶机 获取目标机器I…...
全网最新最全的软件测试面试题
一、前言 与开发工程师相比,软件测试工程师前期可能不会太深,但涉及面还是很广的。 在一年左右的实习生或岗位的早期面试中,主要是问一些基本的问题。 涉及到的知识主要包括MySQL数据库的使用、Linux操作系统的使用、软件测试框架问题、测试…...
如何列出 Ubuntu 和 Debian 上已安装的软件包
当你安装了 Ubuntu 并想好好用一用。但在将来某个时候,你肯定会遇到忘记曾经安装了那些软件包。 这个是完全正常。没有人要求你把系统里所有已安装的软件包都记住。但是问题是,如何才能知道已经安装了哪些软件包?如何查看安装过的软件包呢&a…...
图论---最小生成树问题
在连通网的所有生成树中,所有边的代价和最小的生成树,称为最小生成树。解决最小生成树问题一般有两种算法:Kruskal算法和Prim算法。 Kruskal算法 原理:基本思想是从小到大加入边,是个贪心算法。我们将图中的每个边按…...
elementplus 时间范围选择器限制选择时间范围
<el-date-pickerv-model"form.time" type"daterange"range-separator"-"start-placeholder"开始时间"end-placeholder"结束":disabled-date"disabledDate"calendar-Change"calendarChange" />co…...
【网络】抓包工具Wireshark下载安装和基本使用教程
🍁 博主 "开着拖拉机回家"带您 Go to New World.✨🍁 🦄 个人主页——🎐开着拖拉机回家_Linux,大数据运维-CSDN博客 🎐✨🍁 🪁🍁 希望本文能够给您带来一定的帮助…...
Metasequoia 4 水杉3D建模工具 附序列号
Metasequoia 4是一款非常强大的3D水杉建模工具,它基于多边形建模技术,可以用于创建各种对象并支持多种第三方3DCG软件的文件格式,是一款非常适合从爱好到业务,支持3D电脑绘图,3D印刷,游戏开发等的3D建模软件…...
股票杠杆交易平台排名:淘配网推荐的十大平台
在投资世界中,股票杠杆交易一直以其提供更高回报机会的吸引力而备受欢迎。随着市场的不断发展,出现了越来越多的股票杠杆交易平台。本文将为您介绍淘配网推荐的十大股票杠杆交易平台,并分析它们的特点。 富灯网 - 富灯网以其全面的杠杆产品和…...
CoreData + CloudKit 在初始化 Schema 时报错 A Core Data error occurred 的解决
问题现象 如果希望为 CoreData 支持的 App 增加云数据备份和同步功能,那么 CloudKit 是绝佳的选择。CloudKit 会帮我们默默处理好一切,我们基本不用为升级而操心。 不过,有时在用本地 CoreData NSManagedObjectModel 初始化 iCloud 中的 Schema 时会发生如下错误: Error …...
修炼k8s+flink+hdfs+dlink(三:安装dlink)
一:mysql初始化。 mysql -uroot -p123456 create database dinky; grant all privileges on dinky.* to dinky% identified by dinky with grant option; flush privileges;二:上传dinky。 上传至目录/opt/app/dlink tar -zxvf dlink-release-0.7.4.t…...
Linux 系统性能瓶颈分析(超详细)
Author:rab 目录 前言一、性能指标1.1 进程1.1.1 进程定义1.1.2 进程状态1.1.3 进程优先级1.1.4 进程与程序间的关系1.1.5 进程与进程间的关系1.1.6 进程与线程的关系 1.2 内存1.2.1 物理内存与虚拟内存1.2.2 页高速缓存与页写回机制1.2.3 Swap Space 1.3 文件系统1…...
kafka与zookeeper的集群
基础配置 systemctl stop firewalld && systemctl disable firewalld setenforce 0 sed -i s/SELINUXenforcing/SELINUXdisabled/ /etc/selinux/configvi /etc/hosts ip1 node1 ip2 node2 ip3 node3zookeeper介绍 zookeeper是一个分布式的协调服务,主要用…...
sqlalchemy 连接池
报错 sqlalchemy.exc.TimeoutError: QueuePool limit of size 100 overflow 10 reached, connection timed out, timeout 30 (Background on this error at: http://sqlalche.me/e/3o7r) 查看数据库未活动超时时间 show variables like "interactive_timeout";一般…...
用Blender制作YOLO目标检测器训练数据
推荐:用 NSDT编辑器 快速搭建可编程3D场景 本文将介绍一种非常有吸引力的机器学习训练数据的替代方案,用于为给定的特定应用程序收集数据。 无论应用程序类型如何,这篇博文都旨在向读者展示使用 Blender 等开源资源生成合成数据(S…...
c++视觉处理---均值滤波
均值滤波 cv::blur()函数是OpenCV中用于应用均值滤波的函数。均值滤波是一种简单的平滑技术,它计算每个像素周围像素的平均值,并用该平均值替代原始像素值。这有助于降低图像中的噪声,并可以模糊图像的细节。 以下是cv::blur()函数的基本用…...
QT基础入门——Qt事件(五)
前言: 事件(event)是由系统或者 Qt 本身在不同的时刻发出的。当用户按下鼠标、敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事件。一些事件在对用户操作做出响应时发出,如键盘事件等&#x…...
【Python | matplotlib】从入门到精通:matplotlib.cm颜色映射的实战应用与自定义指南
1. 初识matplotlib.cm:颜色映射的基础概念 第一次接触数据可视化时,我常常被那些色彩斑斓的热力图和散点图吸引。后来才发现,这些漂亮的颜色背后都离不开一个关键组件——颜色映射(colormap)。matplotlib.cm模块就是专…...
如何用Pulover‘s Macro Creator实现Windows自动化:5大实用技巧
如何用Pulovers Macro Creator实现Windows自动化:5大实用技巧 【免费下载链接】PuloversMacroCreator Automation Utility - Recorder & Script Generator 项目地址: https://gitcode.com/gh_mirrors/pu/PuloversMacroCreator Pulovers Macro Creator是一…...
家庭稳定性的具象化的庖丁解牛
它的本质是:家庭不是一个静态的物体,而是一个 动态平衡的复杂自适应系统 (Complex Adaptive System)。其稳定性不取决于“没有冲突”,而取决于系统在遭遇外部冲击(失业、疾病、经济下行)和内部扰动(争吵、代…...
船载AIS的Class A、Class B和接收器到底怎么选?一篇讲清休闲帆船、渔船和小货船的设备配置指南
船载AIS设备选购全指南:从合规到实战的智能决策 清晨的港口,一艘30英尺的休闲帆船正在做最后的出海准备。船长盯着仪表盘上闪烁的AIS接收器信号,思考着是否该升级为收发一体的Class B设备——这个决定可能关系到未来航行中能否被大型商船及时…...
别再被EC11编码器波形坑了!STM32F103外部中断驱动避坑指南(附完整代码)
EC11编码器驱动开发实战:从硬件滤波到软件防抖的全方位避坑指南 旋转编码器作为人机交互的重要组件,在嵌入式系统中应用广泛。EC11以其性价比和可靠性成为许多项目的首选,但实际开发中,工程师常被信号抖动、方向误判等问题困扰。本…...
用STM32F103和DHT11做个智能温湿度报警器,附ESP8266远程监控代码
STM32F103与DHT11打造智能环境监测系统:从本地报警到云端监控全解析 在智能家居和工业物联网快速发展的今天,环境监测系统已成为许多创客和开发者入门的首选项目。本文将带你用STM32F103微控制器和DHT11温湿度传感器,构建一个功能完善的智能…...
智慧图书书脊识别分割数据集labelme格式2100张1类别
数据集格式:labelme格式(不包含mask文件,仅仅包含jpg图片和对应的json文件)图片数量(jpg文件个数):2100标注数量(json文件个数):2100标注类别数:1标注类别名称:["book"]每个类别标注的框数:book …...
【ElevenLabs企业级接入白皮书】:基于17个生产环境案例验证的鉴权体系重构、多租户语音隔离与GDPR合规审计清单
更多请点击: https://intelliparadigm.com 第一章:ElevenLabs企业级接入的演进动因与白皮书方法论 企业语音合成需求正从“能发声”跃迁至“有角色、可治理、可审计、可集成”。ElevenLabs 企业级 API 的演进并非单纯性能叠加,而是响应 GDPR…...
多介质过滤器和活性炭过滤器的区别在哪?
做水处理设备选型快10年,我几乎每周都会遇到客户问:多介质过滤器和活性炭过滤器到底有啥区别?选型选错不仅花冤枉钱,还会直接影响整个水处理系统的寿命。先给大家总结核心结论:两者核心作用不同,多介质偏物…...
数据科学家压力管理的艺术
原文:towardsdatascience.com/the-art-of-stress-management-as-a-data-scientist-e49981cd2aa7 https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/96cbf6100471444654cae4816944e9b1.png Photo by Johnson Wang on Unsplash 数…...
