Modélisation 3D avec le langage VRML

Ph. Dondon © Copyright  Enseirb-Matmeca  2012

 

Avertissement 1 : Cette documentation n’est pas un cours de langage VRML comme les autres. Il existe en effet de nombreux et excellents site WEB décrivant les instructions et leur syntaxe. Il est donc inutile de refaire ce qui existe déjà…

 

Par contre, dans la même optique que ma page «  électronique avec les mains »,  vous trouverez sur cette page des explications en langage de tous les jours, permettant de comprendre ce qui, en première lecture pour un non initié aux langages informatiques, apparait comme un verbiage ésotérique.

 

Pour les électroniciens en particulier, vous trouverez un comparatif  monde de la CAO électronique - monde VRML qui, je l’espère, aidera à démarrer.  Plusieurs exemples sont fournis pour illustrer les propos. Que les puristes me pardonnent si le vocabulaire utilisé n'est pas juste sur le plan informatique. Notre culture d'électronicien nécessite quelques adaptations pour la compréhension des concepts élémentaires.

 

 Avertissement 2 :

 

La mise au point de cette documentation a demandé de nombreuses heures de travail et d’essai. Si vous utilisez tout ou partie de son contenu, merci d’avertir l’auteur au moins par courtoisie, et de citer la source.


 



1. Introduction

 

Le "Virtual Reality Modelling language" a été inventé vers les années 1995 pour permettre le dessin en 3 dimensions et l'animation d'objets quelconques. Le VRML est à la base de modules graphiques implantés dans des logiciels aussi connus que BLENDER ou MATLAB/SIMULINK pour visualiser le déplacement d'un objet en 3D, trajectoire obtenue préalablement par simulation.

Aujourd'hui le VRML est considéré par certains comme obsolète, désuet et en tout cas largement dépassé (cf. § 2). Certes, il y a mieux depuis pour dessiner les objets; les interfaces graphiques ayant fait beaucoup de progrès.

Cependant, VRML est un langage dont l'immense avantage est d'être gratuit et donc utilisable par tous même ceux qui ont peu de moyens. En cela, c'est un outil "développement durable".

Son inconvénient est d'être un langage d'informaticien, avec son vocabulaire d'informaticien, que seuls les adeptes de JAVA et autre comprennent facilement et rapidement.

Pour utiliser VRML, lorsque que l'on a n'a pas la culture informaticienne, il est d'abord nécessaire de se familiariser avec le concept puis d'expérimenter grâce à de nombreux exemples que l'on trouve sur le WEB.

Voici donc ci-après quelques informations utiles pour réaliser quelques modestes animations.

 

2. Comprendre la philosophie de VRML par analogie avec la CAO électronique:

Les sites WEB et ouvrage sur le VRML sont nombreux  et facilement compréhensibles pour qui a déjà les pré-requis en langage informatique orienté objet avec son vocabulaire spécifique. Cependant,  un parallèle  Electronique -VRML est intéressant pour aider à comprendre certains concepts par transposition d’un domaine à l’autre.

  

CAO Electronique

VRML

Conception et simulation d’un circuit électronique

Conception et animation d’un objet  quelconque (maison, pièce mécanique, paysage…) en 3D

Composants élémentaires :

R (résistance), L (inductance), C (condensateur),

T (transistor)

Composants élémentaires :

Boite, Cylindre, Cône, Sphère

Modèle SPICE d’un composant

(Courant de fuite, capacité parasite, coef. de température etc.)

Attributs de la forme élémentaire

(Couleur, intensité lumineuse, texture, transparence…)

Nommer (instancier) un composant R1, C16, etc.

Nommer un objet élémentaire

(DEF…USE)

Description en fichier texte du circuit

 (association de plusieurs composants)

Netlist SPICE  *.cir

Description de l’objet animé en fichier texte

Association des formes élémentaires

fichier*.wrl

Point de polarisation (ou de repos)  V, I, 

Positionnement initial des formes élémentaires

(Instructions Transform, translation, rotation)

Schéma hiérarchisé : Pour des schémas complexes,

Un fichier *.cir peut incorporer plusieurs  sous circuits. Chacun étant lui-même décrit par un fichier *.cir faisant appel à des modèles de composants

Scénario  hiérarchisé : Pour représenter une scène  complexe (paysage incluant plusieurs villages incluant chacun plusieurs maisons, incluant chacune  du mobilier...), un fichier *.wrl  peut incorporer plusieurs  sous fichier *.wrl à la manière de poupées russes  emboitées

Simulation SPICE  “transient”

.TRAN to, tmax , tstep

Animation  temporelle des objets dessinés

(interpolator ou java script)

Fenêtre de visualisation des résultats de simulation

(courbes)

Visualisation des mouvements avec un « plug in »

(Cosmoplayer par exemple)

Logiciel Interface saisie ou capture de schéma

(ORCAD, EAGLE, PROTEUS etc.)

Tout logiciel  de dessin  3D

(Blender Autocad, Solid works etc.)

 

Communication entre SPICE et  VRML ! (très fort… et très utile…)

 

Les résultats d’une simulation « transient » SPICE sont disponibles sous forme d’un tableau de valeur  contenant pour chaque instant « t » de la simulation temporelle,  la valeur des nœuds du circuit (tension et courant)  (ATTENTION : rien à voir avec les « nœuds » VRML). Elles sont stockés  dans un fichier  *.dat,  récupérable pour intégration (après reformatage) dans l’instruction  « interpolator » d’un fichier  VRML. On peut ainsi réaliser une animation représentant un phénomène simulé préalablement en SPICE.   (Pour un exemple très réaliste, cliquer ici)

 

Nota : La même chose est possible à partir d’EXCEL ou MATLAB/ SIMULINK avec son module interface graphique (payant)

 

question : Alors le VRML est- il dépassé, obsolète ?  

 

A la lumière du paragraphe précédent, on peut préciser maintenant ce qui a été rapidement évoqué dans l’introduction :

Dépassé ? En un sens, certes oui… car utiliser le VRML aujourd’hui pour rivaliser avec l’esthétique, la finesse, le réalisme stupéfiant des jeux vidéos actuels serait comme vouloir créer un circuit complexe de 100 000 transistors en le décrivant ligne par ligne dans un fichier *.cir : Autant dire quasiment impossible.

Alors il faut donc chercher les intérêts du VRML ailleurs:

1° Connaitre l’évolution des outils que l’Homme utilise depuis des milliers d’années, présente un intérêt culturel et historique (au sens Histoire de la Science). En effet, sans cette connaissance,  comprendre et utiliser habilement les outils modernes n’est pas toujours simple. Par exemple, utiliser un simulateur électronique moderne  (simple click sur un bouton pour lancer la simulation) sans savoir comment cela se passe « derrière », sans connaitre ni la signification de certains paramètres, ni la philosophie générale de l’outil peut conduire à des erreurs  ou des disfonctionnements, comme l’usage d’un mot de notre langue sans en connaitre ses racines, peut conduire un contre sens dont on mesure les conséquences parfois à ses dépends. Il en est de même du paysan qui connait l’usage de la pioche, du soc : il utilisera son tracteur intelligemment. 

2° En raison de sa rusticité (seulement 4 formes de base possibles), le VRML est un excellent stimulateur de créativité et d’imagination. Car comment  dessiner une pièce mécanique, un bâtiment, un avion, un paysage, un objet de la vie courante, avec une bibliothèque de formes aussi réduite ? De plus, la description sous forme de ligne de texte oblige le cerveau à se représenter spatialement l’objet et sa position avant même sa construction. En cela, c’est un « remue méninge » qui nous rapproche de ce que nos anciens appelaient « géométrie descriptive », avec l’étude de courbes  et de surfaces mais aussi de leur intersection dans l’espace.

3° Le VRML permet aussi de s’intéresser, sur le plan culture générale, à la gestion des couleurs : en cela, on aborde les arts graphiques et les notions d’optique élémentaire, de couleurs primaires,  l’obtention des couleurs par synthèse additive et soustractive,  la télévision et restitution des couleurs sur les tubes cathodiques et maintenant écran a LED. Bref, Une occasion de stimuler la curiosité  pour de nombreux domaines scientifiques connexes.

