实时有偏差Maya到UE的相机预览插件

白嫖!Maya与Unreal实时同步的插件神仙玩法解析 来自深夜小编 CG文章_CG资源

实时有偏差Maya到UE的相机预览插件

*文章授权转自微信公众号「3DTech


这是一个实时有偏差Maya到UE的相机预览插件。


至于为什么写这个,是因为我前段时间沉迷在数学的海洋中,正好在学线代和3D数学方面的东西,正好想写写坐标变换相关的,就整理了以前写过的东西,集合成插件,也许会派上用场吧。


这个我目前还不知道有什么用,如果大佬觉得有用,请告诉我。可能加上一键导入资产和场景信息转换就有用了,不用问了,我就是写过才知道(/doge)。




https://www.bilibili.com/video/BV1fy4y127ED



解压压缩包,maya插件随意放,建议目录不要有空格或者中文,点击install_modules来安装,安装不上或者安装后没有显示插件的,都是因为我的文件夹下maya文件夹中没有modules文件夹。



maya中装了需要重开maya,找到mtouecamera的插件,点开图标即可。



UE插件需要放到UE项目文件夹中,UE插件根据UE版本来进行放置,如果是4.26就就需要4.26,装对应版本的插件!!


目前只编译了4.24, 4.25, 4.26三个版本,其余的没有编都用不了。



保证项目目录中有Plugins文件夹,打开UE后找到maya to UECamera放置场景中即可。



找到Maya Camera这一栏,打开Open即可



maya设置好UE的项目目录后点击Start



注意,需要两边都开启才有效果,可以看到两边画面一致即成功了



经过测试某些机器上需要开启这个选项才能正常使用





因为内容较多,字数上万,本文不会涉及太多理论上的知识,更多的是偏思路分享,某些概念会简单介绍,如果要大家不想看这么多分析,只需要嫖最后的关键代码或者是插件,就直接跳到最后吧~如果大家想要深入学习,可以去网上查询相关资料或者和资深大佬进行交流学习。虽然我做了很长时间的功课,元旦三天都在写这篇文章,我尽可能去保证我文章的准确性,但如果哪里有纰漏或者是错误,大佬们请轻喷。



这个插件最难的地方就是坐标转换和数据交换,关于数据交换我写了两种方式,一种是基于文件读写的缓存,一种就是Socket。文件缓存的话,把数据存成json,在UE中进行tick文件读取就可以了,因为camera,特别是cineCamera,继承的tick是可以在editor的模式下进行。关于Socket我就不多说,讲起来又可以写一篇文章了,我就觉得UE的GC不太好控制,因为我写socket用了多线程,有时候GC时间间隔很长,造成了资源的浪费,不过我觉得应该是我太菜了。。

    第二点就是坐标转换了,物体从Maya到UE的坐标最难的不是位移和缩放,毕竟只需要颠倒一下Y值和Z值就可以了,难就难在旋转值上,接下来我借写这个转换camera插件的思路来进行剖析,我是如何去做这个转换的思路。




欧拉角是在空间中描述从一个用于表示某个固定的参考系的、已知的方向,经过一系列基本旋转得到、新的代表另一个参考系的方向的方式。

    这个方向可以被想成从一个初始的方向,旋转到其确切位置的方向。如下图中描述,原始的参考系的坐标轴被定义为x,y,z,旋转后的坐标系的坐标轴被定义为X,Y,.在几何和物理中,被旋转的坐标系通常被想象成严格附着在一个刚体上。因此,它被称为一个“本地”坐标系,这也意味着它既代表这个刚体的位置,也代表这个刚体的方向。


欧拉角有两种表达形式,简单来说就是经典欧拉角是两轴旋转,泰特布莱恩角是三轴旋转,以下是其所有的旋转顺序:




泰特-布莱恩角中 z-y'-x''这个序列(内旋) 通常被叫做航海角,因为他们可以用来描述一艘船或者一架飞行棋的方向,或者可以叫做万向角,也可以把这几个旋转叫做 heading(摆头),elevation(俯仰)和bank(倾斜),或者叫做 yaw(偏航),pith(俯仰)和roll(翻滚)


所以实际上大多数情况下我们用的是第二种形态的欧拉角,即泰特-布莱恩角,也就是航向角。



划重点了!


3D软件坐标系的定义一般均为:红色X、绿色Y、蓝色Z


我们平时说的旋转都是指按固定轴向旋转,而实际上欧拉角是按照体轴来进行旋转,即旋转顺序为Yaw(Z轴)-> Pitch(Y轴)-> Roll(X轴)


MAYA中欧拉角的旋转轴

因为坐标系是右手坐标系的,所以UE的旋转方向是逆时针旋转,且Z轴朝上。



UE中欧拉角的旋转轴

因为坐标系是左手坐标系的,所以UE的旋转方向是顺时针旋转,且Y轴朝上。




