魔兽世界客户端数据研究(一)
终于决定,还是通过wow model viewer起手,研究一下WOW的数据类型,从另一个角度,体验一把这个唯一让我充过值的游戏。
这将是一系列随笔,即在读代码的时候,顺便记录,以理清思路和加深映象。 其中会有很多让人费解的地方,如果有幸被某位兄弟看见,请勿见笑。
我们从读取模型数据开始。。。
下面是这是顶点结构体 这是wow model viewer中的定义
struct ModelVertex
{
Vec3D pos; //顶点位置
uint8 weights[4];//骨骼权重
uint8 bones[4];//受影响的骨骼索引
Vec3D normal;//法线
Vec2D texcoords;//纹理坐标,只有一层
int unk1, unk2; // 总是0,0 可能没有被使用到
};
读完顶点数据后,我们需要对坐标系做一点修正,因为WOW用的是Z轴向上, Y轴向里(依稀记得torque也是这样子)
很多人用得不是太习惯
若要转换为GL中的坐标(Z向外),则 pos = vec3D(pos.x,pos.z,-pos.y);
若要转换为D3D中的坐标(Z向里),则pos = vec3D(pos.x,pos.z,pos.y);
法线转换方式和坐标一样
转换为了我们想要的坐标数据以后。我们还要强制对法线进行单位化。在这里,为了对法线进行压缩,其实我们可以仅存储X,Y分量就可以了。
不知WOW为什么没有这样子。
同时,在进行模型顶点数据读取的时候,由于我们本来就要进行顶点数据遍历,所以我们可以顺便得出这个模型的半径,用来做球形检测
模型数据读完了,紧接着是BoundingMesh(想说是包围网格,又不太对,又或者,叫碰撞网格,这是一个简化的网格,用于碰撞检测和拾取之类的)数据
它由两个部分组成BoundingVertices & BoundingTriangles (我又词穷了,都懂的。)
BoundingVertices由一串float3组成,顺序读取即可,读取完了后,如果上面的MESH做了坐标系统转换,那这里也得做。
BoundingTriangles由一串uint16索引组成,顺序读取即可。
读取完上面的模型数据后,接下来就是纹理数据。
在WMV中的定义如下
#define TEXTURE_MAX 32 //最大纹理数
struct ModelTextureDef
{
uint32 type; //纹理类型
uint32 flags; //纹理标记
uint32 nameLen; //名字长度
uint32 nameOfs; //名字在DBC中的偏移
};
搞笑得很啊,在结构体定义的时候,没有对上面字段说明,在使用的地方,却有一段描述。不过想想也是,用的时候方便查看嘛。
/*
Texture Types
Texture type is 0 for regular textures, nonzero for skinned textures (filename not referenced in the M2 file!)
For instance, in the NightElfFemale model, her eye glow is a type 0 texture and has a file name,
the other 3 textures have types of 1, 2 and 6. The texture filenames for these come from client database files:
DBFilesClient\CharSections.dbc
DBFilesClient\CreatureDisplayInfo.dbc
DBFilesClient\ItemDisplayInfo.dbc
(possibly more)
0 Texture given in filename
1 Body + clothes 身体和布料
2 Cape 肩膀
6 Hair, beard 头发,胡子
8 Tauren fur 牛头人的皮毛
11 Skin for creatures #1
12 Skin for creatures #2
13 Skin for creatures #3
Texture Flags
Value Meaning
1 Texture wrap X X方向环绕
2 Texture wrap Y Y方向环绕
*/
下面是我对这段说明的理解
0 表示是普通纹理 并且,可以直接获取它的纹理名字
非0表示是皮肤 值得说明的是,纹理名字不包含在M2文件中。
比如说,在暗夜男模型中,他的眼睛发光就是一个类型为0的纹理,并且,有一个文件名(这个文件名就存在本文件中)。其它3个纹理类型是1,2和6. 纹理名字是从客户端数据库文件中提取。nameOfs就是表示其位置
额,写到这里的时候,突然发现,其实是有宏定义的
/*
Texture Types
Texture type is 0 for regular textures, nonzero for skinned textures (filename not referenced in the M2 file!) For instance, in the NightElfFemale model, her eye glow is a type 0 texture and has a file name, the other 3 textures have types of 1, 2 and 6. The texture filenames for these come from client database files:
DBFilesClient\CharSections.dbc
DBFilesClient\CreatureDisplayInfo.dbc
DBFilesClient\ItemDisplayInfo.dbc
(possibly more)
*/
enum TextureTypes
{
TEXTURE_FILENAME=0, // Texture given in filename
TEXTURE_BODY, // Body + clothes
TEXTURE_CAPE, // Item, Capes ("Item\ObjectComponents\Cape\*.blp")
TEXTURE_ITEM=TEXTURE_CAPE,
TEXTURE_ARMORREFLECT, //
TEXTURE_HAIR=6, // Hair, bear
TEXTURE_FUR=8, // Tauren fur
TEXTURE_INVENTORY_ART1, // Used on inventory art M2s (1): inventoryartgeometry.m2 and inventoryartgeometryold.m2
TEXTURE_QUILL, // Only used in quillboarpinata.m2. I can't even find something referencing that file. Oo Is it used?
TEXTURE_GAMEOBJECT1, // Skin for creatures or gameobjects #1
TEXTURE_GAMEOBJECT2, // Skin for creatures or gameobjects #2
TEXTURE_GAMEOBJECT3, // Skin for creatures or gameobjects #3
TEXTURE_INVENTORY_ART2, // Used on inventory art M2s (2): ui-buffon.m2 and forcedbackpackitem.m2 (LUA::Model:ReplaceIconTexture("texture"))
TEXTURE_15, // Patch 12857, Unknown
TEXTURE_16, //
TEXTURE_17, //
};
enum TextureFlags
{
TEXTURE_WRAPX=1,
TEXTURE_WRAPY
};
总之,就是如果遇上是0号类型,则直接读文件名,否则就去DBC中取公共纹理数据。
比如头发什么的,而上面牛头人的毛发单独定义,可能是因为毛发和一般人型生物不一样吧。
另外,从TEXTURE_ARMORREFLECT中可以看出,WOW中的武器和盔甲是加上了反射纹理的,这样才看起来有高光的感觉。
------------------------------------------------------------------------
------------------------------------------------------------------------
读完模型,碰撞网格,纹理数据,接下来,就要读取挂接物了,最常见的挂接物,就是WOW中的肩膀,头盔或者武器上的一些粒子效果。
WMV中,挂接物的定义如下
/*
* This block specifies a bunch of locations on the body - hands, shoulders, head, back,
* knees etc. It is used to put items on a character. This seems very likely as this block
* also contains positions for sheathed weapons, a shield, etc.
*/
struct ModelAttachmentDef
{
uint32 id; // Just an id. Is referenced in the enum POSITION_SLOTS.
uint32 bone; // Somewhere it has to be attached.
Vec3D pos; // Relative to that bone of course.
AnimationBlock unk; // (Int32) Its an integer in the data. It has been 1 on all models I saw. Whatever.
};
无非就是定义了挂接的骨骼索引,偏移位置等。 最后一个参数,是动画块数据。定义如下
// sub-block in block E - animation data, size 28 bytes, WotLK 20 bytes
struct AnimationBlock
{
int16 type; // 插值类型 (0=none, 1=linear, 2=hermite)
int16 seq; // 全局队列ID,-1表示无
//下面的就是数据个数+数据在缓冲区中的偏移
#ifndef WotLK
uint32 nRanges;
uint32 ofsRanges;
#endif
uint32 nTimes; //
uint32 ofsTimes;
uint32 nKeys;
uint32 ofsKeys;
};
上面的定义可以看中,WLK版本中,BLZ对文件进行了改动,加入了一个范围数据。
读取完上面的挂接头信息以后,就可以根据这个信息,实例化一个挂接物,添加到模型身上。
下面是一个模型挂接物的信息
struct ModelAttachment
{
int id; //ID
Vec3D pos; 位置
int bone; //撞接的骨骼
Model *model; //挂接的模型
void init(MPQFile &f, ModelAttachmentDef &mad, uint32 *global);
void setup();
void setupParticle();
};
读完上面的信息后,我发现,还有一个诡异的attLookup数据, 单看字面上意思,应该是拿来装一个供挂接物ID查询的数据的。
就是ModelAttachment中的ID作为下标,进行查询。 目前还没有搞明白。
本来想继续写下去,但发现寸步难行了,后面的数据都没看明白是什么意思,只好留到下次了。
睡觉了,晚安!!!!!
作者:码瘾少年·麒麟子
出处:http://www.cnblogs.com/geniusalex/
蛮牛专栏:麒麟子
简介:09年入行,喜欢游戏和编程,对3D游戏和引擎尤其感兴趣。
版权声明:本文版权归作者和博客园共有,欢迎转载。转载必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
转载:http://www.cnblogs.com/geniusalex/archive/2013/04/20/3031866.html
魔兽世界客户端数据研究(一)相关推荐
- 魔兽世界客户端数据研究(三)
终于决定,还是通过wow model viewer起手,研究一下WOW的数据类型,从另一个角度,体验一把这个唯一让我充过值的游戏. 这将是一系列随笔,即在读代码的时候,顺便记录,以理清思路和加深映象. ...
- 魔兽世界客户端数据研究(四):M2文件头分析
终于决定,还是通过wow model viewer起手,研究一下WOW的数据类型,从另一个角度,体验一把这个唯一让我充过值的游戏. 这将是一系列随笔,即在读代码的时候,顺便记录,以理清思路和加深映象. ...
- 魔兽世界客户端数据研究(二)
终于决定,还是通过wow model viewer起手,研究一下WOW的数据类型,从另一个角度,体验一把这 个唯一让我充过值的游戏. 这将是一系列随笔,即在读代码的时候,顺便记录,以理清思路和加深映象 ...
- 深证信息等三方拟联合开展大数据研究
昨日,深圳证券信息有限公司(下称"深证信息").泛欧交易所.北京新浪互联信息服务有限公司(下称"新浪网")联合签署了合作备忘录,三方将基于各自优势在互联网大数据 ...
- 清华中德大数据研究学生交换项目成果报告会成功举办
由数据科学研究院资助,启动于2017年3月的"清华大学与德国哥廷根大学交换留学生"项目阶段成果报告会2019年4月6日于清华大学熊知行楼举办. 数据科学研究院执行副院长韩亦舜以&q ...
- 面部识别数据研究:43年,100个数据集
点上方蓝字计算机视觉联盟获取更多干货 在右上方 ··· 设为星标 ★,与你不见不散 仅作学术分享,不代表本公众号立场,侵权联系删除 转载于:新智元 AI博士笔记系列推荐 周志华<机器学习> ...
- 实现服务器和客户端数据交互,Java Socket有妙招
摘要:在Java SDK中,对于Socket原生提供了支持,它分为ServerSocket和Socket. 本文分享自华为云社区<Java Socket 如何实现服务器和客户端数据交互>, ...
- C++socket编程(三):3.7 服务端回应send客户端数据
为什么提到反馈send客户端数据,是因为本章博客,目前为止都是单线程的.我们一个服务端只能接收第一个连接进行的客户端发送的数据,在这个客户端断开连接之前,我们的服务端都无法接收其他客户端发过来的数据了 ...
- es客户端工具_超越 Cookie:当今的客户端数据存储
作者:Adam Giese 翻译:疯狂的技术宅 原文:https://blog.logrocket.com/beyond-cookies-todays-options-for-client-side- ...
最新文章
- mybatis 批量查询参数语句
- OS / Linux / SIGKILL 和 SIGTERM、SIGINT
- 完善vim bccalc_linux插件
- 需求工程阅读笔记03
- firewall-cmd
- 【转】面试题:将多个集合合并成没有交集的集合
- 在列表,字典,集合中根据条件来筛选数据
- spark 字符串操作
- boost python错误_Ubuntu-链接boost.python-致命错误:找不到pyconfig
- 学习python的字符串组合
- ubuntu查看cpu温度
- 最小采样频率计算公式_音频文件大小计算公式-好文转载
- 微信内置浏览器清除缓存
- Lample-Ziv文本压缩(java实现)--学习笔记
- 记一次PDFRenderer使用renderImage方法报错java.lang.IndexOutOfBoundsException解决方法
- windows/ps使用技巧
- C语言利用ASCII码表统计字符串每个字符出现的次数
- 中国五大国家级城市群经济图谱
- 计算机程序设计艺术读后感,计算机程序设计艺术(第1卷)读后感1000字
- 驾考记录之科目三(2021-06-16)(上海旗忠考场)