4° Animer des objets ou une scène en VRML ne relève pas de la technique cinématographique : juxtaposition et enchainement d’une succession d’images arrêtées. Il s’agit de décrire un mouvement sous forme  équations mathématiques. Ainsi, utiliser VRML permet de mettre en application de nombreuses notions mathématiques (changement de repère, translation, rotation, fonction mathématiques classiques, trigonométrie etc.) et de lois de physique élémentaire (cinématique du point, équilibre d’un solide en translation en rotation, etc.) enseignées au lycée et après.  Une représentation concrète et visuelle de phénomènes physique et de des équations qui les régissent  peut constituer une aide appréciable sur un plan pédagogique.

5° Sans oublier un argument de poids : VRML est gratuit.
Bref, à condition de ne pas utiliser VRML pour vouloir créer un jeu vidéo sophistiqué avec un graphisme hyperréaliste ou un film d’animation,  on peut s’initier, s’amuser ou travailler sérieusement, visualiser des résultats de simulation complexe SPICE ou MATLAB autrement que par des courbes statiques.  Alors, si vous êtes intéressé,  lisez la suite, sans oublier les limites, mais aussi en prenant conscience de possibilités de VRML. Bonne lecturex …

 

3. Avant de commencer un dessin…

 

Il importe, au moment de la création du dessin, de bien comprendre l'orientation initiale des objets, d'identifier les coordonnées X, Y, Z de chacun, de les regrouper et les hiérarchiser correctement pour éviter la duplication de descriptions et prévoir les mouvements et animation futures.

Avant de démarrer un dessin, on pourra donc par exemple "poser" une boite parallélépipédique (Box) de dimensions L, l, p. En étirant successivement une de ses dimensions, on déterminera les axes X, Y, Z. Ensuite, en faisant une translation sur chaque axe, on déterminera les orientations respectives de chacun. Enfin, en faisant une rotation autour de chacun des trois axes, on trouvera l'origine et l'orientation des angles donnés en radians. Et l’on peut se dessiner « dans un coin »  un repère orthonormé orienté (cylindre étiré pour l’axe + cône pour la flèche), pour faciliter la vision dans l’espace…

 

Nota : Les unités sur les axes sont arbitraires (sans dimension) et les angles sont donnés en radians. 

 

4. Pour bien démarrer  

Avant de démarrer un dessin, et créer des fichiers VRML aussi structurés et lisibles que possible,  il est nécessaire d’avoir réfléchi au préalable à l’organisation général du scénario et de la hiérarchie que l’on veut établir.

4.1 Structure et organisation d’un fichier élémentaire  *.vrml

Un fichier VRML texte peut s’éditer avec un éditeur de texte basique. Un fichier type contient un entête (commentaires de l’auteur en général), un bloc de description  contenant un ou plusieurs objets élémentaires  un bloc réalisant l’animation des objets décrit ci avant, une fin de fichier.
 

Figure 1 : structure fichier VRML

4.2 Organisation hiérarchique

Prévoir une conception hiérarchique et modulaire dés le départ aide à la clarté et la compréhension de la description. Comme indiqué sur  l’exemple en figure 2, on réalise ici un paysage qui inclut divers éléments dont une maison et un château qui font appel au même mobilier.

 

Figure 2: structure hiérarchique VRML

 

L’inclusion du fichier maison.wrl dans paysage.wrl se fait en ajoutant les lignes suivantes :

 

#VRML V2.0 utf8

# --------------------fichier Paysage.wrl -----

#--- inclusion maison

Transform {

            scale 3 3 3

            rotation 0 1 0 1.57

            translation -240 5 900

           

            children [

            Inline {

                  url "maison.wrl" } ]

}

 

A l’i mage des fameuses  poupées russes, on peut imbriquer autant de niveaux( ou presque)  que l’on souhaite.

 

4.2 Petits détails de langage VRML

Attention : lorsque l’on écrit,  il faut respecter la casse (majuscule /minuscule) des caractères et faire très attention aux crochets, parenthèses et accolades imbriquées….

 

4.3 Gestion des couleurs

Il est utile de comprendre comment sont gérer les couleurs des objets dessinés : la couleur d'un objet est composé des trois couleurs de base: rouge, vert, bleu (R, V, B). Le dosage de chaque couleur est représenté par un chiffre compris entre 0 et 1. Le tableau ci-dessous montre la composition de quelques couleurs usuelles. A chaque objet dessiné on associera donc une couleur sous la forme d'un triplet R,V, B.

 

Couleur

Rouge

Vert

Bleu

argent

0.75

0.75

0.75

blanc

1

1

1

bleu foncé

0

0

0.5

Gris

0.5

0.5

0.5

Jaune

1

1

0

Noir

0

0

0

Marron

0.5

0

0

Figure 3 : couleurs

4.3 Gestion de la position d’un objet dans l’espace

La position d’un objet est donnée sous forme d’un triplet de valeur x, y , z :

 translation 0 -10 -15

 

L’orientation d’un objet est donnée sous forme de quatre valeurs  « axe x, axe y, axe z,  angle », par exemple :

rotation  0 1 0 1.57

Signifie une rotation de 1.57 radians autour de l’axe y.

rotation  1 0 0  0.5

Signifie une rotation de 0.5 radians autour de l’axe x.

 

4.4 Notion  « d’enfant » en langage VRML

Une notion de base est celle « d’enfant » (children). A l’image d’une famille, la description  adopte une structure hiérarchique et imbriquée.

Un « enfant » élémentaire est muni d’une forme (Shape), et d’attribut  couleur, transparence etc. On lui adjoint « un point de repos » (translation et rotation initial dans le repère 3D précedemment  expliqué).

Et l’on  nomme l’enfant (muni de ses propriétés)  ici « enfant1 »

DEF enfant1

            Transform {

            translation 0 -10 -15

            children [

            Shape {

            geometry Cylinder {radius 5 height 5

            }

            appearance Appearance {

            material Material {

            ambientIntensity 0.6

            diffuseColor 0.6 0.2 0.2}

            }

            }

            ]}

 

Un ou plusieurs enfants peuvent être rattachés à un même  parent,  lui-même muni de son « point de repos »

 

DEF PARENT

Transform {

rotation 0 1 0 1.57

translation 0 0 160

children [

DEF enfant1

            Transform {

            translation 0 -10 -15

            children [

            Shape {

            geometry Cylinder {radius 5 height 5

            }

            appearance Appearance {

            material Material {

            ambientIntensity 0.6

            diffuseColor 0.6 0.2 0.2}

            }

            }

            ]}

]}

 

A l’image d’un arbre généalogique, on peut créer plusieurs niveaux en « emboitant » plusieurs « enfants ».

 question : Quel est l’intérêt de cette organisation « familiale »?  

Lorsque l’on va animer les objets dans la scène, l’enfant pourra avoir son propre mouvement  individuel  (en faisant évoluer sa position initiale par programmation javascript), et être affecter globalement par  mouvement du parent. A l’image d’un enfant remuant sur le siège arrière d’une voiture, animée d’un mouvement de translation généré par le conducteur (le parent).Dès lors, on comprend la puissance de cette programmation, pour définir des mouvements complexes.

5. Créer un dessin

5.1 Gestion du fond  et mise en scène

La mise en scène peut être assez sophistiquée. Mais la plupart du temps, on peut se limiter à définir une couleur (avec un dégradé) pour le fond du ciel et une couleur de sol. Puis, on définit un éclairage ambiant et un point de vue (comme si on plaçait une caméra) pour observer la scène.


Figure 4 : définition du « background » et du lieu initial de visualisation

Par exemple, pour définir un ciel bleu dégradé, qu'il faut imaginer comme un "sky dome" au dessus de la scène à réaliser, on définit 4 secteurs de couleur bleue différente et 3 angles (cf. figure 4) :

 

DEF fondciel Background {

skyAngle [ 0.8, 1.4, 1.6 ]

 # 3 angles comme montré en figure 2

skyColor [ 0.1 0.1 0.3, 0.2 0.2 0.4, 0.5 0.5 0.8, 0.7 0.7 0.9 ]}

 # 4 secteurs formant un dégradé de bleu dans le ciel

 