这张图很清晰的说明了UE是一个“”,反正几乎全部的软件导到UE都需要坐标转换就是了。





我们先在UE中调整rotation的数值,在蓝图中打印出来,但是在UE4里,蓝图中的rotation的三个值依次为roll,pitch,yaw。C++中FRotator里是pitch,yaw,roll。



可以发现实际数值和显示数值不一样,实际是因为数值转换成四元数后被规范化了。


我们再来Maya中用Python代码的形式来简单解释这个过程。






maya中API的MQuaternion也就是四元数,在欧拉角转换成四元数的形式会自动

规范欧拉角的数值,但是如果用的是cmds的命令或者pymel就需要自己手动规范化,UE中欧拉角转换成四元数的形式后也会自动规范化。



在计算坐标变换时,旋转更方便的表示形式是旋转矩阵(Rotation Matrix)。三维空间的旋转矩阵可以表示成3×3的矩阵,单独绕一个轴旋转θ \thetaθ角度的旋转矩阵为:


如果依次绕x轴、y轴、z轴旋转,该变换的旋转矩阵的python代码为:



例如当我们给z值为90度的时候,旋转矩阵的值应该是这样子的:



当我们把参数带入函数运行后可以发现,误差可以几乎忽略不计,基本一致。


注意,我们使用的是列向量,但是numpy点积计算结果是行向量,所以我们需要对矩阵进行转置,否则就是下面的结果。



我们实际需要的:



不过后面我们运算也是行向量的运算,所以在最终代码里,可以不用转置矩阵。


接下来我们对求出来的旋转矩阵转转换成UE的欧拉角,也就是ZXY顺序。


根据网上的资料和推导,可以在python的代码为:



因为X=π/2的时候,会导致万向锁,因为篇幅有限,就不具体展开,所以我们需要对其进行判断。


常规情况下,我们需要判断矩阵是否是正交矩阵,否则就会发生错误,但是在这里,我们知道我们求出的矩阵一定是正交矩阵,所以不需要耗费资源去判断了。



以下是maya的画面以及相机的旋转值。



下面我们用这段完整代码来检验是否正确。




以下是我们运行的结果,这里我对Z值进行-Z-90是因为maya是Y轴朝上,而UE是Z轴朝上,所以转换需要给X值顺时针旋转π/2,因此我们从ue导出资产到maya也可以看到默认X轴是-90度,而在这里我们就是+90度,但是因为Maya是右手坐标系,而UE是左手坐标系,我们需要给和Z值一个负数,所以就是-(Z+90) = -Z-90。



这是我们设置相同值的结果,可以看到除去焦距因素,物体的方向是一致的。



不过,我们会发现,欧拉角计算旋转变换时,一般需要转换成旋转矩阵,这时候需要计算很多sin, cos,计算量较大,而且我们只针对了ZXY的旋转,如果要转成其他的旋转值轴方向,代码量一定会增加,有没有更高效的办法呢?



其实我们可以用更加直观的轴角来进行表示,那么四元数就是我们重要的工具,它能够很方便的刻画刚体绕任意轴的旋转。四元数是一种高阶复数,四元数q表示为:


q=(x,y,z,w)=xi+yj+zk+w



在虚幻中也是以四元数的形式去存储旋转方向。



所以,我们用四元数可以大大提升效率。


这是从UE源码中查到的关于四元数的转换,我用Python把关于欧拉角转换四元数的函数码下来了。



可以看到在xyz值相同时,结果是一样的。




当然我们不会在python中使用这个,因为在UEC++中,FRotator有一个Quaternion的方法可以转换成四元数。



总结一下,比较容易的方法就是我们根据物体的旋转值求出旋转矩阵,然后转换成UE的欧拉角,轴向角度校正后再把得出的值传到C++中,用Quaternion转换成四元数,存储在FTransform里面就可以实现旋转轴的转换,整体看下来其实并没有什么难度,大佬们也不要被自己吓到了,多试试就出来了hh。


本来我想去根据FTransform拿到旋转矩阵或者四元数,将其转换成适用于UE的四元数,这样直接赋值过去效率会更高,但是咱不是搞研究的,KPI才是重点,所以后来我在OpenMaya中找到了一个傻瓜方法,就是拿到物体的四元数,转换成欧拉角后,再对其进行reorder,转换成ZXY的旋转顺序,再对旋转值进行校正,传到UEC++转成四元数就可以了,真的很快有木有,当然知道原理这样去做是也挺节约时间的。





以下是我扒的旋转矩阵转四元数的源码,有兴趣的话可以研究一下。



终于到了白嫖插件的时间了。



插件应该怎么白嫖呢?  


关注微信公众号:3DTech



回复“mtouc”即可获取百度云盘下载地址



声明:部分内容来源于网络,仅供读者学术交流之目的。文章版权归原作者所有。如有不妥,请联系删除。






加载中