1)笔记
1)旋转的表示
(1)直观的旋转,任何3D物体,你可以把一个物体旋转某个角度,分别绕XYZ旋转多少,然后得到一个朝向
也就是:任何一个3D物体总是可以表示为:绕XYZ轴旋转了多少度
X:30 Y:60 Z:70-->物体的一个方位-->旋转-->欧拉旋转
(2)旋转先后顺序很重要 X:30 Y:60 Z:70 X:30 Y:70 Z:60 顺序不一样,导致的结果可能不一样(拿着一个长方体 绕X轴和Z轴旋转一下就知道了);
游戏引擎规定一个默认的顺序
unity的欧拉旋转顺序: zxy
creator 3d: yzx
顺序不一样结果不一样,所以游戏引擎规定了一个顺序;
(3)欧拉旋转-->3维向量 是垂直于哪个轴旋转 绕x轴旋转多少度 绕y轴旋转多少度 绕z轴旋转多少度
(4)欧拉旋转
优点: 简单、直观
缺点:
不方便参与矩阵计算, 模型坐标变换到世界某个位置,需要乘上变换矩阵 平移*旋转*缩放;
有万向节锁的缺点;
(5)引擎内部运算的时候,我们不使用欧拉角,而是使用四元数-->表示物体旋转的数学工具
(6)四元数也可以表示旋转,但是没有欧拉角那么直观:
(7)方便参与矩阵计算;
没有万向节锁的毛病;
(8)四元素(Quat)和欧拉角的变换 yzx
x y z w, 是个四维向量
Quat(x,y,z,w),静态方法和成员,Vec3类似
静态方法:
欧拉角转四元数: fromEuler: 给定一个欧拉角,可以返回一个表示旋转的四元数对象
四元数转欧拉角: toEuler
[-180,180] [-90.90]
[-180,-90] [90, 180]
成员方法:
getEulerAngles
2)3D物体旋转控制
四元数来控制旋转:
rotation:获取本地旋转,返回对象是一个四元数
worldRotation:世界旋转返回对象也是一个四元数
getRotation(是否new四元数对象):
getWorldRotation: 获取世界旋转,返回一个四元数对象
setRotation(设置节点世界旋转, 有2个版本 四元数对象版本Quat 四元数分量版本(x,y,z,w))
setWorldRotation:设置节点世界旋转(叠加父亲的旋转角度)
欧拉角来控制旋转:
eulerAngles: 表示本地旋转
setRotationFromEuler:使用欧拉角来设置物体的本地旋转(x,y,z) 绕x轴 、绕y轴 、绕z轴 旋转多少度
setWorldRotationFromEuler: 不管父亲旋转多少度, 设置为世界旋转多少度(x,y,z) -->YZX
节点的旋转方法:
rotate(Quat) 旋转增量
// 欧米伽spped
let w_speed: number = 120;
let r: Quat = new Quat();
// 把欧拉角转为四元数,第一个参数r是输出的值
// 接着3个参数是绕着哪个轴旋转,是增量; 默认是局部空间
Quat.fromEuler(r, 0, w_speed * dt, 0);
this.node.rotate(r);
方向的调整: lookAt
x
y
z
foward: -z的方向
lookAt方向-z的方向指向某个点, 让前方对准哪个点,控制角色的朝向,
如:调用lookAt让玩家朝着某个方向走去
lookAt是:-z的方向指向哪里,然后调整物体的旋转,常用来控制物体的朝向
参数:lookAt(
目标位置,
头顶的方向:
哪个是你的正上方,默认是Y,010,可选参数,一般默认向上即可,
正着拍,正着对准,Y轴就是向上; 横着拍就不是Y轴了)
前方:
对于本地坐标来说,本地就是-z;
对世界坐标来说,我们提供一种方式,获取世界坐标系下的前方,即forward,打印是:物体朝着摄像机看的方向
this.node.lookAt(cc.v3(0, 10, 0))
console.log(this.node.forward) // 朝着摄像机看
3)原有的还是new一块内存的
getXXX: 是new出来
xxx: 不new
4)调整摄像机视角为UI编辑器的视角
点击摄像机 + ctrl + shift + f
5)2个四元数之间可以插值
旋转A-->旋转B
我们不能一下子旋转过去的,因此四元素提供了可以方便插值旋转的,
也就是能进行插值过度,平滑过度过去-->平滑差值过度;
2种插值方式:
lerp: 逐元素的线性插值,用的不多
slerp: 四元素的球面插值,一般旋转的话是画了一个圆球,因此采用基于四元数的球面插值来做,
旋转插值一般采用球面插值,来旋转平滑过度;