Puis un (ou plusieurs points de vue) nommé SURVOL : avec les coordonnées x, y, z de la caméra et un angle de vue (ici vue légèrement plongeante).  

 

DEF SURVOL Viewpoint {

 #definition d'un point de vue initial de la scène accessible par le bouton en bas a gouche

      position 0 100 400

            orientation 1 0 0 -0.15

            description "survol"}

 

Nota : Avec le plug-in  « Cosmoplayer », les différents points de vue sont accessibles par le bouton situé en bas a gauche de la fenêtre.

 

Puis un éclairage ambiant omni directionnel dont on règle l’intensité et la couleur :

 

 #definition d’un éclairage ambiant

      PointLight {

      ambientIntensity 1

            color 0.7 0.7 0.7}

 

question : Hormis la clarté  de la programmation, quel est l’intérêt d’une organisation hiérarchique  des fichiers notamment vis-à-vis des points de vue sur la scène ?  

Supposons un viewpoint  défini dans un sous fichier *.wrl. Celui-ci est inclus dans un fichier de plus haut niveau. De fait, ce viewpoint  devient  accessible dans la liste des points de vue au plus haut niveau hiérarchique :

On peut donc zoomer (ou se déplacer) sur des détails ou des objets de la scène globale, en cliquant sur le bouton liste des points de vue.

De plus, si l’on anime l’objet préalablement conçu dans ce sous fichier*.wrl, le viewpoint rattaché à cet objet et situé à l’intérieur de cet objet, est affecté du même mouvement : Telle une caméra embarquée, on suivra donc l’objet en mouvement comme dans les jeux vidéo où  « l’on suit et l’on voit » de l’intérieur la voiture ou l’avion que l’on pilote comme avec le bon vieux « Flight simulator ».   Pour « sortir » de l’objet et le visualiser de l’extérieur et le suivre, il faut modifier ce point de vue en temps réel avec les boutons zoom et rotation.

 

5.3 Dessin des objets

Nous donnons ci -après trois exemples : un bateau, une maison et un paysage.

5.3.1 Le bateau

Figure 5: Bateau

En vue de son animation, le bateau a été réalisé en utilisant la structure « familiale ». Le « parent bateau » a plusieurs enfants nommé « coque » « proue » « antenne », « containers » « bastingage »  etc. Le radar pourra ainsi par exemple tourner sur lui-même, pendant que le bateau, dans son ensemble, subit un mouvement de roulis et une translation  sur la rivière.

5.3.2 La maison

Le 2ème exemple montre une maison dont on a enlevé le toit… L’aménagement intérieur (mobilier)  a été décrit dans un fichier inclus dans un fichier maison de niveau hiérarchique supérieur. Le « canapé » et la « table »  (sortes d’éléments en bibliothèque) peuvent  donc être utilisés plusieurs fois dans la même maison ou dans une autre habitation.

Les façades de la maison sont habillées d’une texture pour plus de réalisme.

Pour réaliser cette texture, nous avons photographié le modèle original de la maison sous ses quatre faces (cf. Projet développement durable) puis  « découpé » les photos pour extraire uniquement la vue de chaque façade. Ces photos, sauvées dans le même répertoire que le programme VRML, sont ensuite plaquées sur des  « box » représentant les murs en ajoutant l’instruction :

texture ImageTexture {url "facade.jpg"}Avec la même stratégie, nous avons accroché un poster décoratif sur le mur intérieur (Pour info: photo perso de voyage en  2011 « delicate arch » UTAH  … souvenir grandiose, fin de parenthèse)Nota : Si  l’image de texture n’est pas dans le même répertoire que le fichier il faut donner le chemin complet dans l’URL.

Figure 6: Maison

5.3.3 Paysage

Le 3ème exemple montre un paysage de montagne avec rivière et barrage.  La maison et le bateau précédemment dessinés peuvent y être intégrés après mise à l’échelle (scale)  et positionnement (translation, rotation). 

 

La réalisation de paysage fait appel à une forme géométrique particulière «  ElevationGrid ». La surface plus ou moins ondulée et accidentée est représentée de façon matricielle.

On donne un nombre de points et un espacement entre points selon les axes X et Z et pour chaque point du tableau  son « altitude » Y.

 


Figure 7: Surface accidentée (attention : vue d’artiste ;  graduations d’axe VRML non respectées)

 

Dans l’exemple ci après, on  réalise les  rochers gris du décor, selon cette méthode (matrice de 15 par 15), en appliquant en plus une texture rocheuse (une image rock012.jpg stockée dans le même répertoire que le fichier VRML) pour   plus de réalisme.

### rochers

             Transform {

            scale 5 100 4

            translation 0 -5 300

            children [

                Shape {

                    appearance Appearance {

                        texture ImageTexture {url "rock012.jpg"}

                        material Material {

                          ambientIntensity 0.1

Z

 
                       diffuseColor 0.3 0.3  0.3}

                    }

                    geometry ElevationGrid {   #forme avec grille 

                          solid FALSE            #

                        creaseAngle 0.3        #angle d'eclairage

                        xDimension 15          #nombre de coords X

                        xSpacing 20             #distance entre les coords X

                        zDimension 15

                        zSpacing 20

                        height [               #coordonnes y

                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

                            0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

                            0, 0, 3, 4, 4, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0,

                            0, 0, 0, 5, 5, 4, 4, 4, 5, 5, 0, 0, 0, 0, 0,

                            0, 0, 4, 5, 5, 5, 5, 5, 5, 5, 4, 0, 0, 0, 0,

                            0, 0, 5, 6, 6, 6, 5, 5, 5, 5, 5, 4, 0, 0, 0,

                            0, 0, 4, 6, 6, 6, 5, 5, 5, 5, 5, 5, 2, 0, 0,

                            0, 0, 0, 5, 5, 5, 5, 5, 5, 0, 4, 5, 3, 0, 0,

                            0, 0, 0, 3, 5, 5, 5, 4, 5, 3, 0, 4, 2, 0, 0,

                            0, 0, 0, 4, 5, 5, 5, 5, 5, 4, 0, 0, 2, 0, 0,

 0, 0, 0, 4, 5, 4, 5, 5, 5, 2, 0, 0, 0, 0, 0,          

                           0, 0, 0, 0, 0, 0, 3, 4, 4, 0, 0, 0, 0, 0, 0,

                         0, 0, 0, 0, 0, 0, 0, 0, 0, 0.2, 0.1, 0, 0, 0, 0,

                        0, 0, 0, 0, 0, 0, 0.5, 1, 0.3, 0.2, 0.5, 0.2, 0.3, 0.3, 0,

                        0, 0, 0, 0, 0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0,                   

                        ]

                    }

                }

            ]

        }

 

En dupliquant, en changeant d’échelle et de couleur cette grille, l’on peut arriver à créer toute sorte de paysage comme montré en figure 8.  

Figure 8: Paysage de montagne avec  barrage, rivière et lacs

Une fois les objets dessinés, les décors « plantés », on peut mettre du mouvement pour obtenir des effets très réalistes.

 

6. Animations 3D

6.1 Introduction

Animer des objets veut dire leur faire suivre une trajectoire. Il y a deux façons de définir ces trajectoires en VRML : en utilisant la fonction interpolateur de trajectoire du VRML ou bien en écrivant les équations mathématiques du déplacement dans un «sous programme» Javascript. Attention : un « fichier VRML » n’est pas un programme séquentiel: plusieurs animations peuvent être jouées en parallèle (simultanément). 

 

Dans tous les cas, on définit un temps de cycle de l’animation (ou plusieurs en changeant le nom, s’il y a des animations de durées différentes dans la scène)  (ici 20 secondes) et un bouclage continu (optionnel) sur elle-même  comme indiqué.  La base de temps est l’horloge du PC sur lequel tourne l’animation.

 

DEF temps TimeSensor {

    cycleInterval 20

    loop TRUE}

 

Dans tous les cas (interpolateur ou javascript),  on travaille avec des variables en temps réduit  ou normalisé par rapport au temps de cycle :

