知识点!!修复Cocos3D四元素线行插值旋转变形问题

在使用cocos3d的四元素旋转过程中,节点会莫名其妙的变形,使用下面代码代替原来的lerp就能解决

function Quat_lerp(a: Quat, b: Quat, t: number, out: Quat = a) {
    Quat.lerp(out, a, b, clamp01(t));
    Quat.normalize(out, out);
    return out;
}

下面解释原因:

cocos3d处于性能的考虑,使用了模型矩阵乘以反向旋转矩阵的方式得到模型比例,而旋转矩阵是基于四元素的逆计算得到的,而对于四元素逆的计算,cocos为了性能直接使用了四元素的共轭,共轭和逆相等的前提是四元素是标准化的,问题就出在四元素线行插值过程中,四元素可能是非标准化的,但这里cocos没有做,cocos没做的原因也很简单,因为他数学部分直接拿了gl-matrix的,gl-matrix没做处理,所以cocos也没做处理。

所以上面这段函数我对插值结果做了标准化处理之后,变形问题就消失了,并且对t做了[0,1]范围的限制。另外值得一提的是四元素使用slerp即球面插值也能解决这问题,因为它计算得到的就是标准化的四元素。

补充

之前解决了cocos旋转会影响缩放的问题,但是四元素简单的线行插值还会有另外一个问题,就是反向旋转,本来我只需旋转30度,插值结果却是旋转了360-30=330度。下面是解决方案

let q_1 = new Quat();
function Quat_lerp(a: Quat, b: Quat, t: number, out: Quat = a) {
    if (Quat.dot(a, b) < 0.0) {
        q_1.set(-b.x, -b.y, -b.z, -b.w);
    }
    else {
        q_1.set(b);
    }
    Quat.lerp(out, a, q_1, clamp01(t));
    Quat.normalize(out, out);
    return out;
}

我建了一个3D交流群475557897,专门来解决cocos的这些奇葩问题,欢迎志同道合的小伙伴加入

16赞

赞啊!!!

非常nice , 白嫖

厉害啊,大佬

我这么一篇好文章竟然石城沉大海了

2赞

好文章,今天学习的时候也碰到了这个问题

mark
好像也遇到类似的问题,先mark下,后面抽时间在看下

mark!!!