您的位置:首页 > 其它

菜鸟学习OGRE和天龙八部之三: GridInfo和HeightMap文件的数据格式(已更正)

2009-09-23 19:19 316 查看
用其他大侠资源提取工具,可以提取到场景数据,有些数据格式是XML文件,很容易看懂,而有些就不能直接打开,要自己提取数据了,比如GridInfo和HeightMap文件,一个是网格文件,一个是高度图文件,十分重要,我准备先研究这2个家伙.



先说网格文件:

找到网上大侠的一些研究资料:

http://www.mobilegamebase.com/blog/article.asp?id=17

不过,此文中有点笔误的地方,就是那个nFirstLayerOP的位标记的描述有点错误,正确的应该如下:

// 图片水平翻转,即左右翻转
#define FLIP_HORIZINTAL 1
// 图片垂直翻转,即上下翻转
#define FLIP_VERTICAL 2
// 逆时针旋转90度
#define ANTICLOCKWISE_90 4
// 以三角形的对角线镜像,IndexOrder==0时就把左上的纹理坐标复制到右下,否则把右上的坐标复制到左下
#define FLIP_DIAGONAL 8



好,那我自己来实验了一下:

先用UE打开 GridInfo文件:





网格就是正方形,4个顶点.

UE的16进制表示法是2个16进制数表示一个字节 正好255个,比如00就是一个字节,

前16个字节是文件头信息, 0x00100002是版本号,表示我这个是5字节版本的数据,我的客户端是比较老的,数据都没加密.

话说看几字节版本靠版本号不靠谱,有错误的,最好就是自己除一下就知道每个网格的字节数,

我的5字节版本,但是前面也有bool值,就是第2排的那个00,这个值要跳过,

看上面的UE图,78 00 9E 00 00就是第一个网格的数据 85 00 00 00 00就是第二个的数据

0x000000C0就是192,就是网格的行和列,一共192X192,

第二行就是实际数据了,5字节版本的数据结构为:

// 单个网格信息
struct GridInfo
{
// 该值即为pixelmap的索引(第几个pixelmap)
BYTE nFirstLayer;
// 对nFirstLayer的操作,取值是上面几个定义的宏,可以互相组合
BYTE nFirstLayerOp;
// 该值为pixelmap的索引
//天龙八部的地表最多可以两层融合,说白了就是每个点里有两层UV,这里为第二层pixelmap的索引
BYTE nSecondLayer;
// 对nSecondLayer的操作,取值同nFirstLayerOp
BYTE nSecondLayerOp;
// 对格子的三角形的操作,可能取值如下
// 0正常三角形索引
// 1不同于正常的三角形索引
BYTE IndexOrder;
};



网格没什么好说的,网上大侠都研究好了,



接下来就是HeightMap,

再次用心爱的UE,打开文件看看:







前16个字节还是文件头信息0x000000C1表示193,是高度图像素顶点的行和列,网格192,那么顶点数就是193啦,多一个

那个一个像素点用几个字节表示的呢,很好算,193*193 就是所有的顶点数,再用这里文件里面的字节数去除一下,就知道了,这里文件的有效字节数是多少?你看UE最左边不是有地址么...我已经算好了,每个高度图的像素顶点占4个字节!!!不是一个哦

为什么不是占1个字节,而是4个,那么只有一种可能性,就是浮点数float表示的,正好占4个字节,



其实即使从图片载入的数据时0到255,也要转换成浮点数或者整数,因为缩放的问题,假如我们要把高度拉很高很高,0到255显然不够精细,

用浮点是一个好办法,而TSM场景管理器的世界场景缩放函数也是转换成float:

void HeightmapTerrainPageSource::requestPage(ushort x, ushort y)



那个高度图的数据格式就显示出来了



比如第一个顶点的数据:0x41A00000

把16进制浮点转化成10进制就OK了哇,怎么转换?我简单写一下:



S 代表符号位,1是负,0是正
E 偏移127的幂,二进制阶码=(EEEEEEEE)-127。
M 24位的尾数保存在23位中,只存储23位,最高位固定为1。



格式 SEEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM
二进制 01000001 10100000 00000000 00000000
十六进制 41 A0 00 00
从这个例子可以得到下面的信息:
符号位是0表示一个正数
幂是二进制10000011或十进制131,131减去127是4,就是实际的幂。
尾数是后面的二进制数01000000000000000000000
在尾数的左边有一个省略的小数点和1,这个1在浮点数的保存中经常省略,加上一个1和小数
点到尾数的开头,得到尾数值如下:
1.01000000000000000000000
接着,根据指数调整尾数.一个负的指数向左移动小数点.一个正的指数向右移动小数点.因为
指数是4,尾数调整如下:
10100.0000000000000000000
结果是一个二进制浮点数,小数点左边的二进制数代表所处位置的2的幂,

例如:10100表示 16+0+4+0+0 = 20
小数点的右边也代表所处位置的2的幂,只是幂是负的。

例如:此例是0
这些值的和是20。因为设置的符号位表示这数是正的,

因此十六进制值0x41A00000表示20



看这个复杂,其实根本不用自己转换,

读取的时候其实写个(float)就OK了哇,看我读的数据

:





这个值得范围是在-7到20.5之间, 假如高度是20,图片192x192 那么xyz就是 192 ,20,192 这个比例就是真实比例,

缩放的话, 都乘以100
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