魔兽世界客户端数据研究(二)

终于决定,还是通过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;
                }
            }
        }
    }

今天暂时写到这里,改天继续。。。

posted @ 2013-04-24 00:47  麒麟子MrKylin  阅读(504)  评论(0编辑  收藏  举报