Le temps réduit est donc compris entre 0 et 1.

 

6.2 Utilisation des instructions interpolator VRML

 

Il y a 6 interpolateurs disponibles, dont trois principaux :

 « ColorInterpolator »  très utile pour faire évoluer la couleur d’un objet ou le fond du ciel pour faire un lever de soleil par exemple, (cf. exemple cliquer ici)

« OrientationInterpolator » pour faire évoluer l’angle ou l’orientation d’un objet

« PositionInterpolator » pour effectuer des translations d’objets  en 3D

 

 

1)      Exemple avec l’interpolateur de position

 

Par exemple, pour faire évoluer la position d’un objet, il suffit de donner dans un tableau « Keyvalue », la position en x,y,z de l’objet pour chaque instant correspondant indiqué dans un tableau « Key ». On définit ainsi sa trajectoire point par point et l’interpolateur assure un mouvement fluide entre chaque point de l’espace.

 

 

 

Temps

(s)

Temps normalisé

Position en X

 

Position en Y

Position en Z

t

t/tmax

x

y

z

0

0

xo

yo

zo

...

ti

ti / tmax

x(i)

y  (i)

z(i)

tmax

1

xmax

ymax

zmax

 

Figure 9: Tableau de valeur « Key value » pour un « PositionInterpolator »

 

DEF mouvement  PositionInterpolator {

     key      [to/tmax ,       ..., ti /tmax ,     …, 1]

keyValue [ xo  yo  z0, ..., xi  yi  zi, …,xn  yn  zn]}

 

Par exemple pour déplacer notre bateau sur la rivière (trajectoire linéaire sur un axe), il suffit d’écrire :

 

DEF mouvbateau PositionInterpolator {

 

      key [ 0 0.1 0.2 0.4 0.6 0.8  1 ]

      keyValue [

            0 0 160, 0 0 130, 0 0 90, 0 0 20, 0 0 -20, 0 0 -90, 0 0 -180]

}

ROUTE temps.fraction_changed TO mouvbateau.set_fraction

ROUTE mouvbateau.value_changed TO BATEAU.set_translation

 

 

La première instruction ROUTE permet de « passer » les fractions de temps générées par le « Time sensor » vers l’interpolateur et la deuxième instruction ROUTE renvoie la valeur de position correspondante de la table vers la position  du « parent » BATEAU.

 

Le bateau passe sous le pont levant, animé de façon similaire pour se lever et s’abaisser au bon moment…pendant que le tramway passe.

 

  

Figure 10a: Le nouveau pont Ba-Ba   (Baccalan-Bastide) (officiellement Chaban-Delmas) de Bordeaux

(et pour les yeux perspicaces, le tramway CITADIS qui passe sur le quai rive gauche)

Figure 10b : Zoom sur l’arrivée du tram en station

 

2)     Autre exemple d’interpolation de position

 

Prenons le cas  d’une balle rebondissant sur le sol en supposant pour simplifier sans amortissement (la balle remonte à la même hauteur de laquelle elle a été lâchée). Il s’agit d’un  mouvement de  translation linéaire le long de l’axe vertical d’un objet soumis à la gravité g.  Le rebond peut être représenté à l’aide de l’interpolateur de position comme indiqué précédemment.

Pour plus de réalisme, on peut ajouter un écrasement ou une déformation de la balle à l’impact sur le sol. Le changement de forme au moment de  l’impact peut se faire en jouant sur le facteur d’échelle si l’on a pris soin de d’introduire dans la description de la balle l’instruction « scale 1 1 1 ». Et toujours avec le même « PositionInterpolator » légèrement détourné de sa fonction initiale.

Sur l’exemple, la balle est initialement a une altitude en y de 10. L’altitude évolue de façon parabolique en fonction du temps et l’impact a lieu a T=0,5. A cet instant le facteur d’échelle est modifié.

 

Figure 10c : Altitude de la balle en fonction du temps normalisé

 

  
Figure 10d: La balle bondissante

 

#VRML V2.0 utf8

#balle.wrl  Ph. dondon

#---------balle bondissante

 

DEF BALLE Viewpoint {

 #definition d'un point de vue initial de la scène accessible par le bouton en bas a gouche

 

      position 0 5 25

                orientation 1 0 0 0

                description "balle"}

     

      PointLight {

      ambientIntensity 0.5

                color 0.7 0.7 0.7 }

  

DEF balle

                Transform {

                translation 0 10 0

                scale 1 1 1

                children [

                Shape {

 

                geometry Sphere {radius 1

                }

                appearance Appearance {

                material Material {

                ambientIntensity 1

                diffuseColor 0.9 0.4 0.2}

                }

                }

                ]}

 

#------sol ---------

 Transform {

               

                translation 0 -1 0

                children [

 

                Shape {

 

                geometry Box {size 10 2 10

                }

                appearance Appearance {

                material Material {

                ambientIntensity 0.6

                diffuseColor 0.6 0.6 0.4}

                }

                }

 

]

}

     

#animation balle temps de cycle 10 secondes

DEF temps TimeSensor {

    cycleInterval 10

    loop TRUE}

 

#----------chute de la balle en 1/2 de g*t^2

DEF chute PositionInterpolator {

 

      key [ 0 0.16 0.22 0.27 0.32 0.35 0.39 0.42 0.45 0.47 0.50

0.53 0.55 0.58 0.61 0.65 0.68 0.73 0.78 0.84 1]

      keyValue [

            0 10 0, 0 9 0, 0 8 0, 0 7 0, 0 6 0, 0 5 0,

0 4 0, 0 3 0, 0 2 0, 0 1 0, 0 0.5 0, 0 1 0, 0 2 0, 0 3 0, 0 4 0, 0 5 0

0 6 0, 0 7 0, 0 8 0, 0 9 0, 0 10 0]

}

 

ROUTE temps.fraction_changed TO chute.set_fraction

ROUTE chute.value_changed TO balle.set_translation

 

#------ ecrasement balle contact sol

#---- le « PositionInterpolator » permet aussi de gérer le facteur d’échelle

DEF echelle PositionInterpolator {

 

      key [ 0  0.47 0.50 0.53  1]

      keyValue [

            1 1 1, 1 1 1, 1 0.5 1, 1 1 1, 1 1 1]

}

ROUTE temps.fraction_changed TO echelle.set_fraction

ROUTE echelle.value_changed TO balle.set_scale

 

 

On pourra complexifier à souhait cet exemple en faisant dépendre la déformation de la hauteur initiale et ajouter un amortissement du mouvement, conserver le volume de la balle pendant l’impact… Une bonne occasion de réviser les lois de la cinétique, des chocs etc. 

 

 

6.3 Description  mathématique de la trajectoire d’un objet,  dans un VRMLscript ou Javascript

 

6.3.1 Introduction 

 

Un VRML script ou java script  est un « programme » qui exécute un certain nombre d’opérations lorsqu’un ou plusieurs évènements  entrants (eventIn) se produisent, par exemple l’écoulement du temps ou le passage de la souris au dessus d’un objet de la scène. Le ou les  évènements sortants  (eventOut) sont le résultat des opérations effectuées. Les uns  comme les autres sont transmis ou passés du  programme principal par les instructions ROUTE. Les calculs ou opérations sont réalisées dans des fonctions (function).

 

- Un VRMLscript peut contenir une ou plusieurs fonctions.

- Mais il doit y avoir une fonction pour chaque évènement entrant.

- Le nom de la fonction doit obligatoirement être celui de l’évènement entrant correspondant.

- Le nom de la fonction est suivi entre parenthèse du ou des noms des variables utilisées dans la fonction pour le calcul.

- Un même fichier VRML peut faire appel à un ou plusieurs scripts (par exemple un pour faire bouger un objet et un autre pour changer la couleur d’un autre objet) ; La programmation par évènement permettant, contrairement à la programmation séquentielle classique des électroniciens, de « lancer » plusieurs processus  en parallèle.

 

Par exemple, le script suivant  fait évoluer une vitesse de rotation au cours du temps.

 

