文档章节

unreal里Actor的旋转

小保哥
 小保哥
发布于 2017/05/04 17:39
字数 2170
阅读 193
收藏 0

仅以Actor为例子。Components与之一样。

仅描述Rotation,不讲Location与Scale。

2个API
> * GetActorRotation(取的是world系)
> * SetActorRotation(设的是world系)

两个重点:
1. unreal里四元数乘法A*B,代表先执行B旋转,再在新的姿态下执行A旋转。这一条与是否局部或全局坐标系没关系,它就是恒成立。
2. 从零姿态开始构建旋转。

讲2个例子。紧紧的围绕着上述真理来思考unreal里的变换,不要想多。

> 例子一:父和子两个物体。要求子物体在当前姿态的基础上,绕自身坐标轴旋转。

> 分析:当前姿态X通过GetActorRotation可以获取。绕自身坐标轴的旋转为N。很自然的,我们可能认为这个旋转需求可以通过N*X来实现。没错,这是正确的,满足上面说的从零姿态运动到X姿态,再执行N旋转得到最终姿态。但问题是,这个N不像我们以为的那样容易描述,因为这个N必须是在子物体处于当前X姿态的世界系中描述的,而它的坐标轴此时很可能不是0、1、0三个数。所以,我们必须变通一下。我们先在子物体处于world零姿态时描述一下N,这时的N是很容易描述的,在执行N旋转后, 再执行X旋转,所得的效果也满足需求。即X*N为所求。这里的X、N均为world系描述。(20170522补充:其实在姿态X的前提下,要描述绕自身坐标轴的旋转N,可以这么求,,其中Local是绕自身坐标轴旋转的世界系描述<此时说是局部系描述也对>,求出的N是在姿态X的前提下,绕自身坐标轴旋转的世界系描述,进而变换合成为,这个推理表明:在某个确定的变换后,要让物体绕自身坐标轴旋转,等价于,先让物体绕自身坐标轴旋转,再做那个确定的变换。不过,这句话里的两个绕自身坐标轴旋转的变换矩阵是不一样的。参考下一篇文章。)(20170531补充:这里其实并没有交换旋转顺序,而是在求N在世界系的描述。如果若干旋转是绕同样的轴,那么这些旋转可以任意交换旋转顺序,不影响最终的姿态结果;但如果这些旋转是绕不同的轴进行,那么它们的合成必须按照旋转发生的顺序连乘,不能交换顺序。)

> 与此同类型的一个重要问题:如何将物体在局部坐标系下进行旋转。

> 答案很简单:X*N即为所求。

> 这里的X是父节点的world系姿态Parent,N为局部旋转描述Local。即Parent*Local即为所求。注意:因为我们是从world系零姿态开始,先描述的N,在这个时候,局部旋转等价于全局旋转描述,但是从数学上来说,N、Local是world系描述。

 

> 例子二:父和子两个物体。要求子物体在当前姿态的基础上,执行已给出world系数值描述的旋转N。

> 分析:当前姿态X通过GetActorRotation可以获取。然后执行新的旋转N,最终姿态N*X即为所求。这个问题其实是例子一的一般化。如果例子一中的绕自身坐标轴的旋转也给出了子物体在姿态X的前提下的world系数值描述,那最终结果就是N*X即可。

 

> 最后说一句,我们求出X*N或者N*X之后,需要将这个值传给SetActorRotation函数来执行它代表的旋转。

 

==============2017.05.05 更新=================

父节点为世界系姿态X时,对子节点SetActorRotation(X*N)等价于SetActorRelativeRotation(N).   N仍为父子物体均处world系零姿时开始构建。

若已知X*N与X,则N=(X^-1) * (X * N),即子物体相对于父物体的RelativeRotation=(Parent(world)^-1) * Child(world).

(Unreal Engine的Editor中,Transform里设置Rotation时,注意x和y值(即Roll和Pitch)的正负定义与一般的左手法则相反,z值(即Yaw)的正负定义与一般的左手法则一致。这一点从FRotator的头文件定义中可以清楚的看到。当FRotator转换成FQuat时,从转换函数里能看到x和y项均加了负号进行修正,以使得四元数的旋转正负定义与一般的左手法则一致。所以,最好以四元数来思考旋转,这样从不同的系统进行坐标变换时,按照一般的左右手法则就能得到正确的结果。)

 

==============更新2017.05.11=================

有一个比较常见也比较重要的例子值得分析一下,就是Unreal里AnimationNode的动画数据。

在AnimationNode插件中,一般会有下面这行代码:

NewRotation = CTParentWorldRotation.Inverse() * NewRotation * WorldRotations[BoneIndex];

代码里的WorldRotations是骨骼的Reference Pose中的原始数据。我面临的现实是:在maya中做好的模型导入到unreal中时,勾选了Import Reference Pose,那么FPoseContext中读取的这个Reference Pose其旋转数值是不为零的。

讲一下正确的处理方法:

首先,很重要的一点是模型的正确导入。模型导入到场景之后是否正确,我认为有一个标准:这里涉及两个坐标系,一个产生数据的坐标系(动捕系统或其他),一个展示数据的坐标系(unreal等)。你可以自己定义这两个坐标系的前方,但是一旦你确定之后,那么在数据源坐标系中面对前方的零姿态必须与展示坐标系中模型面对前方的零姿态一致。如果用数据源的零姿态驱动模型时,模型不是处于面向前方的零姿态,那么这个模型就算导入失败了。用加父节点旋转等等纠正的方式不是万能的,建议果断删掉重新导入。模型导入unreal时,会出现一个Import属性窗口,里面有个Transform栏,这个就是做纠正用的,在这里做完修正,模型导入后,其零姿态肯定是你想要的。这里的修正量就是第一次导入不正确时的offset,这个在第一次导入时要关注一下。

