jpw*_*yan 8 rotation actionscript-3 matrix-multiplication molehill stage3d
我开始在Molehill,并且在掌握Matrix3D时遇到了很多问题.我的第一个问题是如何管理描述单个模型方向的Matrix3D.
我使用Matrix3D.appendRotation()来做到这一点.但是根据我附加的顺序,我得到了不同的结果(显然,因为我在全球空间中一次旋转一个).我知道这是一个常见的问题,我已经用3d软件建模遇到了它.但这一次,我必须以编程方式修复它.这是我需要帮助的地方.
首先,如果有任何混淆,这是图片中的问题:
第1步:我渲染一个模型.

步骤2a:我在X轴上旋转它.看起来不错!

步骤2b:我在Z轴上旋转它.看起来不错!

所以...如果我在模型的X和Z轴上旋转我想要这个:

但是,悲伤,我明白了:

我可以看到问题.我在全球空间一次附加一个轮换.我需要在对象的本地空间中旋转.我不知道如何做到这一点或我甚至应该搜索什么(术语等).代码很简单(和错误):
modelLocalMatrix.identity();
modelLocalMatrix.appendRotation(modelZRot, Vector3D.Z_AXIS);
modelLocalMatrix.appendRotation(modelXRot, Vector3D.X_AXIS);
//eventually y-axis rotation as well...
renderMatrix.append(modelLocalMatrix);
Run Code Online (Sandbox Code Playgroud)
我猜测不是使用Vector3D轴常数,而是想使用一些规范化的矢量和一些......呃,东西......代替modelZRot,modelXRot,最后是modelYRot.谁能告诉我上面应用所需类型的旋转的最佳实践解决方案是什么?
更新:花了一天时间点击"书籍"(在YouTube上称为KhanAcademy)并在此处开始演示:3D旋转矩阵的数学我偶然发现了一种非常接近我想要的"看待"方法解.不幸的是,我只有50%的人理解它.我仍然希望有人可以对这个话题有所了解!
var angleOfRotation:Number = Math.PI / 2; //90 degrees...
var axisOfRotation:Vector3D = new Vector3D(0, 1, 0); //some point to look at...
//normalize the vector!
axisOfRotation.normalize();
var x:Number = axisOfRotation.x;
var y:Number = axisOfRotation.y;
var z:Number = axisOfRotation.z;
var c:Number = Math.cos(angleOfRotation);
var s:Number = Math.sin(angleOfRotation);
var t:Number = 1 - c;
//Graphics Gems (Glassner, Academic Press, 1990).
modelLocalMatrix = new Matrix3D(new <Number>[
t * (x * x) + c, t * x * y - s * z, t * x * z + s * y, 0,
t * x * y + s * z, t * (y * y) + c, t * y * z - s * x, 0,
t * x * z - s * y, t * y * z + s * x, t * (z * z) + c, 0,
0, 0, 0, 1
]);
Run Code Online (Sandbox Code Playgroud)
事情是,这似乎相当笨重.特别是因为Vector3D的旋转角度应该是第四个(w)值.更重要的是,Matrix3D似乎已经有了lookAt()方法.我还没有得到它...请有人从试验和错误的几个小时救我!
好的,我基本上已经弄清楚如何做到这一点。它比我做的简单得多。它还有助于回顾 Matrix3D API(它有一些很棒的功能!)。
首先,我用来在局部轴上旋转模型的源代码:
var raw:Vector.<Number> = modelLocalMatrix.rawData;
var right:Vector3D = new Vector3D(raw[0], raw[1], raw[2]);
var up:Vector3D = new Vector3D(raw[4], raw[5], raw[6]);
var out:Vector3D = new Vector3D(raw[8], raw[9], raw[10]);
modelLocalMatrix.appendRotation(modelXRot, right);
modelLocalMatrix.appendRotation(modelYRot, up);
modelLocalMatrix.appendRotation(modelZRot, out);
Run Code Online (Sandbox Code Playgroud)
“向上”、“向右”和“向外”归一化向量在我原始帖子的链接中进行了讨论。它们基本上是模型的俯仰轴、偏航轴和横滚轴。可以说,当您初始化对象时,这些向量与 Vector3D.X_AXIS、Y_AXIS 和 Z_AXIS 相同。我已经使用 Matrix3D.rawData 属性提取它们,尽管可能有更好的方法。
现在,您可以根据需要沿这些轴中的任何一个旋转,但一旦您这样做,其他两个轴的方向就会立即改变。这是有道理的。您的模型已经旋转,它的“右”、“上”和“前”现在不同了!因此,如果您首先在模型的“右”轴上旋转(请记住,这与全局 X_AXIS 开始时相同),然后您想要在其“出”轴上滚动模型,则需要从模型的本地轴获取它矩阵。显然,它不再与全局Z_AXIS相同。请注意,我没有调用 Matrix3D.identity()。如果我这样做,那么我的模型的轴将被重置!这对于我的渲染循环来说是可以的,尽管我不得不稍微改变我的代码(和思维方式),因为我在应用变换和旋转之前重置了所有矩阵。请注意,modelXRot、modelYRot 和 modelZRot 存储以度为单位的旋转值。
我当然希望这对某人有帮助。我不敢相信如此简单的解决方案却找不到如此常见的问题。不管怎样,它似乎确实在做我想做的事。
| 归档时间: |
|
| 查看次数: |
2007 次 |
| 最近记录: |