用JS去读取【MMD】中vmd文件的那些事
发布网友
发布时间:2024-10-26 08:31
我来回答
共1个回答
热心网友
时间:2024-10-26 08:34
MikuMikuDance(MMD)是一个早期用于为v家角色制作舞蹈动画的三维动画软件,尽管模型和镜头的资源已经相当丰富,但作为一个前端工程师,面对mac不支持MMD的问题,我决定尝试用JavaScript读取MMD中用于保存动作、镜头、表情和关键帧的VMD文件。此行动源于对MMD动作编辑的需求以及对JavaScript二进制流操作的学习兴趣。
JavaScript中的二进制流通过`ArrayBuffer`来表示,虽然直接操作`ArrayBuffer`较为困难,但通过`TypedArray`和`DataView`可以较为灵活地读取和操作数据。获取二进制流的方式通常有从`File`对象直接读取,使用`FileReader`的`readAsArrayBuffer`方法,或者通过HTTP请求头设置为`arraybuffer`等。
在读取VMD文件时,需要理解其格式。VMD文件由不同字节区域组成,每部分代表不同的数据。理解了VMD的结构和格式后,通过读取指定长度的数据并根据预先定义的对照表解析,可以成功读取文件内容。其中,VMD文件采用`SHIFT_JIS`编码,使用浏览器自带的`TextDecoder`可以解码为文字,但`TextEncoder`不行。
为了读取VMD文件,我采取了本地文件服务的方式,利用`fetch`请求读取文件内容,并使用`arrayBuffer`的切片功能获取数据。然而,这种方法在循环操作时效率低下,所以采用了基于索引的读取方式,避免了数据引用变动导致的性能问题。在处理字符串时,需使用特定的解码器,如`shiftjis`库,以正确处理`SHIFT_JIS`编码的文本。
版本信息在VMD文件的开头,长度为30字节,包含模型名称。读取时需注意其格式填充的特殊性,如出现乱码或填充非零字符,需进行处理,例如将0或特定值填充的区域排除。读取关键帧时,遵循VMD文件的区块结构,先读取关键帧数量,然后循环读取各帧数据。
读取过程中,涉及数字的处理需要根据数据类型使用相应的`TypedArray`,如`Uint32Array`。读取时,通过`DataView`的`getUint32`等方法获取整数值,注意不同端序的兼容性问题。编写VMD文件时,与读取过程相反,需要生成`ArrayBuffer`并填充数据,使用特定编码(如`shiftjis`)进行字符串的编码。
通过一系列的读取和编写操作,最终实现了VMD文件的读取与生成功能。为了方便他人使用,我封装了一个名为`vmd.js`的npm包,并在GitHub上公开了代码,欢迎使用与反馈。此外,计划将动作生成功能与`posenet`集成,进一步扩展VMD文件的生成能力。