Ogre学习笔记(6):BspSceneManager

Python开发提效新范式:用GPT-4 Custom Instructions构建编码宪法 Custom Instructions 是大模型时代下 Python 工程规范的结构化载体,其本质是将隐性开发约定(如类型提示、错误处理、日志规范)转化为 AI 可执行、可验证、可继承的元规则。它基于 GPT-4 的指令记忆与上下文补全能力,实现跨会话一致性约束,显著降低认知负荷与风格熵增。相比临时提示词,Custom Instructions 具备账户级持久性、安全红线强制拦截、领域感知生成等技术价值,已广泛应用于 Web API、数据管道、机器学习工程等典型 Python 场景,成为现代 Python 阅读详情

【1. 概览】

       Ogre支持Quake3的bsp格式。相关的代码在“Plugin_BSPSceneManager”工程中。主要的类有以下几个:

 

Class BspSceneNode:

       BspSceneNode是SceneNode的派生类,是专门提供给BSPSceneManager使用的。主要是提供针对于BSP tree的可见性判断。这个类并不是BSP tree的node,BSP tree中的node使用BspNode。BspSceneNode会放入BSP tree的leaf节点中。由于SceneNode使用包裹盒的方法,不可分割,所以一个BspSceneNode可能放入多个Bsp tree的leaf节点中。

       从类的定义看,BspSceneNode并没有额外的保存什么数据。重写的几个虚函数主要是用来通知BspSceneMapager,BspSceneNode::_update()会调用BspSceneManager::_notifyObjectMoved(),detach objcect会调用BspSceneManager::_notifyObjectDetached()。

 

Class BspSceneManager:

       粗略的看BspSceneManager与OctreeSceneManager类似。首先保存了一个BspLevel的指针,然后使用一个walkTree()函数,用来遍历tree结构。由于Quake使用BSP leaf tree,所以多了一个processVisibleLeaf()函数。另外一个明显的不同是有一个renderStaticGeometry()函数,“Renders the static level geometry tagged in walkTree”。此函数渲染“mMatFaceGroupMap”中的所有数据。BSP一个好处是不透明面可以front-back的顺序来渲染,而透明面back-front来渲染,OGRE是如何将此特性保存到MaterialFaceGroupMap的呢?

 

Class BspLevel:

       这是一个核心的class。他存储了BSP的所有数据,关键的数据有:

1.         “BspNode* mRootNode;”――BSP tree的根节点

2.         “VertexData* mVertexData;”――整个level的所有顶点;

3.         “StaticFaceGroup* mFaceGroups;”――faces

4.         “BspNode::Brush *mBrushes;”――用来做碰撞检测的Brush,是QuakeBSP除了渲染以外的另外一个精华!Brush的名字有点怪,其实就是一个convex volume,可以减少CD的运算量。

