• Aucun résultat trouvé

Une ´evaluation assist´ee

4.3 Perspectives

5.2.3 Une ´evaluation assist´ee

L’´evaluation du mod`ele dans le but de son affichage est un proc´ed´e complexe assur´e par Dy-namic Graph. Avant de d´etailler dans le chapitre suivant les subtilit´es de cette ´evaluation, nous donnons ici un premier aper¸cu rapide.

Un organiseur, au moyen de visiteur (voir plus bas), contrˆole l’ordre de l’´evaluation de chaque amplifieur. Ce contrˆole est n´ecessaire pour de nombreuses raisons, notamment `a cause des contraintes ´emanant de l’algorithme de visibilit´e. Ce contrˆole n´ecessite un ´echange complexe entre l’organiseur (via les visiteurs) et les amplifieurs.

Visiteur

Un visiteur est une fonction (un objet) qui parcours l’arbre d’´evaluation et applique un trai-tement sur tous les noeuds (les amplifieurs). Chaque amplifieur est sp´ecialis´e grˆace au polymor-phisme et au m´ecanisme des fonctions virtuelles [Cha98]. Le traitement appliqu´e aux noeuds est donc diff´erent pour chaque couple (visiteur,amplifieur).

Un visiteur sait comment stimuler un amplifieur : de leur ´echange naˆıt l’information d´esir´ee. Voici les visiteurs couramment utilis´es dans Dynamic Graph :

g´en´erateur : ce visiteur construit l’arbre ;

GL GL GL GL GL Commandes GL Classe amplifieur Amplifieur -NISEUR ORGA-V V V Donn´ees d’entr´ee :

Fig. 5.7 – On reprend ici la figure 5.2 en rajoutant l’organiseur et ses visiteurs. L’organiseur s’occupe du bon ordonnancement des tˆaches n´ecessaires aux contraintes ´emanant de certaines fonctionnalit´es (tel que l’algorithme de d´etection d’occultation).

redessinateur : il redessine les informations contenu dans un arbre d´ej`a g´en´er´e ;

visualiseur : il affiche l’arbre de fa¸con formelle (noeud et arˆete), ce qui est utile lors du debogage du mod`ele.

Le g´en´erateur est le visiteur le plus important : c’est lui qui, `a mesure qu’il parcourt l’arbre d’´evaluation, construit ce dernier. Cela peut paraˆıtre paradoxal de parcourir un arbre en mˆeme temps qu’on le construit. Pour que le g´en´erateur puisse visiter un arbre comme s’il ´etait d´ej`a construit, il g´en`ere lui-mˆeme les fils des amplifieurs qu’il veut visiter plus profond´ement. Ce faisant, le g´en´erateur se maintient dans l’illusion de l’existence d’un arbre infini. Cet algorithme est inspir´e des m´ethodes de la th´eorie des jeux telle que le branch and bound [BCL+99].

L’organiseur

L’un des rˆoles fondamental de l’algorithme de rendu est de bien distribuer le temps de calcul et d’activer tel ou tel amplifieur selon des crit`eres de performances particuliers (que nous verrons en d´etails plus tard). L’algorithme de rendu est pour cette raison appel´e l’organiseur : il organise l’activit´e pour optimiser les performances.

On peut ici reprendre les notions qui ont ´et´e n´ecessaires `a la d´efinition de la mod´elisation proc´edurale et en particulier, discuter du d´ecoupage entre“programme”et“donn´ee”(cf. sous-section 3.1.1). L’organiseur, avec ces visiteurs, est la partie du programme qui se trouve `a la fronti`ere des donn´ees d’entr´ee. Les g´en´erateurs d’amplifieurs, les amplifieurs et enfin les commandes OpenGL produites sont les donn´ees utilisateur `a leur diff´erentes repr´esentations au fil de l’´evaluation (cf. figure 5.7).

´

Evaluation par morceau

Comme les amplifieurs g´en`erent d’autres amplifieurs, on pourrait croire qu’une fois l’´evaluation commenc´ee, il est impossible de l’arrˆeter. Ce comportement est celui des fonctions r´ecursives : les appels s’enchaˆınent sans jamais rendre la main jusqu’`a ce que tous les crit`eres d’arrˆet soient satis-faits (cf. figure 5.8). Dynamic Graph propose un comportement similaire `a ces fonctions r´ecursives mais permet un bien meilleur contrˆole de leur ex´ecution.

