当前位置: 首页 > news >正文

【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(xx0)+B(yy0)+C(zz0)=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=Ax0By0Cz0
         方程进一步可以将方程归一化:
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+C2 Ax+A2+B2+C2 By+A2+B2+C2 Cz+A2+B2+C2 D=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视锥体

视锥体是摄像机能看到的区域,只有在视锥体内的物体才能被看到。其由近平面near、远平面far与周围四个面top、bottom、left、right组成,形成一个平截头体区域。
在这里插入图片描述
不过在构建视锥体时一般不直接输入6个平面的方程,常用另外一组更直观易懂的参数:

  1. fov – 视锥体的垂直张角
  2. Near – 视锥体的近平面距离
  3. Far – 视锥体的远平面距离
  4. aspect – 相机视口的长宽比

具体含义建下图:
在这里插入图片描述

三、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代码中包含一段有意思的代码&#xff0c;可以从视图投影矩阵逆推出摄像机的视锥体&#xff0c;本文来分析一下原理 一、平面的方程 视锥体是用平面来表示的&#xff0c;所以先看看平面的数学表达。 平面方程可以由其法线N&#xff08;A, B, C&#xff09;和一个点Q(x0,…...

Linux 安全 - LSM hook点

文章目录 一、LSM file system hooks1.1 LSM super_block hooks1.2 LSM file hooks1.3 LSM inode hooks 二、LSM Task hooks三、LSM IPC hooks四、LSM Network hooks五、LSM Module & System hooks 一、LSM file system hooks 在VFS&#xff08;虚拟文件系统&#xff09;层…...

【iOS逆向与安全】越狱检测与过检测附ida伪代码

首先在网上查找一些检测代码 放入项目运行&#xff0c;用 ida 打开后 F5 得到下面的 __int64 __usercall sub_10001B3F0<X0>(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, __int64 a7, __int64 a8, __int64 a9, __int64 a10, __int64 a11…...

Android Studio gradle手动下载配置

项目同步时&#xff0c;有时候会遇到Android Studio第一步下载gradle就是连接失败的问题。 这种情况&#xff0c;我们可以手动去gradle官网下载好gradle文件&#xff0c;放置在Android Studio的缓存目录下&#xff0c;这样AS在同步代码时就会自动解压下载好的文件。 步骤如下&…...

ChatGPT Prompting开发实战(十三)

一&#xff0e; 如何评估prompts是否包含有害内容 用户在与ChatGPT交互时提供的prompts可能会包括有害内容&#xff0c;这时可以通过调用OpenAI提供的API来进行判断&#xff0c;接下来给出示例&#xff0c;通过调用模型“gpt-3.5-turbo”来演示这个过程。 prompt示例如下&…...

银河麒麟 ARM 架构 离线安装Docker

1. 下载对应的安装包 进入此地址下载对应的docker 离线安装包 下载地址 将文件上传到服务器 解压此文件 tar zxf docker-18.09.1.tgz将 docker 相关命令拷贝到 /usr/bin&#xff0c;方便直接运行命令 cp docker/* /usr/bin/启动Docker守护程序 dockerd &验证是否安装成…...

虹科科技 | 探索CAN通信世界:PCAN-Explorer 6软件的功能与应用

CAN&#xff08;Controller Area Network&#xff09;总线是一种广泛应用于汽车和工业领域的通信协议&#xff0c;用于实时数据传输和设备之间的通信。而虹科的PCAN-Explorer 6软件是一款功能强大的CAN总线分析工具&#xff0c;为开发人员提供了丰富的功能和灵活性。本文将重点…...

SELECT COUNT(*)会不会导致全表扫描引起慢查询

SELECT COUNT(*)会不会导致全表扫描引起慢查询呢&#xff1f; SELECT COUNT(*) FROM SomeTable 网上有一种说法&#xff0c;针对无 where_clause 的 COUNT(*)&#xff0c;MySQL 是有优化的&#xff0c;优化器会选择成本最小的辅助索引查询计数&#xff0c;其实反而性能最高&…...

英国物联网初创公司【FourJaw】完成180万英镑融资

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 猛兽财经获悉&#xff0c;总部位于英国谢菲尔德的物联网初创公司【FourJaw】今日宣布已完成180万英镑融资。 本轮融资完成后&#xff0c;FourJaw的总融资金额已达400万英镑&#xff0c;本轮融资的投资机构包括&#xff1a;…...

