![]() |
|

Installation
Obtenir un visualiseur VRML97 :
Utiliser les exemples :
Introduction
VRML (Virtual Reality Modeling Langage)
Conventions géométriques :
Structure d'un fichier VRML97 :
#VRML V2.0 utf8
MOT_CLÉ {
PARAMÈTRES ... }
et permet de produire des formes ou des transformations géométriques,
de spécifier l'apparence des objets, de rajouter du texte, etc.. Tous
les paramètres sont optionnels, et des valeurs par défaut sont
garanties. Si vous ne voulez que les valeurs par défaut, vous êtes
cependant obligés de mettre les accolades. Ainsi, pour créer un cube,
vous pouvez écrire simplement ceci:
Box { }
Les noeuds du langage ne peuvent pas s'utiliser n'importe comment et à
n'importe quelle place dans le fichier. Il existe en particulier des
noeuds de groupage qui peuvent contenir certains autres noeuds
dans leur paramètres. Nous en verrons certains.
DEF cube Box { size 3 3 3 }
Ensuite, au lieu d'être obligé de réécrire le noeud et l'ensemble de
ses paramêtres à chaque fois que vous en avez besoin, vous pouvez
simplement écrire:
USE cubeNote: l'appel à DEF exécute réellement le noeud en question. Il ne s'agit donc pas seulement d'une définition, car le noeud défini prend effet immédiatement.

Primitives géométriques.
VRML97 reconnaît 4 objets de base : boîtes, cônes, cylindres et
sphères.
Box { size 2 2 2 }
Le paramètre size doit contenir les dimensions de la boîte
selon les trois axes X, Y et Z. Ces dimensions sont des nombres réels
positifs.
Cone {
bottomRadius 1
height 2
side TRUE
bottom TRUE
}
Les paramètres bottomRadius et height définissent la
circonférence et la hauteur du cône. Les paramêtres side et
bottom sont des booléens (valant TRUE ou
FALSE) spécifiant si l'on doit tracer le fond et les côtés du
cône.
Cylinder {
radius 1
height 2
side TRUE
bottom TRUE
top TRUE
}
De même que pour le cône, radius et height spécifient la
taille du cylindre, et top, bottom et side
déterminent les parties du cylindre à tracer.
Sphere { radius 1 }
Le paramètre radius détermine le rayon de la sphère.
Exemple 1 :
#VRML V2.0 utf8
Shape {
geometry Box { }
}

Apparence des objets
Maintenant que nous avons les formes, nous allons donner une apparence aux objets. Il existe deux manières essentielles de modifier l'apparence d'un objet: définir un matériau (couleur de l'objet, manière dont il réfléchi la lumière etc.), et définir une texture (image calquée directement sur l'objet).
Définir un matériau
Material {
ambientIntensity 0.2
diffuseColor 0.8 0.8 0.8
specularColor 0 0 0
emissiveColor 0 0 0
shininess 0.2
transparency 0
}
Exemple 2
#VRML V2.0 utf8
Shape {
geometry Cone {}
}
Shape {
appearance Appearance {
material Material {
diffuseColor 1 0 0.5
ambientIntensity 0.3
specularColor 0.2 0.6 0.2
emissiveColor 0.2 0 0.1
shininess 0.5
transparency 0.3
}
}
geometry Box { }
}
Définir une texture
ImageTexture { url u }
PixelTexture { image 0 0 0 }
Exemple 3
#VRML V2.0 utf8
Shape {
appearance Appearance {
texture PixelTexture {
image 3 3 3
0xffffff 0xffffff 0xffffff
0xff0000 0x00ff00 0x0000ff
0x111111 0x111111 0x111111
}
material Material {
diffuseColor 1 0 0.5
ambientIntensity 0.3
specularColor 0.2 0.6 0.2
emissiveColor 0.2 0 0.1
shininess 0.5
transparency 0.3
}
}
geometry Box { }
}