5.         “VisData mVisData;”――PVS数据,是又一个Quake中的精华!当初Carmark在设计Quake的时候还使用软件渲染,hiden surface removal和减少over draw是最另他头痛的问题。BSP的思想应该是他从网上看来的,不过PVS应该是他所创。PVS大大减少了over draw。(见《Michael Abrash's Graphics Programming Black Book》)

6.         “PatchMap mPatches;”――Quake3支持贝赛尔曲面

关键的函数:

1.  bool isLeafVisible(const BspNode* from, const BspNode* to) const;使用PVS来检测可见性。

2.  void _notifyObjectMoved(const MovableObject* mov, const Vector3& pos);
void _notifyObjectDetached(const MovableObject* mov);
à void tagNodesWithMovable(BspNode* node, const MovableObject* mov, const Vector3& pos);
把MovableObject(注意:不是SceneNode)挂到BSP的leaves上。

 

Class BspNode:

       这是Bsp中的另外一个重要的类了。Node和Leaf都使用这个类。

       重要数据:

1.  Plane mSplitPlane;     BspNode* mFront;     BspNode* mBack;
分割平面和前后节点;

2.  int mVisCluster;
每个cluster占pvs的一个bit,这是为了减少pvs占用的内存。

3.  int mNumFaceGroups;    int mFaceGroupStart;
用来找到BspLevel中哪些face group是属于我这个leaf的,这样做也是为了优化存储;

4.  IntersectingObjectSet mMovables;
和本节点相交的movable对象

5.  NodeBrushList mSolidBrushes;
本节点包含的brush。

另外剩下的OgreQuake3Level.h、OgreQuake3Shader.h、OgreQuake3ShaderManager.h、OgreQuake3Type.h主要是为了把Quake3格式的bsp,shader信息读入,并转换成Ogre本地的bsp定义以及Material。现在quake3的源码已经公开(非常感谢id software以及carmark),可以结合quake3的源码来看。

 

【2. Quake3 bsp的加载】

       以Demo_BSP为例,首先需要修改“quake3settings.cfg”,两个参数,“Pak0Location”是pk包的路径(是一个zip文件),“Map”为想要加载的地图。

       OGRE使用BspLevel来存储Bsp场景信息,这个类是与文件格式无关的。所以需要另外一个类来把Quake3的bsp文件读入。

       Quake3Level的读盘的主要由两个函数完成:

1、“void Quake3Level::loadHeaderFromStream()”。调用的流程是:

BspApplication::loadResources()

à ResourceGroupManager::loadResourceGroup()【A】

à BspSceneManager::estimateWorldGeometry()

à BspLevel::calculateLoadingStages()

àQuake3Level::loadHeaderFromStream()

       Quake3 BSP的文件格式很简单明了,前面是一个文件头,后面是几个数据块。文件头主要存储了几个lump,包含数据块的起始位置和大小,通过lump,可以直接seek到对于的数据块。
      
此函数在加载了文件头之后,调用了Quake3Level:: initialiseCounts ()函数,主要是计算了每个lump包含的对象的个数,例如face,vertex,bursh等等。

       2、第二个函数“void Quake3Level::loadFromStream()”。调用的过程是:

ResourceGroupManager::loadResourceGroup()【A】

àBspSceneManager::setWorldGeometry()

àBspResourceManager::load()

àResourceManager::load()

àResource::load()

àBspLevel::loadImpl()

àQuake3Level::loadFromStream()

在这地方OGRE延续了他罗嗦的风格,BspSceneManager要通过BspResourceManager来加载场景,BspLevel实现为一种Resource,BspResourceManager通过标准的ResourceManager――》Resource来找到BspLevel,然后调用其加载函数。

 

此函数首先构造了一个“MemoryDataStream”对象,在MemoryDataStream的构造函数中把文件数据全部读入其缓冲中(Quake也是这样干的),然后调用“void Quake3Level::initialisePointers(void)”函数,得到所有lump索引的对象的指针。

 

Quake3Level把文件读入并明确了所有数据的指针之后,在void BspLevel::loadImpl()中调用“BspLevel::loadQuake3Level()”函数讲Quake3level中的数据拷贝到自己的数据对象中。主要执行了以下几个操作:

1.         “BspLevel::loadEntities()”,这个lump存的是一个字符串,用来描述一些游戏信息,Ogre的这个函数只读取了Player start信息(位置和角度)。

2.         “Quake3Level::extractLightmaps()”。Quake3 BSP的每个light map都是128×128大,此函数将Light map lump中的数据逐个调用“TextureManager::loadImage()”创建成Texture对象(class D3D9Texture for D3D9 RenderSystem)。

3.         创建VertexData:
[Create vertex declaration] OGRE BspLevel
使用的顶点格式为:Position3,Normal3,Diffuse,uv0,uv1;
[Build initial patches]
调用BspLevel::initQuake3Patches()。此函数遍历Quake3Level中的所有faces,对于每个face type为“BSP_FACETYPE_PATCH”的face,创建一个PatchSurface对象,并调用PatchSurface:: defineSurface()函数进行,然后保存到BspLevel:: mPatches数组中。此函数还计算了BspLevel:: mPatchVertexCount和BspLevel:: mPatchIndexCount;
[
硬件顶点缓冲] 调用HardwareBufferManager创建HardwareVertexBuffer对象;使用“BspLevel::quakeVertexToBspVertex()”函数把q3 bsp顶点格式转换为Ogre BSPLevel的顶点格式。然后绑定到BspLevel::mVertexData;

4.         创建Faces:创建BspLevel:: mLeafFaceGroups数组;创建BspLevel:: mFaceGroups数组,此数组的数据在后面一步中填充;创建indexbuffer,并将Quake3Level::mElements拷贝进来;

5.         Create materials for shaders:对于Quake3Level::mFaces每一个bsp_face_t,找到它索引的Quake3Shader,并创建Material,如果没有找到Quake3Shader的话则使用shader name去查找贴图文件;
在此循环中还进行了“Copy face data”的操作,填充BspLevel:: mFaceGroups中的数据;

6.         Nodes:创建BspLevel:: mRootNode数组,并将数据拷贝进来。

7.         Brushes:将数据拷贝到BspLevel:: mBrushes中;

8.         Leaves:设置每个leaf节点的数据,主要包括包裹盒,mFaceGroupStart,mNumFaceGroups,mVisCluster,mSolidBrushes。参见BspNode类;

9.         Vis data:将数据拷贝到BspLevel:: mVisData中。

Quake3 BSP的load流程基本上就是这些了。

【3. Bsp tree scene的渲染】

       仍然以Demo_BSP为例来分析。渲染的核心操作流程从SceneManager::_renderScene()开始(参见“Ogre学习笔记(3):Mesh的渲染流程”),接下来还有SceneManager:: _updateSceneGraph(),SceneManager::prepareRenderQueue(),BspSceneManager没有重写这几个函数。不过,有一点需要注意,SceneManager:: _updateSceneGraph()调用了BspSceneNode::_update()与OctreeSceneManager类似的,如果有必要的话,会调用BspSceneManager:: _notifyObjectMoved()--》BspLevel:: _notifyObjectMoved(),将SceneNode中的MovableObject attach到正确的leaf node中。
      
接下来是BspSceneManager:: findVisibleObjects(),这是一个从SceneManager重写的函数。顺理成章的,这个函数调用了BspSceneManager::walkTree()。在这个函数中,首先找到了camera所在的leaf node(通过BspLevel::findleaf()函数);然后遍历BspLevel中的每个leaf node,先使用PVS检测可见性(通过BspLevel::isLeafVisible()函数),如果可见再使用camera――bounding box检测,如果还是可见的,则对此leaf node调用BspSceneManager::processVisibleLeaf()函数。此函数主要执行两个操作,一个是把World Geometry加入到渲染数据表中(mFaceGroupSet和mMatFaceGroupMap),另外一个是把与此leaf node相交的MoveableObject加到渲染队列中(mMovablesForRendering)。一件比较有疑问的事情是,walkTree是循环遍历所有leaf node,而没有按照BSP tree递归遍历,这大大削弱了BSP的提前排序的优势。

       然后是BspSceneManager重写了另外一个重要的函数_renderVisibleObjects()。此函数包含两个操作,一个是renderStaticGeometry(),另外一个是调用父类的SceneManager::_renderVisibleObjects()。前者循环遍历mMatFaceGroupMap,然后调用RenderSystem::_rendr();后者已经在“Ogre学习笔记(3):Mesh的渲染流程”中详细分析过了。

 
《矩阵论》学习笔记(四):4.2 矩阵的QR分解 《矩阵论》学习笔记(四):4.2 矩阵的QR分解 文章目录《矩阵论》学习笔记(四):4.2 矩阵的QR分解一. Givens矩阵与Givens变换1.1. 概念与理解1.2. Givens矩阵求解方法二. Householder矩阵与Householder变换2.1. 概念与理解2.2. Householder矩阵求解方法2.3. Givens变换与Householder变换的关系三. 矩阵的QR... 阅读详情

相关推荐

基于JavaFX的Http Server模拟器

源码地址 GitHub - DayRain/http-server-simulator: http server 模拟器 功能描述 HttpServer模拟器,通过简单的配置即可模拟第三方服务端,用于接收和响应HTTP请求。 支持同时模拟多个服务、动态添加接口、动态配置返回值。 使用说明 运行 exe运行 编译代码后,点击exe直接运行 代码运行 下载好代码后,运行主类ApplicationStarter即可 新建服务 主界面如下 点击 文件-新建 创建新的服务 ...

小楼夜听雨的博客 2534

11.scene manager

进入新的一章,建立新一个空项目,依然基于ExampleApplication,createscene()为空。 1.手选scene manager和加载地图 virtual void chooseSceneManager(void) { ResourceGroupManager::getSingleton().addResourceLocation("../../media/pac

526

智能座舱通信技术解析:从CAN总线到车载以太网与V2X

在汽车电子与智能网联快速融合的背景下,座舱智能化已不再是简单的屏幕堆砌,而是依赖底层通信技术构建的复杂系统。CAN总线因高可靠性与确定性传输,持续承担车身控制与安全信号的传递;车载以太网则凭借高带宽优势,成为多屏高清视频与OTA升级的核心通道;V2X车路协同技术进一步将座舱与外界的实时信息互联。理解这些技术的分工协作,是掌握智能座舱架构、开展座舱测试与故障排查的关键。本文从实际测试经验出发,梳理不同总线在座舱内部及外部的应用逻辑,结合低成本的实验台架搭建指南,展示从信号采集、网关转发到多媒体流传输的完整链路

weixin_29284657的博客 344

[转]Ogre学习笔记 BspSceneManager

【1. 概览】Ogre支持Quake3的bsp格式。相关的代码在“Plugin_BSPSceneManager”工程中。主要的类有以下几个:Class BspSceneNode:BspSceneNode是SceneNode的派生类,是专门提供给BSPSceneManager使用的。主要是提供针对于BSP tree的可见性判断。这个类并不是BSP tree的node,BSP tree中的...

weixin_34363171的博客 185

离散数学 --- 图论基础 --- 图的同构,通路与回路,可达性与最短通路

同一个图(这里的图是抽象的数学定义)可以有不同的图形表示方法1.重数:两点之间的平行边的个数1.得到 n!的过程,一个图中的一个结点在另一个图中对应的结点有n种可能(黄框中定义的图来讨论),这个对应好后下一个结点有 n - 1 种可能,再下一个有n-2种,直到最后一个为1,所有可能的结果就等于 n * (n - 1) *(n - 2)*....*1 = n!2.虽然说找对应结点很困难,但不是没有规律可循的。比如1.两个相互对应的结点的度数要相同;

qq_51947882的博客 7441

解决LangChain4j报错HTTP/1.1 header parser received no bytes

当使用调用自己部署的大模型服务时报错: 报错信息如下:

weixin_44455388的博客 2336

Ogre BspSceneManager

1. 概览】       Ogre支持Quake3的bsp格式。相关的代码在“Plugin_BSPSceneManager”工程中。主要的类有以下几个: Class BspSceneNode:       BspSceneNode是SceneNode的派生类,是专门提供给BSPSceneManager使用的。主要是提供针对于BSP tree的可见性判断。这个类并不是BSP tree的n

痞子龙3D编程 1517

AI Agent评估:指标、策略与最佳实践

AI智能体正逐渐融入到各个领域,从日常的对话助手到复杂的工作流程自动化,其应用范围不断拓展。然而,确保这些智能体能够可靠、高效地完成任务至关重要,这就使得AI智能体评估成为了人工智能发展过程中不可或缺的一环。本文将深入探讨AI智能体评估的指标、策略以及最佳实践,为读者全面解读这一关键领域。

llm_way的博客 3498

Ogre经验概述

Ogre插件 OgreMain.dll——提供了所有程序运行需要用到的类的参考,是一个包含了所有基本类型的运行程序必不可少的动态链接库,其需要在exe的当前目录下出现,通过其指定的引擎组件才可以成功的运行程序(其指定的组件可以通过.cfg文件指定,也可以通过包含目录或者放置到当前目录指定) OgrePlatform.dll——此库指定了不同平台使用ogre所需要用到的工具,是通过Ogr

poem_of_sunshine的专栏 1135

区块链入门:用账本、乐高和三台旧电脑讲懂分布式账本

区块链是一种去中心化的分布式账本技术,其核心原理是通过密码学哈希、共识机制和链式结构实现数据不可篡改与多方共同验证。它不依赖单一中心,而是将交易记录同步复制到多个节点,依靠数学规则而非人工信任达成一致,从而在数字世界构建可验证的信用基础设施。这种‘集体见证’模式显著提升了系统抗单点故障与人为干预的能力,广泛应用于供应链溯源、数字身份、教育管理及公益透明等需强信任保障的场景。本文以账本类比、乐高拆解和Ganache实操为线索,面向零基础读者通俗解析哈希值、挖矿与智能合约等关键概念。

weixin_30517215的博客 275

如何用libwebsocket库在stm32F407上实现websocket客户端?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1134

ogre 学习笔记 - Day 15

ogre 学习笔记 - Day 15

weixin_43859510的博客 195

《一》:LBE,VR 大空间系列——场景环境需求解析

当前,大量 VR 体验活动在室内场地开展。因此,对于场地照明有特定要求:除天花板外,场地的所有表面均需有照明覆盖。这是为了保证玩家无论处于场地的哪个位置,地面与墙面都不会出现明显的影子。场地内不建议安装射灯或高强度的点光源,若已安装此类灯具,需使用柔光板进行遮盖。此外,要避免在阳光下使用 VR 设备台。参考图(请忽略其中Maker标签)

unitygroup的博客 944

Ogre::SceneManager 详细之创建

struct SceneManagerMetaData { /// A globally unique string identifying the scene manager type String typeName; /// A text description of the scene manager String description; /// A mask describing which sorts of scenes th

whbzealot的专栏 1358

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

OGRE场景管理

1、SceneGraph(场景图) 的概念 SceneGraph一般以树型结构组织,反映了场景中对象的逻辑关系,这里一定要把用于空间分割的二叉树、八叉树算法区别开来,场景图只是逻辑关系而已。以下是组织高效的场景图的一些准则: 1)不要用场景图来进行可见性检测。 2)不要用场景图来进行碰撞查询。 3)不要以空间关系建立场景图,应该以逻辑关系建立。 2 、O...

weixin_30432179的博客 204

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

ogre html5,OGRE场景管理

http://www.cnblogs.com/cxrs/archive/2012/06/13/2547401.html1、SceneGraph(场景图) 的概念SceneGraph一般以树型结构组织,反映了场景中对象的逻辑关系,这里一定要把用于空间分割的二叉树、八叉树算法区别开来,场景图只是逻辑关系而已。以下是组织高效的场景图的一些准则:1)不要用场景图来进行可见性检测。2)不要用场景图来进行碰...

weixin_42438750的博客 226

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

ogre 学习笔记 - Day 14

ogre 学习笔记 Day - 14

weixin_43859510的博客 215

OGRE学习笔记之_配置文件Plugins.cfg

OGRE学习笔记之 配置文件Plugins.cfg     Plugins.cfg  Ogre的许多功能是以插件的形式提供的.Ogre提供的以Plugin_开头的许多.DLL文件都是所谓的插件。 Plugins.cfg指定了插件的路径和插件文件名, 它们可以放在其它文件夹里,但必须在本文件里指定路径。 在 windows 平台插件的装入过程如下:  Root::()  {     

buku2010的专栏 1296

ogre 场景管理器 scenemanager

声明:本篇转自 痞子龙3D编程 优快云博客,仅留作学习交流之用 ^_^ 原文参照: http://blog.youkuaiyun.com/pizi0475/archive/2010/04/05/5451319.aspx OGRE除了我们已经见过的普通场景以外还支持大型复杂的场景,如:宽阔的野外地形和复杂的大楼和迷宫。3D引擎支持大型复杂场景的主要难度在于对场景的组织和裁减。一个大型场景的三角型数

深入思考 2955

Ogre基本信息回顾

Ogre插件 OgreMain.dll——提供了所有程序运行需要用到的类的参考,是一个包含了所有基本类型的运行程序必不可少的动态链接库,其需要在exe的当前目录下出现,通过其指定的引擎组件才可以成功的运行程序(其指定的组件可以通过.cfg文件指定,也可以通过包含目录或者放置到当前目录指定) OgrePlatform.dll——此库指定了不同平台使用ogre所需要用到的工具,是通过Ogre中的Pla

胖大星的博客 259

OGRE框架杂谈(二)

杂谈第一篇,大概介绍了一下简单的OGRE使用规则。我自己觉得已经非常清楚,昨日被某老友(资深程序员)一句话说得惭愧不已,“你都研究这么久3D知识当然觉得清楚啦!我程序功夫底子也不错,但是只钻研网络数据库方面,你这篇文章基本上对我而言什么用都没有啊!!”     为了弥补这个天大的错误。我决定从最基础的说起。OGRE这个项目,提供了非常多的例子。为了大家能够更快的用起来,我决定介绍3大基础构架:S

debugconsole的专栏 971

ogre3D学习基础15 -- 创建BSP Scene Manager

  BSP(binary-space partitioning) Scene Manager(二叉空间分割)场景管理器比较适合用于室内场景。 第一,添加框架代码如下 1 #include "ExampleApplication.h" 2 class Example1 : public ExampleApplication 3 { 4 public: 5 void...

weixin_30545285的博客 173

ogre的初始化与启动以及显示对象设置

ogre的使用方法1---自动设置 1、ogre初始化: 首先实例化一个Root对象 Root * root = new Root(); Root * root = new Root("plugins.cfg"); Root * root = new Root("plugins.cfg", "ogre.cfg"); Root * root = new Root("plugi

linuxheik的专栏 605

[转载]场景管理器 -----OGRE 3D 1.7 Beginner‘s Guide中文版 第六章

代友转载,原译者:whistleofmysong@gmail.com博客www.singmelody.com   Ogre提供了很多很多的功能。在这章,我们将会接触一些我们之前没有用过的技术,但是有一些在创建复杂的3D场景中很有帮助,比如SceneManagers,创建我们自己的模型,加速我们的程序和有效率的处理大量的3D数据。   在这章,我们将会: ※学习如何改变...

375
上一篇: 3D引擎的基本内容
下一篇: Ineffective C++(1):STL容器不仅仅可以保存指针
yanonsoftware
博客等级 码龄21年 104粉丝 67原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值