新人补钙系列教程之:3D理论 - 二进制空间分割(BSP)树
1. 什么是BSP树
BSP算法的初始数据是一个多边形集,BSP在预处理的时候先在多边形集中选取一个多边形作为支持平面,然后根据这个平面将集合划分成两个部分,每个部分是一个新的子节点,递归进行该过程,直到每个子节点中的多边形都构成一个凸区域(最小凸边型),每个区域是一个叶节点,或成为cell,然后算法预计算在每个区域中可以见到哪些区域,得到PVS(潜在可见集)。
<IGNORE_JS_OP style="WORD-WRAP: break-word; WHITE-SPACE: normal; TEXT-TRANSFORM: none; WORD-SPACING: 0px; COLOR: rgb(51,51,51); FONT: 14px/21px Tahoma, Helvetica, SimSun, sans-serif; ORPHANS: 2; WIDOWS: 2; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(255,255,255); TEXT-INDENT: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">
BSP可以说是八叉树的一般化
每个节点都是一条直线.所有在直线左边的东东都在它的左子树上,所有在它右边的东东都在它的右子树上.
<IGNORE_JS_OP style="WORD-WRAP: break-word; WHITE-SPACE: normal; TEXT-TRANSFORM: none; WORD-SPACING: 0px; COLOR: rgb(51,51,51); FONT: 14px/21px Tahoma, Helvetica, SimSun, sans-serif; ORPHANS: 2; WIDOWS: 2; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(255,255,255); TEXT-INDENT: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">
好,我们用BSP树来想象一幅画面.
假设玩家站在D房间里面向屏幕右方,代号为点'x'
<IGNORE_JS_OP style="WORD-WRAP: break-word; WHITE-SPACE: normal; TEXT-TRANSFORM: none; WORD-SPACING: 0px; COLOR: rgb(51,51,51); FONT: 14px/21px Tahoma, Helvetica, SimSun, sans-serif; ORPHANS: 2; WIDOWS: 2; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(255,255,255); TEXT-INDENT: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px">
我们从树的顶端直线 f 开始.我们站在直线 f 的右边,所以我们向树的左子
树进行下去.这是因为我们想最先画最远的多边形.
我们来到了最左的节点.请在笔记本上记下节点上的东东--"a,c"
当我们不能再往下时,回到父节点.现在回到了根节点,我们还不能马上去右子树.
首先,我们看见了 f 面--写在这个节点上的.我们已经在我们列出的表上得到了
处在它后面的所有东东,我们还将看见它前面的东东,但是我们必须先把它记入我
们的表中.注意,f 面有两个表面--f' 和 f".既然我们已经知道我们处在直线 f
的右边,当然就只能看到它的右表面--所以我们在笔记本上记下 f"( 右面 ).现在本子上
写着 a,c,f".
如果我们以这个次序来画这些墙,将得到正确的图象.建议你使用3D-buffer,这样速度要快的多.
下面是搜索 BSP 树的伪代码:
- struct BSP_tree
- {
- plane partition;
- list polygons;
- BSP_tree *front, *back;
- };
- 这个结构体定义在下面的讨论中将被一直使用。它[来源:GameRes.com]表示BSP树的一个接点,包含有一个分割平面,处于分割平面的多边形列表,以及指向子接点的指针。
- void Buld_BSP_Tree( BSP_tree *tree, list polygons )
- {
- polygon *root = polygons.Get_From_List();
- tree->partition = root->Get_Plane();
- tree->polygons.Add_To_List( root );
- list front_list, back_list;
- polygon *poly;
- while( ( poly = polygons.Get_From_List() ) != 0 )
- {
- int result = tree->partition.Classify_polygon(poly);
- switch( result )
- {
- case COINCIDENT: // 共面
- tree->polygons.Add_To_List(poly);
- break;
- case IN_BACK_OF:
- back_list.Add_To_List(poly);
- break;
- case IN_FRONT_OF
- front_list.Add_To_List(poly);
- break;
- case SPANNING:
- polygon *front_piece, *back_piece;
- split_Polygon( poly, tree->partition, front_piece, back_piece );
- back_list.Add_To_List( back_piece );
- front_list.Add_To_List( front_piece );
- break;
- }
- }
- if( !front_list.Is->Empty_List() )
- {
- tree->front = new BSP_tree;
- Build_BSP_Tree( tree->front, front_list );
- }
- if( !back_list->Is_Empty_List() )
- {
- tree->back = new BSP_tree;
- Build_BSP_Tree( tree->back, back_list );
- }
- }
- Buld_BSP_Tree函数根据以上说明的步骤递归地建立BSP树。它使用输入的多边形列表中的第一个多边形所在的平面作为分割平面,假定此列表中的每一个多边形都为凸多边形。
复制代码
代码来源于网络
新人补钙系列教程之:3D理论 - 二进制空间分割(BSP)树的更多相关文章
- 新人补钙系列教程之:Molehill底层API中最重要的Context3D
Context3D,是一个三维空间的处理环境,负责创建并处理三维对象的各个要素如顶点.片段.透视等等,并将处理的结果使用AGAL(Adobe图形汇编语言)上传给显卡进行运算,运算结果最终被回传给CPU ...
- 新人补钙系列教程之:拒绝CPU高占用
1.关于MovieClip和Sprite的鼠标事件,当不需要鼠标事件的时候将mouseEnabled和mouseChildren设为false. 不断的检测鼠标交互事件会消耗CPU,尤其是大量交互对象 ...
- 新人补钙系列教程之:体验ApplicationDomain 应用程序域
要说应用程序域,就不得不说安全沙箱 安全沙箱在帮助文档的解释是: 客户端计算机可以从很多来源(如外部 Web 站点或本地文件系统)中获取单个 SWF 文件.当 SWF 文件及其它资源(例如共享对象.位 ...
- 新人补钙系列教程之:AS3 与 PHP 简单通信基础
package { import flash.display.Loader; import flash.events.Event; import flash.net.URLLoader; import ...
- 新人补钙系列教程之:AS 与 JS 相互通信
比较常用的,AS 调用 JS private function callJS():void{ ExternalInterface.addCallback("callbackQQPay&quo ...
- 新人补钙系列教程之:AS3 位运算符
ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数).在 ECMAScript 中,所有整数字面量默认都是有符号整数,这意味着什么呢? 有符号整数使用 3 ...
- 新人补钙系列教程之:XML处理方法
初始化XML对象XML对象可以代表一个XML元素.属性.注释.处理指令或文本元素.在ActionScript 3.0中我们可以直接将XML数据赋值给变量: var myXML:XML = <or ...
- 新人补钙系列教程之:AS3事件处理--事件流
一个flash应用程序可能会非常复杂,比如,有很多可视实例嵌套在一起,这样的话会形成一个树形结构,这个结构的根是stage,然后一级级到不同的实例,一般来说,要把这个树形结构倒过来看,即stage在顶 ...
- kali linux 系列教程之metasploit 连接postgresql可能遇见的问题
kali linux 系列教程之metasploit 连接postgresql可能遇见的问题 文/玄魂 目录 kali linux 下metasploit 连接postgresql可能遇见的问题. ...
随机推荐
- Linux忘记Mysql原来root的密码
Linux忘记Mysql原来root的密码 1.首先需要有linux操作系统root的权限 2.ps aux | grep mysql (或者 systemctl status mysql) 发现my ...
- linxu安装方式
安装Linux操作系统的5种方法以及心得这几天没有调别的东西,想起自己还不太会在没有安装光盘的时候安装Linux,于是试了一下Linux的五种安装方法,下面是我的一些 篇一:安装Linux操作系统的5 ...
- 一种机制,与js类似
我们知道,当两个条件进行逻辑与操作的时候,其中任何一个条件为假,则表达式的结果为假.所以,遇到(A 且 B)这种表达式,如果A为假的话,B是不是真假都无所谓了,当遇到一个假条件的时候,程序也就没有必要 ...
- 将GDB中的输出定向到文件
1 set args >output.log 三种方法,一种通过tee在启动时重定向: 1 gdb |tee -a file 第二种在run时加入: 1 run <input.txt &g ...
- 小Z爱划水(NOIP信(sang)心(bin)赛)From FallDream
题目: 小Z在机房.他和其它机房同学都面临一个艰难的抉择,那就是 要不要划水? 每个人都有自己的一个意见,有的人想做题,有的人想划水. 当然,每个人只能选择一个事情做.如果一个人做的事情和他想做的不同 ...
- 三、第一个cocos2d程序的代码分析
http://blog.csdn.net/q199109106q/article/details/8591706 在第一讲中已经新建了第一个cocos2d程序,运行效果如下: 在这讲中我们来分析下里面 ...
- Vue全局异常捕获
之前没注意过这么个小技巧 , 可能在Vue文档里也有 暂时先记下了 方便摘要 Vue全局配置 errorHandler可以进行全局错误收集,我们可以根据这个特性对前端异常做这样的处理:业务错误直接写 ...
- 正则表达式之Regex.Replace()用法
正则表达式替换匹配到的字符串 string txt = "AAA12345678AAAA"; //匹配到的连续数字的前4位用*替换 string m =Regex.Replace( ...
- Good Bye 2016 A. New Year and Hurry【贪心/做题目每道题花费时间按步长为5等差增长,求剩余时间够做几道题】
A. New Year and Hurry time limit per test 1 second memory limit per test 256 megabytes input standar ...
- A/B Testing with Practice in Python (Part Two)
This is the second part of A/B testing notes, which contains the practical issues and alternatives o ...