WebGL 在给定的中心旋转

WebGL rotating over a given center

所以我有一个 XML 文档,我解析它以便在 WebGL 场景中执行操作。 所以我有可以或不能动画的节点。 然后我有一个 CircularAnimation,它有一个 Center(x, y, z),Node 应该围绕该中心旋转一个 Radius 距离。动画的时间跨度、饱和角度和旋转角度。

<ANIMATION id="cir1" span="5" type="circular" center="0 0 0" radius="3" startang="0" rotang="360"/>

在我的 CircularAnimation class 中,我有一个函数可以让对象移动并更新它的水平方向。类似于地球绕着太阳转。

我使用动画中定义的 currTime class 来计算跨度是否结束。

if(this.beg_time == null) this.beg_time = currTime;
else 
{
    if((currTime-this.beg_time) >= this.span) return;
    else 
    {
        // Calculates angles to rotate
        var ang_inc = (this.angle_rot*(currTime-this.beg_time))/this.span;
        var total_rot = ang_inc+this.angle_beg;

        // Rotates node Matrix from the Matrix_Beg
        mat4.rotateY(this.node.matrix, this.node.beg_matrix, total_rot);


        // Moves the node to the desired center
        mat4.translate(this.node.matrix, this.node.matrix, [this.x, this.y, this.z]);

        // Moves the node according to the given radius
        mat4.translate(this.node.matrix, this.node.matrix, [this.radius*Math.cos(ang_inc), 0, this.radius*Math.sin(ang_inc)]);
    }
}

但这似乎无法正常工作,有什么想法吗?

为了以防万一,先介绍一下背景知识:

如果你有一个顶点 v 应该通过 beg_matrix 变换得到 v',矩阵乘法看起来像 v' = beg_matrix * v。如果您随后想通过矩阵 T 转换 v' 以获得 v'',则等式将类似于:v'' = T * v'。现在,如果我们想直接从顶点 v 到顶点 v'',我们可以将这两个方程混合在一起(代入 v')并得到 v'' = T * beg_matrix * v。这基本上就是您要尝试做的事情,除了 T 需要是一个围绕中心点旋转的矩阵。

我相信当您似乎正在使用的 glMatrix 库应用转换时,转换会应用到前一个矩阵 (v'' = beg_matrix * T * v) 的 右侧 侧它在任何以前的转换之前应用新的转换(不是你想要的)。

如果您反转所有变换并将它们应用于新矩阵,然后将这个新矩阵乘以 beg_matrix左侧,我相信它应该会让您更接近您正在寻找的东西。

我没有 运行 这段代码,因为它显然是一个没有提供的更大项目的一部分,但它应该能说明问题。

if(this.beg_time == null) this.beg_time = currTime;
else 
{
    if((currTime - this.beg_time) >= this.span) return;
    else
    {
        // Calculates angles to rotate
        var ang_inc = (angle_rot * (currTime - this.beg_time)) / this.span;
        var total_rot = ang_inc + this.angle_beg;

        // Start with the identity matrix and no transformations.
        // Our end goal is a matrix M where M = T * C * R * beg_matrix.
        // T - radial translation
        // C - translation to center point
        // R - rotation by angle
        // beg_matrix - previous transformations
        mat4.identity(this.node.matrix);

        // Moves the node according to the given radius
        // M = T
        mat4.translate(this.node.matrix, this.node.matrix, [this.radius*Math.cos(total_rot), 0, this.radius*Math.sin(total_rot)]);

        // Moves the node to the desired center
        // M = T * C
        mat4.translate(this.node.matrix, this.node.matrix, [this.x, this.y, this.z]);

        // Rotates node Matrix from the Matrix_Beg
        // M = T * C * R
        // (negative angle since the library rotates clockwise along [0, 1, 0]?)
        mat4.rotateY(this.node.matrix, this.node.beg_matrix, -total_rot);

        // apply previous transformations
        // M = T * C * R * beg_matrix
        mat4.multiply(this.node.matrix, this.node.matrix, this.node.beg_matrix);
    }
}

另外,在您之前的代码中,您在余弦和正弦计算中使用了 ang_inc,我认为您可能想要 total_rot?无论如何希望这有帮助!干杯!