Intégration des point sprites au standard X3D

publicité
Intégration des point sprites au standard X3D
Intégration des point sprites au standard X3D
1 / 13
Intégration des point sprites au standard X3D
2 / 13
INDEXATION DU DOCUMENT
TITRE :
REFERENCE :
Intégration des point sprites au standard X3D
ACTION
NOM
DATE
SIGNATURE
RÉDIGÉ PAR
Adrien COSSA
5 mars 2007
SUIVI DU DOCUMENT
INDICE
DATE
MODIFICATIONS
NOM
Intégration des point sprites au standard X3D
3 / 13
Table des matières
1
Introduction
4
2
Le standard X3D (eXtensible 3D)
4
2.1
Présentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
2.2
La norme ISO/IEC 19775 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
2.2.1
Architecture et composants de base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
2.2.2
Interface de manipulation de la scène . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
2.3
Noeuds de base pour un affichage générique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
2.4
La représentation des nuages de points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
3
La technique de rendu point sprite
8
4
Spécification d’un nouveau noeud X3D
8
4.1
Ajout du noeud PointProperties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
4.2
Modification du noeud Appearance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
4.3
Répercussions sur l’encodage XML et VRML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
4.4
Exemples d’utilisation de PointProperties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
5
6
Implémentation avec Xj3D
11
5.1
Préparation de NetBeans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
5.2
Insertion des sources à modifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5.3
Modification des sources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
5.4
Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Pointeurs
13
Intégration des point sprites au standard X3D
4 / 13
Résumé
Ce document présente le travail qui a été réalisé pour le projet 150 heures du master en informatique de l’image et du calcul
intensif, au sein de l’Université Louis Pasteur. Il a été rédigé en Docbook XML puis exporté au format PDF à l’aide de dblatex.
Le sujet concerne l’étude de la norme X3D définie par le Web 3D Consortium et des techniques de rendu point sprite, la spécification d’un nouveau noeud X3D pour représenter des point sprites, ainsi que l’implémentation de ce dernier dans le toolkit Xj3D.
Le sujet complet original est disponible en ligne à cette adresse : http://co2sa.free.fr/ter/ter.pdf.
Ce projet a été réalisé avec l’aide et le soutien de Raphael Marc et Christophe Mouton, ingénieurs de recherche chez EDF R&D
Clamart, ainsi que de Franck Kolb de l’Institutt For Energiteknikk Halden en Norvège. Il a été encadré par Jean-Michel Dischler,
enseignant chercheur à l’Université Louis Pasteur.
1 Introduction
X3D (eXtensible 3D) se présente comme étant le successeur de VRML (Virtual Reality Modeling Language), un language de
description de scènes 3D interactives. C’est un standard jeune mais populaire, toujours en cours d’évolution. L’objectif de ce
projet est d’inclure à X3D la technique de rendu point sprite.
Un toolkit écrit en Java qui s’appelle Xj3D permet de valider la spécification d’X3D, au fur et à mesure que cette dernière évolue,
en prouvant qu’elle est implémentable de manière pratique. Il s’agit en fait d’un browser qui, de part sa licence LGPL et son
architecture orientée-objet fortement modulable, facilite l’implémentation des modifications que l’on apporte à la norme d’X3D.
Nous commencerons par présenter le langage X3D dans ses grandes lignes, puis nous nous pencherons en détails sur ce qu’il
propose pour représenter des nuages de points. On se livrera ensuite à une petite présentation de la technique de rendu point
sprite avant de voir comment on peut l’intégrer à la spécification d’X3D. Enfin nous implémenterons dans Xj3D, en conjonction
avec le travail précédemment effectué, le nécessaire à l’exploitation des point sprites.
2 Le standard X3D (eXtensible 3D)
2.1 Présentation
Nous avons déjà introduit X3D comme étant une version évoluée du langage de description VRML. Pour être tout à fait exacte,
X3D n’est pas un langage de description mais un système de description. X3D est une abstraction évoluée de VRML, et il faudra
lui associer une technique d’encodage avant de pouvoir l’exploiter. Cette étape d’encodage peut être vue comme la projection d’un
document abstrait X3D au sein d’un langage de description concret. Le Web 3D Consortium propose trois méthodes d’encodage :
– Classic VRML : le document conserve la syntaxe du VRML tout en bénéficiant des évolutions apportées au langage ;
– XML : le document doit strictement respecter les règles d’une DTD (Document Type Definition) XML ;
– binaire : il s’agit d’un stockage compact du document, dans un format compressé binaire.
En pratique, nous utiliserons l’encodage XML, car le VRML est voué à disparaitre et le format binaire n’est pas du tout adapté à
la lecture et l’écriture par un être humain : il a été conçu pour accélérer les transferts entre machines et il n’est pas recommandé
de le manier directement.
2.2 La norme ISO/IEC 19775
La spécification d’X3D a été standardisée en 2004 par la norme ISO/IEC 19775:2004, qui se découpe en deux parties :
– description de l’architecture et des composants de base ;
– description de l’interface de manipulation de la scène (SAI en anglais, pour Scene Authoring Interface).
Un premier amendement, qui date de 2006, a fait évolué la première partie de la norme. Un second amendement est actuellement
en cours de rédaction. La Revision 1 de la partie 1 cumule la version originale, l’amendement 1 ainsi que ce dont on dispose pour
l’instant de l’amendement 2. C’est sur cette Revision 1 que nous allons travailler.
Intégration des point sprites au standard X3D
5 / 13
2.2.1 Architecture et composants de base
Les quelques paragraphes qui suivent sont une traduction libre, c’est à dire non rigoureuse mais fortement inspirée, de l’introduction
officielle à la partie 1 de la norme ISO/IEC 19775.
X3D a été conçu pour servir de standard international, et il doit tenir compte des besoins généraux du marché ainsi que des
différentes technologies qui l’exploiteront. C’est pourquoi les concepteurs d’X3D ont tenu à :
–
–
–
–
–
séparer l’architecture éxécutive de la phase d’encodage ;
supporter une variété de formats d’encodage ;
permettre l’ajout d’objets graphiques, comportementaux ou interactifs ;
offrir des APIs (Application Programming Interfaces) alternatives pour le rendu de scènes 3D ;
définir des profils, qui sont des sous-ensembles de la spécification, afin d’alléger cette dernière et cibler plus particulièrement
certains besoins du marché (par exemple des systèmes informatiques embarqués aux ressources limitées) ;
– permettre à la spécification d’être implémentée à différents niveaux de services ;
– éliminer tant que possibles les comportements non définis ou sous-définis.
L’architecture d’X3D a été définie dans le respect de ces objectifs et pour offrir un large panel de fonctionnalités aux utilisateurs
issus de domaines variés, telle que la visualisation scientifique ou industrielle, la présentation de contenus multimédia, le loisir
et l’éducation, la conception de sites internet ou encore la création de mondes virtuels partagés. On parle de composant pour
désigner un regroupement de fonctionnalités assimilables de part leurs rôles ou les éléments sur lesquels elles agissent. Les
composants les plus utiles servent à :
–
–
–
–
–
–
–
–
afficher des objets 2D ou 3D éclairés et texturés ;
définir des temporisateurs afin de gérer des animations ou de faire du morphing ;
intégrer à la scène des sources audio et vidéo externes ;
gérer les interactions de l’utilisateur avec la scène, définir des caméras mobiles, détecter les collisions ;
définir de nouveaux objects non initialement spécifiés par la norme, et les utiliser comme des objets prédéfinis ;
utiliser des scripts évenementiels pour lier la scène avec une application externe ;
fabriquer une scène à partir de plusieurs sous-scènes distribuées sur des machines reliées en réseau ;
faire de la simulation physique interactive, comme de l’animation humanoïde ou bien la gestion de systèmes de particules.
Bien entendu, toute la puissance d’X3D réside dans sa capacité à combiner plusieurs fonctionnalités issues de composants
différents, et de composer ainsi des scènes complexes formées par une multitude d’objets en relation les uns avec les autres.
On parle de graphe de scène pour désigner le graphe direct acyclique (DAG en anglais, pour Directed Acyclic Graph) qui
représente les objets et leurs liaisons. Un arc partant d’un objet A et allant vers un objet B signifie que A possède B, ou encore
que B est un champ de A (c’est une relation d’aggrégation).
Dans le graphe de scène, certains objets ont des coordonnées (il s’agit typiquement des objets affichables) et d’autres non. Les
coordonnées d’un objet peuvent être exprimées de manière absolue (dans le système de coordonnées du monde) ou bien de
manière relative (dans un système de coordonnées local).
Parmis la multitude de sous-graphes que l’on peut extraire du graphe de scène, on distingue en particulier la hiérarchie de
transformation. Il s’agit de la partie visuellement perceptible du graphe de scène. Elle est composée de l’ensemble des objets qui
sont pourvus de coordonnées ainsi que de leurs liaisons.
Un autre graphe, appelé graphe de comportement, définit les routes qui déterminent de quelle manière les événements générés
par un utilisateur, un script ou encore un temporisateur vont se propager parmis les objets de la scène.
Le graphe de scène et le graphe de comportement peuvent bien sûr être modifiés de manière dynamique, au cours de l’éxécution.
Par souci d’harmonisation, la norme fixe les unités de distance, de mesure d’angle et de temps comme étant respectivement le
mètre, le radian et la seconde. Les couleurs sont exprimées dans le système RGB, à l’aide d’un triplet de flottants qui peuvent
varier entre 0.0 (intensité minimale) et 1.0 (intensité maximale). Le système de coordonnées utilisé par défaut est un système
tri-dimensionnel cartésien direct (obéissant à la règle de la main droite).
Pour plus de détails concernant tout ce qui a été ennoncé ici, et découvrir encore d’autres choses à propos de la définition et de
l’interprétation d’une scène X3D, nous vous invitons à consulter la norme, et en particulier le chapitre 4 de la partie 1 dans lequel
sont exposés les concepts de base.
Intégration des point sprites au standard X3D
6 / 13
2.2.2 Interface de manipulation de la scène
L’interface de manipulation de la scène (SAI en anglais, pour Scene Authoring Interface) est décrite dans la deuxième partie de
la norme ISO/IEC 19775. Son but est d’harmoniser la manière dont les browsers X3D vont manipuler la scène à représenter. Il
ne s’agit pas d’une interface de programmation d’application (API) strictement définie en terme d’implémentation, mais d’une
description sémantique et fonctionnelle des différentes interactions pouvant exister entre l’architecture d’une scène X3D et le
browser qui l’interprète.
De la même manière qu’il existe plusieurs méthodes pour encoder un document X3D, on trouve plusieurs implémentations de
la SAI dans des langages de programmation ou de script. Les encodages XML, Classic VRML et binaire sont spécifiées par la
norme ISO/IEC 19776. La norme ISO/IEC 19777 spécifie les implémentations de la SAI en ECMAScript et Java.
2.3 Noeuds de base pour un affichage générique
Au sein d’un composant, chaque fonctionnalité est spécifiée en X3D par le moyen d’un noeud, que l’on pourrait assimiler à
une classe de programmation orientée-objet. Cependant le terme de noeud parait plus approprié car il représente exactement la
manière dont les fonctionnalités sont intégrées au graphe de scène.
Il y a des noeuds de base ou abstraits, assimilables aux interfaces de la programmation orientée-objet, qui sont non instanciables,
ainsi que des noeuds concrets qui héritent des noeuds abstraits et qui sont directement instanciables.
Sans plus tarder, nous vous proposons un document X3D minimaliste (la définition XML et les entêtes ont été ôtées) :
<Scene>
<Shape>
<TriangleSet solid="false">
<Coordinate point="0 0 0 1 1 0 1 0 0" />
<TextureCoordinate point="0 0 1 1 1 0" />
</TriangleSet>
</Shape>
<Appearance>
<ImageTexture url="image.png" />
</Appearance>
</Scene>
Cet exemple illustre une hiérarchie X3D pour l’affichage d’un triangle texturé. Il est important de noter que pour définir notre
objet Shape, on utilise deux fils de même niveau : un pour l’énonciation des propriétés géométriques et visuelles de base, et
l’autre pour spécifier une technique de rendu avancée (comme le placage de texture).
En fait, le noeud Shape hérite du noeud de base X3DShapeNode, TriangleSet hérite de X3DGeometryNode et Appearance hérite de X3DAppearanceNode. Nous auront l’occasion tout à l’heure de rencontrer d’autres noeuds héritant de ces
noeuds de base. De manière générale :
– un noeud héritant de X3DShapeNode est affichable dès lors qu’il contient un fils qui hérite de X3DGeometryNode ;
– pour lui donner une apparence particulière (aspect matériel, texture ou shader) on peut lui rajouter un fils qui hérite de X3DAppearanceNode.
2.4 La représentation des nuages de points
Le composant Rendering regroupe un ensemble d’objets simples qui héritent de X3DGeometryNode. Ces objets utilisent
des primitives de rendu basiques, comme le tracé de triangle que nous avons eu l’occasion de présenter tout à l’heure. Nous allons
particulièrement nous interesser au noeud PointSet du composant Rendering.
La spécification des noeuds X3D use de notations conventionnelles :
– le signe : est utilisé comme opérateur de l’héritage (même valeur que le mot clé extends en Java) ;
– les accolades { } permettent de constituer des groupes d’éléments hiérarchiques ;
– on liste chacun des champs fils au sein d’accolades, à raison d’un fils par ligne ;
Intégration des point sprites au standard X3D
7 / 13
– pour chacune de ces lignes, on énumère successivement :
– la composition du fils (noeud simple, groupe de noeuds, valeure entière simple, groupe de valeurs flottantes...) ;
– si une route associée à un événement peut accéder au fils en écriture seule ([in]), en lecture seule ([out]), en lecture et
écriture ([in,out]) ou bien pas du tout ([]) ;
– son nom (suite de caractères alpha-numériques) ;
– sa valeur par défaut (en général ce sera la valeur nulle) ;
– son domaine de valeur s’il est restrictif et non implicite (une intervalle s’il s’agit d’un scalaire, ou bien un type de noeud, le
plus souvent abstrait).
Voici la spécification du noeud PointSet qui permet de décrire un ensemble de points :
PointSet
MFNode
SFNode
SFNode
SFNode
SFNode
}
: X3DGeometryNode
[in,out] attrib
[in,out] color
[in,out] coord
[in,out] fogCoord
[in,out] metadata
{
[]
NULL
NULL
[]
NULL
[X3DVertexAttributeNode]
[X3DColorNode]
[X3DCoordinateNode]
[FogCoordinate]
[X3DMetadataObject]
Et une petite description du rôle de ses champs :
–
–
–
–
–
attrib permet d’associer aux points des attributs qui pourront être utilisés par un vertex shader ;
color sert à associer une couleur à chaque point, nous l’avons utilisé précédemment dans notre exemple du triangle texturé ;
coord permet de situer les points dans le système de coordonnées actuellement utilisé ;
fogCoord permet de faire varier l’intensité du brouillard pour chacun des points ;
metadata sert à stocker des informations variées, qui ne revêtent pas d’intêret pour la norme, mais qui pourront servir au
browser ou à tout autre application travaillant avec un document X3D.
Le seul champ qui est vraiment requis est coord, dans lequel on liste les unes après les autres les coordonnées en x, y et z
de chacun des points. Tous les autres champs sont facultatifs, mais s’ils sont présents on attend d’eux qu’ils énumèrent autant
d’informations sémantiques qu’il y a de points.
On rappelle de plus que, comme nous l’avons vu avec l’exemple du triangle texturé, toutes les informations associées à un objet
PointSet ne figure pas forcément dans les champs de ce dernier. En particulier, un noeud Appareance situé au même niveau
que le PointSet peut spécifier des propriétés visuelles avancées comme une surface matérielle, une ou plusieurs textures ou
encore un vertex shader.
<Scene>
<Shape>
<PointSet>
<Coordinate point="0 0 0 1 1 1 1 2 2" />
<Color color="1 0 0 1 0 0 1 0 0" />
</PointSet>
<Appearance>
<ImageTexture url="image.png" />
</Appearance>
</Shape>
</Scene>
Cet exemple de document X3D définit trois points de couleur rouge et leur associe une texture. Il est tout à fait valide vis-à-vis
de la norme... mais en pratique, à quoi peut bien servir le placage d’une texture sur un point ? En effet, la norme X3D ne prévoit
pas (encore) de moduler la taille d’un point, et on suppose donc que les browsers actuels affichent ces derniers avec la taille
minimale d’un pixel à l’écran. Plaquer une texture sur un simple pixel, c’est beaucoup de gaspillage en terme de ressources et
pas franchement utile.
Mais on rappelle que la norme d’X3D évolue continuellement, et le but de ce projet est justement de proposer une modification
de la spécification afin d’intégrer la technique des point sprites à X3D.
Intégration des point sprites au standard X3D
8 / 13
3 La technique de rendu point sprite
L’informatique graphique use abondamment des textures depuis plus de 10 ans, que ce soit dans une optique scientifique ou
ludique. On applique le plus souvent une texture 2D rectangulaire sur un polygone. Le principe du placage de texture est de mettre
en relation des sommets du polygone avec des positions de la texture, que l’on nomme coordonnées de texture. Finalement, on
effectue une interpolation barycentrique pour calculer la couleur que chaque pixel aura à l’écran.
Typiquement, l’affichage d’un quadrilatère texturé nécessite le transfert, depuis le CPU vers la carte graphique, de 4 triplets pour
les coordonnées des sommets du quadrilatère, et des 4 couples de coordonnées de textures associées. Celà représente 20 flottants,
ce n’est pas énorme mais multiplié par des centaines voir des milliers de polygones, ça commence à faire lourd !
Une technique permettant de limiter significativement le volume de données transféré dans certains cas a été inventée il y a
bien longtemps, probablement par des programmeurs de jeux vidéos qui voulaient faire de beaux jeux malgré les contraintes
matérielles de l’époque.
L’astuce consiste, lorsque celà est possible, à ne faire transiter que les coordonnées du centre du polygone, ainsi qu’un scalaire,
en considérant que toutes les autres informations pourront être retrouvées par la carte graphique. Généralement, c’est un carré
de centre le point dont les coordonnées ont été passées, de largeur la valeur du scalaire et qui est orienté vers la caméra qui est
recréé. C’est à dire que la normale du carré pointe vers la caméra utilisée pour représenter la scène à l’écran. Le carré texturé ainsi
affiché s’appelle communément un point sprite, le sprite désignant de manière général un quadrilatère texturé qui fait toujours
face à la caméra de visualisation.
Bien sûr, plusieurs variantes de sprites ont été imaginées, certaines permettent même de simuler de la 3D en plaquant des
textures différentes sur le quadrilatère selon des critères spatio-temporels (position du sprite, position et orientation de la caméra,
temporisateur...). Ainsi, on a vraiment l’impression de tourner autour d’un objet, ou alors qu’un personnage se déplace.
Ces techniques peuvent être utilisées dans des circonstances différentes même si elles sont conceptuellement très raprochées. Par
exemple, on peut utiliser des point sprites pour diminuer la taille de stockage sur le disque dur d’un fichier représentant une scène
3D de jeu vidéo, mais en recalculant ensuite par le CPU le quadrilatère qui servira de support à la texture : ainsi on ne réduit pas
les transferts entre le CPU et la carte graphique. C’est d’ailleurs surement ce type de point sprites qui a été utilisé en premier,
avant l’apparition des cartes accélératrices 3D.
De nos jours, nous disposons de cartes graphiques puissantes, à l’architecture hautement parallèle, offrant de nombreuses extensions efficacement implémentées et que l’on peut même programmer directement à l’aide de shaders.
En associant l’ingéniosité des programmeurs d’antant avec la technologie actuelle, on peut désormais se permettre de rendre
à l’écran des nuages de point sprites très volumineux, pour représenter par exemple un amas d’étoiles. Le fait d’ajouter du
mouvement en décrivant un système de particules, dont chaque élément est un point sprite évoluant dans le temps selon une
formule mathématique pseudo-aléatoire, nous permet de simuler une explosion, de la fumée ou encore une projection de neige
de manière très réaliste.
La technique des point sprites a été officiellement intégrée à OpenGL en 2003, après avoir été introduit par NVidia. Pour plus de
détails concernant son implémentation, se reporter à la spécification de l’extension GL_ARB_point_sprite.
4 Spécification d’un nouveau noeud X3D
Actuellement, la spécification d’X3D ne fait pas mention de la technique de point sprite. Elle permet cependant d’associer une
texture à un ensemble de points, comme nous l’avons vu.
Les premières idées, pour intégrer les point sprites à X3D, ont été d’ajouter directement des attributs au noeud PointSet, ou
bien de créer un nouveau noeud PointSpriteSet basé sur PointSet dans le composant Rendering. Finalement, nous
avons jugé plus judicieux de créer un nouveau noeud PointProperties dans le composant Shape.
En effet, cette solution évite la redondance qu’aurait provoqué la création du noeud PointSpriteSet, et respecte davantage la
hiérarchisation d’X3D, en particulier en ce qui concerne la séparation entre géométrie et apparence de l’objet. De plus, nous avons
constaté qu’il existait dans le composant Shape un noeud LineProperties, qui sert à spécifier les propriétés additionelles
du noeud LineSet, mais pas de PointProperties équivalent pour PointSet... nous allons y remédier !
Intégration des point sprites au standard X3D
9 / 13
4.1 Ajout du noeud PointProperties
Voici la spécification que l’on propose pour ce noeud, qui hérite comme LineProperties de X3DAppearanceChildNode et qui sera donc inclu à un document X3D en tant que fils du noeud Appearance :
PointProperties : X3DAppearanceChildNode {
SFBool [in,out] applied
TRUE
SFFloat [in,out] pointsizeScaleFactor 0
SFFloat [in,out] pointsizeMinValue
0
SFFloat [in,out] pointsizeMaxValue
0
SFVec3f [in,out] pointsizeAttenuation 1 0 0
SFNode [in,out] metadata
NULL
}
[-infinity,infinity]
[-infinity,infinity]
[-infinity,infinity]
[0,infinity]
[X3DMetadataObject]
Le noeud PointProperties spécifie des propriétés additionelles applicables à un ensemble de points. Les champs pointsize*
ne devraient s’appliquer que lorsque applied vaut TRUE. Lorsque applied vaut FALSE, les valeurs qui devraient être utilisées
sont celles définies par défaut par le browser.
Le champ pointsizeScaleFactor est un facteur de multiplication qui est appliqué à la taille qu’utilise effectivement le browser
pour afficher les points. Le champ pointsizeMinValue spécifie la taille minimale d’un point, l’unité étant la plus petite taille
représentable par le système d’affichage. Le champ pointsizeMaxValue spécifie la taille maximale d’un point, l’unité étant la plus
petite taille représentable par le système d’affichage. Une valeur négative ou égale à zéro, pour l’un de ces 3 champs, réfère à la
plus petite taille représentable par le système d’affichage.
La taille d’un point diminue avec l’éloignement, comme spécifiée par les trois coefficients d’atténuation pointsizeAttenuation =
(a, b, c). Le facteur d’atténuation est 1 / max(a + b * r + c * r * r, 1), où r est la distance du point à la caméra utilisée pour le
rendu. Les valeurs par défaut correspondent à l’absence d’atténuation. Les valeurs (0, 0, 0) sont identiques à (1, 0, 0). Les valeurs
d’atténuation devraient être supérieures ou égales à zéro.
4.2 Modification du noeud Appearance
La spécification X3D du noeud est complète mais si on ne l’inclue pas dans la grammaire qui définit un document X3D valide,
il ne sert à rien. On le rajoute donc en tant que champ du noeud Appeareance en redéfinissant ce dernier de cette manière :
Appearance : X3DAppearanceNode {
SFNode [in,out] fillProperties
SFNode [in,out] lineProperties
SFNode [in,out] pointProperties
SFNode [in,out] material
SFNode [in,out] metadata
MFNode [in,out] shaders
SFNode [in,out] texture
SFNode [in,out] textureTransform
}
NULL
NULL
NULL
NULL
NULL
[]
NULL
NULL
[FillProperties]
[LineProperties]
[PointProperties]
[X3DMaterialNode]
[X3DMetadataObject]
[X3DShaderNode]
[X3DTextureNode]
[X3DTextureTransformNode]
Le champ pointProperties, si spécifié, devrait contenir un noeud PointProperties. Si pointProperties est NULL ou nonspécifié, le champ pointProperties n’a aucun effet.
Lorsque le champ pointProperties est correctement spécifié :
– et que le champ texture est lui aussi spécifié, ce dernier est utilisé pour afficher les points sous forme de point sprites ;
– et que le champ texture n’est pas défini, les points sont affichés anti-aliasés.
4.3 Répercussions sur l’encodage XML et VRML
Il reste enfin à spécifier comment ces modifications de la norme d’X3D doivent être encodées, pour qu’elles soient utilisables de
manière pratique. On reprend le même système de notation que celui utilisée par la norme ISO/IEC 19776:2005.
Intégration des point sprites au standard X3D
10 / 13
En XML :
<PointProperties
DEF=""
USE=""
pointsizeScaleFactor="0"
pointsizeMinValue="0"
pointsizeMaxValue="0"
pointsizeAttenuation="1 0 0"
containerField="pointProperties"
/>
ID
IDREF
SFFloat
SFFloat
SFFloat
SFVec3f
NMTOKEN
On considère que l’encodage XML du noeud Appearance n’a pas à être modifié, car les champs de ce dernier sont spécifiés de
manière dynamique par la norme. Le fait d’avoir fait dériver PointProperties de X3DAppearanceChildNode suffit.
En Classic VRML :
PointProperties {
inputOutput SFBool
inputOutput SFFloat
inputOutput SFFloat
inputOutput SFFloat
inputOutput SFVec3f
inputOutput SFNode
}
applied
pointsizeScaleFactor
pointsizeMinValue
pointsizeMaxValue
pointsizeAttenuation
metadata
Appearance {
inputOutput
inputOutput
inputOutput
inputOutput
inputOutput
inputOutput
inputOutput
}
fillProperties
lineProperties
pointProperties
material
metadata
texture
textureTransform
SFNode
SFNode
SFNode
SFNode
SFNode
SFNode
SFNode
4.4 Exemples d’utilisation de PointProperties
Voyons maintenant comment utiliser en pratique le nouveau noeud que nous venons de définir. Pour que la technique de point
sprites soit exploitée, il faut qu’une texture et qu’un PointProperties soient spécifiés dans le même noeud Appeareance.
<Scene>
<Shape>
<PointSet>
<Coordinate point="0 0 0 1 1 1 1 2 2" />
<Color color="1 0 0 1 0 0 1 0 0" />
</PointSet>
</Shape>
<Appearance>
<PointProperties pointsizeScaleFactor="10" />
<ImageTexture url="image.png" />
</Appearance>
</Scene>
Cet exemple affichera 3 carrés de côté 10 (l’unité est dépendante du browser), qui sont centrés à partir des valeurs spécifiées dans
Coordinate, et qui sont orientés de telle manière à ce que leurs normales pointent toujours vers l’objectif de la caméra. On
leur applique de plus la texture image.png, qui est entièrement utilisée.
On peut aussi faire varier la taille des points par rapport à leur éloignement de la caméra, en jouant avec le paramètre pointsizeAttenuation de PointProperties :
Intégration des point sprites au standard X3D
11 / 13
<Scene>
<Shape>
<PointSet>
<Coordinate point="0 0 0 1 1 1 1 2 2" />
<Color color="1 0 0 1 0 0 1 0 0" />
</PointSet>
</Shape>
<Appearance>
<PointProperties pointsizeScaleFactor="10" pointsizeAttenuation="1 .01 0.001" />
<ImageTexture url="image.png" />
</Appearance>
</Scene>
Les attributs pointsizeMinValue et pointsizeMaxValue s’utilisent de la même manière.
5 Implémentation avec Xj3D
Nous allons maintenant décrire les différentes étapes qui ont permis d’implémenter les modifications apportées à la norme dans
le toolkit Xj3D.
Nous n’avons pas réussi à compiler les sources d’Xj3D, que ce soit Linux ou Windows, avec le Makefile fourni, en utilisant l’IDE
Eclipse ou encore Cygwin. Finalement nous avons utilisé une technique qui nous a été suggérée par Franck Kolb. Elle consiste
à importer toutes les classes précompilées dans des JARs au sein d’un projet NetBeans, puis à ne rajouter que les seuls fichiers
sources que l’on veut modifier dans le répertoire source du projet.
Nous avons donc utilisé l’IDE NetBeans sous Windows, mais cette procédure devrait aussi fonctionner avec Eclipse et/ou sous
Linux.
5.1 Préparation de NetBeans
Xj3D est un toolkit Java utilisant la librairie Aviatrix3D, qui est elle-même une surcouche à JOGL, une implémentation d’OpenGL
pour Java. Dans cette section, nous allons préparer tout ce qui est nécessaire à la modification et la compilation des sources
d’Xj3D avec NetBeans.
Commencez par télécharger et installer le Java Development Kit (JDK) 6 qui est disponible ici. Faites de même pour l’IDE
NetBeans 5.5 qui se trouve là. Téléchargez et installez ensuite le JAR auto-extractible d’Xj3D daté du 09/01/2007 : ici ou là.
Récuperez par CVS les sources d’Xj3D qui sont censées avoir servies à la création du précédent JAR, en tapant :
$ export CVSROOT=:pserver:[email protected]:/cvs/xj3d/cvsroot
$ cvs login
$ cvs -q checkout -D "09 Jan 2007" -P Xj3D
Cette opération peut durer plusieurs minutes... Pour accélérer le téléchargement, nous vous proposons une archive équivalente
qui est disponible ici. Il vous suffira de l’extraire quelque part sur votre disque dur.
Exceptionnellement, nous aurons aussi à modifier un fichier de la librairie Aviatrix3D. C’est pourquoi vous êtes invités à télécharger les sources d’Aviatrix3D et à les extraire quelque part sur votre disque dur. Elles sont disponibles là.
Lancez maintenant NetBeans, puis créez un nouveau projet de type Java Application. Appelez-le par exemple Xj3D et situez-le
dans C:. Cochez éventuellement Set as Main Project mais décochez Create Main Class. Cliquez enfin sur Finish.
Faites un clic droit sur le projet pour éditer ses propriétés et supprimez le Test Package Folder qui a été défini par défaut. Dans
l’onglet Compile de la catégorie Librairies, ajoutez C:/ProgramFiles/Xj3D/apps/browser/xj3d_browser_2.0.
0.jar ainsi que tous les JARs situés dans C:/ProgramFiles/Xj3D/jars.
Dans la catégorie Run, saisissez à la main pour Main Class la valeur xj3d.browser.Xj3DBrowser, meme si en cliquant
sur Browse aucune classe n’est trouvée. Pour Working Directory, choisissez <project>/dist, où <project> est le répertoire
qui stocke votre projet. Enregistrez les paramètres avec le bouton OK.
Intégration des point sprites au standard X3D
12 / 13
Vérifiez si jusque là tout va bien en cliquant droit sur le projet puis en choisissant Build Project. Copiez toutes les DLL qui sont
dans C:/ProgramFiles/Xj3D/bin dans <project>/dist. Vous pouvez désormais lancer Xj3D en double-cliquant sur
<project>/dist/Xj3D.jar.
5.2 Insertion des sources à modifier
Les sources d’Xj3D sont composés d’une multitude de fichiers organisés en plusieurs packages. On souhaite n’insérer ici que les
fichiers que l’on va devoir modifier. Pour savoir desquels il s’agit, la lecture de ces quelques articles sera certainement très utile :
http://www.xj3d.org/arch.html.
Les modifications que nous allons apporter sont localisées dans les packages org/web3d/vrml/renderer/common/nodes/shape et org/web3d/vrml/renderer/ogl/nodes/shape. Nous allons agir sur le noeud Appareance pour
lui rajouter le support de PointProperties, et créer ce nouveau noeud et se basant sur LineProperties.
Copiez, depuis les sources CVS d’Xj3D vers votre répertoire <project>/src, les fichiers suivant en recréant leurs arborescence :
config/3.0/profiles.xml
config/3.0/XMLcontainerfields.properties
org/web3d/vrml/renderer/common/nodes/shape/BaseAppearance.java
org/web3d/vrml/renderer/common/nodes/shape/BaseLineProperties.java
org/web3d/vrml/renderer/ogl/nodes/shape/OGLAppearance.java
org/web3d/vrml/renderer/ogl/nodes/shape/OGLLineProperties.java
Faites de même pour celui-ci qui se situe dans les sources d’Aviatrix3D :
java/org/j3d/aviatrix3d/PointAttributes.java
Ces fichiers, qui ont été directement inclus dans le répertoire src de votre projet, seront utilisés en priorité par rapport aux fichiers
pré-compilés qui sont dans les JARs.
5.3 Modification des sources
Pour commencer, nous allons ajouter la reconnaissance du nouveau noeud PointProperties à Xj3D. L’application n’utilise
pas de grammaire strictement définie. Nous allons lui faire prendre connaissance, dans un premier temps, de l’existence du
nouveau noeud puis c’est directement dans BaseAppearance.java que les champs de ce dernier seront pris en charge.
Dans le fichier profiles.xml, rajoutez juste en dessous de :
<node name="LineProperties">
la ligne suivante :
<node name="PointProperties">
Puis dans XMLcontainerfields.properties, insérer selon l’ordre alphabétique la ligne :
PointProperties: pointProperties
Ensuite, dans chacun des fichiers BaseAppearance.java et OGLAppearance.java, ajouter le support du champ pointProperties en vous inspirant de lineProperties. Parfois, l’opération nécessite un minimum d’analyse, par exemple pour les champs
FIELD_* qui sont définis incrémentalement.
Renommez les deux fichiers BaseLineProperties.java et OGLLineProperties.java en BasePointProperties.
java et OGLPointProperties.java. Adaptez leurs contenus à la spécification de PointProperties. En particulier,
OGLPointProperties.java utilise la classe PointAttributes d’Aviatrix3D pour définir la taille des points, à l’aide
des méthodes setPointSize, setMinPointSize, setMaxPointSize et setAttenuationFactors.
Nous allons maintenant faire en sorte d’utiliser les point sprites lorsqu’une texture est spécifiée, et d’activer l’anti-aliasing sinon. La encore, nous n’avons pas besoin d’utiliser directement JOGL puisqu’Aviatrix3D gère l’extension GL_ARB_point_sprite
Intégration des point sprites au standard X3D
13 / 13
d’OpenGL depuis sa version 2.0. Les modifications s’effectuent dans OGLAppeareance.java, en particulier au sein des méthodes setupFinished et textureImageChanged. Pour savoir si PointProperties a été spécifié dans le noeud Appearance,
on teste le champ de classe vfPointProperties. Pour savoir si une texture a été définie, on teste le champ vfTexture. Les méthodes
d’Aviatrix3D dont on doit se servir sont listées ci-dessous :
–
–
–
–
PointAttributes.setPointSize pour paramétrer la taille d’un point ;
PointAttributes.setPointSpriteEnabled pour activer l’utilisation des point sprites ;
PointAttributes.setAntiAliased pour activer l’anti-aliasing sur les points ;
TextureAttributes.setPointSpriteCoordEnabled pour activer le calcul automatique des coordonnées de textures lorsque
l’on utilise des point sprites.
Enfin, il faut apporter une modification au fichier PointAttributes.java d’Aviatrix3D, pour corriger un petit bug relatif
aux coefficients d’atténuation. Dans la méthode setAttenuationFactors, aux alentours de la ligne 480, remplacez :
if ((a == 1) && (b == 1) && (c == 1))
needAttenuation = false;
Par :
if ((a == 1) && (b == 0) && (c == 0))
needAttenuation = false;
else
needAttenuation = true;
5.4 Tests
Vous n’avez plus qu’à recompiler le projet en cliquant sur Build Project dans son menu contextuel, puis double-cliquez sur
<projet>/dist/Xj3D.jar pour lancer Xj3D. Vous pouvez essayez le chargement de ces quelques fichiers de tests : ici.
6 Pointeurs
http://www.web3d.org/x3d/specifications : toutes les spécifications ISO/IEC relatives à X3D.
http://www.web3d.org/x3d/learn : ressources complémentaires sur X3D.
http://www.web3d.org/x3d/content/examples/Basic/index.html : des exemples de document X3D.
http://www.web3d-fr.com/X3D/DossierX3D.php : des articles d’introduction à X3D.
http://www.swirlx3d.com/tutorials.htm : des tutoriaux VRML et X3D.
http://www.xj3d.org : site officiel d’Xj3D, avec entre autres des documentations utiles aux développeurs ici.
http://aviatrix3d.j3d.org : site officiel d’Aviatrix3D.
http://www.opengl.org/registry/... : spécification de l’extension OpenGL relative aux point sprites.
http://helios.univ-reims.fr/Labos/... : cours d’OpenGL sur les point sprites.
Téléchargement