DEF mouvement Script {

           

            eventIn   SFFloat set_temps

            eventOut SFRotation rotationpale

           

 url "vrmlscript:

                        function set_temps(t) {  

if(t<=0.5)

{k=1-Math.exp(-t/0.08)}

if (t>0.50 && t<=0.6)

{k=0.6}

if (t>0.6 && t<=0.7)

{k=0.15}

if (t>0.7 && t<=0.8)

{k=0.05}

if (t>0.8 && t<=0.9)

{k=0.01}

if (t>0.9 && t<=1)

{k=0.0}

                       

            N=0.25*k*120

            rotationpale= new SFRotation (0, 1, 0, (2*3.14*N*t));

            }   "

}

 

Bref, définir un mouvement par ses équations mathématiques est un exercice cérébral intéressant.  C’est  une excellente occasion voir ou  revoir, comme disent les cinéphiles, par exemple, les équations classiques qui régissent le mouvement d’une bielle.

 

 

6.3.2 Exemple de la bielle

 

Pour aider à la compréhension, nous avons superposé au schéma de la bielle les axes du repère choisi pour ce dessin.

 

Figure 11: L’exemple de la bielle

 

 Le fichier VRML de description et d’animation est donné ci-dessous.

 

#VRML V2.0 utf8

# VErsion améliorée Ph D

Group {

    children [

            Background {                                                                 

      skyColor [

            0.85 0.85 0.87]

}

       DEF entree Viewpoint {

            position -0 0 20

            orientation 5 2 0 0

        },

        NavigationInfo {

            headlight FALSE

        }

        PointLight {

            ambientIntensity 0.5

            color 1 1 1

            location  0.0 8.0 10.0

        },

        DEF MOUV Transform {

        rotation 0 1 0 0.7

        children [ 

        DEF PISTON Transform {

#piston

            translation  -2.0 0.0 0.0

            scale 1 1 1

            center -3 0 0

            children [

                Shape {

                    appearance Appearance {

                        material Material {

                    diffuseColor 0.7 1.0 0.0        

                        specularColor 0.2 0.2 0.2

                    }

                    }

                    geometry Box {

                    size   5 0.5 0.5

                    }

                }

            ]

        },

 

        DEF BIELLE Transform {

#manivelle

            translation 1.3 0 0.3

# ----center permet de définirle coentre de rotation au bout du piston------

            center -3 0 0

            scale 1 1 1

            rotation 0 0 1 0

            children [

                Shape {

                    appearance Appearance {

                        material Material {

                        diffuseColor 0.8 0.8 0.8        

                        specularColor 0.0 0.0 1.0 }       

 

                    }

                    geometry Box {

                    size   6 0.5 0.5

                    }

                }

            ]

        },

        DEF ROTULETIGE Transform {

            translation -2.0 0.0 0.0

            rotation 1 0 0 1.57

            scale 0.5 0.6 0.5

            children [

                Shape {

                    appearance Appearance {

                        material Material {

                      diffuseColor 0.8 0.5 0.2        

                        specularColor 0.2 0.2 0.2

                                                 }

                    }

                    geometry Cylinder {

                    }

                }

            ]

        },

 

        DEF MANIV Transform {

#roue

            translation 4.0 0.0 0.0

            scale 2.5 0.1 2.5

            rotation 1 0 0 1.57

            children [

                Shape {

                    appearance Appearance {

                        material Material {

                    diffuseColor 1.0 1.0 1.0        

                        specularColor 0.5 0.5 0   }

                    }

                    geometry Cylinder {

                    }

                }

            ]

        },

      

        DEF TETONBIELLE Transform {

            translation 6 0 0.0

            scale 0.5 0.75 0.5

            rotation 1 0 0 1.57

           

            children [

                Shape {

                    appearance Appearance {

                        material Material {

                       diffuseColor 1.0 0.0 0.0        

                        specularColor 0.0 0.0 1.0  }

                    }

                    geometry Cylinder {

                    }

                }

            ]

        } 

        ,

        DEF CENTREMANIVELLE Transform {

            translation 4 0.0 0.0

            scale 1 1 1

            rotation 1 0 0 1.57

            children [

                Shape {

                    appearance Appearance {

                        material Material {

                       diffuseColor 1.0 1.0 0.0        

                        specularColor 0.7 0.7 0.0  }

                    }

                    geometry Cylinder {

                    

                    radius  2

                          height 0.5}

                }

            ]

        },

 

    ]

}

]

}

 

 

# -----------------definition du cycle de l'animation, boucle infinie-------------

DEF temps TimeSensor {

    cycleInterval 20

    loop TRUE

}

#----------------javascrip Ph.D ----animation

# t =temps réduit de 0 a 1

#offset de -6 sur rotule[0] pour t =0  à cause de l'arcsin

DEF mouvement Script {

           

            eventIn   SFFloat set_temps

            eventOut  SFVec3f tige

            eventOut SFVec3f rotationmaniv

            eventOut SFVec3f rotule

            eventOut  SFVec3f bielle

            eventOut  SFRotation bielle1

  url "vrmlscript:

            function set_temps(t) {  

 

            rotule[0]=-2-6+2*Math.cos(2*3.14*20*t)+6*Math.cos(Math.asin(Math.sin(2*3.14*20*t)/3));

            rotule[1]=0;

            rotule[2]=0;

            rotationmaniv[0]= 4+2*Math.cos (2*3.14*20*t);

            rotationmaniv[1]= 0+2*Math.sin (2*3.14*20*t) ;

            rotationmaniv[2]= 0;

            bielle[0]=1-6+2*Math.cos(2*3.14*20*t)+6*Math.cos(Math.asin(Math.sin(2*3.14*20*t)/3));

            bielle[1]=0;

            bielle[2]=0;

            bielle1= new SFRotation (0, 0, 1, Math.asin(Math.sin(2*3.14*20*t)/3));

} "

}

ROUTE temps.fraction_changed TO mouvement.set_temps

ROUTE mouvement.rotule TO ROTULETIGE.set_translation

ROUTE mouvement.rotationmaniv TO TETONBIELLE.set_translation

ROUTE mouvement.bielle TO BIELLE.set_translation

ROUTE mouvement.bielle1 TO BIELLE.set_rotation

 

 

6.3.3 Trajectoire d’un boulet de canon

 

Prenons l’exemple classique du mouvement d’un boulet de canon projeté à une vitesse initiale Vo (m/s) avec un angle a.



  

 

 

Figure 12

 

En négligeant les frottements, le boulet est soumis seulement à l’accélération gravitationnelle « g (m/s2)». La trajectoire est régit par les équations suivantes :

Vitesse horizontale : Vx= Vo.cos a

Vitesse verticale : Vz =Vo.sin a –g.t   où t est le temps

Par intégration de la vitesse, il vient :

X= Vo.cos a. t

Y= -1/2. g.t2 + Vo.sin a t + Yo , où Yo est l’altitude du canon (à l’origine).

 

L’équation Y=f(X) est donc :

 

 

 

 

 


En supposant Zo =0, pour simplifier,  le point de chute du boulet est obtenu pour Zc =0.

Soit deux solutions pour x :

Xc1=0 ;  le tir a fait long feu, situation peu intéressante…

Et :

Xc2=  (2.Vo2/g). cosa. sin a    

Ouf ! On retrouve logiquement que Xc2 = 0 si a est nul (tir horizontal)  ou égal à 90° (tir vertical et pas de vent)

 

On obtient  l’angle de tir optimal pour un tir le plus long possible, lorsque dXc2/da=0

soit : a opt= 45°

En VRML,  le tir est programmé comme suit :

 

#VRML V2.0 utf8

#boulet.wrl  Ph. dondon

#---------boulet de canon

#--------------point de vue

 

DEF vue Viewpoint {

      position 50 30 130

            orientation 1 0 0 -0.2

            description "balle"}

     

      PointLight {

      ambientIntensity 0.8

            color 0.7 0.7 0.7

        }

#-----------fond de ciel

 

  DEF fondciel Background {                                                           

      skyAngle [ 0.8, 1.4, 1.6 ]                         # dégradé de bleu dans le ciel

      skyColor [

            0.1 0.1 0.3,

            0.2 0.2 0.4,

            0.5 0.5 0.8,

            0.7 0.7 0.9 ]}

