最終更新: teruteruteruchu 2017年10月29日(日) 17:08:01履歴
anm文件格式数据结构解析
按字节顺序来:
0A
大小1bytes,表示后面的文件头标识字符串长度
43 4D 33 44 32 5F 41 4E 49 4D
大小10bytes,文件头标识字符串,字符串的文本型是CM3D2_ANIM
xx xx 00 00
大小4bytes,版本号,通常是 E9 03 代表版本1001
==================循环A开始==================
01
大小1bytes,标识(a0)
xx
大小1〜2bytes,指示后面骨骼名称的长度 (*1)
01
大小1bytes,原因不明,从样本看名字带Finger的骨骼都有这个字节
但这个字节不包含在名字长度的统计中(要注意)
不明原因,但编程时可以考虑为如果前个字节大于128时才有这个字节(暂时没发现bug)
更新:这个解释见"paths.dat"分析的(*A) 终于明白为什么 —_—
xx xx ... xx xx
大小不确定,长度是上个字节的值,内容是骨骼名称的字符串
==================循环B开始==================
xx
大小1bytes,骨骼类的序列(标识),从100开始,也就是64,下一个就是65,累推
如果读到这个值为01,表示回到(a0)位置,即跳出了循环B,重新循环A,也就是下一个骨骼
xx xx 00 00
大小4bytes,指示当前骨骼类所包含的帧数,Int32 (c0)
至少要有两帧,所以最小是02 00 00 00
==================循环C开始==================
xx xx xx xx
大小4bytes,当前帧的时间轴,单精度(c1)
xx xx xx xx
大小4bytes,x数据[?],单精度(c2)
xx xx xx xx
大小4bytes,y数据[?],单精度(c3)
xx xx xx xx
大小4bytes,z数据[?],单精度(c4)
循环c由(c1)-(c2)-(c3)-(c4),次数为(c0)
跳出循环c时,回到循环B开始处,读取下一个骨骼类的序列或标识
(c2)(c3)(c4)这三个并不是xyz三坐标系
==================循环C结束==================
==================循环B结束==================
==================循环A结束==================
00 {00 00}
大小3bytes,最后三个字节,第一个00作用猜测等同(a0)
那么紧接两个00 00用于结束判定(还是猜测)
从样本中发现,所有的静帧(其实也不是真的静帧)anm都是以00 00 00结尾的
但解析dance用anm时发现最后里有一个00作为结束判定,作用初步确定同(a0)
另外,dance中除结束的00外,再前面的部分数据只有骨骼名称(重复出现的)
因为这块数据之前已经出现了针对相应骨骼的动作数据用的循环B和循环C
而后面重复出现的骨骼名称中单纯的只有循环A的三项,直到文件末端
通过代码实验加载一个静帧样本后,再逆向进行数据流输出得到一个新的anm
当忽略循环A中的不明字节时,游戏无法加载这个anm
但是忽略末端3个空字节的最后两个时,游戏并没有出现异常
*1 关于用1〜2个字节表示长度,解释见"paths.dat"分析的(*A)
按字节顺序来:
0A
大小1bytes,表示后面的文件头标识字符串长度
43 4D 33 44 32 5F 41 4E 49 4D
大小10bytes,文件头标识字符串,字符串的文本型是CM3D2_ANIM
xx xx 00 00
大小4bytes,版本号,通常是 E9 03 代表版本1001
==================循环A开始==================
01
大小1bytes,标识(a0)
xx
大小1〜2bytes,指示后面骨骼名称的长度 (*1)
01
大小1bytes,原因不明,从样本看名字带Finger的骨骼都有这个字节
但这个字节不包含在名字长度的统计中(要注意)
不明原因,但编程时可以考虑为如果前个字节大于128时才有这个字节(暂时没发现bug)
更新:这个解释见"paths.dat"分析的(*A) 终于明白为什么 —_—
xx xx ... xx xx
大小不确定,长度是上个字节的值,内容是骨骼名称的字符串
==================循环B开始==================
xx
大小1bytes,骨骼类的序列(标识),从100开始,也就是64,下一个就是65,累推
如果读到这个值为01,表示回到(a0)位置,即跳出了循环B,重新循环A,也就是下一个骨骼
xx xx 00 00
大小4bytes,指示当前骨骼类所包含的帧数,Int32 (c0)
至少要有两帧,所以最小是02 00 00 00
==================循环C开始==================
xx xx xx xx
大小4bytes,当前帧的时间轴,单精度(c1)
xx xx xx xx
大小4bytes,x数据[?],单精度(c2)
xx xx xx xx
大小4bytes,y数据[?],单精度(c3)
xx xx xx xx
大小4bytes,z数据[?],单精度(c4)
循环c由(c1)-(c2)-(c3)-(c4),次数为(c0)
跳出循环c时,回到循环B开始处,读取下一个骨骼类的序列或标识
(c2)(c3)(c4)这三个并不是xyz三坐标系
==================循环C结束==================
==================循环B结束==================
==================循环A结束==================
00 {00 00}
大小3bytes,最后三个字节,第一个00作用猜测等同(a0)
那么紧接两个00 00用于结束判定(还是猜测)
从样本中发现,所有的静帧(其实也不是真的静帧)anm都是以00 00 00结尾的
但解析dance用anm时发现最后里有一个00作为结束判定,作用初步确定同(a0)
另外,dance中除结束的00外,再前面的部分数据只有骨骼名称(重复出现的)
因为这块数据之前已经出现了针对相应骨骼的动作数据用的循环B和循环C
而后面重复出现的骨骼名称中单纯的只有循环A的三项,直到文件末端
通过代码实验加载一个静帧样本后,再逆向进行数据流输出得到一个新的anm
当忽略循环A中的不明字节时,游戏无法加载这个anm
但是忽略末端3个空字节的最后两个时,游戏并没有出现异常
*1 关于用1〜2个字节表示长度,解释见"paths.dat"分析的(*A)
コメントをかく