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 autours de son centre, ou autours 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 deplacer votre objet dans les 3 dimensions de l'espace.

Zoom ou scale en anglais, vous permet de faire un changement d'echelle 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'applatir, 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 une 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 :

Image non disponible
Rotation puis Translation

et faire une translation puis une rotation :

Image non disponible
Translation puis 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 4 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 camera 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 élements 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 interêt.

 
Sélectionnez

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 ecran. Element primordial puisque c'est celui dans lequel les données seront affichées.
	var ecran:ClipScreen = new ClipScreen( this.createEmptyMovieClip('ecran', 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, ecran);
	// 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 creation de la scene
	createScene( bg );
	// maintenant que tout est créé nous pouvons lancer le rencu 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  les dimensions d'hauteur, profondeur, largeur, sont les memes
	// genè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 replissage, 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 creer.
	var tg1:TransformGroup = new TransformGroup();
	var tg2:TransformGroup = new TransformGroup();
	// Nous créeons 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 autours de l'axe defini par le vector 1, 1, 1 
	//(ce qui correspond à une rotation équivalente dans les 3 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 imporant selon le résultat voulu!
	tg1.addChild( tg2 );
	// nous ajoutons le transformGroup comme filds du BranchGroup afin de créer l'arborescence 
	//et rendre l'object affichable.
	bg.addChild( tg1 );
}
// Nous lançons la création du monde 3D
init();

III-C. Le rendu



III-D. Les sources