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 树的伪代码:

  1. struct BSP_tree
  2. {
  3. plane     partition;
  4. list      polygons;
  5. BSP_tree  *front, *back;
  6. };
  7. 这个结构体定义在下面的讨论中将被一直使用。它[来源:GameRes.com]表示BSP树的一个接点,包含有一个分割平面,处于分割平面的多边形列表,以及指向子接点的指针。
  8. void Buld_BSP_Tree( BSP_tree *tree, list polygons )
  9. {
  10. polygon *root = polygons.Get_From_List();
  11. tree->partition = root->Get_Plane();
  12. tree->polygons.Add_To_List( root );
  13. list front_list, back_list;
  14. polygon  *poly;
  15. while( ( poly = polygons.Get_From_List() ) != 0 )
  16. {
  17. int result = tree->partition.Classify_polygon(poly);
  18. switch( result )
  19. {
  20. case COINCIDENT: // 共面
  21. tree->polygons.Add_To_List(poly);
  22. break;
  23. case IN_BACK_OF:
  24. back_list.Add_To_List(poly);
  25. break;
  26. case IN_FRONT_OF
  27. front_list.Add_To_List(poly);
  28. break;
  29. case SPANNING:
  30. polygon *front_piece, *back_piece;
  31. split_Polygon( poly, tree->partition, front_piece, back_piece );
  32. back_list.Add_To_List( back_piece );
  33. front_list.Add_To_List( front_piece );
  34. break;
  35. }
  36. }
  37. if( !front_list.Is->Empty_List() )
  38. {
  39. tree->front = new BSP_tree;
  40. Build_BSP_Tree( tree->front, front_list );
  41. }
  42. if( !back_list->Is_Empty_List() )
  43. {
  44. tree->back = new BSP_tree;
  45. Build_BSP_Tree( tree->back, back_list );
  46. }
  47. }
  48. Buld_BSP_Tree函数根据以上说明的步骤递归地建立BSP树。它使用输入的多边形列表中的第一个多边形所在的平面作为分割平面,假定此列表中的每一个多边形都为凸多边形。

复制代码

代码来源于网络

新人补钙系列教程之:3D理论 - 二进制空间分割(BSP)树的更多相关文章

  1. 新人补钙系列教程之:Molehill底层API中最重要的Context3D

    Context3D,是一个三维空间的处理环境,负责创建并处理三维对象的各个要素如顶点.片段.透视等等,并将处理的结果使用AGAL(Adobe图形汇编语言)上传给显卡进行运算,运算结果最终被回传给CPU ...

  2. 新人补钙系列教程之:拒绝CPU高占用

    1.关于MovieClip和Sprite的鼠标事件,当不需要鼠标事件的时候将mouseEnabled和mouseChildren设为false. 不断的检测鼠标交互事件会消耗CPU,尤其是大量交互对象 ...

  3. 新人补钙系列教程之:体验ApplicationDomain 应用程序域

    要说应用程序域,就不得不说安全沙箱 安全沙箱在帮助文档的解释是: 客户端计算机可以从很多来源(如外部 Web 站点或本地文件系统)中获取单个 SWF 文件.当 SWF 文件及其它资源(例如共享对象.位 ...

  4. 新人补钙系列教程之:AS3 与 PHP 简单通信基础

    package { import flash.display.Loader; import flash.events.Event; import flash.net.URLLoader; import ...

  5. 新人补钙系列教程之:AS 与 JS 相互通信

    比较常用的,AS 调用 JS private function callJS():void{ ExternalInterface.addCallback("callbackQQPay&quo ...

  6. 新人补钙系列教程之:AS3 位运算符

    ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数).在 ECMAScript 中,所有整数字面量默认都是有符号整数,这意味着什么呢? 有符号整数使用 3 ...

  7. 新人补钙系列教程之:XML处理方法

    初始化XML对象XML对象可以代表一个XML元素.属性.注释.处理指令或文本元素.在ActionScript 3.0中我们可以直接将XML数据赋值给变量: var myXML:XML = <or ...

  8. 新人补钙系列教程之:AS3事件处理--事件流

    一个flash应用程序可能会非常复杂,比如,有很多可视实例嵌套在一起,这样的话会形成一个树形结构,这个结构的根是stage,然后一级级到不同的实例,一般来说,要把这个树形结构倒过来看,即stage在顶 ...

  9. kali linux 系列教程之metasploit 连接postgresql可能遇见的问题

    kali linux 系列教程之metasploit 连接postgresql可能遇见的问题 文/玄魂   目录 kali linux 下metasploit 连接postgresql可能遇见的问题. ...

随机推荐

  1. 【Luogu】P3760异或和(权值树状数组)

    题目链接 再次声明以后我见到位运算一定第一时间想把它拆成每一位算 本题就是有个前缀和sum[],然后让你求每一位有多少对i,j满足sum[i]-sum[j]在那一位上是1 考虑怎样才能减出1来 如果s ...

  2. 【Luogu】P2154虔诚的墓主人(树状数组)

    题目链接 这题就是考虑我们有这样一个情况

  3. Codeforces Round #357 (Div. 2) A

    A. A Good Contest time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  4. java中截取字符串的方式

    1.length() 字符串的长度 例:char chars[]={'a','b'.'c'}; String s=new String(chars); int len=s.length(); 2.ch ...

  5. for 循环里的i++

    写代码的时间也不短了,今天看快速排序的算法的时候才去更深层次得理解... for (语句 1; 语句 2; 语句 3) {     被执行的代码块 } 语句 1 (代码块)开始前执行 语句 2 定义运 ...

  6. "贪心"的考试

    先来落实比较简单的T3,T4 T3  团结的队伍 team 题目描述 众所周知,长郡信息组是一个团结友爱的优秀团队.为了弘扬团队精神,践行社会主义核心价值观,秉承朴实沉毅的校训,信息组决定外出游玩(. ...

  7. Unicode 和 ANSI

    Project Properties -> General-> Character set,里面显示了是不是unicode. Unicode处理String的方式不一样,一定要注意!!   ...

  8. Centos 6.3nginx安装

    1. 增加源: vi /etc/yum.repos.d/nginx.repo CentOS: [nginx] name=nginx repo baseurl=http://nginx.org/pack ...

  9. 计蒜客 28319.Interesting Integers-类似斐波那契数列-递推思维题 (Benelux Algorithm Programming Contest 2014 Final ACM-ICPC Asia Training League 暑假第一阶段第二场 I)

    I. Interesting Integers 传送门 应该是叫思维题吧,反正敲一下脑壳才知道自己哪里写错了.要敢于暴力. 这个题的题意就是给你一个数,让你逆推出递推的最开始的两个数(假设一开始的两个 ...

  10. (10)java基础知识-字符串

    String s和 new String 的区别 String s1="hello"; String s2= new String("hello"); Stri ...