Appel d’une sous-fonction

temps CPU n´ecessaire `a l’´evaluation Parcours

de l’´evaluation

Fonction principale

Fig. 5.8 – Dans Dynamic Graph, la construction de l’arbre d’´evaluation est parfaitement contrˆol´ee par l’organiseur. Contrairement `a de simples fonctions r´ecursives, Dynamic Graph permet de rendre la main `a l’organiseur apr`es la fin de l’´evaluation de chaque amplifieur. De cette fa¸con, l’organiseur a tous les pouvoirs pour diriger les op´erations dans un ordre ad´equat.

G´en´eration et parcours de l’arbre d’´evaluation (par commodit´e)

Distance `a la cam´era

Fig. 5.9 – Un parcours tri´e en profondeur d’abord assure un rendu de l’avant vers l’arri`ere. Un noeud envoie ses commandes OpenGL d`es que possible. Les feuilles visibles repr´esent´ees par deux cercles imbriqu´es sont les amplifieurs les plus susceptibles de s’afficher. Sur ce sch´ema, par commodit´e de repr´esentation, les amplifieurs `a droite de l’arbre sont les plus distants de la cam´era.

Ce contrˆole est essentiel pour diverses raisons. Notamment, l’ordre d’affichage des amplifieurs est important : l’algorithme de visibilit´e qui sera expliqu´e dans la section 6.3 n´ecessite un rendu de l’avant vers l’arri`ere. On pourrait construire tout l’arbre d’´evaluation d’abord pour le trier et l’afficher ensuite. Malheureusement, ce mˆeme algorithme n´ecessite d’afficher les amplifieurs le plus tˆot durant la construction : le premier amplifieur est rendu alors que la construction vient `a peine de commencer.

Pour r´esoudre ce probl`eme, l’arbre est construit approximativement de l’avant vers l’arri`ere (d’autres contraintes peuvent peser sur la construction). Lorsqu’un amplifieur est prˆet `a ˆetre affich´e, l’organiseur le place dans une liste d’attente qui r´etablit un ordre plus strict. Pour r´ealiser cela, un amplifieur, lorsqu’il g´en`ere des amplifieurs fils, construit ces derniers sans les ´evaluer. L’organiseur choisira plus tard s’il d´ecide de les ´evaluer ou s’il est temps de lancer l’affichage de certains amplifieurs pour cela.

´

Echange entre le mod`ele et le programme

L’organiseur doit ˆetre capable de communiquer avec les amplifieurs directement ou via un visiteur. Les fonctions d’´echange s’occupent d’une partie de ce travail : elles fournissent notamment l’amplifieur axiome et assurent aussi certaines initialisations sans lesquelles le mod`ele ne peut pas ˆetre ´evalu´e. De plus, Dynamic Graph sait comment communiquer avec chaque g´en´erateur d’amplifieurs car ceux-ci h´eritent d’une classe virtuelle connue par l’organiseur.

Voici les fonctions que l’organiseur est susceptible d’appeler sur chaque amplifieur :

– initialisation ;

