我开始在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);
我猜测不是使用Vector3D轴常数,而是想使用一些规范化的矢量和一些......呃,东西......代替modelZRot,modelXRot,最后是modelYRot。谁能告诉我上面应用所需类型的旋转的最佳实践解决方案是什么?
更新:花了一天时间点击“书籍”(在YouTube上称为KhanAcademy)并在此处开始演示:The Mathematics of the 3d Rotation Matrix我偶然发现了一种非常接近我的“看待”方法期望的解决方不幸的是,我只有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
]);
事情是,这看起来相当笨重。特别是因为Vector3D的旋转角度应该是第四个(w)值。更重要的是,Matrix3D似乎已经有了lookAt()方法。我还没有得到它...请有人从试验和错误的几个小时中救我!
答案 0 :(得分:2)
好的,我基本上已经想出了如何做到这一点。它比我制作它简单得多。它还有助于审查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);
我的原帖中的链接中讨论了“向上”,“向右”和“向外”规范化向量。它们基本上是模型的俯仰,偏航和滚动轴。可以说,在初始化对象时,这些向量与Vector3D.X_AXIS,Y_AXIS和Z_AXIS相同。我使用Matrix3D.rawData属性提取它们,虽然可能有更好的方法。
现在,您可以根据您的选择沿这些轴中的任何一个旋转,但是当您执行此操作时,其他两个轴的方向会立即更改。这是有道理的。你的模型已经旋转,它的“右”,“向上”和“向前”现在是不同的!因此,如果您首先在模型的“右”轴上旋转(请记住,这与全局X_AXIS相同)然后您想要在其“out”轴上滚动模型,您需要从模型的本地获取它矩阵。显然,它不再与全局Z_AXIS相同。请注意,我不会调用Matrix3D.identity()。如果我这样做,那么我的模型的轴将被重置!这对我的渲染循环来说没问题,虽然我不得不改变我的代码(以及思考方式),因为我在应用变换和旋转之前已经重新设置了所有矩阵。请注意,modelXRot,modelYRot和modelZRot以度为单位存储旋转值。
我当然希望这有助于某人。我无法相信这样一个简单解决方案的常见问题无处可寻。无论如何,它确实似乎正在做我想要的。