2009-12-14 3 views
8

Ich versuche, einen Sprite in drei Dimensionen um seinen Mittelpunkt zu drehen, und ich habe Mühe, etwas von dem Verhalten von matrix3D zu verstehen.wie 3D-Rotation um Zentrum in AS3 mit Matrix3D zu tun?

Ive überschrieben die eingestellten rotationX, rotationY und rotationZ Methoden des Sprite wie folgt:

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); 

} 

I prependTranslation bin mit dem Mittelpunkt der Drehung zu korrigieren, und die erste prependRotation jede previously- auszulöschen angewandte Rotation.

Beim Testen funktioniert rotationX genau wie erwartet und der Sprite dreht sich um seine horizontale Achse.

rotationY und rotationZ scheinen auch gut zu funktionieren. Es gibt jedoch ein Problem: Immer wenn rotationY oder rotationZ gesetzt sind, ändern sich auch alle anderen Rotationswerte. Dies ist kein Problem mit rotationX - wenn ich rotationX setze, ändert sich nichts. Aber wenn ich rotationY oder rotationZ setze, ändern sich alle Rotationswerte, was ein Problem für meine App ist (die versucht, Werte zu speichern und wiederherzustellen).

Ich glaube, mir fehlt nur etwas Verständnis darüber, was mit Matrix3D passiert. Wie kann ich dies umsetzen, so dass keine gegenseitige Abhängigkeit zwischen den Werten besteht?

+0

Beste Sache ist es, [UIComponent # transformAround] (http://opensource.adobe.com/svn/opensource/flex/sdk/trunk/frameworks/projects/framework/src/mx/core/UIComponent.as) und die zugehörige AdvancedLayout.as-Implementierung. Sie tun genau das, Wrapping Matrix3D. –

+0

Sie suchen nicht in Ihrem Code, aber haben Sie Gimbal Lock? http://en.wikipedia.org/wiki/Gimbal_lock –

Antwort

3

Eine weitere einfache Lösung besteht darin, das Objekt hinzuzufügen und es in einem Container-Sprite zu zentrieren und die 3D-Transformationen auf dem umgebenden Sprite durchzuführen.

+0

yeh das ist viel einfacher. erstellen Sie einen Halter Sprite, fügen Sie dann die Sprite mit x: -mysprite.width * 0,5 und y: -mysprite.height * 0,5 und dann den Halter drehen – daidai

1

Ich weiß nichts über AS3 usw. Aber wenn ich nur auf Ihren Code schaue, frage ich mich, warum Sie auf der z-Achse mit dem, was ich verstehe, x- und y-Werte (Breite und Höhe) übersetzen. Sollte die z-Achse nicht mit etwas wie "Tiefe" übersetzt werden?

0

Dies ist sehr einfach, Sie versuchen, den folgenden Code verwenden:

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

während s ist Ihr Sprite, der dritte Parameter, Vector3D zeigen Mittelposition Ihres Sprites.

Der obige Code lässt die Sprites um -1 Grad rotieren.