如何在AS3中使用matrix3D围绕中心进行3D旋转?

8

我正在尝试围绕其中心点在三维空间内旋转一个Sprite,并且我正在努力理解matrix3D的一些行为。

我已经重写了Sprite的set rotationX、rotationY和rotationZ方法,如下所示:

override public function set rotationX (_rotationX:Number) : void {  

    this.transform.matrix3D.prependTranslation(this.width/2.0, this.height/2.0, 0);
    this.transform.matrix3D.prependRotation(-this.rotationX, Vector3D.X_AXIS);
    this.transform.matrix3D.prependRotation(_rotationX, Vector3D.X_AXIS);
    this.transform.matrix3D.prependTranslation(-(this.width/2.0), -(this.height/2.0), 0);

}

override public function set rotationY (_rotationY:Number) : void {

    this.transform.matrix3D.prependTranslation(this.width/2.0, this.height/2.0, 0);
    this.transform.matrix3D.prependRotation(-this.rotationY, Vector3D.Y_AXIS);   
    this.transform.matrix3D.prependRotation(_rotationY, Vector3D.Y_AXIS);
    this.transform.matrix3D.prependTranslation(-(this.width/2.0), -(this.height/2.0), 0);   

}

override public function set rotationZ (_rotationZ:Number) : void {

    this.transform.matrix3D.prependTranslation(this.width/2.0, this.height/2.0, 0);
    this.transform.matrix3D.prependRotation(-this.rotationZ, Vector3D.Z_AXIS);   
    this.transform.matrix3D.prependRotation(_rotationZ, Vector3D.Z_AXIS);
    this.transform.matrix3D.prependTranslation(-(this.width/2.0), -(this.height/2.0), 0);   

} 

我正在使用prependTranslation来修正旋转的中心点,第一个prependRotation用于取消之前应用的旋转。

经过测试,rotationX的效果完全符合预期,Sprite围绕其水平轴旋转。

rotationY和rotationZ也似乎工作得很好。然而,存在一个问题:每当设置rotationY或rotationZ时,所有其他旋转值也会改变。这对我的应用程序是个问题(它试图保存和恢复值)。

我认为我只是缺乏一些关于matrix3D的理解。如何实现这样的效果,使各值之间没有相互依赖?


最好的方法是查看UIComponent#transformAround以及相关的AdvancedLayout.as实现。它们正是这样做的,围绕Matrix3D进行包装。 - Lance
不看你的代码,但是你是否遇到了万向节锁定问题?http://zh.wikipedia.org/wiki/%E4%B8%87%E5%90%91%E8%8A%82%E9%94%81 - Merlyn Morgan-Graham
3个回答

3

另一个简单的解决方案是将对象添加到容器精灵中并使其居中,然后在包含精灵上进行3D变换。


这个简单多了。创建一个容器 Sprite,然后将 Sprite 添加到容器中,x 坐标为:-mysprite.width0.5,y 坐标为:-mysprite.height0.5,最后旋转容器即可。 - daihovey

1

我对AS3等编程语言一无所知。但是仅仅看了你的代码,我就想知道为什么你要使用我理解为x和y值(宽度和高度)来沿z轴进行平移。难道不应该使用类似于“深度”之类的东西来平移z轴吗?


0

这很简单,你可以尝试使用以下代码:

var matrix3d:Matrix3D = s.transform.matrix3D;
matrix3d.appendRotation( -1, Vector3D.Z_AXIS , new Vector3D( 390, 360, 0 ) );

在编程中,当s表示您的精灵时,第三个参数Vector3D表示您的精灵的中心位置。

上述代码将使精灵s旋转-1度以上。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接