<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="rapport.xsl"?>
<document title="Rapport complet">
	<documentclass option="a4paper, 10pt" class="book"/>
	<usepackage package="fullpage"/>
	<usepackage package="url"/>
	<usepackage option="T1" package="fontenc"/>
	<usepackage option="latin1" package="inputenc"/>
	<usepackage option="french" package="babel"/>
	<usepackage package="color"/>
	<usepackage package="epsfig"/>
	<usepackage package="float"/>
	<!--%\usepackage{fancyhdr}-->
	<usepackage package="algorithmic"/>
	<usepackage package="algorithm"/>
	<usepackage package="subfigure"/>
	<usepackage package="pstricks"/>
	<usepackage package="makeidx"/>
	<!--%\pagestyle{fancy}-->
	<title>TER Stage<br/>MOTEUR PHYSIQUE</title>
	<authors>
		<author href="eric@skbo.net">
			<first>Éric</first>
			<name>Mounhem</name>
		</author>
		<author href="bowno@noos.fr">
			<first>Bruno</first>
			<name>Paillier</name>
		</author>
	</authors>
	<date/>
	<makeindex/>
	<doc>
		<input>titre.tex</input>
		<frontmatter/>
		<!--maketitle/-->
		<vspace dimension="5cm"/>
		<center>
			<textbf>
				<large>Présentation</large>
			</textbf>
		</center>
		<em>Ce travail a été effectué dans le cadre d'un <acronym><title>Travail d'Étude et de Recherche</title>TER-Stage</acronym> au <acronym><title>Laboratoire d'Informatique pour la Mécanique et les Sciences de l'Ingénieur</title>LIMSI</acronym>, projet d'une durée de six mois imposant une demi-journée hebdomadaire en laboratoire encadré par un chercheur, au cours de notre Maîtrise d'informatique à l'Université Paris-Sud Orsay.</em><br/>
		<em>Le sujet proposé était de réaliser un moteur physique pour le logiciel de description de scènes <url href="http://virchor.sourceforge.net/index.html">Virtual Choreographer</url> créé par Christian Jacquemin. Ce logiciel permet de construire des scènes qui pourront ensuite être rendues en temps réel avec <url href="http://www.opengl.org">OpenGL</url> ou par des programmes externes tels que <url href="http://www.povray.org">PovRay</url> et <url href="http://www.renderman.org">Renderman</url>.</em><br/>
		<em>Le domaine de la physique étant extrêmement large, nous avons décidé de travailler essentiellement au niveau de la gestion des collisions, élément important d'un moteur physique. Le rendu temps réel de <em>Virtual Choreographer</em> impose des coûts réduits en temps et par conséquent un algorithme adapté.</em><br/>
		<em>Pour la partie physique pure, nous nous sommes limités à des collisions sans déformations, ni frottements et à la gestion de la gravité.</em>
		<tableofcontents/>
		<mainmatter/>
		<chapter>
			<title>Introduction</title>
			<sec1>
				<title>Le problème des collisions</title>
				Le but de la gestion de collision est de corriger le comportement des éléments d'une scène afin d'empêcher des comportements impossibles tels que le chevauchement de deux objets, ou un objet qui en traverse un autre, etc. Intuitivement on comprend bien qu'il faut tester chaque objet avec les autres éléments de la scène afin de voir s'il entre en collision avec un autre auquel cas on lui applique une fonction <guill>réaction physique</guill> qui corrigera les trajectoires.

				Cependant l'idée naïve de tester chaque objet avec l'ensemble de la scène est irréaliste dans un rendu temps réel d'une scène pouvant contenir des centaines d'objets sachant qu'il est nécessaire, pour améliorer le réalisme, de connaître les triangles des maillages en contact. De tels algorithmes ne conviennent donc pas à un traitement brutal sur l'ensemble de la scène.

				De nombreuses recherches ont donc été effectuées afin d'optimiser au mieux ce processus coûteux.
			</sec1>
			<sec1>
				<title>Principe de traitement</title>La méthode retenue est un traitement par phases de plus en plus précises.
				<enumerate>
					<item><em>Détection des collisions</em><nbsp/>:<br/><index>Collision!Détection</index>
						On cherche les paires d'objets qui peuvent être en collision parmi toute la combinatoire possible pour la scène. On se contente de faire des approximations peu précises des objets, l'important étant que le traitement élimine rapidement les éléments qui ne peuvent être en collision parce qu'ils sont trop éloignés les uns des autres.</item>
					<item><em>Détermination de la collision</em><nbsp/>:<index>Collision!Détermination</index><br/>
						ou encore <em>Localisation du contact</em>,

						Cet algorithme prend en entrée deux objets et indique s'ils sont en situation de collision. Si c'est le cas, il peut renvoyer des informations supplémentaires telles que le point de collision, la normale au point, le ou les triangle(s) de contact, la distance de pénétration, etc.

						Cet algorithme coûteux n'est appelé que sur les objets qui n'ont pas été éliminés à l'étape précédente limitant les calculs inutiles.</item>
					<item><em>Résolution de la collision</em><nbsp/>:<index>Collision!Résolution</index><br/>
						On agit sur les objets en réaction à la collision afin de corriger la scène en supprimant les comportements impossibles physiquement. Cette phase n'est pas vraiment complexe du point de vue algorithmique, mais elle l'est du point de vue physique suivant le degré de réalisme que l'on veut atteindre.</item></enumerate>Il existe également des détecteurs de collision qui séparent la phase de détermination de la collision en deux avec une première passe cherchant si des triangles sont susceptibles de se chevaucher et une seconde pour les trouver. Toutes ces étapes intermédiaires permettent de gagner du temps dans le cas où les phases suivantes sont inutiles et évitent d'appliquer des algorithmes coûteux pour rien.</sec1>
			<sec1>
				<title>Structure du rapport</title>
				Dans le deuxième chapitre, nous verrons quelques méthodes de détection de collisions. Ensuite, nous décrirons les algorithmes de détermination de collisions sur lesquels nous nous sommes documentés. Dans le quatrième chapitre nous expliciterons la physique utilisée avant de conclure sur l'intégration du moteur au sein de <em>Virtual Choreographer</em>.
			</sec1>
		</chapter>
		<chapter>
			<title>Détection de collisions</title>
			<index>Collision!Détection</index>
			Comme nous l'avons dit, le but de cette partie est d'éliminer rapidement les objets qui n'ont aucune chance d'être en contact. Il ne s'agit donc pas d'être trop précis et on peut se permettre d'approximer les objets par des volumes englobants <index>Volume englobant</index>. Le choix de ce volume englobant n'en reste pas moins une question délicate dépendante du cadre de l'application. Par exemple, dans le cadre d'un jeu, il est plus intéressant d'approximer un personnage par un cylindre que par une sphère et de se contenter de faire des tests sur le cylindre.

			Ici nous allons voir deux volumes englobants classiques que sont la sphère et la boîte englobante. Ensuite nous décrirons rapidement une autre méthode de test de collision par l'utilisation d'arbres BSP.

			<sec1>
				<title>Deux premiers volumes englobants</title>
				<sec2>
					<title>La sphère</title>
					<index>Volume englobant!Sphère</index>
					La sphère est un volume qui se prête bien à ce rôle de volume englobant (Fig. <ref>sphere1</ref>). En effet le test de collision entre deux sphères ne coûte rien puisqu'il suffit de voir si la distance entre les centres est inférieure à la somme des rayons. De plus la sphère n'a pas besoin d'être orientée, juste positionnée.<br />

					Par contre, le calcul de la sphère englobante n'est pas aussi simple qu'il n'y paraît, car, s'il est facile de trouver une sphère, obtenir la sphère optimale est plus complexe. Il est toutefois possible d'accélérer le calcul en appliquant des heuristiques telles que l'algorithme linéaire de Ritter décrit sur le site de Dan Sunday <cite>ritter</cite><nbsp/>:
					<itemize><item>On parcourt la liste des points de l'objet à la recherche de deux points éloignés (mais pas obligatoirement les plus éloignés de l'ensemble). Ces deux points constituent le diamètre de la sphère initiale.</item><item>On parcourt une nouvelle fois l'ensemble de points en testant si les points sont à l'intérieur de la sphère. À l'étape <m>i</m>, si le point <m>p<s>i+1</s></m> est inclus dans la sphère <m>S<s>i</s></m>, alors <m>S<s>i+1</s> = S<s>i</s></m>. Si <m>p<s>i+1</s></m> est en dehors de <m>B<s>i</s></m>, il faut alors agrandir <m>B<s>i</s></m> jusqu'à avoir <m>p<s>i+1</s></m>. Pour cela, on trace une ligne partant de <m>p<s>i+1</s></m>, passant par le centre de <m>B<s>i</s></m>, que l'on prolonge jusqu'à atteindre l'autre côté de la sphère. Cette ligne sera le nouveau diamètre de la nouvelle sphère <m>B<s>i+1</s></m> qui contient <m>p<s>i+1</s></m> ainsi que <m>B<s>i</s></m>, et par conséquent tous les points déjà vus, comme on peut le voir sur le dessin (Fig. <ref>bsphere</ref>).</item></itemize>
					<figure position="!htb">
						<subfigure>
							<input type="pstex" scale="0.7" href="figures/BoundingBall.tex"/>
							<caption>Construction itérative d'une sphère englobante</caption>
							<label>bsphere</label>
						</subfigure>
					</figure>

					Cette méthode approximative permet de calculer rapidement une sphère englobante proche de l'optimale et Ritter estime que l'erreur commise est de moins de 5%.

					Néanmoins, dans certains cas, l'approximation peut se révéler un peu trop forte et peu adaptée à l'objet (Fig. <ref>sphere2</ref>). La sphère est alors essentiellement constituée de vide.

					<figure position="!htb">
						<subfigure>
							<input type="eps" href="figures/sphereEnglobanteNormale.eps"/>
							<caption>Sphère englobante bien adaptée à la forme de l'objet</caption>
							<label>sphere1</label>
						</subfigure>
						<subfigure>
							<input type="eps" href="figures/sphereEnglobanteNulle.eps"/>
							<caption>Sphère englobante trop grande pour l'objet</caption>
							<label>sphere2</label>
						</subfigure>
					</figure>
				</sec2>
				<sec2>
					<title>Les <em>Axis Aligned Bounding Boxes</em></title>
					<index>Volume englobant!AABB</index>
					Mis à part pour les objets sphériques, les sphères ne constituent pas une très bonne approximation risquant de réduire le nombre d'objets éliminés pendant la phase de détection de collisions. Pour un coût pratiquement équivalent, il est donc plus judicieux de remplacer la sphère par une boîte englobante dont les côtés sont parallèles aux axes du repère. Ce sont les <em><acronym><title>Axis Aligned Bounding Boxes</title>AABB</acronym></em> (Fig. <ref>aabb1</ref> et <ref>aabb2</ref>).

					<figure position="!htb">
						<subfigure>
							<input type="eps" href="figures/AABBNormale.eps"/>
							<caption>AABB</caption>
							<label>aabb1</label>
						</subfigure>
						<subfigure>
							<input type="eps" href="figures/AABBGere.eps"/>
							<caption>AABB réduite</caption>
							<label>aabb2</label>
						</subfigure>
					</figure>

					Pour construire une AABB d'un objet, il suffit de prendre le maximum et minimum des coordonnées suivant les trois axes du repère puis de tracer les plans passant par ces coordonnées. L'intersection de ces plans forme l'AABB (Fig. <ref>constructionaabb</ref>).

					<figure position="!htb">
						<subfigure>
							<input type="eps" scale="0.7" href="figures/ConstructionAABB.eps"/>
							<caption>Construction d'une boîte englobante axée sur les axes (<em>AABB</em>)</caption>
							<label>constructionaabb</label>
						</subfigure>
					</figure>

					Cependant certains objets se prêtent mal aux AABB, notamment si l'objet est incliné à 45<degres/> (Fig. <ref>aabbnulle</ref> et <ref>bonnesphere</ref>).

					<figure position="!htb">
						<subfigure>
							<input type="eps" href="figures/AABBNulle.eps"/>
							<caption>AABB moins optimale</caption>
							<label>aabbnulle</label>
						</subfigure>
						<subfigure>
							<input type="eps" href="figures/sphereEnglobanteAussiNulle.eps"/>
							<caption>Sphère englobante identique</caption>
							<label>bonnesphere</label>
						</subfigure>
					</figure>

					Après avoir vu ce que sont les AABB, nous allons les utiliser pour la première phase du traitement des collisions.
			</sec2></sec1>
			<sec1>
				<label>collisionAABB</label>
				<title>Détection de collision avec les AABB</title>
				<index>Collision!Détection</index>
				Comme il a été dit précédemment, un des problèmes majeurs de la détection de collisions est que l'algorithme doit être en mesure d'indiquer rapidement les objets qui ne peuvent pas être en situation de collision. Or, nous avons vu que tester tous les objets entre eux est une solution beaucoup trop coûteuse, même en utilisant les AABB. Heureusement, il est possible de simplifier le problème grâce à la <em>cohérence temporelle</em>.

				<sec2>
					<title>La cohéerence temporelle</title>
					<index>Cohérence Temporelle</index>
					La cohérence temporelle est une hypothèse simplificatrice qui suppose qu'entre deux frames il ne peut pas y avoir de grands changements au niveau des objets. Plus précisément cela revient à dire que d'une frame à l'autre les objets ne se déplacent pas de grands intervalles (et de même pour les déformations etc.).
				</sec2>
				<sec2>
					<title>Utilisation de la cohérence temporelle</title>
					Dans un premier temps, on projette les boîtes englobantes sur les trois axes du repère. Ceci nous donne des intervalles sur chaque axe pour chaque objet. Deux boîtes se chevaucheront si et seulement si les intervalles se chevauchent sur les trois axes.

					Pour détecter le chevauchement d'un intervalle sur un axe, on procède comme suit<nbsp/>:
					<itemize>
						<item>Pour chaque objet <m>i</m>, on appelle <m>s<s>i</s></m> le début de l'intervalle, <m>e<s>i</s></m> la fin de l'intervalle<nbsp/>;</item>
						<item>On trie les intervalles par <m>s<s>i</s></m> croissant<nbsp/>;</item>
						<item>On parcourt la liste obtenue. Pour chaque <m>s<s>i</s></m> rencontré, on le place dans un ensemble <m>E</m>. Lorsque l'on rencontre <m>e<s>i</s></m>, on retire <m>s<s>i</s></m> de <m>E</m>. Si on rencontre un <m>s<s>i</s></m> alors que <m>E</m> n'est pas vide, c'est que les intervalles se chevauchent.</item>
					</itemize>

					On procède de même sur les trois axes (exemple en dimension 2, Fig. <ref>chevauchementboites</ref> et <ref>pascollision</ref>).

					<figure position="!htb">
						<subfigure>
							<input type="eps" scale="0.5" href="figures/1-axisCollision.eps"/>
							<caption>Chevauchement des boîtes</caption>
							<label>chevauchementboites</label>
						</subfigure>
						<subfigure>
							<input type="eps" scale="0.5" href="figures/1-axisNoCollision.eps"/>
							<caption>Les intervalles se chevauchent sur l'axe des ordonnées, mais pas sur l'axe des abscisses, les boites ne sont pas en contact.</caption>
							<label>pascollision</label>
						</subfigure>
					</figure>

					L'algorithme complet est le suivant<nbsp/>:
					<enumerate>
						<item>À la première frame, on construit les trois listes d'intervalles, puis on les trie sur les débuts d'intervalle en appliquant un algorithme complexe tel que le <em>quicksort</em><nbsp/>;</item>
						<item>On parcourt les listes triées en notant les paires d'intervalles qui se chevauchent<nbsp/>;</item>
						<item>Lorsque les intervalles se chevauchent sur les trois axes, on ajoute la paire d'objets correspondants à la liste des objets pour la suite du traitement<nbsp/>;</item>
						<item>À la frame suivante, la cohérence temporelle nous assure qu'il n'y a pas eu de grands déplacements d'objets et par conséquent les listes d'intervalles sont pratiquement encore triées. On peut donc les trier en appliquant un tri simple comme le <em>tri par insertion</em> ou le <em>tri bulle</em> qui sont efficaces sur les listes triées (<m>O(n)</m>). Ce tri se contentera de parcourir les listes en échangeant simplement quelques débuts d'intervalles.</item>
						<item>On revient à l'étape 2.</item>
					</enumerate>

					Dans le cas de <em>Virtual Choreographer</em>, les AABB ne sont pas fixes<nbsp/>: elles peuvent non seulement être modifiées par un déplacement de l'objet, mais également par une déformation. Ceci n'est cependant pas une difficulté puisqu'on peut également appliquer la cohérence temporelle pour les déformations.
			</sec2></sec1>
			<sec1>
				<title>Détection de collisions utilisant les arbres BSP</title>
				<index>Arbres BSP</index>
				Cet algorithme permet de tester la collision entre un objet et une scène décrite par un arbre BSP.

				Un arbre BSP est un arbre binaire représentant une scène. Il est construit en choisissant un axe placé à un n<oe/>ud de l'arbre et en séparant les polygones de la scène en un ensemble à gauche et un à droite de l'axe, formant les deux fils du n<oe/>ud. On utilise également deux types de feuilles pour savoir si on est à l'intérieur (feuille <guill>pleine</guill>) ou à l'extérieur d'un objet (feuille <guill>vide</guill>). 

				La détection de collision est ensuite effectuée en testant si lors du déplacement dans la scène, et par conséquent dans l'arbre, on est passé par une feuille <guill>pleine</guill>. Si ce n'est pas le cas, le déplacement est valide, sinon il y a eu collision.

				Cette méthode est efficace et très utilisée dans les jeux, notamment les <guill>doom-like</guill>, pour représenter les décors statiques. Dans le cadre de <em>Virtual Choreographer</em>, où nous testons les collisions entre un nombre indéterminé d'objets en mouvement, elle devient inefficace puisqu'il faudrait reconstruire l'arbre BSP à chaque frame.
			</sec1>
			<sec1>
				<title>Conclusion</title>
				Étant donné que dans <em>Virtual Choreographer</em> l'AABB de chaque objet est fournie, nous nous sommes naturellement tournés vers l'algorithme de détection de collisions basé sur ce type de volume englobant. Les AABB sont un bon compromis en terme de simplicité de calcul et d'utilisation et sont suffisament proches des contours des objets pour cette première passe.
			</sec1>
		</chapter>
		<chapter>
			<title>Détermination de collisions</title>
			<index>Collision!Détermination</index>
			La détermination des collisions fait suite à la détection des collisions vue à la section précédente et consiste à déterminer plus précisément l'endroit du contact entre les objets, s'il se trouve qu'il y a effectivement contact. En effet, la détection seule est insuffisante pour modéliser un comportement réaliste des objets. Il est nécessaire, d'une part, de confirmer le contact potentiel relevé à la détection, et d'autre part d'avoir des informations plus précises sur l'endroit du contact, ce qui joue un rôle important dans la réponse physique. Par exemple, lors de rotations des objets à la suite d'un choc, il est intéressant de connaître l'emplacement du contact sur l'objet afin d'avoir un angle de rotation proportionnel à la distance de la projection du point de contact sur la perpendiculaire à la normale passant par le centre de l'objet au centre de gravité de l'objet (voir section <ref>vectRot</ref>).

			<!--% Ici un dessin-->
			Malgré sa précision, la localisation doit pouvoir être effectuée dans des temps raisonnables, particulièrement dans le cas d'applications temps réel.

			Une méthode classique pour atteindre cet objectif est d'utiliser des hiérarchies de volumes englobants. <index>Volume englobant!Hiérarchie</index> Aussi nous allons commencer par voir ce que sont ces hiérarchies, comment les construire et les utiliser efficacement. Puis nous présenterons succintement trois algorithmes de détection de collision avec la méthode utilisée.

			<sec1>
				<title>Hiérarchie de volumes englobants</title>
				Une hiérarchie de volumes englobants est une représentation d'un objet par un arbre, où les n<oe/>uds internes sont des volumes englobants qui entourent tous leurs fils à l'intérieur de leur volume et les feuilles un ensemble non vide de primitives (Fig. <ref>hierarchievolumes</ref>). En général ce sont des arbres binaires qui sont utilisés, étant plus simples et rapides à construire, tout en permettant un traitement efficace.

				<figure position="!htb">
					<subfigure>
						<input type="eps" scale="0.4" href="figures/HierarchiesTree.eps"/>
						<caption>Représention d'une hiérarchie de sphères englobantes. Chaque n<oe/>ud contient une sphère englobant un objet complexe. Cet objet est coupé en deux dans les fils du n<oe/>ud jusqu'à atteindre les feuilles qui ne contiennent, elles, que des primitives de base.</caption>
						<label>hierarchievolumes</label>
					</subfigure>
				</figure>

				Nous allons nous attarder sur ces arbres en abordant leur construction et leur utilisation.

				<sec2>
					<title>Construction d'une hiérarchie</title>

					On note trois manières de construire une hiérarchie<nbsp/>: les méthodes <em>bottom-up</em>, <em>incremental tree-insertion</em> et <em>top-down</em>. 

					<sec3>
						<title>La méthode <em>bottom-up</em></title> <index>Volume englobant!Hiérarchie!Bottom-Up</index> 
						On commence par regrouper des primitives proches par un volume englobant, puis on recommence avec d'autres primitives, ou en combinant les volumes englobants, jusqu'à obtenir un volume unique représentant l'ensemble de la scène qui devient la racine de l'arbre.

						La difficulté est bien évidemment de trouver les primitives à regrouper.
					</sec3>
					<sec3>
						<title>La méthode <em>incremental tree-insertion</em></title> <index>Volume englobant!Hiérarchie!Top-Down</index>
						On part avec un arbre vide, puis on ajoute les primitives et leur volume englobant une par une. Étant donné que le but est de minimiser le volume de l'arbre total, on insère chaque primitive au niveau de l'arbre où l'augmentation du volume sera le plus petit.

						Cette méthode est essentiellement utilisée dans les algorithmes de <em>raytracing</em>.
					</sec3>
					<sec3>
						<title>La méthode <em>top-down</em></title> <index>Volume englobant!Hiérarchie!Incremental tree-insertion</index>
						C'est la méthode la plus courante dans les algorithmes de construction. Le principe est simple<nbsp/>: on commence par trouver un volume englobant la scène dans son ensemble, puis on le divise, on cherche pour chaque partie les primitives incluses et on trouve un nouveau volume englobant ces primitives. Par récursion, on obtient la hiérarchie (Fig. <ref>constructionhierarchie</ref>). 

						Elle est assez simple à mettre en place, mais coûteuse pour une application temps-réel s'il faut la construire pendant le rendu.
					</sec3>

					<figures position="!htb">
						<subfigures>
							<subfigure type="eps" scale="0.2" href="figures/HierarchieVolumes_1.eps"/>
							<subfigure type="eps" scale="0.2" href="figures/HierarchieVolumes_2.eps"/>
							<subfigure type="eps" scale="0.2" href="figures/HierarchieVolumes_3.eps"/>
							<subfigure type="eps" scale="0.2" href="figures/HierarchieVolumes_4.eps"/>
						</subfigures>
						<caption>Construction récursive d'une hiérarchie de volumes englobants</caption>
						<label>constructionhierarchie</label>
					</figures>

					D'une manière générale c'est cette dernière méthode qui est la plus utilisée.

					Dans une application temps réel aucune de ces méthodes ne peut être appliquée à chaque frame, c'est pourquoi la construction des hiérarchies est faite lors d'une étape de pré-traitement et n'a donc pas besoin d'être réalisée en temps réel où on se contente d'effectuer de petites mises à jours sur les hiérarchies après des transformations de l'objet (translations, rotations, déformations). Cela permet d'effectuer des optimisations qui se traduiront par une amélioration des performances pendant l'usage en temps réel des hiérarchies au moment de la détermination des collisions.

					Un autre élément à prendre en compte dans la construction des hiérarchies est la structure de données qui peut être statique ou dynamique.

					Une structure statique, <index>Structure!Statique</index> une fois créée, ne peut pas être facilement modifiée pour ajouter ou enlever des objets de la scène et doit alors être reconstruite entièrement. Elle est en générale construite en appliquant une approche <em>top-down</em>.

					Au contraire, une structure dynamique <index>Structure!Dynamique</index> permet de faire des mises à jour sur la scène sans recalculer l'ensemble des hiérarchies, ce qui peut être très long. Cependant ces mises à jour doivent être effectuées en temps réel nécessitant des opérations très optimisées. En général les structures dynamiques sont construites par la méthode <em>bottom-up</em>.

					<u>Conclusion</u><nbsp />: Dans <em>Virtual Choreographer</em>, chaque scène est décrite avec tous les objets qu'elle comporte. Nous avons donc choisi pour <em>Virtual Choreographer</em> une structure statique. Cette approche est également celle de la plupart des packages de détection de collision disponibles, partant du principe qu'une fois que l'environnement a été modélisé, il y a peu de chances qu'il soit modifié.

				</sec2>

				<sec2>
					<title>Utilisation de hiérarchies</title>
					<index>Volume englobant!Hiérarchie!FindFirstHitCD</index>
					Le but des hiérarchies de volumes englobants est de faciliter les tests de collisions entre deux objets. Pour cela, l'algorithme de calcul de collision appliqué est le même quel que soit le choix du volume englobant (algorithm <ref>FFHCD</ref>).

					L'algorithme est appelé sur <m>A</m> et <m>B</m> qui sont des n<oe/>uds des deux hiérarchies testées, initialement les racines des hiérarchies.

					L'algorithme parcourt ensuite récursivement les hiérarchies jusqu'à trouver des triangles des maillages qui se chevauchent ou épuiser une des hiérarchies. 

					<algorithm position="!htb">
						<caption>FindFirstHitCD(<m>A</m>,<m>B</m>)</caption>
						<label>FFHCD</label>
						<algorithmic>
							<ENSURE> returns <m>({TRUE,FALSE})</m></ENSURE>
							<IF><CONDITION>isLeaf(<m>A</m>) and isLeaf(<m>B</m>)</CONDITION>
								<THEN>
									<FORALL><PRE>triangle pair <m>T<s>A</s> <in /> A<s>c</s></m> and <m>T<s>B</s> <in /> B<s>c</s></m></PRE>
										<IF><CONDITION>overlap(<m>T<s>A</s></m>,<m>T<s>B</s></m>)</CONDITION>
											<THEN><STATE>return TRUE</STATE></THEN>
										</IF>
									</FORALL>
								</THEN>
								<ELSIF><CONDITION>isNotLeaf(<m>A</m>) and isNotLeaf(<m>B</m>)</CONDITION>
									<THEN>
										<IF><CONDITION>Volume(<m>A</m>) <m>&gt;</m> Volume(<m>B</m>)</CONDITION>
											<THEN>
												<FORALL><PRE>child <m>C<s>A</s> <in /> A<s>c</s></m></PRE>
													<STATE>FindFirstHitCD(<m>C<s>A</s></m>,<m>B</m>)</STATE>
												</FORALL>
											</THEN>
											<ELSE>
												<FORALL><PRE>child <m>C<s>B</s> <in /> B<s>c</s></m></PRE>
													<STATE>FindFirstHitCD(<m>A</m>,<m>C<s>B</s></m>)</STATE>
												</FORALL>
											</ELSE>
										</IF>
									</THEN>
								</ELSIF>
								<ELSIF><CONDITION>isLeaf(<m>A</m>) and isNotLeaf(<m>B</m>)</CONDITION>
									<THEN>
										<FORALL><PRE>child <m>C<s>B</s> <in /> B<s>c</s></m></PRE>
											<STATE>FindFirstHitCD(<m>A</m>,<m>C<s>B</s></m>)</STATE>
										</FORALL>
									</THEN>
								</ELSIF>
								<ELSE>
									<FORALL><PRE>child <m>C<s>A</s> <in /> A<s>c</s></m></PRE>
										<STATE>FindFirstHitCD(<m>C<s>A</s></m>,<m>B</m>)</STATE>
									</FORALL>
								</ELSE>
							</IF>
							<STATE>return FALSE</STATE>
						</algorithmic>
					</algorithm>

					Le test sur les volumes de <m>A</m> et <m>B</m> permet de descendre systématiquement le n<oe/>ud ayant le plus grand volume ce qui tend à améliorer les performances.<br/>

					Cependant cet algorithme générique n'utilise pas les propriétés de facilité de test d'intersection des volumes englobants. Aussi on utilise un autre algorithme de parcours (algorithm <ref>TT</ref>) utilisant cette fois les volumes englobants des n<oe />uds pour descendre dans l'arbre. Dans notre cas, c'est cet algorithme que nous avons également choisi.

					<algorithm position="!htb">
						<caption>TraverseTrees(<m>A</m>,<m>B</m>)</caption>
						<label>TT</label>
						<algorithmic>
							<ENSURE>returns <m>({TRUE,FALSE})</m></ENSURE>
							<IF><CONDITION><m>b(A) <cap /> b(B) <neq /> 0</m></CONDITION>
								<THEN>
									<IF><CONDITION>isLeaf(<m>A</m>)</CONDITION>
										<THEN>
											<IF><CONDITION>isLeaf(<m>B</m>)</CONDITION>
												<THEN>
													<FORALL><PRE>triangle pair <m>T<s>A</s> <in /> A<s>c</s></m> and <m>T<s>B</s> <in /> B<s>c</s></m></PRE>
														<IF><CONDITION>overlap(<m>T<s>A</s></m>,<m>T<s>B</s></m>)</CONDITION>
															<THEN>
																<STATE>return TRUE</STATE>
															</THEN>
														</IF>		
													</FORALL>
												</THEN>
												<ELSE>
													<FORALL><PRE>child <m>C<s>A</s> <in /> A<s>c</s></m></PRE>
														<STATE>TraverseTrees(<m>C<s>A</s></m>,<m>B</m>)</STATE>
													</FORALL>
												</ELSE>
											</IF>
										</THEN>
										<ELSE>
											<FORALL><PRE>child <m>C<s>B</s> <in /> B<s>c</s></m></PRE>
												<STATE>TraverseTrees(<m>A</m>,<m>C<s>B</s></m>)</STATE>
											</FORALL>
										</ELSE>
									</IF>
								</THEN>
							</IF>
							<STATE>return FALSE</STATE>
						</algorithmic>
					</algorithm>

					L'étape suivante est le choix du volume englobant utilisé dans la hiérarchie ce que nous allons voir dans les algorithmes présentés qui utilisent respectivement les arbres d'OBB, les arbres d'AABB et les arbres de k-dop. 

					Ce choix est déterminant et guidé par des contraintes naturelles<nbsp/>:
					<itemize>
						<item>Le volume englobant doit <guill>coller</guill> au plus près à l'objet afin d'en minimiser le volume global<nbsp/>;</item>
						<item>Le test entre deux objets doit être le plus rapide possible<nbsp/>;</item>
						<item>Comme le volume doit suivre l'évolution de l'objet, la mise à jour doit être rapide.</item>
					</itemize>
				</sec2>
			</sec1>
			<sec1>
				<title>Volumes englobants et packages existant</title>

				Sur internet, chaque type de hiérachie est lié à un <sep/> ou plusieurs <sep/> packages de traitement de collisions. C'est pourquoi nous donnerons pour chaque volume englobant un package les implémentant. Ces packages nous ont également permis de bénéficier de <em>benchmarks</em> afin de comparer les performances respectives des volumes.

				Pour informations, les packages de détection de collision peuvent être caractérisés par plusieurs aspects en plus de l'efficacité<nbsp/>:
				<itemize>
					<item><em>Nbody ou 2Body</em><nbsp/>:<index>Nbody</index><index>2Body</index> un package est NBody s'il peut être appliqué sur <m>n</m> objets et 2Body si on ne peut l'appliquer que sur deux objets à la fois. On peut toutefois noter qu'un package 2Body peut facilement être rendu NBody en lui ajoutant une première passe de détection de collision comme celle vue dans le chapitre <ref>collisionAABB</ref>.</item>
					<item>Les types d'objets acceptés<nbsp/>: certaines méthodes imposent d'avoir des objets convexes en entrée, ou bien prennent des soupes de polygones (objets sans contrainte sur leur forme telle que la convexité<dots/>). Cependant, il existe des méthodes pour se ramener à des objets convexes afin de permettre de traiter les soupes de polygones.</item>
				</itemize>

				<sec2>
					<title>Arbres OBB <sep/> <em>RAPID</em> et <em>VCollide</em></title>
					<index>Volume englobant!OBB</index><index>Algorithme!RAPID</index><index>Algorithme!VCollide</index>
					Les OBB sont des boîtes orientées pour mieux convenir aux contours de l'objet (Fig. <ref>constructionOBB</ref>). Elles sont décrites dans l'article de Gottschalk, Lin et Manocha <cite>obb</cite>.

					<figures position="!htb">
						<subfigures>
							<subfigure type="eps" scale="0.5" href="figures/UtilisationOBBA.eps"/>
							<subfigure type="eps" scale="0.5" href="figures/UtilisationOBB.eps"/>
						</subfigures>
						<caption>OBB offrant peu d'espace vide quelle que soit l'orientation de l'objet</caption>
						<label>constructionOBB</label>
					</figures>

					<sec3>
						<title>Construction d'une OBB</title>
						<index>ACP</index>
						L'étape cruciale de la construction d'une OBB est la détermination de la meilleure orientation de la boîte. Pour cela, on utilise un traitement statistique nommé <em><acronym><title>Analyse en Composantes Principales</title>ACP</acronym></em> (<cite>pca</cite> et <cite>acp</cite>).

						L'analyse en composantes principales est une technique mathématique permettant de réduire un système complexe de corrélations en un plus petit nombre de dimensions. Elle est beaucoup utilisée dans le domaine de l'analyse de données ou de la compression. 

						Grossièrement, considérant un ensemble d'informations, elle consiste à placer des axes <guill>expliquant</guill> au mieux ces informations. Dans notre cas, nos informations sont des points et les résultats de l'application de l'ACP sont les axes principaux de la répartition des points. Ce sont ces axes suivant lesquels les points sont répartis qui orienteront la boîte (Fig. <ref>acp</ref>).

						<figure position="!htb">
							<subfigure>
								<input type="pstex" scale="0.7" href="figures/ACP.pstex_t"/>
								<caption>Sur cette distribution de points, l'axe <m>A<s>1</s></m> est l'axe principal décrivant la répartition des points et l'axe <m>A<s>2</s></m>, orthogonal à <m>A<s>1</s></m>, le second axe de répartition des points.</caption>
								<label>acp</label>
							</subfigure>
						</figure>

						Pour calculer les axes à partir des sommets de l'objet, on commence par calculer la moyenne <m><mu /></m> (<ref>moyenne</ref>), puis la matrice de covariance <m>C</m> (<ref>covariance</ref>). Si les sommets du i-ème triangle sont <m>p<S>i</S></m>, <m>q<S>i</S></m> et <m>r<S>i</S></m>, on calcule pour <m>n</m> triangles<nbsp/>:<br/>

						<equation text="\mu = \Sigma_{i=0}^n(p^i+q^i+r^i)">
							<label>moyenne</label>
						</equation>
						<equation text="C_{jk} = \frac{1}{3n}\Sigma_{i=0}^n(\overline{p_j^i}\overline{p_k^i} + \overline{q_j^i}\overline{q_k^i} + \overline{r_j^i}\overline{r_k^i}), \quad  1 \leq j,k \leq 3">
							<label>covariance</label>
						</equation>

						où <m><overline>p<S>i</S></overline> = p<S>i</S> - <mu />,<overline>q<S>i</S></overline> = q<S>i</S> - <mu />,<overline>r<S>i</S></overline> = r<S>i</S> - <mu /></m>. Chacun d'eux est un vecteur à trois composantes représentant les coordonnées sur les axes repère, par exemple, <m><overline>p<S>i</S></overline> = (<overline>p<S>i</S><s>1</s></overline>,<overline>p<S>i</S><s>2</s></overline>,<overline>p<S>i</S><s>3</s></overline>)</m> et les <m>C<s>jk</s></m> sont les éléments de la matrice de covariance de dimension 3x3.

						Ensuite, on calcule les valeurs propres de la matrice, puis on obtient les vecteurs propres qui forment une base après les avoir normalisés (étant deux à deux orthogonaux). Ils représentent également les axes de plus grandes variances et permettent ainsi d'orienter la boîte. Une fois que nous avons ces vecteurs, il suffit de projeter les points suivant chacun des axes pour obtenir la boîte.

						Malheureusement, il peut y avoir des erreurs d'orientation pour certaines distributions spatiales. En effet lors du calcul de la matrice de covariance, on tient également compte des points à l'intérieur de l'objet et un regroupement très dense de points à l'intérieur de l'objet peut amener la boîte englobante à s'aligner dessus. Une solution est de ne considérer que l'enveloppe convexe de l'objet pour calculer la matrice de covariance.

						L'arborescence de OBB est construite par la méthode <em>top-down</em>, en coupant en deux la boîte suivant l'axe principal (l'axe <m>A<s>1</s></m> de la figure <ref>acp</ref>) et en répartissant les polygones suivant le côté où ils se trouvent.
					</sec3>
					<sec3>
						<title>Mise à jour</title>
						Dans le cas d'objets rigides, la mise à jour des OBB est très aisée, aussi bien pour les translations que pour les rotations, puisqu'il suffit d'appliquer la transformation sur la boîte. Par conséquent, la mise à jour d'une hiérarchie est également très simple puisqu'il suffit de parcourir l'arbre OBB de la racine aux feuilles en mettant à jour les boîtes de chaque n<oe/>ud.

						Par contre, si l'objet se déforme, il faut recalculer les axes ce qui est coûteux. Les OBB s'appliquent donc assez mal à des objets déformables.
					</sec3>
					<sec3>
						<title>Test de chevauchement</title>
						La deuxième difficulté est de tester le chevauchement de deux OBB. En effet, l'orientation de ces boîtes pouvant varier, il faut en tenir compte dans le test ce qui amène à effectuer 144 tests faces-côtés ce qui est impensable. Pour cela on utilise une méthode de test rapide<nbsp/>: <em><acronym><title>Separating Axis Test</title>SAT</acronym></em>.<index>SAT</index>

						Cette méthode est basée sur le théorème de <em>l'axe séparateur</em><nbsp/>: deux polygones sont disjoints s'il existe au moins un axe séparateur. Un axe est dit séparateur pour deux polygones s'il existe un plan dans l'espace orthogonal à cet axe qui sépare les deux polygones, et que cet axe soit orthogonal à la face d'un des deux polygones ou orthogonal à deux côtés de chaque polygone.

						Tester si un axe est séparateur est très simple en projetant les centres des boîtes ainsi que leur radius (distance la plus grande du centre aux coins de la boîte) et de tester si la somme des radii est plus petite que la projection de la distance entre les centres. Si c'est le cas, les intervalles sont disjoints et par conséquent les boîtes aussi (Fig. <ref>testOBB</ref>).

						<figure position="!htb">
							<subfigure>
								<input type="pstex" scale="0.7" href="figures/testOBB.pstex_t"/>
								<caption><m><vec>L</vec></m> est un axe de séparation pour les OBB <m>A</m> et <m>B</m> car <m>A</m> et <m>B</m> deviennent des intervalles disjoints une fois projetés sur <m><vec>L</vec></m><nbsp/>; les demi-dimensions (ou <em>radii</em>) de <m>A</m> et <m>B</m> sont <m>a<S>i</S></m> et <m>b<S>i</S></m> avec <m>i=1,2,3</m><nbsp/>; les axes de <m>A</m> et <m>B</m> sont les vecteurs unitaires <m><vec>A<S>i</S></vec></m> et <m><vec>B<S>i</S></vec></m> avec <m>i=1,2,3</m>.</caption>
								<label>testOBB</label>
							</subfigure>
						</figure>

						En utilisant ce test rapide, on arrive à 15 tests dans le cas le pire puisque chaque boîte a 3 uniques orientations des faces et 3 uniques orientations des côtés (soit donc 3 faces pour la première boîte, 3 faces pour la seconde et 9 combinaisons deux à deux des côtés).

						Cependant il est possible de se ramener à 6 tests comme le suggère Van den Bergen <cite>aabb</cite> en ne faisant pas les 9 derniers tests qui, d'après des résultats pratiques, servent rarement. Cela revient alors à transformer une des OBB et AABB orientée dans le repère de l'autre, faire un test de chevauchement des boîtes, puis recommencer pour la seconde boîte (Fig. <ref>collisionobb</ref> et <ref>faussecollisionobb</ref>).

						Cette réduction du nombre de tests peut parfois conduire à croire, à tort, que deux boîtes se chevauchent alors que ce n'est pas le cas, cependant il n'y a pas de risque de manquer une intersection par cette optimisation.

						<figure position="!htb">
							<subfigure>
								<input type="eps" scale="0.5" href="figures/testsOBBCollisions.eps"/>
								<caption>Le test indique un chevauchement correct.</caption>
								<label>collisionobb</label>
							</subfigure>
							<subfigure>
								<input type="eps" scale="0.5" href="figures/testsOBBPasCollisions.eps"/>
								<caption>Le test SAT ne trouve pas de chevauchement des boîtes englobantes ce qui correspond bien à une situation de non chevauchement.</caption>
								<label>faussecollisionobb</label>
							</subfigure>
						</figure>
					</sec3>
					<sec3>
						<title>Caractéristiques des packages</title>
						Les hiérarchies OBB sont implémentées dans le package <em>RAPID</em> <cite>rapid</cite>, qui gère uniquement la détermination de collisions, lui même utilisé dans le package <em>VCollide</em> <cite>vcollide</cite>.
						VCollide est NBody et permet de traiter des soupes de polygones sans conditions particulières. Cependant, il est difficile de construire la hiérarchie de boîtes OBB et il peut parfois croire que des objets se chevauchent alors que ce n'est pas le cas à cause de la transformation des OBB en AABB.
					</sec3>
				</sec2>
				<sec2>
					<title>Arbre d'AABB <sep/> <em>SOLID</em></title>
					<index>Volume englobant!AABB</index><index>Algorithme!SOLID</index>
					Les hiérarchies d'AABB ont été développées et implémentées par Van den Bergen <cite>aabb</cite>. Cette méthode est moins efficace que celle des boîtes englobantes orientées, mais présente tout de même quelques avantages.

					D'une part, elle est moins gourmande en mémoire. D'autre part la construction et la mise à jour est plus simple sans avoir des performances catastrophiques. De plus elle permet de gérer les déformations d'objets.

					La construction de l'arbre se fait par une approche <em>top-down</em> en partitionnant la boîte suivant l'axe le plus long. La construction de l'arbre est plus rapide que pour les OBB pour lesquelles la recherche de la bonne orientation implique des calculs supplémentaires.

					Le test de chevauchement est réalisé en appliquant la méthode SAT comme les arbres OBB.

					<sec3>
						<title>Mise à jour de la hiérarchie</title>
						Les arbres AABB se prêtent bien à la gestion d'objets déformables (ensemble de primitives dont les coordonnées évoluent au cours du temps). La gestion des déformations est un problème délicat car reconstruire l'ensemble de l'arbre après une déformation occasionnerait un coût trop élevé. Par contre, il est bien plus judicieux de mettre à jour l'arbre en agissant sur les boîtes englobantes aux n<oe/>uds de l'arbre. L'intérêt des AABB vient alors de la propriété suivante<nbsp/>: soit <m>S</m> un ensemble de primitives, <m>S<S>+</S></m> et <m>S<S>-</S></m> deux sous-ensembles de <m>S</m> tels que <m>S=S<S>+</S> <cup /> S<S>-</S></m>, <m>B<S>+</S></m> et <m>B<S>-</S></m> les deux plus petites AABB de <m>S<S>+</S></m> et <m>S<S>-</S></m>, et <m>B</m> la plus petite AABB englobant <m>B<S>+</S> <cup /> B<S>-</S></m>, alors, <m>B</m> est la plus petite AABB de <m>S</m>.

						Cette propriété, partagée par les k-dops mais pas par les OBB, permet de mettre à jour l'arbre en adoptant une approche <em>bottom-up</em><nbsp/>: on descend aux feuilles, on recalcule leur AABB, puis on remonte l'arbre, en recalculant les AABB des n<oe/>uds à partir des AABB des fils. Cela revient à un parcours postfixe de l'arbre AABB.

						Le défaut de cette méthode est que lors de fortes déformations, les boîtes recalculées risquent de plus se chevaucher que les boîtes d'un arbre que l'on aurait entièrement reconstruit. Cependant, on observe peu de baisse de performances tant que les relations d'adjacences entre les triangles du maillage sont conservées.
					</sec3>
					<sec3>
						<title>Caractéristiques du package</title>
						Le package SOLID utilisant les arbres AABB permet de gérer des soupes de polygones.
						Des tests pratiques montrent que les arbres AABB restent nettement moins performant que les arbres OBB pour les collisions sans déformations.
				</sec3></sec2>
				<sec2>
					<title>Conclusion intermédiaire<nbsp/>: arbres OBB <sep/> arbres AABB</title>
					Au vue des performances de ces deux types de hiérarchies, les arbres OBB restent les plus intéressants. La diminution du coût de construction des arbres AABB entraînent également une perte importante en précision pour des performances inférieures aux arbres OBB dans la majorité des cas de collisions. L'intérêt des arbres AABB vient essentiellement du traitement simple des déformations. Cependant pour que ce traitement soit efficace, il est impératif que les déformations ne soient pas trop importantes. Notamment les relations d'adjacence entre les faces du maillage ne doivent pas être modifiées et la déformation ne doit pas radicalement changer les proportions de l'objet. Or les déformations possibles dans <em>Virtual Choreographer</em> dépassent le cadre des déformations à la suite de chocs (notamment lors d'interpolations d'objets), et il n'est pas assuré que l'arbre AABB permette de gérer correctement ces déformations.
				</sec2>
				<sec2>
					<title>Arbres k-dops <sep/> <em>QuickCD</em></title>
					<index>Volume englobant!k-dop</index><index>Algorithme!QuickCD</index>
					Décrits dans la thèse de J. T. Klosowski <cite>kdop</cite>, les <em><acronym><title>discrete orientation polytopes</title>k-dops</acronym></em> sont des polygones convexes dont les faces sont déterminées par des demi-plans dont les normales proviennent d'un <em>ensemble fixé de <m>k</m> orientations</em> (Fig. <ref>kdop1</ref> et <ref>kdop2</ref>). Par exemple, les boîtes AABB sont des 6-dops dont les vecteurs orientations sont les vecteurs du repère.

					<figure position="!htb">
						<subfigure>
							<input type="eps" scale="0.6" href="figures/UtilisationKDOP1.eps"/>
							<caption>La boîte englobante est optimale initialement (8-dop)</caption>
							<label>kdop1</label>
						</subfigure>
						<subfigure>
							<input type="eps" scale="0.6" href="figures/UtilisationKDOP2.eps"/>
							<caption>Approximation après rotation de l'objet (8-dop)</caption>
							<label>kdop2</label>
						</subfigure>

					</figure>
					<sec3>
						<title>Construction des k-dops</title>
						Les k-dops permettent d'avoir un contrôle sur le degré de complexité du polygone englobant. Plus la valeur de <m>k</m> est élevée, plus il sera <guill>proche</guill> de l'objet.

						Par ailleurs, il est très simple de calculer l'enveloppe d'un objet. En effet, il faut voir les k-dops comme des intervalles basés sur <m>k/2</m> directions. Par exemple dans le cas d'un 8-dop, on se fixe quatre vecteurs de base (par exemple en 2 dimensions <m>(1,0) (0,1) (1,1) (1,-1)</m>) puis on calcule le produit scalaire de ces vecteurs avec les sommets de l'objet considéré et on garde le maximum et le minimum sur chaque direction. La construction d'un k-dop est obtenue par le calcul de produits scalaires entre les vertexes de l'objet et les <m>k</m> vecteurs. Dans le cas d'un objet contenant <m>n</m> vertexes, la construction en une complexité en temps de <m>O(kn)</m> contre <m>O(n)</m> pour la construction d'un AABB ce qui reste dans le même ordre de grandeur à une constante près.

						De plus, il est judicieux d'utiliser des vecteurs composés de 0 et de 1 pour les axes (il n'est pas nécessaire qu'ils soient normalisés) afin de simplifier le calcul des produits scalaires.

						<!--% une référence ici-->
						Sur la figure <ref>constructionkdop</ref>, on voit graphiquement la construction d'un 8-dop d'axes <m>(0,1),(1,0),(1,1),(1,-1)</m> pour le triangle <m>(1,2),(5,1),(3,5)</m>. L'intersection des projections des sommets extrêmes sur chacun des axes forme les contours du 8-dop.

						<!--% des dessins des dessins -->

						<figures position="!htb">
							<subfigures>
								<subfigure type="eps" scale="0.5" href="figures/ConstructionKDOP1.pstex"/>
								<subfigure type="eps" scale="0.5" href="figures/ConstructionKDOP.pstex"/>
							</subfigures>
							<caption>Construction d'un 8-dop sur un triangle. Le k-dop est obtenu en prenant l'intersection des intervalles projetés sur chacun des quatre axes fixés.</caption>
							<label>constructionkdop</label>
						</figures>

						<index>splatter</index>
						Pour construire la hiérarchie de k-dops, on applique l'approche <em>top-down</em> en subdivisant chaque ensemble en deux sous-ensembles par la méthode <em>splatter</em>. Cette méthode consiste à projeter le centre de gravité de chaque triangle du maillage sur chacun des axes du k-dop, puis de choisir l'axe sur lequel on observe la plus grande variation (Fig. <ref>splatter</ref>). Une fois connu l'axe suivant lequel on va séparer l'ensemble, il reste à déterminer le point de subdivision. Pour cela, on prend la moyenne des coordonnées des projections des centres de gravité sur l'axe de subdivision. Les résultats expérimentaux montrent que prendre la moyenne plutôt que simplement le milieu de l'axe minimise le volume global de l'arbre.

						<figure position="!htb">
							<subfigure>
								<input type="eps" scale="0.7" href="figures/ProjectionKDOP.eps"/>
								<caption>Chaque centre de gravité des triangles est projeté sur sur les deux axes. Sur l'axe Ox, on observe une plus grande variation entre les projections que sur l'axe Oy, on choisit donc de séparer l'objet orthogonalement à cet axe (4-dop).</caption>
								<label>splatter</label>
							</subfigure>
						</figure>
					</sec3>
					<sec3>
						<title>Mise à jour</title>
						Étant donné que les axes du k-dop sont fixés initialement, après une rotation de l'objet, on ne peut pas calculer le k-dop de l'objet transformé en faisant une simple rotation du k-dop. Cependant, il est tout de même possible de traiter les rotations sans recalculer une nouvelle hiérarchie de k-dop et en se contentant de mettre à jour chaque n<oe/>ud interne au prix d'une approximation.

						On calcule en effet le k-dop résultant en appliquant la transformation sur les sommets au coin du k-dop, puis en construisant un nouveau k-dop uniquement sur les sommets transformés. Ainsi, le travail est réduit tant que l'objet contient moins de sommets que le k-dop. Le défaut de cette approximation est qu'elle augmente nécessairement la taille du k-dop (Fig. <ref>rotationkdop</ref>).

						<figure position="!htb">
							<subfigure>
								<input type="eps" scale="0.6" href="figures/RotationKDOP1.eps"/>
								<caption>Cette figure montre le résultat de l'appoximation sur le k-dop à la suite d'une rotation<nbsp/>: le tracé gris correspond au k-dop original après rotation, le tracé noir le nouveau k-dop obtenu à partir du tracé gris. On observe une augmentation du volume du k-dop par rapport au k-dop optimal (Fig. <ref>kdop2</ref>)</caption>
								<label>rotationkdop</label>
							</subfigure>
						</figure>
					</sec3>
					<sec3>
						<title>Test de chevauchement</title>
						Vu que l'on considère les k-dops comme des intervalles alignés sur <m>k/2</m> directions, il suffit donc de réaliser <m>k/2</m> tests de chevauchement d'intervalles ce qui est beaucoup plus simple que les tests que nous avons vu sur les OBB.
					</sec3>
					<sec3>
						<title>Caractéristiques du package</title>
						Le package QuickCD de Klosowski <cite>kdop</cite> utilise les k-dops<nbsp/>; il est NBody, mais ne gère pas les déformations. Il obtient des performances proches, voire supérieures à RAPID pour des coûts mémoires bien moindre.
				</sec3></sec2>
				<sec2>
					<title>Conclusion</title>
					Notre objectif dans <em>Virtual Choreographer</em> est de réaliser des collisions simples entre des objets sur lesquels peuvent s'appliquer des transformations telles que des rotations ou des déformations. Les k-dops, par leur faible coût mémoire (<m>k/2</m> axes et <m>k</m> valeurs par rapport aux stockage matrices de transformation des OBB), leur simplicité de construction et de test de chevauchement, sont les volumes englobants que nous avons choisis. Ils sont un peu moins performants lors des rotations, mais peuvent permettre de gérer les déformations sans reconstruire les hiérarchies en tentant de transposer la méthode des arbres AABB aux arbres k-dops.

					Nous souhaitons tester deux k-dops<nbsp/>:
					<itemize>
						<item>14-dops<nbsp/>: Axes <m>(1,0,0),(0,1,0),(0,0,1),(1,1,1),(1,-1,1),(1,1,-1),(1,-1,-1)</m><nbsp/>;</item>
						<item>18-dops<nbsp/>: Axes <m>(1,0,0),(0,1,0),(0,0,1),(1,1,0),(1,0,1),(0,1,1),(1,-1,0),(1,0,-1),(0,1,-1)</m>.</item>
					</itemize>
				</sec2>
			</sec1>
		</chapter>
		<chapter>
			<title>La physique</title>
			<sec1>
				<title>Réponse à la collision</title>
				<index>Collision!Réponse</index>
				La réponse à la collision est la dernière étape dans le traitement de la collision. Elle est beaucoup moins complexe au niveau algorithmique, mais nécessite une recherche théorique si on souhaite obtenir des effets réalistes.

				En général, on modélise le contact entre deux corps par un point et un plan de contact tangent aux deux corps. On doit alors déterminer les efforts tangentiels et normaux (Fig. <ref>plan</ref>). Les effort tangentiels correspondent aux forces de frottement que l'on va, pour le moment, négliger. Il existe deux grandes méthodes pour calculer les efforts normaux<nbsp/>: la méthode basée sur la notion d'impulsion et la méthode de pénalité.

				<sec2>
					<title>Méthode d'impulsion</title>
					<index>Collision!Réponse!Impulsion</index>
					Les méthodes sont basées sur la notion de force <em>d'impulsion</em><nbsp/>: l'impact est une collision quasi-instantanée (soit de durée négligeable) pendant laquelle les deux objets (parfaitement rigides) exercent une force (dite impulsion) très importante sur eux-mêmes. Au moment de l'impact, la composante normale de la vitesse du point peut être modifiée en réponse à la collision. Une grandeur scalaire, le coefficient de restitution <m>e</m>, située entre 0 et 1, peut être appliquée à la vitesse résultante pour modéliser le degré d'élasticité de la collision (si <m>e=1</m>, la norme de la vitesse résultante est égale à la norme de la vitesse initiale, il n'y a aucune perte d'énergie, la collision est parfaitement élastique). Le calcul du vecteur vitesse résultant peut être fait en appliquant la méthode décrite dans la section <ref>vectvitessseresult</ref>. 

					Le principe est simple<nbsp/>: quand les deux objets sont suffisament proches, l'impulsion est calculée de sorte qu'elle soit capable de les séparer en une seule itération.

					Cependant il est possible dans cette méthode de permettre un traitement plus précis de l'instant de la collision en <guill>remontant</guill> le temps jusqu'au point d'impact (en assimilant les objets à des points) à partir de l'instant où on a détecté un chevauchement des objets. Pour cela, on condidère la trajectoire de l'objet aux instants de la collision. 

					Une première méthode consiste à appliquer une recherche dichotomique sur les intervalles de temps. Si on sait qu'à l'instant <m>t<s>i-1</s></m> les objets étaient séparés alors qu'ils se chevauchent à l'instant <m>t<s>i</s></m>, on initialise l'intervalle de recherche à <m>[t<s>i-1</s>,t<s>i</s>]</m> (Fig. <ref>remtemps1</ref>).

					Une seconde méthode, plus rapide, consiste à supposer la vitesse constante et le trajet linéaire sur l'intervalle de temps. Les positions du point de la trajectoire avant le chevauchement et à l'instant de la détection du chevauchement peuvent alors être utilisées pour déterminer un trajet linéaire et ainsi calculer analytiquement le point de contact avec une surface plane (Fig. <ref>remtemps2</ref>).

					<figure position="!htb">
						<subfigure>
							<input type="pstex" scale="0.75" href="figures/RemonteTemps1.pstex_t"/>
							<caption>L'instant et lieu de collision est calculé précisément par dichotomie<nbsp/>: dans un premier temps l'intervalle vaut <m>[t<s>i-1</s>,t<s>i</s>]</m>, puis est ramené à  <m>[(t<s>i</s>-t<s>i-1</s>)/2,t<s>i</s>]</m>, et ainsi de suite.</caption>
							<label>remtemps1</label>
						</subfigure>

						<subfigure>
							<input type="pstex" scale="0.75" href="figures/RemonteTemps2.pstex_t"/>
							<caption>La trajectoire réelle du point est approximée par une trajectoire linéaire joignant <m>P(t<s>i-1</s>)</m> à <m>P(t<s>i</s>)</m>. Le point de contact approximé peut être alors calculé comme l'intersection d'une droite et d'un plan.</caption>
							<label>remtemps2</label>
						</subfigure>
					</figure>

					Cette approche, bien que plus précise, peut devenir lourde dans un environnement complexe où de nombreuses collisions très rapprochées se produisent.
				</sec2>
				<sec2>
					<title>Méthode de pénalité</title>
					<index>Collision!Réponse!Pénalité</index>
					Dans les méthodes dites de <em>pénalité</em>, en général, les objets sont déformables, et la période de la collision ne peut être considérée comme négligeable. Ces méthode sont alors mieux adaptées pour traiter la collision. Le principe consiste à générer dynamiquement une force répulsive qui dépend de la valeur de l'interpénétration fictive entre les deux objets. La force engendrée par cette méthode nécessite plusieurs itérations pour séparer les deux objets, contrairement aux méthodes d'impact qui séparent les deux objets en une seule itération. Le plus souvent la force répulsive est générée par un mécanisme de type <guill>ressort/amortisseur</guill> (Fig. <ref>penalisation</ref>), et elle peut être donnée dans ce cas par la formule suivante<nbsp/>:
					<displaymath><overrightarrow>F<s>c</s></overrightarrow> =
						<left>{</left><array format="ll">
							(-<lambda/> x - <mu/> <dot>x</dot>)<vec>k</vec> <arrayshift/> <textrm>si x &lt; 0</textrm><br/>
							<vec>0</vec> <arrayshift/> <textrm>sinon</textrm>
						</array><right/>
					</displaymath>
					où <m><lambda /></m> est la rigidité de la collision, <m><mu /></m> la viscosité de la collision (qui représente la dissipation de l'énergie), <m>x</m> est la distance entre les deux points en contact, <m><dot>x</dot></m> est la dérivée de <m>x</m>, <m><vec>k</vec></m> est la direction de la collision (orientée d'un point vers l'autre).

					<figure position="!htb">
						<subfigure>
							<input type="pstex" scale="0.7" href="figures/Penalisation.pstex_t" />
							<caption>Après pénétration du plan par la trajectoire de l'objet, on applique un ressort de pénalisation à partir du point pénétré pour séparer les objets en plusieurs itérations.</caption>
							<label>penalisation</label>
						</subfigure>
					</figure>

					
				</sec2>

				<sec2>
					<title>Informations géométriques pour une collision</title>
					Pour utiliser ces méthodes, il faut en général avoir des informations précises telles que les normales aux faces en contact. Ces normales ne sont généralement pas fournies par les algorithmes de détermination de collision. Cela impose donc un traitement qui peut être coûteux.

					Cependant, il faut noter que les expériences de O'Sullivan et Dingliana <cite>osullivan</cite> ont montré qu'il est difficile pour un être humain de juger si la réponse à une collision en 3D est correcte. Il est même possible d'utiliser une réponse aléatoire qui sera malgré tout perçue comme crédible.

					On voit donc qu'on peut se permettre de simplifier énormément le modèle physique de gestion de la collision.
				</sec2>
				<sec2>
					<title>Réponse physique aux chocs</title>
					Dans le cadre du stage, nous allons uniquement considérer des chocs élastiques (c'est à dire sans déformation des objets), dans des référentiels fixes.

					<sec3>
						<label>vectvitessseresult</label>
						<title>Vecteur vitesse résultant</title>
						Nous utilisons une réponse simple par impulsion, sans recherche du moment précis du contact. Une fois qu'on a obtenu le point de contact et la normale par l'algorithme de détermination de collision, on projette le vecteur vitesse de chaque objet en collision sur la normale et sur le plan orthogonal à la normale. On prend ensuite l'opposé de la composante normale du vecteur vitesse et on garde la composante tangentielle (ou on la multiplie par un coefficient <m>k <leq/> 1</m> représentant la perte d'énergie lors du contact) ce qui donne le nouveau vecteur vitesse de l'objet (Fig. <ref>plan</ref>).

						<figure position="!htb">
							<subfigure>
								<input type="pstex" scale="0.85" href="figures/ReponseCollisionPlan.pstex_t"/>
								<caption>La composante normale du vecteur vitesse est l'opposée de la composante normale du vecteur initial. De plus, le vecteur vitesse résultant est multiplié par un coefficient <m>k \in [0,1]</m>.</caption>
								<label>plan</label>
							</subfigure>
						</figure>

						Pour obtenir la normale, on applique le principe suivant<nbsp/>:
						lorsque l'on approxime les objets par des sphères, la direction de la normale est portée par la droite passant par les centres des deux sphères (Fig. <ref>normale</ref>). Le plan tangent à la collision est le plan orthogonal au vecteur normal obtenu précédemment.

						<figure position="!htb">
							<subfigure>
								<input type="pstex" scale="0.75" href="figures/DirectionNormale.pstex_t"/>
								<caption>La normale est portée par la droite passant par les centres des sphères approximant les objets.</caption>
								<label>normale</label>
							</subfigure>
						</figure>

						À l'implémentation, il est tout à fait possible d'utiliser le centre du volume englobant sans avoir à se ramener nécessairement à une sphère.

						Il est à noter que cette approximation s'applique bien dans le cas d'objets de volumes comparables, mais fonctionnera mal dans le cas d'une collision point--plan où la normale obtenue ne correspondra pas à la normale du plan (Fig. <ref>normaleratee</ref>).

						<figure position="!htb">
							<subfigure>
								<input type="pstex" scale="0.75" href="figures/NormaleRatee.pstex_t"/>
								<caption>La normale, portée par la droite passant par le centre de la sphère et le centre du plan, est très éloignée de la normale utilisée dans une collision point--plan.</caption>
								<label>normaleratee</label>
							</subfigure>
						</figure>

					</sec3>
					<sec3>
						<label>vectRot</label>
						<title>Vecteur rotation résultant</title>
						Lors du choc, les objets peuvent pivoter sur eux-même. Cette rotation est modélisée de la façon suivante<nbsp/>:
						<itemize>
							<item>l'axe de rotation <m>A<s>1</s></m> passe par le centre <m>O<s>1</s></m> du solide et sa direction est obtenue en calculant le produit vectoriel du vecteur vitesse <m><vec>v<s>1</s></vec></m> par le vecteur joignant les centres des objets en contact <m><overrightarrow>O<s>1</s>O<s>2</s></overrightarrow></m> (Fig. <ref>vecteurrotation</ref>)<nbsp/>;</item>
							<item>la vitesse angulaire <m>w<s>1</s></m> est proportionnelle à la distance <m>d<s>1</s></m> du projeté du point de contact sur l'axe principal de l'objet au centre de l'objet. Ainsi, plus le choc se produit près du centre de gravité de l'objet et moins la vitesse angulaire est importante.</item>
						</itemize>

						<figure position="!htb">
							<subfigure>
								<input type="pstex" scale="0.65" href="figures/VecteurRotation.pstex_t"/>
								<caption>Les axes de rotations sont obtenus par produit vectoriel entre les vecteurs vitesses de chaque objet et le vecteur joignant les centres des objets. Les vitesses angulaires sont proportionnelles aux distances aux centres des projection du point de contact sur les axes principaux des objets.</caption>
								<label>vecteurrotation</label>
							</subfigure>
						</figure>
						
					</sec3>
				</sec2>
			</sec1>
			<sec1>
				<title>Gravité</title>
				<index>Gravité</index>
				Nous souhaitons gérer la gravité dans le moteur afin de permettre la chute libre avec vitesse initiale. Il faut alors calculer la trajectoire de l'objet en fonction du temps.

				Soit <m>v<s>0</s><nbsp/>(v<s>0<s>x</s></s>,v<s>0<s>y</s></s>,v<s>0<s>z</s></s>)</m> le vecteur vitesse initial, après projection sur les axes du repère <m>Oxyz</m>. À l'instant <m>t</m>, la variation de vitesse <m>dv</m> vaut<nbsp/>:
				<displaymath>
					<left>{</left> <array format="l">
						dv<s>x</s> = 0<br/>
						dv<s>y</s> = -dg<br/>
						dv<s>z</s> = 0
					</array><right />
				</displaymath>

				où <m><vec>g</vec> = (0,0,-g)</m> est le vecteur gravité (Fig. <ref>gravite</ref>).

				<figure position="!htb">
					<subfigure>
						<input type="pstex" scale="0.6" href="figures/ApplicationGravite.pstex_t"/>
						<caption>Pour une variation de temps <m>dt</m>, on ajoute le vecteur <m><vec>dg</vec></m> au vecteur vitesse <m><vec>v</vec></m> initial pour obtenir le nouveau vecteur vitesse.</caption>
						<label>gravite</label>
					</subfigure>
				</figure>

			</sec1>
			<sec1>
				<title>Améliorations</title>
				Comme nous nous sommes essentiellement concentrés sur la partie détection de collisions, il est possible de faire de nombreuses améliorations au modèle physique que nous utilisons.

				Par exemple, il pourrait être intéressant d'attribuer une masse aux objets géométriques afin d'en tenir compte lors du calcul de la réponse au choc. En effet, le comportement des objets n'est pas le même s'ils ont tous deux la même masse et si l'un est beaucoup plus lourd que l'autre. De même, on pourrait également gérer les matériaux constituants les objets, certains pouvant se fissurer, se briser d'une manière qui leur est propre. La gestion des frottements pourrait également être ajoutée. 

				Un autre point intéressant serait la résolution des contacts permanents entre un ou plusieurs objets (appelés contacts de repos ou encore d'équilibre) qui est l'un des problèmes de dynamique les plus compliqués de l'animation informatique. Pour se donner une idée de la difficulté, le principe est le suivant<nbsp/>: pour chaque point de contact, il existe une force normale à la surface de contact comme dans le cas du contact par collision. L'objectif est de trouver la grandeur de cette force pour une configuration donnée des objets. Ces forces doivent<nbsp/>:
				<enumerate>
					<item> être suffisament puissantes pour éviter une interpénétration<nbsp/>;</item>
					<item> repousser uniquement les objets les uns des autres<nbsp/>;</item>
					<item> devenir nulles au point de contact au moment où les objets commencent à se séparer.</item>
				</enumerate>
				La résolution de ce problème requiert l'utilisation de travaux complexes dépassant le cadre de ce TER--Stage.
				
			</sec1>
		</chapter>
		<chapter>
			<title>Implémentation dans <em>Virtual Choreographer</em></title>
			<sec1>
				<title>Objectifs</title>
				Le but que nous nous somme fixé pour incorporer la gestion des collisions dans <em>Virtual Choreographer</em> est de rester aussi modulaire que possible. Nous souhaitons essentiellement fournir une architecture de moteur physique avec l'application des forces <guill>simples</guill> et la gestion de collisions qui sera simple à améliorer. 

				De plus nous insistons particulièrement sur la partie concernant gestion des collisions qui est plus complexe au niveau algorithmique et structure de données que la partie physique pure.
			</sec1>
			<sec1>
				<title>Préparation du programme existant</title>
				Afin de faciliter la mise en place du moteur physique un certains nombres de modifications ont été nécessaires<nbsp/>:
				<itemize>
					<item>un vecteur gravité a été ajouté dans le fichier de configuration de la scène afin de pouvoir spécifier une unique force de gravité par scène<nbsp/>;</item>
					<item>des classes permettant de manipuler le maillage des objets (accéder aux triangles du maillage, etc.) ont été codées, permettant de construire les hiérarchies de volumes englobants<nbsp/>;</item>
					<item>une classe d'attributs physiques des objets a été mise en place<nbsp/>;</item>
					<item>des transformations locales spéciales ont été ajoutées avant chaque objet dans le graphe de scène afin que les modifications des positions des objets dues à la physique se fassent par leur intermédiaire.</item>
				</itemize>
			</sec1>
			<sec1>
				<title>Organisation générale</title>
				<sec2>
					<title>Application de la physique</title>
					<label>applicationphysique</label>
					<index>Implémentation!Physique</index>
					Chaque objet possède un attribut physique permettant de définir ses caractéristiques. Notamment, il possède un vecteur <em>impulsion</em> qui indique le vecteur vitesse courant de l'objet. Ensuite, c'est en agissant sur ce vecteur que l'on peut modifier le comportement de l'objet (par exemple à la suite de collisions), de même pour la vitesse angulaire. Ces modifications sont ensuite répercutées à chaque frame par l'appel d'une méthode de mise à jour des objets.
				</sec2>
				<sec2>
					<title>Gestion des collisions</title>
					<index>Implémentation!Collisions</index>
					Le traitement des collisions suit l'organisation décrite dans le rapport.

					Dans un premier temps, on limite la combinatoire en appliquant l'algorithme <em>sweep and prune</em>. Pour cela, on construit trois tableaux d'intervalles (un par axe du repère) (Fig. <ref>classes2</ref>) que l'on trie en appliquant le tri <em>qsort</em> de la librairie standard du C++. Par la suite, les mises à jours modifient les valeurs des éléments des intervalles, puis les tableaux sont triés par un tri à bulle que nous implémentons. À chaque frame, il suffit de parcourir les tableaux et construire trois listes de couples (une par axe) des <em>id</em> des objets correspondant aux intervalles qui se chevauchent. Les couples qui apparaissent dans les trois listes indiquent des objets qui se chevauchent et sont ajoutés dans la liste des couples d'objets susceptibles de se chevaucher.

					Cette liste de couples est ensuite utilisée dans la phase de détermination de collisions. À l'initialisation de la scène, on construit les arbres de k-dop pour chaque objet (Fig. <ref>classes1</ref>). Les arbres sont placés dans la classe <em>PhysicalProperties</em> ce qui évite de les construire pour les objets sur lesquels on ne souhaiterait pas appliquer de la physique. À chaque frame, la fonction de détermination de collision est appelée sur les couples d'objets en contact potentiel repérés lors de la phase précédente. Pour chaque couple, elle applique la fonction de parcours des arbres de k-dop des deux objets afin de déterminer s'ils sont réellement en contact. Si ce n'est pas le cas, on retire les couples de la liste.

					Au final, on a la liste des couples d'objets qui sont réellement en situation de collision. Pour chaque couple, on résout la collision en appliquant la fonction physique qui se charge de séparer les objets et modifier leur trajectoire en agissant sur leurs attributs de la classe <em>PhysicalProperties</em> comme il a été vu à la section <ref>applicationphysique</ref>.

					<em>Virtual Choreographer</em> permet de faire des rendus temps réels, mais également offline. Pour profiter pleinement de ces deux modes de rendu, nous modifions le comportement de la détermination de collision en fonction du mode demandé par l'utilisateur<nbsp/>: dans un rendu temps réel, les arbres k-dop sont mis à jour avec les méthodes d'approximations pour les rotations et les déformations<nbsp/>; par contre, dans un rendu différé, on reconstruit les hiérarchies des objets modifiés, permettant d'avoir au final une gestion plus fine des collisions.
				</sec2>
			</sec1>
			<sec1>
				<title>Organisation du code</title>
				<figure positions="!htb">
					<subfigure>
						<input type="eps" scale="0.5" href="figures/Classes1.eps"/>
						<caption>Diagramme de classes de la hiérarchie de k-dop. Les noeuds de l'arbre contiennent ici un k-dop, mais la définition de nos classes permet de changer aisément de volume englobant du moment que les fonctions de test d'intersection et de mise à jour sont implémentées.</caption>
						<label>classes1</label>
					</subfigure>
				</figure>
				<figure positions="!htb">
					<subfigure>
						<input type="eps" scale="0.5" href="figures/Classes2.eps"/>
						<caption>Diagrame de classes de la classe CollisionDetermination manipulant trois tableaux d'Element1D. Un Element1D est un élément d'intervalle (début ou fin d'intervalle signalée par le booléen <em>start</em>). Il contient en plus un champ <em>id</em> qui permet d'accéder à l'objet lié à l'intervalle.</caption>
						<label>classes2</label>
					</subfigure>
				</figure>

						<sec2>
							<title>Structure de l'implémentation</title>
						<index>Implémentation!Structure</index>
						L'affichage au sein de <em>Virtual Choreographer</em> est découpé en plusieurs phases où viennent s'insérer le moteur physique. La fonction de mise à jour de la scène commence par mettre à jour les positions des objets en appliquant les transformations définies dans le script <em>.xml</em> décrivant la scène s'il y en a. Ensuite, les forces globales (gravité, etc.) sont appliquées modifiant les positions des objets. On cherche alors les éventuelles collisions et on les résout en modifiant de nouveau les positions, qui étaient incohérentes, des objets. Enfin, le rendu graphique est calculé et la scène s'affiche.

						La difficulté de l'intégration vient du fait que la scène est décrite sous forme d'un graphe de scène et que les objets sont décrits dans leur propre système de coordonnées. Or pour gérer la physique, il faut avoir une vue de la scène dans le repère canonique afin de pouvoir comparer les positions des objets. Il faut donc en permanence faire attention aux système de coordonnées et appliquer les changements de repères adéquats.
						La figure <ref>structurecode</ref> montre les regroupements que nous avons fait afin de pouvoir centraliser le moteur physique et le rendre le plus indépendant possible de <em>Virtual Choreographer</em>. Nous avons donc une classe <em>PhysicalOverview</em> qui s'occupe d'appliquer correctement les différentes passes du moteur physique. Il suffit donc de faire appel à la fonction de mise à jour de cette classe dans la fonction de rendu de <em>Virtual Choreographer</em> pour que la physique s'exécute.

				<figure positions="!htb">
					<subfigure>
						<input type="eps" scale="0.4" href="figures/StructureCode.eps"/>
						<caption>Structure du code utilisé dans <em>Virtual Choreographer</em>.</caption>
						<label>structurecode</label>
					</subfigure>
				</figure>

				</sec2>
			</sec1>
		</chapter>
		<chapter>
			<title>Conclusion</title>

			Nous avons pris un grand plaisir à suivre ce TER--Stage qui nous a été bénéfique sur bien des points.

			Il nous a, en premier lieu, permis de découvrir un problème classique, mais complexe, de l'animation graphique que l'on retrouve dans un vaste champ d'applications (jeux, simulations réalistes, etc.). De plus, il nous a amené à effectuer un travail de recherche poussé passant par la lecture d'extraits de thèses et d'articles de recherches en plus des traditionnelles recherches de sites internet.

			Mais plus encore, nous avons eu une grande liberté dans le choix du sujet. Le domaine de la physique étant extrêmement vaste, nous avons du nous auto-limiter et privilégier certains sujets. Nous avons donc travaillé sur les sujets qui nous motivaient le plus ce qui nous a soutenu pour réaliser les recherches.

			Cependant nous regrettons de n'avoir pas pu consacrer plus de temps à l'implémentation de ces techniques, notamment à la phase de détermination des collisions.

			Malgré tout, nous restons satisfaits de ce que nous avons fait et nous espérons que d'autres auront l'occasion de poursuivre notre travail puisqu'il reste de nombreux problèmes à couvrir dans ce domaine.
			
		</chapter>
		<backmatter/>
		<thebibliography num="99">
			<bibitem name="ref1">Tomas Akenine-Möller and Eric Haines. Real-Time Rendering A.K. Peters Ltd., 2nd edition.</bibitem>
			<bibitem name="ref2" href="http://www.irisa.fr/bibli/publi/theses/2003/meyer/meyer.html">Tangi Meyer. Retour d'effort et réalité virtuelle<nbsp/>: Proposition d'une boîte à outils pour l'intégration logicielle générique de la détection de collisions et de la simulation physique. 1er octobre 2003.</bibitem>
			<bibitem name="kdop" href="http://www.ams.sunysb.edu/~jklosow/quickcd/QCD_publications.html">James Thomas Kloswski. Efficient Collision Detection for Interactive 3D Graphics and Virtual Environments. 1998</bibitem>
			<bibitem name="obb" href="ftp://ftp.cs.unc.edu/pub/users/manocha/PAPERS/COLLISION/obb.ps.gz">S. Gottschalk, M. C. Lin, et D. Manocha. OBBTree: A Hierarchical Structure for Rapid Interference Detection. Sggraph'96.</bibitem>
			<bibitem name="aabb">Gino Van Den Bergen. Efficient Collision Detectin of Complex Deformable Models using AABB Trees. 6 novembre 1998.</bibitem>
			<bibitem name="ref6">Kenneth E. Hoff III, Tim Culver, John Keyser, Ming Lin, et Dinesh Manocha. Fast Computation of Generalized Voronoi Diagrams Using Graphics Hardware.</bibitem>
			<bibitem name="vcollide" href="http://cs.unc.edu/~geom/V_COLLIDE/">VCollide. Site de l'algorithme de Hudson</bibitem>
			<bibitem name="icollide" href="http://www.cs.unc.edu/~geom/I_COLLIDE/index.html">ICollide. Site de l'algorithme de Lin et Canny</bibitem>
			<bibitem name="solid" href="http://www.win.tue.nl/~gino/solid/index.html#papers">SOLID. Site de l'algorithme de Gino van den Bergen.</bibitem>
			<bibitem name="rapid" href="http://cs.unc.edu/~geom/OBB/OBBT.html">RAPID. Site de l'algorithme de Gottschalk</bibitem>
			<bibitem name="ref10" href="http://membres.lycos.fr/javamus/articles/obb.pdf">Mustapha Bismi. COLLISIONS<nbsp/>: Oriented Bounding Box et SphereTree</bibitem>
			<bibitem name="ritter" href="http://softsurfer.com/Archive/algorithm_0107/algorithm_0107.htm">Dan Sunday. Bounding Containers for Polygons, Polyhedra, and Point Sets (2D and 3D)</bibitem>
			<bibitem name="ref12" href="http://www.inrialpes.fr/sharp/people/sundaraj/papers/dea00.pdf">Kenneth Sundaraj. Détection et traitement de collision en simulation dynamique</bibitem>
			<bibitem name="osullivan" href="http://isg.cs.tcd.ie/cosulliv/publications.htm">O'Sullivan, C. Dingliana. Collisions and Perception<br/> J. ACM Transactions on Graphics. Vol. 20, No. 3. Juillet 2001.</bibitem>
			<bibitem name="pca" href="http://www.cis.hut.fi/~jhollmen/dippa/node30.html">Principal Component Analysis.<br/>J. Hollmen.</bibitem>
			<bibitem name="acp" href="http://www.ulg.ac.be/pedaexpe/cours/glosaire/acp.htm">Analyse en composantes principales (ACP).<br/>Cours de l'université de Liège.</bibitem>
		</thebibliography>
		<printindex/>
	</doc>
</document>