Production des objets
Comme vous l'avez sans doute remarqué, nous n'avons jusqu'ici jamais utilisé les primitives géométriques ou les noeuds d'apparence tous seuls dans le corps du fichier VRML. Ceci s'explique par le fait qu'un objet est nécessairement défini par le couple (géométrie, apparence) qui le caractérise. VRML dispose donc des noeuds suivants:
Spécification d'apparence :
Appearance {
material m
texture t
}
Les champs material et texture contiennent des noeuds tels que ceux définis précédemment. Si le champ material est nul, aucune lumière n'est prise en compte. Si le champ texture est nul, l'objet n'est pas texturé.
Spécification de forme :
Shape {
appearance a
geometry g
}
Le champ appearance, si non nul, contient un noeud Appearance tel que défini précédemment. Le champ geometry contient un noeud spécifiant une géometrie d'objet, par exemple les primitives géométriques définies en première partie.

Transformation et positionnement des objets
Maintenant que nous savons créer des objets et leur donner une apparence, nous allons pouvoir les transformer et les positionner dans la scène 3D.
Les objets précédents peuvent être manipulés :
Transform {
center 0 0 0
translation 0 0 0
rotation 0 0 1 0
scale 1 1 1
scaleOrientation 0 0 1 0
children [ ... ]
}
Ce noeud fait partie de ce qu'on appelle les noeuds de groupage. Ce sont des noeuds qui ont la propriété de pouvoir contenir d'autres noeuds du langage au niveau de leurs paramètres. Ici, le paramètre children contient d'autres noeuds (en particulier des Shape), auxquels les transformations géométriques seront appliquées.
Les transformations géométriques effectuées par ce noeud sont les suivantes:
Exemple 4
#VRML V2.0 utf8
Transform {
translation -2 0 0
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 0 0.8 0.1
transparency 0.2
}
}
geometry Box { }
}
]
}
Transform {
translation 2 0 0
children [
Shape {
appearance Appearance {
material Material {
diffuseColor 0 0.1 0.8
}
}
geometry Cone { }
}
]
}
Pour mieux comprendre le noeud Transform...
Considérons que les opérations géométriques effectuées se déroulent dans l'ordre suivant:
Transform {
translation T
rotation R
scaleFactor S
scaleOrientation SR
center C
}
|
<==> |
- Translation de -C - Rotation de -RS - Homothétie de S - Rotation de RS - Rotation de R - Translation de C - Translation de T |

Lumière !
En général, les visualiseurs s'occupent de mettre une lumière ambiante dans les scènes, et offrent souvent la possibilité de mettre une head light, c'est-à-dire une lampe collée sur votre front ! Il peut parfois être utile de définir soi-même ses propres sources de lumière. Il en existe trois :
Source ponctuelle
PointLight {
intensity 1
color 1 1 1
location 0 0 0
radius 100
attenuation 1 0 0
ambientIntensity 0
}
Projecteur
SpotLight {
intensity 1
direction 0 0 -1
color 1 1 1
location 0 0 0
radius 100
attenuation 1 0 0
ambientIntensity 0
beamWidth 1.570796
cutOffAngle 0.785398
}
Source directionnelle
DirectionalLight {
direction x y z
color r v b
intensity i
ambientIntensity ai
}
Exemple 5
#VRML V2.0 utf8
SpotLight {
location 2 0 0
direction -1 0 0
}
Shape {
appearance Appearance {
material Material {
diffuseColor 0 0.1 0.8
}
}
geometry Sphere { }
}

