Tutoriel: premiers pas 3D avec x3dom

Première chose : le navigateur

Je fais mes tests avec Chrome DevChannel sous Windows.

Il se télécharge ici: http://www.google.com/chrome/eula.html?extra=devchannel

Après l’avoir installé, il faut éditer l’icône de lancement : faites un clic-droit sur l’icône Chrome dans votre menu Démarrer et éditez les Propriétés en ajoutant « –enable-webgl –no-sandbox » à la fin de la partie « Cible » (après « chrome.exe »).

Puis (re)démarrez Chrome.

Pour les autres OS/navigateurs, voir sur la pge de X3dom dédiée: http://www.x3dom.org/?page_id=9.

Pour les malheureux utilisateurs de Mac (en ce moment je suis un peu remonté contre Apple) sachez qu’il faut du Mac OS X 10.5 ou + sinon vous l’avez dans l’os.

Ensuite, le fichier js

Créez un répertoire pour vos tests (par exemple « \testx3dom »).

Le fichier js est ici: http://x3dom.org/x3dom/example/x3dom.js

Enregistrez-le dans votre répertoire de test, ne pointez pas directement dessus dans vos fichiers sources, c’est impoli.

Et puis créez le fichier html.

Avec votre éditeur html préféré, créez un fichier « hello3d.html » dont la source sera:

<html>
<head>
<script type= »text/javascript » src= »x3dom.js »></script>
</head>
<body>
</body>
</html>

C’est la base.

Créez la fenêtre x3d

A l’intérieur du body, il faut déclarer la fenêtre x3d:

<x3d>
<scene>
</scene>
</x3d>

En rechargeant la page, vous devriez avoir un rectangle noir qui est la fenêtre x3d. Si vous ne le voyez pas, c’est probablement un soucis entre le navigateur et WebGL (J’insiste, tout ceci est testé sur Windows + ChromeDevChannel).

Cette déclaration, même si elle fait bien apparaître quelque chose, est loin d’être parfaite et la balise x3d contient normalement plusieurs attributs dont l’utilité est dans le nom. Voici la balise un peu plus correctement déclarée:

<x3d xmlns= »http://www.web3d.org/specifications/x3d-namespace » showStat= »false » showLog= »false » width= »1000px » height= »700px » altImg= » »>
  • altimg défini une image par défaut si le navigateur n’utilise pas WebGL,
  • showStat et showLog, s’ils sont à « true » font apparaître quelques infos d’aide au codage,
  • width et height définisse largeur et hauteur de la fenêtre x3d.

C’est à l’intérieur de <scene></scene> qu’on va commencer à créer nos premiers machins 3D.

Le premier machin 3D

Un cube. La forme de base qui permet de voir tout de suite si ça marche.

<shape>
<box></box>
</shape>

Tout simplement.

En rechargeant la page, vous devriez voir un carré au milieu et en cliquant dans la scène, vous pouvez le faire tourner.

Le code complet de la page doit maintenant ressembler à ceci:

<html>
<head>
<script type= »text/javascript » src= »x3dom.js »></script>
</head>
<body>
<x3d xmlns= »http://www.web3d.org/specifications/x3d-namespace » showStat= »false » showLog= »false » width= »800px » height= »400px » altImg= » »>
<scene>
<shape>
<box></box>
</shape>
</scene>
</x3d>
</body>
</html>

Amusant mais un peu pauvre, on ne va pas passer des heures à faire tourner des cubes dans le vide.

Un mot sur la navigation

  • Clic-gauche en laissant appuyé permet de faire tourner la scène.
  • Clic-droit en laissant appuyé permet d’avancer ou reculer la caméra.
  • La touche « a » permet de positionner la caméra sur un plan d’ensemble assez large englobant tous les objets de la scène. Très utile si vous ne savez plus où vous êtes.

Les formes de base

Remplacez <box></box> par <sphere></sphere> et un globe apparaîtra à la place du cube.

Les formes de base:

  • box
  • sphere
  • cylinder
  • cone
  • torus

Toutes ces formes ont des attributs permettant d’ajuster la taille et l’affichage des faces. Par exemple :

<box size= »2 .5 1″></box>

Il y a deux nouvelles notions dans cette balise:

  • les données x y z : dans notre environnement 3D, tout est référencé par ces coordonnées. Ici, ces données sont un attribut unique de la balise <box> et sont donc entre guillemets. Elles représentent largeur, hauteur et profondeur. Elles sont séparées par un espace.
  • « .5 » est comme « 0.5 » inutile d’écrire le zéro.

Pour le cylindre, on doit attribuer d’autres données:

<cylinder radius= »2″ height= ».5″></cylinder>

Voici une page avec les références complètes de tous les attributs de toutes les formes:

http://www.web3d.org/x3d/content/X3dTooltips.html

Notez bien que x3dom est en cours de développement et que beaucoup de choses n’ont pas encore été implémentées ! Par exemple si vous mettez :

<cylinder top= »false »></cylinder>

Le haut du cylindre devrait disparaître (utile pour économiser de la ressource de calcul si cette face ne doit jamais apparaître), mais à ce jour cela ne fonctionne pas encore.

Un peu de couleur

Le gris par défaut est un peu tristoune, changeons donc la couleur de notre cylindre.

Modifiez le code:

<shape>
<cylinder radius= »2″ height= ».5″></cylinder></shape>

Par:

<shape><appearance>

<material diffusecolor= ».9 .1 .1″></material>

</appearance>

<cylinder radius= »2″ height= ».5″></cylinder>

</shape>

Vous devriez après rechargement voir apparaître votre cylindre en rouge. L’attribut « diffusecolor » définit les couleurs rouge-vert-bleu, avec des valeurs comprises entre 0 et 1, et séparées par un espace.

Cet attribut appartient à l’élément « material » qui lui-même appartient à l’élément « appearance ». « appearance » peut également contenir un élément essentiel au look de vos objets: la texture. Collons donc une photo sur un cube (ça sera plus joli que sur un cylindre).

<shape><appearance>

<material diffusecolor= ».9 .1 .1″></material>

<imagetexture url= »http://lh6.ggpht.com/_opMtHwffI3M/Svf9kd91XCI/AAAAAAAAACc/SJs90lWQxtI/DSC_0084.JPG »></imagetexture>

</appearance>

<box></box>

</shape>

Un sympathique phoque australien recouvre maintenant les six faces de notre cube. Pour bien faire, une image carrée eu été plus adaptée.

Positionner dans l’espace

Pour l’instant, nous nous sommes contenté d’un seul objet à l’écran. Il est temps de faire les choses en un peu plus grand.

Notre élément « shape » est pour l’instant directement attaché à la racine de la scène. Nous allons créer un élément intermédiaire qui nous permettra de le positionner dans l’espace à l’endroit de notre choix. C’est l’élément « transform » qui se charge de cela.

« transform » doit contenir « shape » comme ceci:

<transform><shape>

</shape>

</transform>

« transform » a plusieurs attributs permettant de modifier (entre autres) la position et l’orientation de ce qu’il contient.

L’attribut de position s’appelle « translation » avec toujours les coordonnées x, y et z entre guillemets, séparées par un espace. Déplaçons notre cube un peu à gauche:

<scene><transform translation= »-2 0 0″>

<shape>

<appearance>

<imagetexture url= »http://lh6.ggpht.com/_opMtHwffI3M/Svf9kd91XCI/AAAAAAAAACc/SJs90lWQxtI/DSC_0084.JPG »></imagetexture>

</appearance>

<box></box>

</shape>

</transform>

</scene>

En rechargeant la page, le cube apparaît plus à gauche que précédemment. Nous allons pouvoir créer plusieurs objets et les placer à divers endroits. Nous sommes débutants et donc un copier-coller avec changement de quelques paramètres suffira bien pour l’instant (plus tard il sera possible de concaténer ce bazar pour un code plus maigre).

<scene><transform translation= »-2 0 0″>

<shape>

<appearance>

<imagetexture url= »http://lh6.ggpht.com/_opMtHwffI3M/Svf9kd91XCI/AAAAAAAAACc/SJs90lWQxtI/DSC_0084.JPG »></imagetexture>

</appearance>

<box></box>

</shape>

</transform>

<transform translation= »2 0 0″>

<shape>

<appearance>

<imagetexture url= »http://lh5.ggpht.com/_opMtHwffI3M/Svf9ki1v1OI/AAAAAAAAACo/AzM_Fq3rlFE/s144/DSC_0231.JPG »></imagetexture>

</appearance>

<box></box>

</shape>

</transform>

</scene>

Voilà deux cubes côte-à-côte ayant des textures différentes.


Arbres d’éléments

L’élément « transform » peut contenir d’autres éléments « transform » ce qui est très pratique pour manipuler plusieurs objets à la fois. Appliquons une rotation au cube de droite, pour l’orienter différemment de son voisin. L’attribut « orientation » de « transform » sert à ça:

<transform orientation= »0 1 0 -1″>

</transform>

Cet attribut contient 4 données : les 3 axes, et une valeur d’angle. Le « 0 1 0 » signifie que la rotation va se faire autour de l’axe « y ». La valeur de l’angle est en radians, donc pour un demi-tour ça serait 3.14 (environ pi).

