I. Les différentes transformations▲
Les transformations vous permettent de réaliser divers effets sur vos objets, et en voici la liste : rotation, translation et zoom.
La rotation vous permet de faire tourner les points de votre objet autour de son centre, ou autour d'un point relatif à son centre, selon différents axes (x, y, z ou personnalisé).
La translation vous permet de décaler votre objet dans l'espace, par exemple pour le positionner. Vous pouvez donc déplacer votre objet dans les trois dimensions de l'espace.
Zoom ou scale en anglais, vous permet de faire un changement d'échelle sur votre objet. Par exemple vous aimeriez « déformer » verticalement votre objet, et bien alors vous n'avez qu'à tout simplement changer son scale sur l'axe Y pour soit l'aplatir, soit l'étirer.
II. Combiner des transformations▲
Maintenant que cela est dit, sachez que vous pouvez mélanger les transformations. Par cela, il faut comprendre que vous pouvez enchainer les transformations les unes aux autres.
L'ordre dans lequel vous appliquez les transformations est important !
Pour illustrer ce dernier commentaire, voici en image la différence obtenue entre faire une rotation puis une translation :
et faire une translation puis une rotation :
Comme vous le voyez, vous pouvez très facilement tomber sur un résultat différent de celui souhaité.
III. Exemple▲
Maintenant, cela bien expliqué, passons à notre petit exemple.
Nous partons toujours de notre cube, mais avec un habillage différent (histoire de vous montrer un autre skin) et un mode différent : Le mode QUAD.
III-A. Le mode Quad▲
Dans cet exemple, j'ai choisi de rajouter/d'exploiter un paramètre. Il s'agit du mode utilisé pour la détermination du nombre de points par faces. Deux modes sont disponibles, et ce sur la plupart des primitives ‘tri' (defaut) et 'quad'. Le premier met toujours trois points par face, alors que le second permet de mettre quatre points par faces (et plus encore si possible, cf. Cylindre). Nous pouvons gagner en performance avec le mode 'quad'. Mais attention le skin TextureSkin par exemple ne peut s'appliquer sur des primitives qui ne sont pas en mode 'tri'.
Veuillez vous référer à la documentation pour de plus amples détails.
III-B. Le code▲
Auparavant pour visualiser l'objet, nous reculions la caméra de sa position initiale afin de prendre assez de recul, et rendre ainsi l'objet visible. Maintenant nous allons avoir une approche différente, il s'agit de déplacer non plus la caméra, mais l'objet lui-même.
Ce morceau de code réalise une combinaison de deux transformations, il s'agit d'une rotation puis une translation.
Vous pourrez voir pour la première fois l'arborescence de la scène 3D de Sandy se mettre en place.
Cette construction de scène demande un peu d'efforts au niveau du code, les éléments peuvent sembler redondants et parfois inutiles, seulement lorsque vous avancerez dans des constructions de scènes plus complexes, vous verrez que cette méthode à un grand intérêt.
import
sandy.
core.
data
.*;
import
sandy.
core.
group.*;
import
sandy.
primitive.*;
import
sandy.
view.*;
import
sandy.
core.*;
import
sandy.
skin.*;
import
sandy.
util.*;
import
sandy.
core.
transform.*;
import
sandy.
events.*;
function
init
(
Void
):
Void
{
// nous créons notre écran. Élément primordial puisque c'est celui dans lequel les données seront affichées.
var
ecran:
ClipScreen =
new
ClipScreen
(
this
.
createEmptyMovieClip
(
'écran'
,
1
),
600
,
600
);
// nous créons notre camera. Le second paramètre est la distance nodale, qui donne donc l'effet
// de perspective aux objets affichés
var
cam:
Camera3D =
new
Camera3D
(
700
,
écran);
// nous ajoutons notre camera au monde 3D
World3D.
getInstance
(
).
addCamera
(
cam );
// nous créons notre Group qui servira de racine
var
bg:
Group =
new
Group
(
);
// et l'ajoutons au monde 3D. Par défaut le dernier branchGroup ajouté est celui qui est actif
// lors de la demande de rendu
World3D.
getInstance
(
).
setRootGroup
(
bg );
// nous lançons la création de la scène
createScene
(
bg );
// maintenant que tout est créé nous pouvons lancer le rendu du monde
World3D.
getInstance
(
).
render
(
);
}
function
createScene
(
bg:
Group ):
Void
{
// nous créons notre objet. Pour cela nous utilisons ici la primitive box.
// cela créé une boite qui, dans le cas où les dimensions de hauteur, profondeur, largeur, sont les mêmes
// génère un cube. Ici nous créons donc un cube de 50 pixels.
var
o:
Object3D =
new
Box
(
50
,
50
,
50
,
'quad'
);
// on créé un skin qui va permettre d'habiller un peu mieux notre objet 3D.
// ici le skin SimpleColor qui demande une couleur de remplissage, la valeur de l'alpha et l'épaisseur du trait.
var
skin:
Skin =
new
MixedSkin
(
0x00FF00,
100
,
0
,
100
);
// on applique le skin sur l'objet.
o.
setSkin
(
skin );
// Nous créons deux transform Group différents. Chacun correspondant à un noeud de la branche de transformations
// que nous voulons créer.
var
tg1:
TransformGroup =
new
TransformGroup
(
);
var
tg2:
TransformGroup =
new
TransformGroup
(
);
// Nous créerons de même deux instances de la classe Transform3D.
// Profitons-en d'ailleurs pour commencer à nommer nos variables correctement. Vous le verrez ceci
// deviens vite très important
var
translation:
Transform3D =
new
Transform3D
(
);
var
rotation:
Transform3D =
new
Transform3D
(
);
// translation de 500 pixels dans l'axe des Z.
translation.
translate
(
0
,
0
,
500
);
// Rotation de 30 degrés autour de l'axe défini par le vector 1, 1, 1
//(ce qui correspond à une rotation équivalente dans les trois dimensions)
rotation.
rotAxis
(
new
Vector
(
1
,
1
,
1
),
30
);
// Nous appliquons ces transformations aux noeuds
tg1.
setTransform
(
translation );
tg2.
setTransform
(
rotation );
// nous ajoutons notre objet comme enfant du noeud correspondant à la rotation.
// l'opération de rotation lui sera donc appliquée avant celle de translation
tg2.
addChild
(
o );
// Maintenant nous relions nos deux noeuds, en mettant la translation en opération parent à celle de rotation.
// Cet ordre est très important selon le résultat voulu !
tg1.
addChild
(
tg2 );
// nous ajoutons le transformGroup comme fils du BranchGroup afin de créer l'arborescence
//et rendre l'objet affichable.
bg.
addChild
(
tg1 );
}
// Nous lançons la création du monde 3D
init
(
);