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
?无论如何希望这有帮助!干杯!
所以我有一个 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
?无论如何希望这有帮助!干杯!