【MMD】用python解析VMD格式读取

【MMD】用python解析VMD格式读取,第1张

  MikuMikuDance(简称MMD)是一款动画软件,早期视为Vocaload角色制作动画的软件,现在还经常能在B站等视频网站,或一些动画网站(某I站)看到MMD作品。

  我在高中也简单学过 *** 作这款软件以及PE、水杉等软件,学会了简单k帧、套动作、调渲染、加后期、压缩等技术,这与我学习计算机专业有很大的关系(虽然学校学的和这个八竿子打不着,或许我应该学美术去),现在已经分不清很多东西了,封面静画就是杂七杂八过气MME一锅扔的成果,得益于G渲的强大,还能看出一点效果。

  现在我想学一些3D的开发,包括用程序读取模型、动作等,很快我就想到之前用过的MMD。

  一些3D姿势估计(3D pose estimate)或许能得到骨骼位置以及PAF(骨骼间关系),但我需要知道3D动画是如何储存动作数据的,才能想到怎样将姿势估计得到的数据转化为动作数据。

  因此我找了一些资料解析MMD的动作数据VMD(Vocaload Mation Data)文件,并写下这篇记录。

  本文会用python解析vmd文件,并纠正上述文章的一点错误。

  根据MMD的规矩,上借物表:

封面静画:

  首先,vmd文件本身是一个二进制文件,里面装着类型不同的数据:uint8、uint32_t、float,甚至还有不同编码的字符串,因此我们需要二进制流读入这个文件。

  vmd格式很像计算机网络的协议格式,某某位是什么含义,区别是,vmd文件的长度 理论 上是无限的,让我们来看看。

  vmd的大致格式如下:

  最开始的就是 头部(header) ,看到这就有十分强烈的既视感:

  其中, 版本信息(VersionInformation) 长度为30,是ascii编码的字符串枣没枯,翻译过来有两种,一为“Vocaloid Motion Data file”,二为“Vocaloid Motion Data 0002”,长度不足30后用\0(或者说b'\x00')填充。这是由于vmd版本有两种,大凳洞概是为了解决模型名称长度不足,因此后续只影响模型名称的占用长度。

   模型名称(ModelName) ,是动作数据保存时用的模型的模型名,通过这个我们可以获取到那个名称,我们知道,一个动作数据想要运作起来,只要套用模型的骨骼名称是标准的模板就可以,因此我想象不出这个名称有何用处,或许某些模型带有特殊骨骼,例如翅膀之类的,这样能方便回溯?模型名称的长度根据版本而决定,version1为10,version长度为20。编码原文写的是shift-JIS,是日语编码,这样想没错,然而我试验后发现并非如此,例如经常改模型的大神 神帝宇 的模型,他的模型名称用shift-JIS为乱码,用gb2312竟然能正察老常读出来;还有 机动牛肉 大神的模型,他的模型名称用gb2312无法解码,用shift-JIS解码竟然是正常的简体中文???怎么做到的?

  骨骼关键帧,分为两部分:骨骼关键帧数、骨骼关键帧记录:

  我们可以查一下,每个骨骼关键帧的数量为111字节。

  一开始还没发现,旋转坐标竟然有四个,分别为x, y, z, w,急的我去MMD里查看一下,发现和我印象中没有什么差别

  为何补间曲线的类型不确定呢?上面csdn博客的教程说 “uint8_t那里有冗余,每四个只读第一个就行” 。说的没有问题,首先我们要清楚这个补间曲线坐标的含义。

  我们打开MMD,读入模型,随意改变一个骨骼点,记录帧,就会发现左下角会出现补间曲线。

  后面的格式与这个格式大同小异。

  表情关键帧分为:表情关键帧数、表情关键帧记录:

  镜头关键帧分为:镜头关键帧数、镜头关键帧记录:

  距离是我们镜头与中心红点的距离,在MMD中,我们可以通过滑轮改变

  Orthographic似乎是一种特殊的相机,没有近大远小的透视关系(不确定),不过在我的实验中,它一直取值为0。和上面的已透视没有关系,当取消已透视时,透视值会强制为1。

  下面的骨骼追踪似乎没有记录,可能是强制转换成骨骼所在的坐标了。

  后面的格式与这个格式大同小异。

  表情关键帧分为:光线关键帧数、光线关键帧记录:

  rgb颜色空间之[0, 1]之间的数,类似html的RGB(50%, 20%, 30%)这种表示方法,转换方式就是把RGB值分别除以256。

  光线投射方向是[-1, 1]之间的小数。正所对的投射方向是坐标轴的负方向,例如将Y拉到1, 光线会从上向下投影。

  我依旧会使用面向对象的方式构建VMD类,不过构造方法无力,属性太多,我选择用静态方法添加属性的方式构建对象

  随意掰弯一些关节并注册、使用:

output:

  因为前面提到的编码模式,我选择用gb2312解码,在很多(也许是大部分)动作数据都会报错,可以去掉编码方式:

  我们没有移动方块骨骼,因此位置信息都是0。

  不喜欢看欧拉角的话,可以写一个转换方法:

  这样只要调用:

即可得到转换成欧拉角的结果,同样的方式还可以编写转换RGB、弧度、角度等

  python内置的json包可以很方便得将字典转换成json格式文档储存。

  我们也可以试着写一些将VMD转换成vmd文件的方法。

  通过学习VMD的文件结构,大致了解了储存动作数据的格式和一些方法,或许可以类比到一些主流的商业3D软件上。

  读取程序并不难,我写程序的很多时间都是查二进制 *** 作消耗的,通过这个程序,还巩固了二进制 *** 作的知识。

  我在google上找到了一个包 saba ,专门用于 *** 控MMD的文件,包括模型、动作数据等

  现在学一下图形学,等学有所得再做出更多东西。

