360 lines
12 KiB
HTML
360 lines
12 KiB
HTML
|
<!DOCTYPE html>
|
|||
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
|||
|
<head>
|
|||
|
<meta charset="utf-8" />
|
|||
|
<meta name="generator" content="pandoc" />
|
|||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
|||
|
<title>rapport</title>
|
|||
|
<style>
|
|||
|
html {
|
|||
|
line-height: 1.5;
|
|||
|
font-family: Georgia, serif;
|
|||
|
font-size: 20px;
|
|||
|
color: #1a1a1a;
|
|||
|
background-color: #fdfdfd;
|
|||
|
}
|
|||
|
body {
|
|||
|
margin: 0 auto;
|
|||
|
max-width: 36em;
|
|||
|
padding-left: 50px;
|
|||
|
padding-right: 50px;
|
|||
|
padding-top: 50px;
|
|||
|
padding-bottom: 50px;
|
|||
|
hyphens: auto;
|
|||
|
overflow-wrap: break-word;
|
|||
|
text-rendering: optimizeLegibility;
|
|||
|
font-kerning: normal;
|
|||
|
}
|
|||
|
@media (max-width: 600px) {
|
|||
|
body {
|
|||
|
font-size: 0.9em;
|
|||
|
padding: 1em;
|
|||
|
}
|
|||
|
h1 {
|
|||
|
font-size: 1.8em;
|
|||
|
}
|
|||
|
}
|
|||
|
@media print {
|
|||
|
body {
|
|||
|
background-color: transparent;
|
|||
|
color: black;
|
|||
|
font-size: 12pt;
|
|||
|
}
|
|||
|
p, h2, h3 {
|
|||
|
orphans: 3;
|
|||
|
widows: 3;
|
|||
|
}
|
|||
|
h2, h3, h4 {
|
|||
|
page-break-after: avoid;
|
|||
|
}
|
|||
|
}
|
|||
|
p {
|
|||
|
margin: 1em 0;
|
|||
|
}
|
|||
|
a {
|
|||
|
color: #1a1a1a;
|
|||
|
}
|
|||
|
a:visited {
|
|||
|
color: #1a1a1a;
|
|||
|
}
|
|||
|
img {
|
|||
|
max-width: 100%;
|
|||
|
}
|
|||
|
h1, h2, h3, h4, h5, h6 {
|
|||
|
margin-top: 1.4em;
|
|||
|
}
|
|||
|
h5, h6 {
|
|||
|
font-size: 1em;
|
|||
|
font-style: italic;
|
|||
|
}
|
|||
|
h6 {
|
|||
|
font-weight: normal;
|
|||
|
}
|
|||
|
ol, ul {
|
|||
|
padding-left: 1.7em;
|
|||
|
margin-top: 1em;
|
|||
|
}
|
|||
|
li > ol, li > ul {
|
|||
|
margin-top: 0;
|
|||
|
}
|
|||
|
blockquote {
|
|||
|
margin: 1em 0 1em 1.7em;
|
|||
|
padding-left: 1em;
|
|||
|
border-left: 2px solid #e6e6e6;
|
|||
|
color: #606060;
|
|||
|
}
|
|||
|
code {
|
|||
|
font-family: Menlo, Monaco, 'Lucida Console', Consolas, monospace;
|
|||
|
font-size: 85%;
|
|||
|
margin: 0;
|
|||
|
}
|
|||
|
pre {
|
|||
|
margin: 1em 0;
|
|||
|
overflow: auto;
|
|||
|
}
|
|||
|
pre code {
|
|||
|
padding: 0;
|
|||
|
overflow: visible;
|
|||
|
overflow-wrap: normal;
|
|||
|
}
|
|||
|
.sourceCode {
|
|||
|
background-color: transparent;
|
|||
|
overflow: visible;
|
|||
|
}
|
|||
|
hr {
|
|||
|
background-color: #1a1a1a;
|
|||
|
border: none;
|
|||
|
height: 1px;
|
|||
|
margin: 1em 0;
|
|||
|
}
|
|||
|
table {
|
|||
|
margin: 1em 0;
|
|||
|
border-collapse: collapse;
|
|||
|
width: 100%;
|
|||
|
overflow-x: auto;
|
|||
|
display: block;
|
|||
|
font-variant-numeric: lining-nums tabular-nums;
|
|||
|
}
|
|||
|
table caption {
|
|||
|
margin-bottom: 0.75em;
|
|||
|
}
|
|||
|
tbody {
|
|||
|
margin-top: 0.5em;
|
|||
|
border-top: 1px solid #1a1a1a;
|
|||
|
border-bottom: 1px solid #1a1a1a;
|
|||
|
}
|
|||
|
th {
|
|||
|
border-top: 1px solid #1a1a1a;
|
|||
|
padding: 0.25em 0.5em 0.25em 0.5em;
|
|||
|
}
|
|||
|
td {
|
|||
|
padding: 0.125em 0.5em 0.25em 0.5em;
|
|||
|
}
|
|||
|
header {
|
|||
|
margin-bottom: 4em;
|
|||
|
text-align: center;
|
|||
|
}
|
|||
|
#TOC li {
|
|||
|
list-style: none;
|
|||
|
}
|
|||
|
#TOC ul {
|
|||
|
padding-left: 1.3em;
|
|||
|
}
|
|||
|
#TOC > ul {
|
|||
|
padding-left: 0;
|
|||
|
}
|
|||
|
#TOC a:not(:hover) {
|
|||
|
text-decoration: none;
|
|||
|
}
|
|||
|
code{white-space: pre-wrap;}
|
|||
|
span.smallcaps{font-variant: small-caps;}
|
|||
|
span.underline{text-decoration: underline;}
|
|||
|
div.column{display: inline-block; vertical-align: top; width: 50%;}
|
|||
|
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
|||
|
ul.task-list{list-style: none;}
|
|||
|
</style>
|
|||
|
<script defer=""
|
|||
|
src="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/katex.min.js"></script>
|
|||
|
<script>document.addEventListener("DOMContentLoaded", function () {
|
|||
|
var mathElements = document.getElementsByClassName("math");
|
|||
|
var macros = [];
|
|||
|
for (var i = 0; i < mathElements.length; i++) {
|
|||
|
var texText = mathElements[i].firstChild;
|
|||
|
if (mathElements[i].tagName == "SPAN") {
|
|||
|
katex.render(texText.data, mathElements[i], {
|
|||
|
displayMode: mathElements[i].classList.contains('display'),
|
|||
|
throwOnError: false,
|
|||
|
macros: macros,
|
|||
|
fleqn: false
|
|||
|
});
|
|||
|
}}});
|
|||
|
</script>
|
|||
|
<link rel="stylesheet"
|
|||
|
href="https://cdn.jsdelivr.net/npm/katex@0.15.1/dist/katex.min.css" />
|
|||
|
<!--[if lt IE 9]>
|
|||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
|
|||
|
<![endif]-->
|
|||
|
</head>
|
|||
|
<body>
|
|||
|
<h1 align="center">
|
|||
|
Projet de Modélisation Géométrique<br> Création et suivi de trajectoire
|
|||
|
de caméras<br> Option longue 1
|
|||
|
</h1>
|
|||
|
<div style="
|
|||
|
text-align:justify;
|
|||
|
max-width:800;
|
|||
|
margin-left: auto;
|
|||
|
margin-right: auto;
|
|||
|
">
|
|||
|
<p align="center">
|
|||
|
<a href="mailto:laurent.fainsin@etu.inp-n7.fr">Laurent Fainsin</a> —
|
|||
|
<a href="mailto:damien.guillotin@etu.inp-n7.fr">Damien Guillotin</a>
|
|||
|
</p>
|
|||
|
<h2 id="description">Description</h2>
|
|||
|
<p>L’objectif de ce projet était de construire, à partir des
|
|||
|
connaissances acquises durant le cours d’interpolation et
|
|||
|
d’approximation, un module sous Unity3D qui permet de réaliser un suivi
|
|||
|
de trajectoire de caméra en ne fournissant qu’un nombre restreint
|
|||
|
d’informations, à savoir quelques points (trois coordonnées spatiales,
|
|||
|
trois coordonnées axiales).</p>
|
|||
|
<p>Nous avons décidé (avec l’accord de notre professeur, Julien
|
|||
|
Desvergnes) de modifier légèrement la consigne de ce projet. Nous avons
|
|||
|
opté pour le developpement d’un plugin pour un serveur <a
|
|||
|
href="https://www.minecraft.net/fr-fr">Minecraft</a> <a
|
|||
|
href="https://www.spigotmc.org/">Spigot</a>, permettant aux joueurs de
|
|||
|
créer des travelings.</p>
|
|||
|
<h2 id="api-spigot">API Spigot</h2>
|
|||
|
<p>L’API Spigot nous permet d’interfacer avec le monde / les propriétés
|
|||
|
/ les entités de notre serveur Minecraft.</p>
|
|||
|
<p>Le serveur Minecraft (<a href="https://papermc.io/">paperMC</a>)
|
|||
|
étant écrit en Java, nous devons utiliser ce langage de programmation
|
|||
|
pour développer notre plugin.</p>
|
|||
|
<p>Pour développer notre plugin nous avons donc créé un environnement de
|
|||
|
developpement sous VSCode via le gestionnaire de dépendance Java: <a
|
|||
|
href="https://gradle.org/">Gradle</a>.</p>
|
|||
|
<p>Pour compiler notre plugin nous pouvons générer une archive
|
|||
|
<code>.jar</code> via la commande <code>gradle jar</code>. Pour déployer
|
|||
|
notre plugin sur notre serveur, nous plaçons notre archive dans le
|
|||
|
dossier <code>plugins</code> de notre serveur.</p>
|
|||
|
<p>Pour améliorer le déployment et le lancement du serveur Minecraft,
|
|||
|
nous avons de plus utilisé un <a
|
|||
|
href="https://docs.docker.com/compose/">docker-compose</a>.</p>
|
|||
|
<p>Une fois le plugin déployé, et le serveur démarré, nous pouvons
|
|||
|
utiliser notre plugin. Si celui-ci n’est pas activé, nous pouvons
|
|||
|
utiliser la commande <code>/reload confirm</code> pour relancer les
|
|||
|
plugins.</p>
|
|||
|
<h2 id="choix-de-courbe">Choix de courbe</h2>
|
|||
|
<p>Pour le traveling de notre caméra, nous utilisons des courbes de
|
|||
|
Bezier. Pour réaliser la courbe complète, nous faisons suivre des
|
|||
|
courbes de degrés 3.</p>
|
|||
|
<p>La courbe finale s’apparente à une spline mais nous avons choisi ce
|
|||
|
type de modélisation car nous souhaitons que notre caméra passe
|
|||
|
exactement par certains points de contrôles (interpolation). Il est
|
|||
|
ainsi plus intuitif pour l’utilisateur de modifier la courbe.</p>
|
|||
|
<p>Ces courbes de bézier sont générées par évaluation, nous avons fait
|
|||
|
ce choix car la subdivision semblait peu adapté à la génération d’un
|
|||
|
nombre de point précis. De plus, le temps de calcule de la courbe reste
|
|||
|
négligeable, l’optimisation temporelle que permettrait la subdivision ne
|
|||
|
serait pas perceptible.</p>
|
|||
|
<p>Puisque la caméra dans Minecraft ne permet pas de rotation “row”,
|
|||
|
nous avons directement interpolé nos rotations selon un schéma de bézier
|
|||
|
(sans passer par des quaternions).</p>
|
|||
|
<h3 id="avantages-inconvénients">Avantages / Inconvénients</h3>
|
|||
|
<p>Grace a cette méthode, nous pouvons interpolé des points tout en
|
|||
|
gardant le contrôle sur la courbe. On arrive donc à obtenir une courbe
|
|||
|
très maléable tout en restant stable. Parcontre, le placement des points
|
|||
|
de contrôle peut devenir assez long si l’on souhaite obtenir une
|
|||
|
trajectoire très precise étant donné qu’il y a quatre points à gérer par
|
|||
|
segment.</p>
|
|||
|
<p>Un autre point positif de cette construction est que nous avons le
|
|||
|
choix de positionner les points (grâce a une commande) de sorte que la
|
|||
|
courbe soit <span class="math inline">C^1</span>.</p>
|
|||
|
<h3 id="démonstrations-mathématiques">Démonstrations mathématiques</h3>
|
|||
|
<p>Les polynomes de Bernstein sont definit comme étant :</p>
|
|||
|
<p><span class="math inline">\displaystyle B_k^n(t) = \binom{n}{k} t^k
|
|||
|
(1 - t)^{n-k}</span></p>
|
|||
|
<p>Le <span class="math inline">i^{ème}</span> tronçon de courbe est
|
|||
|
alors définit par :</p>
|
|||
|
<p><span class="math inline">\displaystyle S_i(t) = \sum_{k=0}^{n}
|
|||
|
P_i^k\ B_k^n(t)</span></p>
|
|||
|
<p>Pour garder le caractère <span class="math inline">C^1</span> de la
|
|||
|
courbe, il faut donc que la dérivé en <span class="math inline">1</span>
|
|||
|
du <span class="math inline">i^{ème}</span> tronçon soit égale à la
|
|||
|
dérivé en <span class="math inline">0</span> du <span
|
|||
|
class="math inline">i^{ème}+1</span>.</p>
|
|||
|
<p>Soit, <span class="math inline">\displaystyle S_i'(1) = S_{i +
|
|||
|
1}'(0)</span></p>
|
|||
|
<p>avec, <span class="math inline">\displaystyle S_i'(t) = n
|
|||
|
\sum_{k=0}^{n - 1} (P_i^{k + 1} - P_i^k)\ B_k^{n - 1}(t)</span></p>
|
|||
|
<p>Ce qui fait :</p>
|
|||
|
<p><span class="math inline">\displaystyle n (P_i^{n} - P_i^{n - 1}) = n
|
|||
|
(P_{i + 1}^{1} - P_{i + 1}^{0})</span></p>
|
|||
|
<p>Le résultat <span class="math inline">\displaystyle P_i^{n} - P_i^{n
|
|||
|
- 1} = P_{i + 1}^{1} - P_{i + 1}^{0}</span> se traduit géométriquement
|
|||
|
par l’alignement et l’équidistance des points de contrôle à l’ancre à la
|
|||
|
qu’elle ils sont ratachés.</p>
|
|||
|
<h2 id="démonstrations">Démonstrations</h2>
|
|||
|
<style>
|
|||
|
video {
|
|||
|
max-width: 100%;
|
|||
|
}
|
|||
|
</style>
|
|||
|
<table>
|
|||
|
<tr>
|
|||
|
<td>
|
|||
|
<video src="https://fainsil.users.inpt.fr/content/ModéGéom/tuto.webm" autoplay loop controls>
|
|||
|
</video>
|
|||
|
</td>
|
|||
|
<td>
|
|||
|
<video src="https://fainsil.users.inpt.fr/content/ModéGéom/circle.webm" autoplay loop controls>
|
|||
|
</video>
|
|||
|
</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td>
|
|||
|
<video src="https://fainsil.users.inpt.fr/content/ModéGéom/waterfall.webm" autoplay loop controls>
|
|||
|
</video>
|
|||
|
</td>
|
|||
|
<td>
|
|||
|
<video src="https://fainsil.users.inpt.fr/content/ModéGéom/island.webm" autoplay loop controls>
|
|||
|
</video>
|
|||
|
</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td>
|
|||
|
<video src="https://fainsil.users.inpt.fr/content/ModéGéom/demo_show.webm" autoplay loop controls>
|
|||
|
</video>
|
|||
|
</td>
|
|||
|
<td>
|
|||
|
<video src="https://fainsil.users.inpt.fr/content/ModéGéom/demo_noshow.webm" autoplay loop controls>
|
|||
|
</video>
|
|||
|
</td>
|
|||
|
</tr>
|
|||
|
<tr>
|
|||
|
<td>
|
|||
|
<video src="https://fainsil.users.inpt.fr/content/ModéGéom/full_show.webm" autoplay loop controls>
|
|||
|
</video>
|
|||
|
</td>
|
|||
|
<td>
|
|||
|
<video src="https://fainsil.users.inpt.fr/content/ModéGéom/full_noshow.webm" autoplay loop controls>
|
|||
|
</video>
|
|||
|
</td>
|
|||
|
</tr>
|
|||
|
</table>
|
|||
|
<h2 id="conclusion">Conclusion</h2>
|
|||
|
<p>Notre interpolation fonctionne bien, nos résultats sont
|
|||
|
satisfaisants.</p>
|
|||
|
<p>Seul bémol, notre serveur fonctionne assez lentement par rapport au
|
|||
|
serveur. Tandis qu’un client Minecraft tourne au minimum à 60 fps, notre
|
|||
|
serveur étant monothreadé, celui-ci “tourne” plutôt aux alentour des 20
|
|||
|
tps. On obtient alors un rendu avec quelques secousses dans certains
|
|||
|
cas.</p>
|
|||
|
<h2 id="les-commandes-utiles">Les commandes utiles</h2>
|
|||
|
<p><code>/show</code> permet d’afficher/cacher la courbe et les points
|
|||
|
de contrôle.</p>
|
|||
|
<p><code>/exec [true/false] [#start] [#end]</code> permet de lancer le
|
|||
|
traveling en commençant à la <code>#start</code> courbe et en s’arretant
|
|||
|
à la <code>#end</code>. L’attribut <code>true/false</code> permet de se
|
|||
|
déplacer de manière plus fluide le long de la courbe (cependant il est
|
|||
|
expérimental, il n’y a pas d’interpolation des rotations).</p>
|
|||
|
<p><code>/close</code> : ferme/ouvre la courbe et passe en mode
|
|||
|
repeat/simple.</p>
|
|||
|
<p><code>/point <add|rm|set|fix> [index]</code><br />
|
|||
|
<code>add</code> : ajoute un point à la suite de la courbe.<br />
|
|||
|
<code>rm</code> : enlève le groupe de point indiqué.<br />
|
|||
|
<code>set</code> : déplace le point indiqué.<br />
|
|||
|
<code>fix</code> : modifie le point indiqué de sorte à ce que la courbe
|
|||
|
soit <span class="math inline">C^1</span>.</p>
|
|||
|
<p><code>/reset</code> : supprime l’entièreté des points.</p>
|
|||
|
<p><code>/save <file></code> : permet de sauvegarder les points
|
|||
|
actuels dans un fichier.</p>
|
|||
|
<p><code>/load <file></code> : permet de charger les points dans
|
|||
|
un fichier.</p>
|
|||
|
<p><code>/points</code> : permet de lister l’ensemble de points de
|
|||
|
contrôle éxistant.</p>
|
|||
|
<p><code>/runas <player> <command></code> : exécute une
|
|||
|
commande à la place d’un autre joueur.</p>
|
|||
|
</div>
|
|||
|
</body>
|
|||
|
</html>
|