许战海战略文库|无增长则衰亡:中小型制造企业增长困境

竞争环境不是匀速变化&#xff0c;而是加速变化。企业的衰退与进化、兴衰更迭在不断发生&#xff0c;这成为一种不可避免的现实。事实上&#xff0c;在产业链竞争中增长困境不分企业大小&#xff0c;而是一种普遍存在的问题&#xff0c;许多收入在1亿至10亿美元间的制造企业也同…...

广州华锐互动:候车室智能数字孪生系统实现交通信息可视化

随着科技的不断发展&#xff0c;数字化技术在各个领域得到了广泛的应用。智慧车站作为一种新型的交通服务模式&#xff0c;通过运用先进的数字化技术&#xff0c;为乘客提供了更加便捷、舒适的出行体验。 将智慧车站与数字孪生大屏结合&#xff0c;可以将实际现实世界的实体车站…...

智慧工地:助力数字建造、智慧建造、安全建造、绿色建造

智慧工地管理系统融合计算机技术、物联网、视频处理、大数据、云计算等&#xff0c;为工程项目管理提供先进的技术手段&#xff0c;构建施工现场智能监控系统&#xff0c;有效弥补传统监理中的缺陷&#xff0c;对人、机、料、法、环境的管理由原来的被动监督变成全方位的主动管…...

增强基于Cortex-M3的MCU以处理480 Mbps高速USB

通用串行总线&#xff08;USB&#xff09;完全取代了PC上的UART&#xff0c;PS2和IEEE-1284并行接口&#xff0c;现在已在嵌入式开发应用程序中得到广泛认可。嵌入式开发系统使用的大多数I / O设备&#xff08;键盘&#xff0c;扫描仪&#xff0c;鼠标&#xff09;都是基于USB的…...

山海鲸汽车需求调研系统:智慧决策的关键一步

随着社会的发展和科技的进步&#xff0c;汽车行业也迎来了新的挑战和机遇。如何更好地满足用户需求、提高产品竞争力成为了汽车制造商们关注的焦点。在这个背景下&#xff0c;山海鲸汽车需求调研互动系统应运而生&#xff0c;为汽车行业赋予了智慧决策的力量。 智慧决策的核心&…...

视频缩放的概念整理-步长数组

最近在读ffmpeg的代码时候&#xff0c;这个接口不是很能看懂int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]); 多方请教后&#xff0c;记录结果如…...

TensorFlow入门(二十一、softmax算法与损失函数)

在实际使用softmax计算loss时,有一些关键地方与具体用法需要注意: 交叉熵是十分常用的,且在TensorFlow中被封装成了多个版本。多版本中,有的公式里直接带了交叉熵,有的需要自己单独手写公式求出。如果区分不清楚,在构建模型时,一旦出现问题将很难分析是模型的问题还是交叉熵的使…...

UDP通信:快速入门

UDP协议通信模型演示 UDP API DatagramPacket&#xff1a;数据包对象&#xff08;韭菜盘子&#xff09; public DatagramPacket(byte[] buf, int length, InetAddress address, int port)创建发送端数据包对象 buf&#xff1a;要发送的内容&#xff0c;字节数组 length&…...

修炼k8s+flink+hdfs+dlink(四:k8s(一)概念)

一&#xff1a;概念 1. 概述 1.1 kubernetes对象. k8s对象包含俩个嵌套对象字段。 spec&#xff08;规约&#xff09;&#xff1a;期望状态 status&#xff08;状态&#xff09;&#xff1a;当前状态 当创建对象的时候&#xff0c;会按照spec的状态进行创建&#xff0c;如果…...

redis与 缓存击穿、缓存穿透、缓存雪崩

什么是缓存击穿、缓存穿透、缓存雪崩 缓存击穿、缓存穿透和缓存雪崩是与缓存相关的三种常见问题&#xff0c;它们可以在高并发的应用中导致性能问题。以下是它们的解释&#xff1a; 缓存击穿&#xff08;Cache Miss&#xff09; 缓存击穿指的是在高并发情况下&#xff0c;有大…...

印度网络安全:威胁与应对

