转自:http://www.xuebuyuan.com/1482609.html

一.世界地图

将整个世界切分成多个Tile,每个Tile大小相同,用二维坐标形式索引起来,如图:

中心点(0,0)位置的Tile为世界地图的中心点,例如坐标可以定位为(0,0,0),由于Tile大小相等,世界坐标与Tile就可以进行转换,可以根据玩家所在的坐标快速的定位Tile。例如,当tile长度为12000时,玩家坐标为(13000,13000) 那么可以知道玩家在索引为(1,1)的Tile上。

二.Tile实现

从顶点组织和材质两个主要方面做说明

顶点组织

Tile可以设置用多少个顶点来表达真实世界的多大单位,如用513*513个顶点来渲染出游戏世界的12000*12000面积的地表。

由于要支持LOD,既根据相机到地表的距离,提交渲染的三角形要相应的减少。我们采用顶点数目不变,通过提交不同的索引来达到减少三角形的目的。

现在的问题是,如果规划这些索引来满足这个需求。用四叉树进行分割是比较好的方式。

由于是基于Ogre实现,就可以把顶点交由Rendable对象管理,这样材质的处理和到相机的距离判断都很方便。四叉树从根节点开始每一个节点都是一个Readable对象。树的根结点用最粗糙的索引,越向下越精细。这样当玩家站在这个大Tile上时,通过相机去查看有哪些节点可以被玩家看到,然后再根据距离和节点的高度(delta值)计算lod来决定是当前节点被渲染还是它的子节点应该被渲染。被渲染的节点被加入到渲染队列,渲染时回调Rendable对象的getRenderOption函数来要求提供顶点和索引,这时节点可以在这里提供自己的索引和顶点。

注意顶点的组织有一些特殊。以下以2049*2049个顶点来表示一块Tile为例做说明

LOD 0: 2049 vertices, 32 x 65 vertex tiles (tree depth 5)vdata 0-15 [129x16]

LOD 1: 1025 vertices, 32 x 33 vertex tiles (tree depth 5)vdata 0-15 [129x16]

LOD 2: 513 vertices, 16 x 33 vertex tiles (tree depth 4)vdata 0-15 [129x16]

LOD 3: 257 vertices, 8 x 33 vertex tiles (tree depth 3)vdata 16-17 [129x2]

LOD 4: 129 vertices, 4 x 33 vertex tiles (tree depth 2)vdata 16-17 [129x2]

LOD 5: 65 vertices, 2 x 33 vertex tiles (tree depth 1)vdata 16-17 [129x2]

LOD 6: 33 vertices, 1 x 33 vertex tiles (tree depth 0) vdata 18 [33]

LOD 0 为最清晰的级别定点数最多,根结点(tree depth 0)为做粗糙的级别,顶点数最少

树的级别还有LOD的计算公式见Terrain::determineLodLevels()函数。

LOD0 行的信息表明这个LOD级别有2049*2049个顶点,节点数有32*32个,每个节点有65*65个顶点。

LOD1行的信息表明这个LOD级别是与LOD0位于同一个树深度上,只不过是以不同的索引来确定顶点数

LOD2行的信息表明这个LOD级别位于深度为4的树节点上,节点数为16*16,每个节点的顶点数为33*33

以上3个LOD级别可以共用一套顶点,位于深度为4的树节点上,每个节点上顶点数为129*129

LOD3行的信息表明这个LOD级别位于深度为3的树节点上,节点数为8*8,每个节点上的顶点数为33*33

LOD4行的信息表明这个LOD级别位于深度为2的树节点上,节点数为4*4,每个节点上的顶点数为33*33

LOD5行的信息表明这个LOD级别位于深度为1的树节点上,节点数为2*2,每个节点上的顶点数为33*33

以上三个LOD级别共用一套顶点,挂在树的深度为1的节点上

LOD6行的信息表明这个LOD级别位于树的根结点上,节点数为1,节点上顶点数为33*33

解读一下以上绿色部分让人疑惑的内容

l 为什么出现的各种数据都是2N+1?

很简单,因为整个地表都是根据四叉树分割的规则的格子,例如5*5个顶点才可以表示4*4个格子

l 为什么实际节点块的大小是129?

因为索引数据是用的16位整数,最大寻址能到129*129,下一个257*257超出了范围

l 为什么叶子节点有2个LOD级别?

计算公式(Math::Log2(mMaxBatchSize- 1.0f) -Math::Log2(mMinBatchSize
- 1.0f) + 1.0f); 上例中的最大批次为65,最小批次为33。所以计算出叶子节点上的lod级别为2,最大级别65是最精细的lod,33是次级,这样做是为了配合地表高度(delta)和相机距离来计算出更多样的lod层级。

l 怎么知道哪些LOD层级/树深度可以共用一套顶点?

顶点块都是129*129的,如上例所示16*16那一深度的129*129个顶点可够它自己和下一个深度的32*32的节点使用。2*2那一个树深度的129*129个顶点可供4*4和8*8的节点使用。具体的计算公式见Terrain::distributeVertexData()

