【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
  其本身的代码没啥好说的,无非就是公式的翻译。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/157077.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开发一个npm组件包(2)

通过vueelement 原来后台 开发npm包的时候 会遇到一下几个问题 入口文件变化为package/index 需要再配置打包方法 package.json下 "scripts": {"package": "vue-cli-service build --target lib ./src/package/index.js --name managerpage --dest…

C# 搭建一个简单的WebApi项目23.10.10

一、创建Web API 1、创建一个新的web API项目 启动VS 2019&#xff0c;并在“开始页”选择“创建新项目”。或从“文件”菜单选择“新建”&#xff0c;然后选择“项目”。 选择ASP.NET Web应用程序(.NET Framework) 2.点击下一步&#xff0c;到这个页面时选择Web API。 3.选中…

智能制造优化,RFID生产线管理系统解决方案

一、背景介绍 随着全球经济的发展&#xff0c;传统制造业面临着越来越高的成本和低利润的挑战&#xff0c;为了提升企业的整体利润率&#xff0c;优化管理流程成为必要的手段之一&#xff0c;在传统的制造企业中&#xff0c;生产线通常采用单件流生产模式&#xff0c;但这种模…

『heqingchun-ubuntu系统下安装nvidia显卡驱动3种方法』

ubuntu系统下安装nvidia显卡驱动3种方法 一、安装依赖 1.更新 sudo apt updatesudo apt upgrade -y2.基础工具 sudo apt install -y build-essential python图形界面相关 sudo apt install -y lightdm注:在弹出对话框选择"lightdm" 二、第一种&#xff1a;使用…

【网络编程】Linux网络编程基础与实战第一弹——网络基础

这里写目录标题 网络基础什么是协议典型协议 分层模型OSI七层模型TCP/IP四层模型 网络应用程序设计模式优缺点具体体现&#xff1a; 网络基础 什么是协议 从应用的角度出发&#xff0c;协议可理解为“一组规则”&#xff0c;是数据传输和数据的解释的规则。 假设&#xff0c;…

如何使用CSS和JavaScript实施暗模式?

近年来&#xff0c;暗模式作为用户界面选项备受追捧。它提供了更暗的背景和更亮的文本&#xff0c;不仅可以减轻眼睛疲劳&#xff0c;还可以节省电池续航时间&#xff0c;尤其是在OLED屏幕上。 不妨了解如何结合使用CSS和JavaScript为网站和Web应用程序添加暗模式选项。 了解暗…

来自小魔推的八大优势应用场景,这些你都了解吗?

进入2023年&#xff0c;大多数在做短视频宣传的实体商家都在考虑新的推广方式&#xff0c;而近期商家宣传工具已经逐渐被小魔推所种草&#xff0c;今天就把小魔推的应用场景与八大优势&#xff0c;统一给大家讲清楚&#xff01; 1&#xff1a;员工专属推广码&#xff0c;商家可…

3.3 数据定义

思维导图&#xff1a; 前言&#xff1a; **核心概念**&#xff1a; - 关系数据库支持**三级模式结构**&#xff1a;模式、外模式、内模式。 - 这些模式中包括了如&#xff1a;模式、表、视图和索引等基本对象。 - SQL的数据定义功能主要包括了模式定义、表定义、视图和索引的定…

基于深度学习的“语义通信编解码技术”框架分类

目录 基于神经网络的语义提取基于神经网络的语义信源编码基于神经网络的语义信源信道联合编码基于神经网络的语义编码与数字调制联合设计参考文献 基于神经网络的语义提取 在现有的信源编码前端加上一个语义提取神经网络[53] &#xff0c;如图所示。语义提取神经网络的输入是原…

基于工业5G网关的工业机器人监测控制方案

随着智能制造、自动化生产的发展进步&#xff0c;工业机器人的身影越来越多地出现在工厂现场&#xff0c;成为新型无人化、智能化生产制造的中坚力量。 工业机器人的运行伴生着海量的数据采集、传输、分析和反馈执行&#xff0c;因此也需要高速、低延迟的5G网络&#xff0c;支撑…

K8s Kubernetes Namespave Pod Label Deployment Service 实战

本章节将介绍如何在kubernetes集群中部署一个nginx服务&#xff0c;并且能够对其进行访问。 Namespace Namespace是kubernetes系统中的一种非常重要资源&#xff0c;它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离。 默认情况下&#xff0c;kubernetes集群中…

甘特图组件DHTMLX Gantt示例 - 如何有效管理团队工作时间?(一)

如果没有有效的时间管理工具&#xff0c;如工作时间日历&#xff0c;很难想象一个项目如何成功运转。这就是为什么我们的开发团队非常重视项目管理&#xff0c;并提供了多种选择来安排DHTMLX Gantt的工作时间。使用DHTMLX Gantt这个JavaScript库&#xff0c;您可以创建一个强大…

使用Tortoisegit界面拉起master主分支以副分支以及命令行操作

文章目录 1、Gui操作界面2、命令行操作3、合并分支到master分支上面 1、Gui操作界面 "小乌龟"通常指的是Git的图形用户界面&#xff08;GUI&#xff09;工具&#xff0c;其中比较常见的是TortoiseGit。下面是使用TortoiseGit来拉取&#xff08;checkout&#xff09;一…

android之TextView自由选择复制

文章目录 前言一、效果图二、实现步骤1.OnSelectListener2.SelectionInfo类3.TextLayoutUtil类4.复制弹框的xml布局5.弹框背景Drawable6.倒三角Drawable7.复制工具类8.调用 总结 前言 根据时代进步&#xff0c;那些干产品的也叼砖起来了&#xff0c;今天就遇到一个需求&#x…

Xcode升级到15.0 解决DT_TOOLCHAIN_DIR问题

根据个人开发遇到的问题做的总结&#xff0c;公司要求Xcode 14.2 &#xff0c;Swift 5.7开发&#xff0c;由于升级了Mac 14.0系统后&#xff0c;Xcode 14.2不能使用&#xff0c;解决方案目前有2个 一、在原来Xcode 14.2 的显示包内容&#xff0c;如图 二、升级到Xcode的15.0后…

yolov8 (2) : 模型训练

yolov8 github: https://github.com/ultralytics/ultralytics yolov8 网络详解参见: YOLOv8 (1) : 网络讲解1. 环境安装 安装ultralytics包pip install ultralytics在终端输入yolo命令࿰

软件TFN 2K的分布式拒绝攻击(DDos)实战详解

写在前头 本人写这篇博客的目的&#xff0c;并不是我想成为黑客或者鼓励大家做损坏任何人安全和利益的事情。因科研需要&#xff0c;我学习软件TFN 2K的分布式拒绝攻击&#xff0c;只是分享自己的学习过程和经历&#xff0c;有助于大家更好的关注到网络安全及网络维护上。 需要…

饥荒服务器阿里云租用价格表一年和一个月收费报价表

饥荒阿里云服务器多少钱一个月&#xff1f;阿里云服务器价格9元一个月&#xff0c;阿里云轻量应用服务器2核2G3M带宽轻量服务器一年108元&#xff0c;2核4G4M带宽轻量服务器一年297.98元12个月&#xff1b;阿里云ECS云服务器e系列2核2G配置182元一年、2核4G配置365元一年、2核8…

信必优收到全国性综合类证券客户表扬信

近日&#xff0c;信必优收到全国性综合类证券客户表扬信&#xff0c;客户高度表扬我司驻场员工认真负责的态度和专业扎实的技术能力&#xff0c;任务承担快&#xff0c;工作效率高&#xff0c;对项目顺利开展做出了积极贡献。 客户成立于1988年&#xff0c;在全国21个省级区域…

京东数据平台:2023年9月京东洗衣机行业品牌销售排行榜

鲸参谋监测的京东平台9月份洗衣机市场销售数据已出炉&#xff01; 9月份洗衣机行业销售呈下滑状态。鲸参谋数据显示&#xff0c;9月京东平台洗衣机的总销量为116万&#xff0c;环比下滑约1%&#xff0c;同比下滑约13%&#xff1b;月销售额为17亿&#xff0c;环比下滑约7%&…