随着今年过半&#xff0c;我们需要评估并了解不断崛起的网络威胁复杂性&#xff0c;这些威胁正在改变我们的数字景观。 从破坏性的网络钓鱼攻击到利用人工智能的威胁&#xff0c;印度的网络犯罪正在升级。然而&#xff0c;在高调的数据泄露事件风暴中&#xff0c;我们看到了政…...

【Python MCP服务器安全开发黄金模板】:20年专家亲授7大零信任实践与3层防御体系

第一章&#xff1a;Python MCP服务器安全开发黄金模板概览Python MCP&#xff08;Model-Controller-Protocol&#xff09;服务器是一种面向协议驱动、可扩展性强的后端服务架构&#xff0c;广泛应用于物联网控制平台与微服务网关场景。本章所介绍的“黄金模板”并非通用框架&am…...

手把手教你学Simulink——基于Simulink的模型预测控制(MPC)PFC整流器快速动态响应

目录 手把手教你学Simulink ——基于Simulink的模型预测控制(MPC)PFC整流器快速动态响应 一、问题背景 二、系统建模与控制目标 1. 单相 Boost PFC 拓扑 2. 动态方程(αβ 静止坐标系) 3. 控制目标 三、有限控制集 MPC(FCS-MPC)设计 1. 预测模型(离散化) 2. 代…...

Llama-3.2V-11B-cot与Dify集成:零代码构建企业AI智能体

Llama-3.2V-11B-cot与Dify集成&#xff1a;零代码构建企业AI智能体 最近和几个做企业服务的朋友聊天&#xff0c;大家普遍有个感觉&#xff1a;现在AI模型能力越来越强&#xff0c;但真要把它们用起来&#xff0c;门槛还是有点高。特别是对于业务部门的人来说&#xff0c;看着…...

Aurix/Tricore实验解析:从链接脚本到汇编指令的Trap向量表构建

1. 理解Trap机制与向量表基础 在Aurix/Tricore架构中&#xff0c;Trap&#xff08;陷阱&#xff09;是处理器响应异常事件的硬件机制&#xff0c;相当于汽车的安全气囊——平时看不见&#xff0c;但遇到碰撞时会立即触发保护。与中断不同&#xff0c;Trap是同步触发的&#xff…...

船舶水动力学与运动控制技术指南:从理论建模到工程实践

船舶水动力学与运动控制技术指南&#xff1a;从理论建模到工程实践 【免费下载链接】FossenHandbook Handbook of Marine Craft Hydrodynamics and Motion Control is an extensive study of the latest research in marine craft hydrodynamics, guidance, navigation, and co…...

Winhance中文版:让Windows系统管理不再复杂的全能工具

Winhance中文版&#xff1a;让Windows系统管理不再复杂的全能工具 【免费下载链接】Winhance-zh_CN A Chinese version of Winhance. C# application designed to optimize and customize your Windows experience. 项目地址: https://gitcode.com/gh_mirrors/wi/Winhance-zh…...

多平台资源下载解决方案:res-downloader实现数字内容自由获取

多平台资源下载解决方案&#xff1a;res-downloader实现数字内容自由获取 【免费下载链接】res-downloader 视频号、小程序、抖音、快手、小红书、直播流、m3u8、酷狗、QQ音乐等常见网络资源下载! 项目地址: https://gitcode.com/GitHub_Trending/re/res-downloader 在数…...

TEdit终极指南:如何用免费地图编辑器10倍提升泰拉瑞亚创作效率

TEdit终极指南&#xff1a;如何用免费地图编辑器10倍提升泰拉瑞亚创作效率 【免费下载链接】Terraria-Map-Editor TEdit - Terraria Map Editor - TEdit is a stand alone, open source map editor for Terraria. It lets you edit maps just like (almost) paint! It also let…...

GHelper:华硕笔记本轻量级替代方案与性能优化指南

GHelper&#xff1a;华硕笔记本轻量级替代方案与性能优化指南 【免费下载链接】g-helper Lightweight, open-source control tool for ASUS laptops and ROG Ally. Manage performance modes, fans, GPU, battery, and RGB lighting across Zephyrus, Flow, TUF, Strix, Scar, …...

终极PDF批量处理指南:如何用PDF Arranger自动化文档操作

终极PDF批量处理指南&#xff1a;如何用PDF Arranger自动化文档操作 【免费下载链接】pdfarranger Small python-gtk application, which helps the user to merge or split PDF documents and rotate, crop and rearrange their pages using an interactive and intuitive gra…...