Animation
VRML97 permet d'animer les objets de façon plus ou moins complexe:
Les événements
Les horloges
TimeSensor {
exposedField SFTime cycleInterval 1.0
exposedField SFBool enabled TRUE
exposedField SFBool loop FALSE
exposedField SFTime startTime 0.0
exposedField SFTime stopTime 0.0
eventOut SFTime cycleTime
eventOut SFFloat fraction_changed
eventOut SFBool isActive
eventOut SFTime time
}
Le champ cycleInterval détermine la durée d'un intervalle de
temps en secondes (par défaut, une seconde). Le booléen enabled
permet d'activer l'horloge tandis que loop permet de génèrer
continuellement des événements au lieu de s'arrêter au premier
intervalle. Les champs startTime et stopTime
permettent de définir les dates de début et de fin de génération
d'événements à partir du début de la scène. Les événements en sortie
sont utilisés pour créer des animations; en particulier, l'événement
fraction_changed pourra être récupéré par un interpolateur.
Les interpolateurs
PositionInterpolator {
eventIn SFFloat set_fraction
exposedField MFFloat key []
exposedField MFVec3f keyValue []
eventOut SFVec3f value_changed
}
Le champ key est la liste des instants-clés de l'animation
(ici, un déplacement), et le champ keyValue est la liste
correspondante des valeurs-clés (ici, des positions). L'événement en
entrée set_fraction permet de récupérer les fractions de temps
générées par un TimeSensor, et l'événement en sortie
value_changed renvoie la valeur-clé ou la valeur interpolée
correspondant à la fraction de temps reçue.
Exemple 6
#VRML V2.0 utf8
DEF CONE Transform {
children [
Shape {
appearance Appearance {
material DEF CONE_COLOR Material {
diffuseColor 1.0 1.0 0.0
}
}
geometry Cone {}
}
]
}
DEF POSITION_CLOCK TimeSensor {
cycleInterval 6
loop TRUE
stopTime -1
}
DEF POSITIONS PositionInterpolator {
key [ 0.0 0.25 0.5 0.75 1.0 ]
keyValue [ -3.0 0.0 0.0,
0.0 1.0 0.0,
3.0 0.0 0.0,
0.0 1.0 0.0,
-3.0 0.0 0.0 ]
}
ROUTE POSITION_CLOCK.fraction_changed TO POSITIONS.set_fraction
ROUTE POSITIONS.value_changed TO CONE.translation
DEF COLOR_CLOCK TimeSensor {
cycleInterval 2
loop TRUE
stopTime -1
}
DEF COLORS ColorInterpolator {
key [ 0 0.33 0.66 1 ]
keyValue [ 1.0 1.0 1.0,
1.0 0.0 0.0,
1.0 1.0 0.0,
1.0 1.0 1.0 ]
}
ROUTE COLOR_CLOCK.fraction_changed TO COLORS.set_fraction
ROUTE COLORS.value_changed TO CONE_COLOR.diffuseColor
Les capteurs
Exemple 7
#VRML V2.0 utf8
Transform {
children [
Shape {
geometry Cone {
bottom FALSE
}
appearance Appearance {
material Material {
diffuseColor 1.0 0.0 0.0
}
}
},
DEF LIGHT SpotLight {
on FALSE
color 1.0 1.0 0.0
},
DEF LIGHT_SENSOR TouchSensor {}
]
translation 0.0 3.0 0.0
}
Shape {
geometry Box {}
appearance Appearance {
material Material {
diffuseColor 0.0 0.0 1.0
}
}
}
ROUTE LIGHT_SENSOR.isActive TO LIGHT.on

Quelques autres noeuds...
Voici en vrac quelques autres noeuds intéressants. Attention, tous ne sont pas nécessairement supportés par le viewer que vous utilisez...
Ancres WWW
Anchor {
url []
description ""
children []
}
Billboard
Billboard {
axisOfRotation 0 1 0
children []
}
Collisions
Collision {
collide TRUE
children []
}
Texte
Text {
string []
maxExtent 0.0
}

Un exemple complet
Un bon bout de code vaut mieux qu'un long discours... voici donc en
cadeau une tête de clown, avec presque tous les
noeuds étudiés dans ce tutoriel. Triturez, déformez, cliquez-lui sur
le nez...

Conclusions
Pour conclure ce tutoriel, nous voudrions faire les remarques suivantes :