– fonctions diverses de navigation au sein d’un arbre (indiquer le fils, le p`ere...) ;

– affichage de la forme ;

– calcul de la visibilit´e ;

– calcul de la pr´ecision.

Dans certains cas, ces fonctions sont virtuelles pures, ce qui signifie que le cr´eateur doit obliga-toirement donner le code de cette fonction. Dans d’autres cas, ces fonctions sont virtuelles “tout court”, ce qui signifie qu’un comportement par d´efaut est disponible. Pour des raisons diverses (performances, qualit´e, contrˆole), le cr´eateur peut choisir de personnaliser ces derni`eres pour un amplifieur particulier.

5.2.4 Animation

Dynamic Graph propose une ´evaluation de la forme visible `a la vol´ee. Afin de permettre l’op-timisation par coh´erence temporelle, des m´emoires `a plus ou moins long terme sont propos´ees au cr´eateur. Un exemple simple et concret motive ce besoin.

M´emoire de l’information `

A chaque pas de temps, un nouvel arbre d’´evaluation est enti`erement r´eg´en´er´e (i.e. la sc`ene est enti`erement reconstruite). En effet, la structure tr`es dynamique de Dynamic Graph impose une ´evaluation `a la vol´ee. Utilis´ee na¨ıvement, cette r´eg´en´eration supprime toute possibilit´e d’optimiser le programme par coh´erence temporelle. Afin de ne pas passer son temps `a recalculer la mˆeme fonction mille fois, Dynamic Graph permet une certaine m´emoire des op´erations effectu´ees aux pas de temps pr´ec´edents.

Cette m´emoire est principalement impl´ement´ee via un tampon d’arbres qui stocke les n der-niers arbres d’´evaluation. Chaque arbre d’´evaluation a acc`es aux arbres plus anciens et peut donc retrouver des r´esultats effectu´es r´ecemment. Plus g´en´eralement, Dynamic Graph permet d’utiliser toute une panoplie de m´emoires `a plus ou moins long terme et propose diff´erentes fr´equences de calculs selon le type de fonction.

Voyons maintenant au travers d’un exemple simple une utilisation possible de la m´emoire et de la coh´erence temporelle.

Exemple : la brise l´eg`ere

L’animation est calcul´ee durant la construction d’un objet. Les fonctions d’animation modifient certaines donn´ees pr´esentes dans les amplifieurs. Elle incr´emente une position : x = x + v.δt. Dynamic Graph propose des fonctionnalit´es avanc´ees dans la gestion de la persistance des donn´ees. C’est un point essentiel du fonctionnement de Dynamic Graph, mais il est difficile `a motiver de fa¸con g´en´erale. Je vais donc l’introduire par un exemple.

On peut imaginer impl´ementer un mouvement par d´efaut de l’herbe, comme une brise l´eg`ere2. Cette fonction d’animation est r´ealis´ee par la donn´ee d’une position du brin d’herbe au repos : la brise l´eg`ere induit de l´eg`eres oscillations autour de cette position. Compte tenu de la g´en´eration `a la vol´ee, cette m´ethode pose un probl`eme a priori anodin : o`u stocker cette position au repos ? Dur´ee de vie d’une information

Voici deux fa¸cons extrˆemes et inappropri´ees d’acc´eder `a cette information :

permanent : m´emoriser les positions au repos de tous les brins d’herbe induirait une description partielle au niveau le plus fin `a ´eviter absolument ;

´

eph´em`ere : une fonction pseudo-al´eatoire peut g´en´erer `a la vol´ee et `a chaque pas de temps une position au repos pour chaque brin d’herbe. Ceci implique, pour tous les brins d’herbe, un calcul reproduit `a l’identique `a chaque pas de temps. De plus, l’information de cette position

2La brise l´eg`ere anime donc tous les brins d’herbe, mais elle laisse aux autres primitives de vent la possibilit´e d’influencer. Du point de vue de l’amplifieur, on peut parler d’animation interne (la brise l´eg`ere) et d’animation externe (les autres primitives de vent).

au repos sera stock´e dans chaque amplifieur `a chaque pas de temps, r´esultant en un gaspillage de place m´emoire.

Dans le cas de description au niveau le plus fin, le probl`eme de la dur´ee de vie ne se pose pas : toute l’information existe `a tous les pas de temps. En revanche, dans le cas d’une g´en´eration `a la vol´ee, la gestion de la persistance m´emoire est beaucoup plus d´elicate. Dans l’exemple cit´e plus haut, il serait souhaitable, dans l’id´eal, de n’allouer la position au repos d’un brin d’herbe qu’une fois par apparition sur l’´ecran : si, d’une image `a l’autre, le mˆeme brin est visible, la mˆeme information peut ˆetre utilis´ee. Dynamic Graph permet ce genre de m´ecanisme et propose une gamme de m´emoires dont la dur´ee de vie varie de permanente `a ´eph´em`ere. Ces fonctionnalit´es sont une premi`ere forme simpliste d’optimisation par coh´erence temporelle et sont le fondement de toute utilisation plus complexe de ce dispositif.

5.3 Bilan interm´ediaire