终于决定,还是通过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; } } } }今天暂时写到这里,改天继续。。。