欢迎您,请 登录 或 注册会员

偶久网

搜索
偶久网 首页 改图教学 查看内容

魔兽争霸3的MPQ文件及模型格式分析

2017-5-22 15:35| 查看: 3241 |原作者: 邪恶叔

1 魔兽争霸3的模型数据都被打包压缩在*.mpq里,可以通过SFmpq_static.lib提供的接口获取相应的数据段句柄(MPQHANDLE)。
2 读取MPQ时,首先要知道这个MPQ里有多少个被打了包的文件数目以及每个文件的名字,可以通过SFmpq_static.lib的SFileOpenFile(LPCSTR lpFileName, MPQHANDLE *hFile)接口查找数据段标记(TAG)为(listfile)在MPQ里的位置句柄,然后继续用接口获取到数据段长度后,将这段数据Read到内存里来,这些数据全是关于文件名及相对路径的字符串,接下来可以创建一个临时文件,把数据fwrite到这个临时文件里,这样就可以用fscan逐一读出文件名并保存起来了(比如保存成一个table)。
3 现在有了文件的索引了,在读取模型时,还是用SFileOpenFile获取这个模型在MPQ的句柄,然后再用接口读到内存,这样就可以专门针对这段模型数据段进行分析了。
下面是魔兽3的模型文件格式:
MDLX  --  4个char,即4个字节一个DWORD的长度,这个是魔兽3模型格式的专用头标记,如果没有则表示出错
VERS  --  4个char,一个DWORD的长度,即4个字节
version data  --  DWORD类型  实际的version数据
MODL  --  4个char  这个模型的属性数据,如boundingbox
MODL size  --  DWORD  在模型数据段中的长度,一般就是372的固定长度
MODL name1  --  80个字节
MODL name2  --  260个字节
MODL unknow float  --  4个字节,float类型  功能未知
MODL boundingbox min vector  --  3个float,12个字节  boundingbox min vector
MODL boundingbox max vector  -- 3个float,12个字节
MODL unknow DWORD  --  4个字节 ( 80+260+4+12+12+4=372 )
SEQS  --  4个字节  动作数据
SEQS size  --  4个字节
SEQS data  --  上面读出来的SEQS size个字节
(  单个动作数据的struct:
struct SequenceName
{
char mName[80];
int  mUnk1;
int  mUnk2;
float mUnk3;
int  mUnk4;
float mUnk5;
int  mUnk6;
float mUnk7;
Vec3 mMins;
Vec3 mMaxs;
};
动作的数量:
mNumSequences = SEQS size / sizeof(SequenceName);
)
unknow TAG  --  4个字节
unknow TAG size  --  4个字节
unknow TAG data  --  unknow TAG size个字节
MTLS  --  4个字节
MTLS size  --  4个字节
MTLS data  --  MTLS size个字节
(
class mdxMaterial
{
#define MAX_LAYER 8
public:
int    mUnk1;
int    mUnk2;
// 'LAYS'
int    mNumLayers;
Layer1   mLayers[MAX_LAYER];
......
};
struct Layer1
{
int  mLayerSize; // in Bytes
int  mBlendMode;
int  mUnk3;
int  mTexture;
int  mUnk5;
int  mUnk6;
float mUnk7;  // alpha ?
BOOL mKMTA;
};
MTLS data里具体的材质数据读取是:
先读一个4个字节的单个mdxMaterial的size(layer1的数量不同导致mdxMaterial的大小不同),然后按照结构顺序填充,碰到layer1时,用同样的方法,先读4字节Layer1的size,然后按照顺序填充layer1,总共填充mNumLayers次
)
TEXS  --  4个字节  模型使用的贴图纹理数据
TEXS size  --  4个字节
(
struct Texture
{
DWORD mUnk1;
char mName[MAX_PATH]; // 260
DWORD mUnk2;
};
由若干个Texture构成,Texture Numbers = TEXS size / sizeof(Texture)
)
TEXS data  --  TEXS size个字节  贴图纹理数据
GEOS  --  4个字节
GEOS size  --  4个字节
GEOS data  --  GEOS size个字节
(
GEOS数据段由若干个mdxGeoChunk构成
单个mdxGeoChunk具体数据分布如下:
VRTX  --  4个字节
number of vertex  --  4个字节
vertex data  --  number of vertex * 12个字节  每个顶点占用3*4个字节
NRMS  --  4个字节
number of normals  --  4个字节
normal data  --  number of normals * 12个字节  法线数据
PTYP  --  4个字节  primitives type
PTYP size  --  4个字节
PTYP data  --  PTYP size * 4个字节
PCNT  --  4个字节  primitives count
PCNT size  --  4个字节
PCNT data  --  PCNT size * 4个字节
PVTX  --  4个字节  primitives vertices  构成IB的primitive数据
PVTX size  --  4个字节
PVTX data  --  PVTX size * 2个字节
(
struct Triangle
{
short ind[3];
};
PVTX data里含PVTX size*2/sizeof(Triangle)个Triangle
)
GNDX  --  4个字节  vertex group indices
GNDX size  --  4个字节
GNDX data  --  GNDX size个字节
MTGC  --  4个字节  group matrix counts
MTGC size  --  4个字节
MTGC data  --  MTGC size*4个字节
MATS  --  4个字节  matrices
MATS size  --  4个字节
MATS data  --  MATS size*4个字节
unknow DWORD*4  --  4*4个unknow DWORD
chunk bounding box  --  2*3*4个字节
unknown struct number  --  4个字节
unknown struct data  --  unknown struct number*(4+12*2)个字节
UVAS  --  4个字节
UVAS size  --  4个字节
UVBS  --  4个字节
UVBS size  --  4个字节
UVBS data  --  UVBS size*8个字节
)
unknown TAG  --  4个字节
unknown TAG size  --  4个字节
unknown TAG data  --  unknown TAG size个字节
BONE  --  4个字节
BONE size  --  4个字节
BONE data  --  BONE size个字节
unknown TAG  --  4个字节
unknown TAG size  --  4个字节
unknown TAG data  --  unknown TAG size个字节
重复上面的unkown TAG读取过程5遍

搜索