l 为什么总的顶点数要多于2049*2049?

2049^2 = 4198401 vertices

最后使用的顶点数:(16 * 129)^2 + (2 * 129)^2 + 33^2 = 4327749 vertices

因为不是简单的平面切分顶点,而是用四叉树做分割,根据总的顶点数和最大批次最小批次等参数来决定数的深度以及顶点如何共用,所以要有2049只是作为一个基数来参考,最后用的129*129的块数才决定最终的顶点数。

具体的计算方法见Terrain::distributeVertexData()

http://blog.csdn.net/xuantao/article/details/7304073

http://blog.csdn.net/pizi0475/article/details/6321094

http://blog.csdn.net/swq0553/article/details/5888954

[Ogre][地形]OgreTerrain的实现原理分析的更多相关文章

  1. [Ogre][地形]OgreTerrain分析以及使用

    Ogre 1.7.2中的地形教程 ○读者可以对照着Ogre1.7.2中的terrain.h源码进行阅读加深理解,蓝色部分均为源码 ○去除了一些具体场景比如添加mesh,设置setAmbientLigh ...

  2. Handler系列之原理分析

    上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...

  3. Java NIO使用及原理分析(1-4)(转)

    转载的原文章也找不到!从以下博客中找到http://blog.csdn.net/wuxianglong/article/details/6604817 转载自:李会军•宁静致远 最近由于工作关系要做一 ...

  4. 原子类java.util.concurrent.atomic.*原理分析

    原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...

  5. Android中Input型输入设备驱动原理分析(一)

    转自:http://blog.csdn.net/eilianlau/article/details/6969361 话说Android中Event输入设备驱动原理分析还不如说Linux输入子系统呢,反 ...

  6. 转载:AbstractQueuedSynchronizer的介绍和原理分析

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  7. Camel运行原理分析

    Camel运行原理分析 以一个简单的例子说明一下camel的运行原理,例子本身很简单,目的就是将一个目录下的文件搬运到另一个文件夹,处理器只是将文件(限于文本文件)的内容打印到控制台,首先代码如下: ...

  8. NOR Flash擦写和原理分析

    NOR Flash擦写和原理分析 1. NOR FLASH 的简单介绍 NOR FLASH 是很常见的一种存储芯片,数据掉电不会丢失.NOR FLASH支持Execute On Chip,即程序可以直 ...

  9. 使用AsyncTask异步更新UI界面及原理分析

    概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的内部实现是一个线程池,所有提交的异步任务都会在这个线程池中的工作线 ...

随机推荐

  1. ios-chart 不支持渐变的底色 --- 后面支持了渐变

    https://github.com/danielgindi/ios-charts/issues/186 后话,最近库更新了,可以支持渐变色

  2. IOS Suppot Font 苹果默认支持的字体一览(配图)

    这些字体都是IOS设备(使用ipad2测试) 默认支持的字体,也就是在AIR中不用设置绑定字体情况下 看到的样子 感觉上应该IOS仅为中文设置了一种字体就是 Heiti SC

  3. java 获取当前系统系时间

    //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式 SimpleDateFo ...

  4. 转:Java环境变量配置

    工具/原料 windows系统 jak安装包 方法/步骤   安装jdk,这个没有的百度就能搜到,不再赘述 首先,右键计算机---属性---高级系统设置---环境变量   建议是都设置系统变量,一般P ...

  5. [转]JqueryEasyUI教程入门篇

    什么是jQueryEasyUI? JqueryUI是一组基于jQuery的UI插件集合 学习jQueryEasyUI的条件? 必须掌握Jquery的基本语法知识 jQueryEasyUI的特点? 1. ...

  6. linux下MYSQL备份与恢复

    1.用命令实现备份 数据库备份是很重要的.如果定期做好备份,这样就可以在发生系统崩溃时恢复数据到最后一次正常的状态,把损失减小到最少.MySQLl提供了一个mysqldump命令,我们可以用它进行数据 ...

  7. 经过本人 6 年.net 工作经验证明 .net 工资确实比 Java 低

    很久没有逛博客园了,很久没有出来吐槽了.怎么呢?生活压力大,就需要找地方吐槽. 排版不怎么好,文笔不怎么好,可以看出我不是雇佣的写手. 工作到今夏,已经有6个年头了,一直使用着.net技术,但是最近工 ...

  8. 如何使用highmaps制作中国地图

    如何使用highmaps制作中国地图 文章目录 Highmaps 所需文件 地图初始化代码 highmaps 渲染讲解 highmaps 中国各城市坐标的json文件 highmaps 线上DEMO ...

  9. ThinkPHP讲解(六)——添加数据

    添加数据到数据库有三种方式 第一种:使用数组添加 $model=D("Info"); //实例化对象 //添加数据的第一种方式:使用数组添加 //要添加的数组,必须是关联数组,ke ...

  10. zw版【转发·台湾nvp系列Delphi例程】HALCON SetLineStyle2

    zw版[转发·台湾nvp系列Delphi例程]HALCON SetLineStyle2 procedure TForm1.Button1Click(Sender: TObject);var img : ...