#------sol herbeux---------

 Transform {

            translation 50 -5 0

            children [

 

            Shape {

            geometry Box {size 150 10 50

            }

            appearance Appearance {

            material Material {

            ambientIntensity 0.6

            diffuseColor 0.3 0.6 0.4}

            }

            }

]

}

#--------- boulet sphérique  

DEF boulet

            Transform {

            translation 0 3 0

            children [

            Shape {

 

            geometry Sphere {radius 1

            }

            appearance Appearance {

            material Material {

            ambientIntensity 1

            diffuseColor 0.9 0.4 0.2}

            }

            }

            ]}

 

#--------------canon

DEF canon

            Transform {

            translation 0 3 0

            rotation 0 0 1 0

            scale 1 1 1

            children [

            Shape {

 

            geometry Cylinder {radius 1 height 5

            }

            appearance Appearance {

            material Material {

            ambientIntensity 1

            diffuseColor 0.2 0.2 0.2

            specularColor 0.2 0.2 0.3}

            }

            }

            ]}

#-----support canon

 

 Transform {

           

            translation 0 0 0

            children [

 

            Shape {

 

            geometry Box {size 1 8 1

            }

            appearance Appearance {

            material Material {

            ambientIntensity 0.6

            diffuseColor 0.3 0.3 0.4}

            }

            }

]

}

 

#----marquage ligne blanche  distance au sol

PROTO marquage

      [

     field SFVec3f offset  0 0 0

    

      ]

{

 

DEF marque Transform {

  children [

            DEF trait Transform {

            translation IS offset

            rotation 1 0 0 1.57

            children [

                Shape {

                geometry

                        Cylinder  {radius 0.4 height 50}

            appearance Appearance {

                material Material {

                                  

                                    diffuseColor 0.9 0.9 0.9

                        }

                        }

                        }

                       ]}

                        ]}

 

}

#----- placement des lignes blanches

DEF ENSMARQUE Transform {

children [

marquage {offset 30 0 0 }

marquage {offset 40 0 0 }

marquage {offset 50 0 0 }

marquage {offset 60 0 0 }

marquage {offset 70 0 0 }

marquage {offset 80 0 0 }

marquage {offset 90 0 0 }

marquage {offset 100 0 0 }

]}

 

# -----animation balle temps de cycle 10 secondes

 

DEF temps TimeSensor {

    cycleInterval 10

    loop TRUE}

# ----- mouvement boulet

#   variables :

#   t= temps normalisé

#   a= angle de tir par rapport a l'horizontal  (modifiable par l'utilisateur) 0<a<1.57

#   anglecanon= calculé à partir de a pour orienter le fut du canon ( pb origine des angles)

#   Vo =vitesse intiale

#   y0 =offset altitude du canon

#