APPLICATION就是应用程序的意思。TApplication类是用于描述Delphi编制的应用程序的一个类。通过对这个类的灵活应用可以编制许多有特点的程序。下面我们就举几个这方面的例子。1检测当前Windows程序是否被激活:Tapplication类有一个属性——Active,这个属性就可以描述当前运行的程序是否被激活,成为Windows的焦点。检测的代码如下:IfApplication.Active=FalsethenShowMessage('当前窗口没有被激活');2取得当前程序的名称:Tapplication类的EXEName属性可以返回这个可执行程序的完整文件名(包含路径)。实现的代码如下所示:ShowMessage(Application.ExeName)3改变程序极小化时的标题如果您细心观察可以发现,一些程序的标题和程序的名称并不一致,尤其是一些英文程序,窗体的标题栏比较长,可以容纳比较多的文字,而在最小化时,往往变成了很少的几个字母。这中间起作用的就是Tapplication类的Title属性。这个属性决定了程序最小化时的标题,而窗口中标题栏的标题是由Form的Caption属性来决定的。其代码如下:Form1.Caption:='窗口的标题'Application.Title:='程序的标题'其实我们也可以在在程序设计时指定Tapplication类的Title属性值。 *** 作的方法是在开发环境中拉下Project菜单选择Options菜单时d出如图1(略)的对话框。在这个对话框中的Title栏中填写程序的标题一样也可以达到这种效果。并且因为一般的工程文件都是以英文命名的,所以程序运行过程中d出的消息框中的标题是英文。但在指定了这个属性之后,这个程序的所有消息窗口的标题都变为Title的值。这就使得程序看起来更加完整。4指明程序的主窗口Windows系统中的界面都是窗口,但一般来讲有一个主窗口。Tapplication的MainForm属性就可以返回程序的主窗纯旦口。5显示消息框Delphi有许多显示消息框的函数与过程,比较常用的是ShowMessage,它用起来虽然十分方便,但是却有一个问题,那就是这个消息框的按钮是以英文显示的。如果要生成一个含有中文显示的按钮就要求助于Tapplication的MessageBox函数了。这个函数的原形如下:functionMessageBox(Text,Caption:CharFlags:Longint):Integer在这个函数中,前两项分别是显示的提示信息和消息窗口的标题,Flags是一个长整值,用来指定按钮的个数及功能。熟悉Delphi的用户可能会注意到,这个函数和Delphi3所提供的同名函数有一点不同,那不是这个版本中字符串参数都以字符的形式给出,而不再要求将其转化成指针。我们在使用时要注意加以区别。Application.MessageBox('需要存盘吗?','提示信息',MB_OKCANCEL);这个语句在运行时显示的样式如图2(略)所示。最后就这个函数的返回值作一些说明,实际上这个函数返回的是一个整型的数值,而这个数值被系统指定了具体的含义,比如:按下“确定”按钮时返回的值是“1”,而其它按钮的值列在表1中。表1按钮的意义及系统中对其定义的值按钮的意义按下此按世裤宴钮时函数返回的值IDABORT3IDCANCEL2IDIGNORE5IDNO7IDOK1IDRETRY4IDYES66控制窗口的尺寸一般可以用窗口手柄来调整窗口的尺寸,但是也可以用Application的事件来调整。实现的方法是用以下两个过程:Application.MinimizedApplication.Restore前一个过程用来将程序的搜银主窗口最小化,而后一个过程用来将最小化的窗口恢复到原来的尺寸。7链接联机帮助文件Application的CurrentHelpFile属性能够指定当前程序所用的联机帮助文件的文件名。这个属性经常与另一个方法联合在一起使用。举例如下:Application.HelpFile:='联机帮助文件名'Application.HelpJump('联机帮助文件的主题’)通过这一命令组合,我们就能使系统d出一个显示某主题的联机帮助文件。8在程序运行时动态地创建窗口一般情况下,窗口是在设计时加入到工程项目中的,但是有时也需要我们在程序运行时动态地加入窗口,这就要用到Application的CreateForm过程,举例如下:Form3:Tform3//声明窗口类Application.CreateForm(TForm3,Form3)//创建窗口9结束程序虽然我们可以用关闭主窗口的方法来关闭一个程序,但是更好的法是用Application的Terminate过程。它能够起到更彻底地关闭程序的效果。10Destroy属性.虽然Delphi提供了这一属性,但是并不提倡使用它,如果要终结程序就要调用Terminate过程,而Destroy过程一般是用来在程序发生悬挂时来退出程序时才调用,有些类似Windows中的结束任务功能。它不仅能关闭程序实例本身,而且还能释放程序所占用的资源,能够达到将程序彻底清除出系统的目的。

含义1:乱者VMD 是一个分子可视化程序,该程序采用3D图形以及内置握陪冲脚本来对大型生物分子系统进行显示、制成动画以及分析等 *** 作。

含义2:VMD(Visual Merchandising),即 “视觉段歼营销”或者“商品计划视觉化”。

VMD不仅仅涉及到陈列、装饰、展示、销售的卖场问题,还涉及到企业理念以及经营体系等重要“战略”,需要跨部门的专业知识和技能,并不是通常意义上我们狭义理解的“展示、陈列”,而实际它应该是广义上“包含环境以及商品的店铺整体表现”。

目前在发达国家视觉营销包含,空间:通过空间立体视觉效果营造品牌氛围。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12455954.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-23
下一篇2023-05-23

发表评论

登录后才能评论

评论列表(0条)

    保存