Imbriquons notre deuxième cube dans ce nouvel élément transform, lui-même dans le « transform » qui définissait sa position.

<scene><transform translation= »-2 0 0″>

<shape>

<appearance>

<imagetexture url= »http://lh6.ggpht.com/_opMtHwffI3M/Svf9kd91XCI/AAAAAAAAACc/SJs90lWQxtI/DSC_0084.JPG »></imagetexture>

</appearance>

<box></box>

</shape>

</transform>

<transform translation= »2 0 0″>

<transform rotation= »0 1 0 -1″>

<shape>

<appearance>

<imagetexture url= »http://lh5.ggpht.com/_opMtHwffI3M/Svf9ki1v1OI/AAAAAAAAACo/AzM_Fq3rlFE/s144/DSC_0231.JPG »></imagetexture>

</appearance>

<box></box>

</shape>

</transform>

</transform>

</scene>

Et voilà.

Nous savons comment créer des formes, leur appliquer des textures, les positionner et les orienter dans l’espace. Il est possible de définir les valeurs de plusieurs attributs dans « transform » mais je le déconseille car les résultats sont un peu périlleux…

Et maintenant, un peu de javascript
Jusqu’ici, rien de fondamentalement nouveau pour ceux qui avaient l’habitude de x3d avec un plugin à l’ancienne.
La grande nouveauté avec x3dom est la facilité de brancher des commandes javascript là dessus.
Reprenons notre cube de base pour la simplicité du code et ajoutons une petite touche d’interactivité avec un petit onClick-alert…
<shape>
<box onClick=’alert(« touché ! »);’></box>
</shape>
Voici votre cube devenu interactif avec votre document !
Pas très utile en soi mais c’est une étape pour la suite…
Il est possible de donner un Id aux objets x3d. Ces objets deviennent ainsi des enfants de l’objet « document » et donc accessibles par javascript.
Créons une fonction qui change la couleur de notre cube. Dans le header de votre fichier html, il faut rajouter:
<script type= »text/javascript »>
function turnToGreen(materialId) {
var m = document.getElementById(materialId) ;
m.setAttribute(« diffuseColor », »0 1 0″);
}
</script>
La fonction récupère un id en paramètre. Cet Id doit être celui d’un élément « material » défini dans la scene x3d. Il faut donc un peu modifier notre cube comme ceci:
<shape>
<appearance>
<material id= »myColor » diffusecolor= »1 0 0″></material>
</appearance>
<box onClick=’turnToGreen(« myColor »);’></box>
</shape>
Pour que l’action onClick appelle la fonction javascript « turnToGreen » avec l’identifiant de l’élément material de notre cube.
Notez que dans la fonction setAttribute, l’attribut est « diffuseColor » avec un C majuscule. A l’avenir x3dom devrait comprendre le tout minuscule (pour linstant les specs HTML5 et xHTML se téléscopent un peu sur ce projet).
Vous connaissez désormais les bases pour utiliser x3d et javascript grâce à x3dom. Pour la création à la volée d’objets x3d, il faudra utiliser document.createElement(« shape ») par exemple.
Pour aller plus loin:
Si vous avez lu jusque là, bravo pour votre ténacité ! Vous êtes un sacré passionné 🙂

5 réflexions au sujet de « Tutoriel: premiers pas 3D avec x3dom »

  1. ok, ca m’interesse, j’ai lu, c’est « so easy » mais c’est pour l’instant compatible avec aucun browser si j’ai bien compris.., sauf des versions speciales, beta ou machin truc… donc pour l’instant ca ne me motive pas plus que ca…

    à quand l’integration native ( sans attendre de l’utilisateur lambda qu’il telecharge le plugins bidule, configure la fenetre machin , etc…) dans les pricipaux browsers??

  2. je relisais le billet precedent…

    et donc, c’est pour quand html 5 grand chef ?

  3. J’avoue que y a pas de date hélas 🙁
    Il semble Firefox 3.7 alpha l’utilise actuellement en natif, mais de là à ce que ça soit dans la version finale, ça ne me semble pas sûr.

    En tous cas dès que j’en sais plus je posterai ça ici !

  4. enfin y a pas de date pour la 3D je voulais dire, parce que sinon html5, c’est déjà là, d’ailleurs ce blog est en html5 (pas très stricte, mais presque 😛 )

  5. Bonjour,

    C’est juste pour prévenir que pour la section du transform, un demi-tours correspondrai plutôt à 3.14 / 2, car 3.14 en radian représente un tours complet sur le repère trigonométrique 😉

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *