Encore une petite classe, cette fois-ci pour passer du « mode » 3D au « mode » 2D : Matrix3DToMatrix
Re,
Comme le fait remarquer Jeanphi sur son blog lorsqu’on affecte les propriétés en rapport avec la 3D d’un DisplayObject, celui-ci est « bitmapisé ». Ce qui a pour conséquence de le rendre légèrement flou (antialiasing).
Normalement c’est un avantage pour éviter le crénelage (les petites marches que fait un ligne oblique) lors de la déformation du visuel. Seulement cet antialiasing est également présent lorsque les propriétés « 3D » sont remises à 0.
En fait, les transformations tels-que : x, y, rotation, scaleX, scaleY, et j’en passe, sont toutes faite par l’intermédiaire d’une matrice de transformation. Cette matrice est une propriété de la classe Transform, elle-même présente dans la classe DisplayObject sous le nom de… (roulement de tambours) : « transform ». Il s’agit des propriétés matrix et matrix3D.
Elles représentent, respectivement, les transformations dans l’espace en 2D et dans l’espace en 3D, avec comme contrainte, que lorsque l’une est définie, l’autre ne l’est pas.
En effet, un objet est soit dans l’espace 2D et utilise la propriété matrix (de la propriété transform) pour les transformations dans cet espace, soit dans l’espace 3D et utilise la propriété matrix3D. Du coup quand on est dans l’espace 2D la propriété matrix3D vaut « null » (alors que la propriété matrix est affectée) et quand on est dans l’espace 3D la propriété matrix vaut « null » (alors que la propriété matrix3D est affectée).
De plus, le passage de l’espace en deux dimensions à l’espace en trois dimensions se fait automatiquement en affectant une valeur à une propriété propre à la 3D.
Ainsi, il suffit de faire :
-
monDisplayObject.z = 0;
pour passer dans l’espace 3D.
Or, une fois dans cet espace, il n’y pas de manière de repasser dans l’espace 2D si ce n’est l’astuce de Jeanphi qui consiste à remettre la propriété « matrix3D » (de la propriété « transform » de l’objet) sur « null ». Ainsi, on sort de l’espace 3D pour revenir dans le 2D. Malheureusement, on perd aussi les propriétés 2D de l’objet ( x, y , scaleX, scaleY, rotation,…) qui sont toutes initialisées.
L’astuce que je propose, quant à moi, consiste à récupérer les propriétés relatives à la 2D dans la matrix3D pour les affecter à la propriété matrix. Et pour faire cela simplement, j’ai créé des petites fonctions que j’ai regroupées dans une classe nommée Matrix3DToMatrix, sous la forme de méthodes statiques.
L’utilisation est simple quand notre objet voit ses propriétés 3D initialisées on appelle la fonction :
-
Matrix3DToMatrix.reduceOn(monObjet);
qui réaffecte automatiquement les propriétés.
Ou
-
monObjet.transform.matrix = Matrix3DToMatrix.reduce(monObjet.transform.matrix3D);
Ou encore
-
monObjet.transform.matrix = Matrix3DToMatrix.reduceFromRaw(monObjet.transform.matrix3D.rawData);
À noter tout de même, que si l’objet a ses propriétés modifiées dans l’espace 3D (comme la rotationX ou la rotationY) la représentation isométrique de l’objet sera perdu.
Ça c’est pour la prochaine version (si tant est que ce soit possible ce qui n’est pas gagné ;)).
Pour intégrer ce code dans une classe qui ferait cela automatiquement on pourrait imaginer un override sur les propriétés 3D concernées comme ceci :
-
package {
-
import com.inkProd.maths.Matrix3DToMatrix;
-
import flash.display.Sprite;
-
-
public class SpriteAuto3DTo2D extends Sprite{
-
override public function set rotationX(value:Number):void {
-
super.rotationX = value;
-
_check3DTo2D();
-
}
-
-
override public function set rotationY(value:Number):void {
-
super.rotationY = value;
-
_check3DTo2D();
-
}
-
-
override public function set z(value:Number):void {
-
super.z = value;
-
_check3DTo2D();
-
}
-
-
public function SpriteAuto3DTo2D() {
-
// constructor code
-
}
-
-
protected function _check3DTo2D():void {
-
if ( rotationX%360 == 0 && rotationY%360 == 0 && z==0 ) {
-
Matrix3DToMatrix.reduceOn(this);
-
}
-
}
-
}
-
-
}
Voici les sources de la classe Matrix3DToMatrix
Et un exemple avec 2 images, Ã gauche un Sprite normal, Ã droite un SpriteAuto3DTo2D