游戏研究室

文档-资料-开源

英雄联盟ANM文件结构

文件采用小端(little-endian)字节序

char[8]

文件类型标识,没有扩展名时可以判断文件类型 

int32

格式版本

int32

意义不详(不知道什么作用)

uint32

骨骼数量

uint32

动画帧数

uint32

动画帧频(fps)

(char[36]+char[28]*动画帧数)*骨骼数量

骨骼数据

char[32]

骨骼名称

int32

类型(2:根骨骼,0:普通骨骼)

char[28]*动画帧数

动画帧数据

float

四元数的x

float

四元数的y

float

四元数的z

float

四元数的w

float

位置x

float

位置y

float

位置z


下面给出一个命令行下运行C++工具代码

#include
#include
#include
using namespace std;

typedef struct s_AnmHeader {
char fileType[8];
int version;
int uk;
unsigned int nbBones;
unsigned int nbFrames;
float fuk;
} _AnmHeader;

typedef struct s_BoneHeader {
char name[32];
int flags;
} _BoneHeader;

void dumpAnm(string infile, string outfile) {
ifstream fin;
fin.open(infile.c_str(), ios::binary);
if (fin.fail()) {
cout << "ERROR: could not open " << infile << endl;
exit(1);
}
ofstream fout(outfile.c_str());
_AnmHeader header;
fin.read((char*)&header, sizeof(_AnmHeader));
cout << "Found " << header.nbBones << " bones for " << header.nbFrames << " frames" << endl;
fout << header.fileType << endl;
fout << header.version << endl;
fout << header.uk << endl;
fout << header.nbBones << endl;
fout << header.nbFrames << endl;
fout << header.fuk << endl;
for (int i = 0; i < header.nbBones; i++) {
_BoneHeader bone;
fin.read((char*)&bone, sizeof(_BoneHeader));
fout << bone.name << endl;
fout << bone.flags << endl;
for (int j = 0; j < header.nbFrames; j++) {
float pos[7];
fin.read((char*)&pos, sizeof(float) * 7);
for (int k = 0; k < 7; k++)
fout << pos[k] << " ";
fout << endl;
}
}
}

void compileAnm(string infile, string outfile) {
ifstream fin;
fin.open(infile.c_str());
if (fin.fail()) {
cout << "ERROR: could not open " << infile << endl;
exit(1);
}
ofstream fout;
fout.open(outfile.c_str(), ios::binary);
_AnmHeader header;

fin >> header.fileType;
fin >> header.version;
fin >> header.uk;
fin >> header.nbBones;
fin >> header.nbFrames;
fin >> header.fuk;

fout.write((const char*)&header, sizeof(_AnmHeader));
for (int i = 0; i < header.nbBones; i++) {
_BoneHeader bone;
memset(bone.name, 0, 32);
fin >> bone.name;
fin >> bone.flags;
fout.write((const char*)&bone, sizeof(_BoneHeader));
for (int j = 0; j < header.nbFrames; j++) {
float pos[7];
for (int k = 0; k < 7; k++)
fin >> pos[k];
fout.write((const char*)&pos, sizeof(float) * 7);
}
}
}

int main(int argc, char *argv[]) {

if (argc != 4) {
cout &lt;&lt; "Usage: anmtool <command></command>
" &lt;&lt; endl;
cout &lt;&lt; "Valid commands are: c (compile), d (decompile)" &lt;&lt; endl;
return 2;
}
string cmd = string(argv[1]);
string inputFile = string(argv[2]);
string outputFile = string(argv[3]);

if (cmd == "compile" || cmd == "c") {
cout &lt;&lt; "Compiling ASCII file: " &lt;&lt; inputFile &lt;&lt; " to binary .anm file: " &lt;&lt; outputFile &lt;&lt; endl;
compileAnm(inputFile, outputFile);
cout &lt;&lt; "Done!" &lt;&lt; endl;
} else if (cmd == "decompile" || cmd == "d") {
cout &lt;&lt; "Decompiling binary .anm file: " &lt;&lt; inputFile &lt;&lt; " to ASCII file: " &lt;&lt; outputFile &lt;&lt; endl;
dumpAnm(inputFile, outputFile);
cout &lt;&lt; "Done!" &lt;&lt; endl;
} else {
cout &lt;&lt; "Unsupported command" &lt;&lt; endl;
return 2;
}
return 0;
}

, , ,

发表评论