DEF mouvboulet Script {

           

            field SFVec3f trajectoire 0 0 0

           

            eventIn   SFFloat set_temps 

            eventOut SFVec3f trajet

            eventOut SFRotation rotationcanon

             url "vrmlscript:

                        function set_temps(t) {           

            a=0.75           

            anglecanon= a-1.57;

            Vo=30;

            yo=3

            g=10;

            T=10*t;

            trajectoire[0]= Vo*Math.cos(a)*T ;

            trajectoire[1]= -0.5*g*T*T+Vo*Math.sin(a)*T+yo;

            trajectoire[2]= 0;

            Xmax=trajectoire[0]

 

if(trajectoire[1]<0)

{trajectoire[0]=xmax;

trajectoire [1]=0;

trajectoire[2]= 0;

}

            trajet[0]=trajectoire[0];

            trajet[1]=trajectoire[1];

            trajet[2]=trajectoire[2];

rotationcanon= new SFRotation (0, 0, 1, anglecanon)

}

"}

 

ROUTE temps.fraction_changed TO mouvboulet.set_temps

ROUTE mouvboulet.trajet TO boulet.set_translation

ROUTE mouvboulet.rotationcanon TO canon.set_rotation

 

  
 Figure 13 : tir du boulet

 

6.3.4 Exemple  d’un vol en hélicoptère

Ci après, un exemple de réalisation juste pour montrer quelques possibilités d’animations combinées : Ici, un vol en montagne d’un hélicoptère. Après une montée verticale  au dessus du point de départ, notre hélicoptère décrit une ellipse avant de se reposer sur l’aire aménagée. Nous avons combiné la rotation des pales, avec un mouvement ascensionnel linéaire et une rotation au dessus du barrage.

Figure 14a : Zoom sur l’hélicoptère

  

Figure 14b : Vol en montagne

6.3.5 Faire « tourner » le soleil et changer sa couleur.

Pour ajouter encore du réalisme à une scène on peut programmer la rotation du soleil et des cycles jour/nuit avec changement de couleur du soleil et du ciel. Ci-dessous, nous donnons un autre exemple (avec le code)  qui permet de faire tourner un soleil dans le ciel  en le faisant passer du rouge le matin et le soir au jaune en après midi.

Figure 15 : Trajectoire soleil

 

#------------------soleil ou spot simulation le soleil

# Ph DONDON enseirb matmeca

 

        DEF SOLEIL Transform {

            translation 20 0 0

            rotation 1 0 0 0

                        scale 20 20 20

            children [

                Shape {

                        geometry Sphere {radius 5}

                appearance Appearance {

                        material DEF Couleursoleil Material {

                        ambientIntensity 1

                        diffuseColor 1 1 0

                                   }

                     }

                            #sphere 1 metre de rayon par defaut

                     }

            ]

        }

#---definition du cycle de l'animation, boucle infinie-------------

#-------------durée d'un cycle 60sec

 

DEF temps TimeSensor {

    cycleInterval 60

    loop TRUE}

 

#-----------------------------------animation soleil (trajectoire , couleur) Ph DONDON

# cercle a distance D =1600 centré sur 0,0,0  incliné par rapport à la verticale d'un angle "elevation"

# élévation max =2.44 rd par rapport a l'axe vert Y soit 2.44-1.57= 0.87 par rapport a l'horizon,

# ici, on prend le complement a PI/2 soit elevation =1.57-0.87=0.75 

# couleur du jaune ( en journée) au rouge  (lever et coucher)

# variation de lumière 2 fois par cycle =>v=2

#azimuth et elevation en rd

#on définit une trajectoire circulaire dans le plan X Y puis on fait une rotation autour de l'axe X

# d'un angle elevation .Ph Dondon

# jour :0<t<0.5 ,  nuit : 0.5<t<1  donc minuit t=0.75

 

DEF couleur Script {

           

 

            field SFVec3f trajectoire 0 0 0

 

            eventIn   SFFloat set_temps

            eventOut SFColor Couleursoleil

             

            eventOut SFVec3f trajet

           

             url "vrmlscript:

                        function set_temps(t,tm) {  

            v=2;

            distance=1600;

            Rs=  0.8+ 0.2*Math.sin (2*3.14*v*(t+0.1));

            Vs = 0.5- 0.2*Math.sin (2*3.14*v*(t+0.1));

            Bs =0.3;

            Couleursoleil =new SFColor ( Rs, Vs, Bs);

            azimuth= 2*3.14*t

            elevation= -0.75

            trajectoire[0]=distance*Math.cos(azimuth);

            trajectoire[1]= distance*Math.sin(azimuth);

            trajectoire[2]= 0;

            trajet[0]=trajectoire[0];

            trajet[1]=trajectoire[1]*Math.cos (elevation)+trajectoire[2]*Math.sin(elevation);

            trajet[2]=-trajectoire[1]*Math.sin(elevation)+trajectoire[2]*Math.cos(elevation) } "}

 

ROUTE temps.fraction_changed TO couleur.set_temps

ROUTE couleur.Couleursoleil TO Couleursoleil.set_diffuseColor

ROUTE couleur.trajet TO SOLEIL.set_translation

 

6.3.5 Combiner plusieurs mouvements

 

Nous donnons ici l’exemple d’un petit avion qui effectue un mouvement rectiligne uniforme avec un looping  puis un virage sur l’aile de 90°, et reprend un vol rectiligne avec un tonneau.

 

Attention,  cette animation ne reflète pas les véritables lois de pilotage mais illustre simplement l’utilisation de VRML.   Il s’agit donc de combiner une translation puis une rotation autour d’un axe et une inclinaison de l’avion 

 

L’avion étant décrit dans un fichier *.wrl, (non donné dans l’exemple) il est muni implicitement d’un repère X,Y, Z local. 

 

Dans ce repère, un premier centre de rotation est fixé (au barycentre de l’avion) pour permettre l’action  sur l’assiette ou l’inclinaison de l’avion en 0, 0, 0.

 

Un deuxième centre de  rotation (nécessairement à l’extérieur de l’avion  et sur le coté de l’avion  pour le virage, par exemple (0, 0, R) où R est le rayon  (ici, le virage s’effectuera sur la droite de l’avion).

 

Un troisième centre de  rotation (nécessairement à l’extérieur de l’avion  et au dessus de l’avion  pour le looping, par exemple (0, R, 0) où R est le rayon  (ici, le virage s’effectuera sur la droite de l’avion).

Figure 16 : repère local avion

  

Pour agir séparément sur chacun des paramètres, on adopte une structure hiérarchique familiale à deux niveaux :

 

Au plus haut niveau, on pourra agir sur  la translation  pour la partie de trajectoire rectiligne et sur la rotation pour effectuer le « looping » et  le virage.

Au niveau inférieur, on pourra régler l’inclinaison. (Nota : Il faudrait ajouter un troisième niveau si l’on voulait régler  l’assiette.)

Figure 17: repères terrain d'aviation


 

L’avion est placé au dessus d’un « terrain d’évolution  vert » ou sont inclus les repères X Y Z  absolus et où est figuré le centre de rotation pour le virage pour une meilleure compréhension.

 

 La trajectoire est programmée par morceau :

1° mouvement rectiligne uniforme,

2° looping avec premier centre de rotation,

3° virage sur l’aile (avec changement du centre de rotation),

4° Reprise trajectoire rectiligne avec  1 tonneau,

5° trajectoire rectiligne   

 

Le code VRML est donné ci après (sans le fichier décrivant l’avion) :

 

 

##VRML V2.0 utf8 PH DONDON

# ---------------------avion

#---------------------- point de vue sur la scene       

 

DEF SURVOL Viewpoint {

 #definition d'un point de vue initial de la scène accessible par le bouton en bas a gouche

 

            position 0 0 600

            orientation 1 0 0 0

            description "avion"}

 

 

  DEF fondciel Background {                                                            # fond du ciel

 

      skyAngle [ 0.8, 1.4, 1.6 ]                         # dégradé de bleu dans le ciel

      skyColor [

            0.1 0.1 0.3,

            0.2 0.2 0.4,

            0.5 0.5 0.8,

            0.7 0.7 0.9 ]}

 

   PointLight {

      ambientIntensity 0.8

            color 0.7 0.7 0.7

   

    }

 

#-------- base sol vert

 Transform {

           

            translation 0 -40 0

            children [

 

            Shape {

 

            geometry Box {size 1000 40 1000

            }

            appearance Appearance {

            material Material {

             

              diffuseColor 0.5 0.7 0.5

              ambientIntensity 0.5}

            }

            }

 

]

}

 

 

 

#####repere X,Y absolu en ligne bleue  0, -20, 0

#-------- ligne au sol

 Transform {

           

            translation 0 -20 0

            rotation 0 1 0 1.57

            children [

 

            Shape {

 

            geometry Box {size 1 5 500

            }

            appearance Appearance {

            material Material {

             

              diffuseColor 1 1 1

              ambientIntensity 0.5}

            }

            }

 

]

}

 

 

#-------- ligne au sol

 Transform {

           

            translation 0 -20 0

            children [

 

            Shape {

 

            geometry Box {size 1 5 500

            }

            appearance Appearance {

            material Material {

             

              diffuseColor 1 1 1

              ambientIntensity 0.5}

            }

            }

 

]

}

####marquage adaptatif du centre de rotation au sol

# la position est parametrée automatiquement dans le script en changeant uniquement le rayon

# du virage

#-----poteau centre rotation

DEF poteau Transform {

           

            translation -100 0 100

            children [

 

            Shape {

 

            geometry Cylinder  {radius 1 height 50

            }

            appearance Appearance {

            material Material {

             

              diffuseColor 0.9 0.7 0.5

              ambientIntensity 0.5}

            }

            }

 

]

}

 

 

#-------- axe poteau en X

DEF axepoteauX Transform {

           

            translation -100 -20 100

            children [

 

            Shape {

 

            geometry Box {size 1 5 50

            }

            appearance Appearance {

            material Material {

             

              diffuseColor 0.9 0.7 0.5

              ambientIntensity 0.5}

            }

            }

 

]

}

 

#-------- axe poteau en Y

DEF axepoteauY Transform {

           

            translation -100 -20 100

            rotation 0 1 0 1.57

            children [

 

            Shape {

 

            geometry Box {size 1 5 50

            }

            appearance Appearance {

            material Material {

             

              diffuseColor 0.9 0.7 0.5

              ambientIntensity 0.5}

            }

            }

 

]

}

 

 

### ------structure en enfant

# plus haut niveau reglage translation de l'avion et virage

# niveau inférieur reglage inclinaison

# rajouter un troisiem niveau si reglage assiette necessaire

 

#

# centre de rotation avion pour le virage : ATTENTION

# il est defini par rapport au repere local de l 'avion 

#  Rayon du virage = parametrable dans  le script

 

DEF avion

            Transform {

 

            translation -1000 0 0

            center 0 0 100

            rotation 0 1 0 0

           

            children [

 

#---- inclusion  avion

DEF barycentreavion

Transform {

            #centre de rotation avion pour l'assiette et l'inclinaison

            center 0 0 0

            rotation 1 0 0 0

            translation 0 0 0

           

            children [

            Inline {

                  url "avion.wrl" } ]

}

 

]}

 

 

#--animation  Ph DONDON

DEF temps TimeSensor {

    cycleInterval 20

    loop TRUE}

 

# ------Definition des variables pour une rotation de 90°

 

# alpha = angle instantané par rapport au centre du virage

# vit = vitesse tangentielle pendant le virage (calculée)

#entre t =0 et 0.25 approche a vitesse contante

#entre 0.25 et 0.25+0.25/N rotation de 90° a vitesse contante et inclinaison

#au delà trajectoire linéaire a vitesse constante

#-----------

# N = coef de reglage vitesse ...superieur a 2 (a regler par l'utilisateur)

# Rayon =rayon  de virage  (a regler par l'utilisateur Rayon positif)

#-----------------

# entre 0 et 0.25  trajectoire rectiligne

#puis looping en choisissant le centre de rotation "avion"

#puis virage de 90° en affectant le centre de rotation "avion"

#puis trajectoire rectiligne en changeant le centre de rotation "avion"

# puis vrille 1 tour autour du centre de rotation "barycentreavion"

 

DEF mouvement Script {

           

            field SFVec3f trajectoire 0 0 0

            eventIn   SFFloat set_temps

           

            eventOut SFRotation rotationavion

            eventOut SFRotation inclinaison

            eventOut SFVec3f trajet        

            eventOut SFVec3f centre       

            eventOut SFVec3f poteau      

           

 url "vrmlscript:

 

function set_temps(t) {  

            N=5;

            Rayon=100;

            vit=1.57*Rayon*N/0.25;

            centre[0]= 0

            centre[1]= 0

            centre[2]= Rayon

 

            poteau[0]= -Rayon

            poteau[1]= -20

            poteau[2]= Rayon

 

if (t<0.25)

 

            {

            trajectoire[0]= -(0.25-t)*vit-Rayon ;

            trajectoire[1]=0;       

            trajectoire[2]= 0;

            trajet[0]=trajectoire[0];

            trajet[1]=trajectoire[1];

            trajet[2]=trajectoire[2];

            rotationavion= new SFRotation (0, 1, 0, 0);

            inclinaison = new SFRotation (1, 0, 0, 0)

            }

 

if (t>0.25 && t<0.25+1/N)

           

            {

            centre[0]= 0;

            centre[1]= Rayon;

            centre[2]= 0;

           

 

            alpha=2*3.14*N*(t-0.25)

            rotationavion= new SFRotation (0, 0, 1, (alpha));

            inclinaison = new SFRotation (1, 0, 0, 0)

            }

 

if (t>(0.25+1/N) && t<(0.25+1/N+0.25/N))

            {

            alpha=-2*3.14*N*(t-(0.25+1/N))

           

            rotationavion= new SFRotation (0, 1, 0, (alpha));

            inclinaison= new SFRotation (1, 0, 0, (0.75*Math.sin(2*alpha)*Math.sin(2*alpha)));

           

            }

 

           

if (t>(0.25+0.25/N +1/N))

 

            {

            centre[0]= 0;

            centre[1]= 0;

            centre[2]= 0;

            trajectoire[0]= 0 ;

            trajectoire[1]=0;       

            trajectoire[2]= vit*(t-(0.25+0.25/N +1/N))+Rayon;

            trajet[0]=trajectoire[0];

            trajet[1]=trajectoire[1];

            trajet[2]=trajectoire[2];

            rotationavion= new SFRotation (0, 1, 0, -1.57);

                        alpha=8*3.14*N*(t-(0.25+0.25/N +1/N));

 

                        if (alpha>6.28)

                        {inclinaison = new SFRotation (1, 0, 0, 0);

                        }

                        else

                        {inclinaison = new SFRotation (1, 0, 0, alpha);

                        }

            }

 

 

            } "

}

 

ROUTE temps.fraction_changed TO mouvement.set_temps

 

#----passage paramètres centre rotation et marquage au sol

ROUTE mouvement.centre TO avion.set_center

ROUTE mouvement.poteau TO poteau.set_translation

ROUTE mouvement.poteau TO axepoteauX.set_translation

ROUTE mouvement.poteau TO axepoteauY.set_translation

 

#---- passage pour la partie mouvmeent rectiligne

ROUTE mouvement.trajet TO avion.set_translation

 

#----- passage pour la partie virage 

 

ROUTE mouvement.rotationavion TO avion.set_rotation

 

ROUTE mouvement.inclinaison TO barycentreavion.set_rotation

 

7. Interactivité avec l’utilisateur

Le VRML permet à l’utilisateur d’agir de manière interactive (en direct) avec  la scène ou l’animation qui est jouée dans le « plug in » grâce a un certain nombre de capteurs. (Cf. autres cours  sur le VRML)

Par exemple, on peut, avec un simple clic de souris sur un objet de la scène, interagir en modifiant sa couleur, sa position, sa transparence pour le faire disparaitre ou apparaitre,   ou bien encore sur  une vitesse de déplacement programmée dans un java script.

Pour ce faire, le « capteur »  de clic doit être impérativement associé à l’objet ( instruction Group) avec lequel il doit interagir : Par exemple un capteur PS2 est associé a un tronçon supplémentaire optionnel de cheminée cylindrique EL2, que l’on veut placer ou pas sur le haut de la cheminée.

 #-----element de cheminée-------------

Group {

 

      children [

DEF PS2 TouchSensor {enabled TRUE}

 

DEF EL2

      Transform {

            translation  0 12  0

            children [

                Shape {

                geometry

                        Cylinder {radius 3 height 12 }

            appearance Appearance {

                material DEF TEL2 Material {

                                    ambientIntensity 0.5

                                    diffuseColor 0.9 0.9 0.9

                             specularColor 0.2 0.2 0.2

                             transparency 0.6

}

                                   }

                        }

           ]}

]}

 

Ensuite il faut détecter l’évènement « clic de la souris sur l’objet désigné »( PS2.isActive)  à l’aide d’un java script  (dans l’exemple « mouvement »). Cet évènement est de type  booléen ou binaire (« clic » ou « pas clic »).Il est  passé sous forme d’une variable mouvement.survolEL2 au java script comme suit :

 

ROUTE PS2.isActive TO mouvement.survolEL2

 

 Le script mouvement contient une fonction « survol EL2 » qui  effectuera selon que « survolEL2 » est vrai ou faux uen action ou une autre par exemple changer la couleur du tronçon de cheminée ou sa transparence pour le rendre invisible ( c a dire le supprimer virtuellement)

 

DEF mouvement Script {

           

            eventIn   SFBool survolEL2

            eventOut   SFFloat trEL2

                       

 url "vrmlscript:

 

                        function survolEL2 (survolEL2)

{  

if (survolEL2)

{ action si clic }

else {

action si pas clic}

}

}

 

Enfin le résultat du script est retransmis sous la forme :

ROUTE mouvement.trEL2 TO TEL2.transparency

 

Ici, par exemple,  on change la transparence du tronçon.

8. Un exemple complet

Ph. Dondon © Copyright  Enseirb-Matmeca/ 2012

 

Nous avons choisi de réaliser la modélisation complète de notre maquette développement durable (cliquer ici pour les détails) .

Cela représente environ 4000 lignes de VRML. Nous ne donnons pas la source et ses petits secrets (évidemment), mais le résultat.

Tous les accessoires sont animés conformément à leur fonctionnement mécanique et /ou électronique. Cependant la taille prohibitive du Clip vidéo ne permet de l’inclure dans cette page. Seule figurent des images capturées.

 

Le soleil tourne autour de la maquette en changeant de couleur au cours de la journée. Le ciel (background) change de couleur au lever et coucher de soleil, et un nuage passe.

Figure 18 : une journée complète

 

Pendant la nuit, la grande ourse et l’étoile polaire apparaissent furtivement. L’éclairage extérieur de la maison est allumé. On distingue à gauche de la maison, un système de récupération d’eau. On peut enlever le toit de la maison pour voir l’intérieur par un clic de souris.

 

  

Figure 19 : le paysage, la maison et la grande ourse

 

Les traqueurs solaires traquent le soleil  en azimuth et en élévation (conformément à un  modèle établi préalablement et simulé dans SPICE), pendant la journée et retournent se positionner face à l’Est pendant la nuit.

Le cuiseur solaire avec sa marmite noire au foyer,  est asservi selon la même loi, mais ne traque le soleil qu’entre 11h et 13h.

 

        

Figure 20 : les traqueurs solaires et le cuiseur solaire

 

Le moulin à eau tourne ainsi que le moteur Stirling : la flamme qui chauffe le moteur Stirling change de couleur au cours du temps.

    

Figure 21 : moulin et moteur Stirling

 

Notre maquette de  tour solaire préalablement caractérisée et modélisée est fidèlement reproduite. L’hélice tourne avec une vitesse dépendant de la hauteur de la tour (hauteur que l’on peut changer interactivement avec un clic de souris) ainsi que du nombre d’ouvertures « entrée air » actives. L’inertie thermique est prise en compte : l’hélice ralenti puis s’arrête pendant la nuit. Les éoliennes tournent, elles, à vitesse constante.

 

  

Figure 22 : Tour solaire et éolienne

 

Et pour finir,  un dernier coup d’œil sur la cabane canadienne en rondin, cachée dans la montagne. Pour les petits curieux, en regardant à travers la fenêtre, on aperçoit le poêle à bois.

 

   

Figure 23 : Ma cabane au Canada…

 

 

Et bien d'autres possibiltés pour jouer avec les mouvements de rotations, translations, et loi de la physique...

Figure 24: Evocation de l'ingénieuse et spectaculaire roue écluse de Falkirk en Ecosse

 

 

Figure 25 à 29: Le lancement de la navette spatiale

 

Figure 25 : base de lancement
(le fichier navette spatiale est inspiré de celui donné sur le site http://marinplanes.8m.com/ )

 

Figure 26: mise à feu ....................................................Figure 27 : le départ

Figure 28: séparation des boosters ....................................................Figure 29 : orbite

 

Ph. Dondon © Copyright  Enseirb-Matmeca/ 2012

 

 

  retour page accueil Ph.Dondon