魔兽世界客户端数据研究(二)
终于决定,还是通过wow model viewer起手,研究一下WOW的数据类型,从另一个角度,体验一把这
个唯一让我充过值的游戏。
这将是一系列随笔,即在读代码的时候,顺便记录,以理清思路和加深映象。 其中会有很多让人费
解的地方,如果有幸被某位兄弟看见,请勿见笑。
上次弄到nAttachLookup就不行了,这次继续弄。
最近四川地震了,所以弄得比较慢。
好吧,我们接着nAttachLookup说。
读完挂接数据后,我们接着读了堆nAttachLookup个的uint16数据。这串数据最后被存了下来。在
WMV中用了一个uint16的数组来存储,叫attLookup
经过多方面分析,这个attLookup正如其名字一样,是用来查询挂接点的。
而attLookup的值可以是以下枚举成员
enum POSITION_SLOTS
{ // wxString Attach_Names[]
ATT_LEFT_WRIST = 0, // Mountpoint
ATT_RIGHT_PALM,
ATT_LEFT_PALM,
ATT_RIGHT_ELBOW,
ATT_LEFT_ELBOW,
ATT_RIGHT_SHOULDER, // 5
ATT_LEFT_SHOULDER,
ATT_RIGHT_KNEE,
ATT_LEFT_KNEE,
ATT_RIGHT_HIP,
ATT_LEFT_HIP, // 10
ATT_HELMET,
ATT_BACK,
ATT_RIGHT_SHOULDER_HORIZONTAL,
ATT_LEFT_SHOULDER_HORIZONTAL,
ATT_BUST, // 15
ATT_BUST2,
ATT_FACE,
ATT_ABOVE_CHARACTER,
ATT_GROUND,
ATT_TOP_OF_HEAD, // 20
ATT_LEFT_PALM2,
ATT_RIGHT_PALM2,
ATT_PRE_CAST_2L,
ATT_PRE_CAST_2R,
ATT_PRE_CAST_3, // 25
ATT_RIGHT_BACK_SHEATH,
ATT_LEFT_BACK_SHEATH,
ATT_MIDDLE_BACK_SHEATH,
ATT_BELLY,
ATT_LEFT_BACK, // 30
ATT_RIGHT_BACK,
ATT_LEFT_HIP_SHEATH,
ATT_RIGHT_HIP_SHEATH,
ATT_BUST3, // Spell Impact
ATT_PALM3, // 35
ATT_RIGHT_PALM_UNK2,
ATT_DEMOLISHERVEHICLE,
ATT_DEMOLISHERVEHICLE2,
ATT_VEHICLE_SEAT1,
ATT_VEHICLE_SEAT2, // 40
ATT_VEHICLE_SEAT3,
ATT_VEHICLE_SEAT4
};
上面这个枚举成员,定义了WOW中一个带动画的模型可以挂接物体的位置。又可以说,是骨头ID。在
先前我们的ModelAttachment或者ModelAttachmentDef结构体中定义的id,就正好是上面的枚举值中
的一个。
读完挂接信息以后,就是颜色和透明度数据了,WOW的模型中,一个模型可以持有由若干颜色和透明
度组成的序列,在每帧渲染的时候,动态插值计算出当前的值。 即可以实现颜色闪烁和透明度变化
的效果。 幽灵虎和凤凰什么的,就是用到了这个。
//这是颜色结构体的定义,可以看出,它定义了一个颜色值,和一个16位的透明度值
struct ModelColorDef {
AnimationBlock color; // (Vec3D) Three floats. One for each color.
AnimationBlock opacity; // (UInt16) 0 - transparent, 0x7FFF - opaque.
};
//这是透明度结构体的定义,也是一个16位的透明度值。
struct ModelTransDef {
AnimationBlock trans; // (UInt16)
};
这两个定义,导致了模型透明度的重复。 而在WMV中的代码,也确实是这样写的。先将颜色进行了
插值,而后又用透明队列的值对颜色中的ALPHA通道进行修改。
读取完了上面的数据后,接下来的,就是模型的LOD数据。 LOD中则包含了对应的材质数据。 在WMV
中,只读取了LOD0的模型。
读取完LOD后,WMV对模型的顶点数据建立了一个索引。
if (nIndices) {
IndiceToVerts = new size_t[nIndices+2];
for (size_t i=0;i<nIndices;i++){
size_t a = indices[i];
for (size_t j=0;j<header.nVertices;j++){
if (a < header.nVertices && origVertices[a].pos == origVertices[j].pos){
IndiceToVerts[i] = j;
break;
}
}
}
}
今天暂时写到这里,改天继续。。。
作者:麒麟子
出处:http://www.cnblogs.com/qilinzi/
蛮牛专栏:麒麟子
简介:麒麟子,编程15年,科技创始人,技术作家。
09年进入游戏行业,16年创立成都幼麟科技有限公司。十年从业经验练就了游戏全栈技能,目前专注于手机游戏领域。
版权声明:本文版权归作者和博客园共有,欢迎转载。转载必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。