其实模型导入正确后,后面的数据接入就比较容易了。如果在错误模型导入的基础上做数据变换,有时现实会打脸打得很残酷。不要太过于自信。一定要在正确的基础上,做下一步的事情。外部欧拉角进unreal时,其实很简单,抓住Pitch、Yaw、Roll三个概念来对,Pitch和Pitch对上,Yaw和Yaw对上,Roll和Roll对上。然后再来看符号。符号这样确定,unreal是左手系,伸出左手,握住Yaw即竖直轴,大拇指向上,其余四指抓握的绕向就是unreal里Yaw的正方向,如果数据源的Yaw(具体哪个手,视具体情况而定)的正方向也是这个绕向,那么,两个Yaw符号相同。剩余两轴同此操作过程,但是一定要注意:unreal里握住Pitch或Roll轴,且大拇指朝向两根轴的正方向时,其余四指抓握的绕向分别为Pitch和Roll的负方向。不要问为什么这么奇怪,它实践上就是如此。三个轴对应上,且符号也正确后,最后调用FRotator(Pitch, Yaw, Roll)即可拿到正确的旋转。后续如果还需要对这个旋转进行修正的话,一定不要修改这个已对好的Rotator,而应该构造新的旋转施加到这个Rotator上,来达到最终的目的。

如果你非要在一个错误的模型上变换。那你还不如像下面这样,在unreal里建一个带轴向的小方块,用数据驱动它,只要它对了,数据肯定就对了。剩下的再视情况导入正确的模型或者在正确的旋转上额外加变换,来达到变态的目的。

 

==================2017.09.10补充 ↓====================

Unreal里的这些变换类太好使了,以至于都快忘了下面这些东西了:

在ZED中就没有unreal那么方便,还得根据上图里的这些东西来计算矩阵,麻烦。

 

© 著作权归作者所有

共有 人打赏支持
小保哥
粉丝 6
博文 37
码字总数 36776
作品 0
朝阳
程序员
Libgdx学习笔记:Scene2d之Group

UI组件之Group 当Group旋转或缩放时,它的孩子们正常绘制,并且Batch变换后正确的旋转或缩放。 绘制Group前,Batch flush使得变换可以设置。有很多Group时这将可能成为性能瓶颈。如果在一组演...

flyoahc
2014/11/04
0
2
1,000,000 Stupid Questions for UE4 Developers

My dumpster of random questions and answers for UE4. Let’s say you have a blueprint and you want to get access to the particle system and the audio file sub-components. What do......

2steper
2016/06/08
131
0
Unreal教学(8)——蓝图学习快速开始(Blueprints Quick Start Guide)

之前几个篇章中主要讲到如何使用C++的代码实现相关游戏的相关功能,我们已经学习到了Actor是什么东西, 经常会使用Empty Actor这个东西,那么它到底是什么,我们可以这样假设Actor是我们定义...

WAN_EXE
2017/11/27
0
0
UE4入门单词及蓝图节点 (作者初学时的个人笔记)

因为作者英语水平很渣,学习UE4又面临众多陌生单词 于是将见到的所有默认的单词都一一记录,每天看一遍, 尽量保重自己第二次碰见的时候能认识,然后日积月累 遇到的陌生单词也越来越多,记录...

qq_36409711
2017/11/05
0
0
UE4 框架

  有很多人是从UE3 接触到Unreal,如果你也对UE3非常了解,便能很快的上手UE4。但是,UE4的开发模式还是有所不同的。      1.谈谈过往,UE1和UE2。   我知道在那个时候咱们一样挥霍美...

robslove
2016/08/11
17
0

没有更多内容

加载失败,请刷新页面

加载更多

线性一致性和 Raft

作者:沈泰宁 在讨论分布式系统时,共识算法(Consensus algorithm)和一致性(Consistency)通常是讨论热点,两者的联系很微妙,很容易搞混。一些常见的误解:使用了 Raft [0] 或者 paxos ...

TiDB
16分钟前
0
0
兄弟连区块链教程以太坊源码分析core-state-process源码分析

## StateTransition状态转换模型 /* The State Transitioning Model 状态转换模型 A state transition is a change made when a transaction is applied to the cu......

兄弟连区块链入门教程
18分钟前
0
0
linear-gradient渐变中的参数

在看张鑫旭的博客 遇到渐变数值后面带参数不太理解 @supports (-webkit-mask: none) or (mask: none) { .box { border: none; background: linear-gradient(to bottom, #34538...

红羊在厦门
19分钟前
0
0
Python yagmail模块自动发邮件

Python发邮件yagmail模块 import yagmail#连接服务器yag=yagmail.SMTP('xx@163.com','yy','smtp.163.com')#邮箱正文contents=["test","email send"]#发送邮件#yag.send('...

小白兔_球球
20分钟前
1
0
pada mysql

CREATE SCHEMA `exchange` DEFAULT CHARACTER SET utf8mb4 ;

qwfys
29分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部