Logbook
=======
.. _19042021:
19/04/2021
----------
**10h05** Discussion avec M. Bonvin sur le travail qui devrait être fait
au début de ce travail de diplôme. La première chose que je vais faire
est de faire un struct ``Model`` pour stocker les modèles 3D. Ensuite,
je ferais une classe 3DPicture qui s'occupera de séparer l'affichage
mathématique (en coordonnées) de l'affichage sur l'image (en pixels).
**10h22** Création d'un nouveau Git afin de mieux m'organiser.
**10h53** Je me renseignais sur comment poster la documentation sur
``readthedocs`` et leur article recommande d'utiliser ``Sphinx`` pour
générer la documentation. Cet outil utilise un format qui s'appelle le
``reStructuredText``. Il est également possible d'utiliser ``Markdown``,
mais ``readthedocs`` et `cet
article `__
recommandent d'utiliser ``reStructuredText``. Je vais donc utiliser
``Markdown`` pour le logbook et ``reStructuredText`` pour la
documentation technique.
**11h40** J'ai fini de mettre en place la documentation qui est
auto-générée sur
`readthedocs `__.
**13h00** J'ai importé l'ancien code que j'ai fait pendant le POC.
**16h10** J'ai fait la partie "Cahier des Charges" de la documentation.
.. _20042021:
20/04/2021
----------
**9h50** J'ai fait la partie "Organisation" de la documentation.
**11h00** Fin de la partie "Technologies Utilisées" de la documentation.
**13h00** Fin de la partie "Environnement de développement". Je vais me
concentrer sur le code pour le reste de la journée, car je ne vois pas
trop ce que je pourrais ajouter dans la doc. Je pense que la section
"Environnement de développement" pourrait être mieux expliquée, mais je
ferais ça plus tard.
**16h00** J'ai essayé de refactoriser mon code afin qu'il utilise un
struct "Model" plutôt que une liste de face. J'ai réussis à créer le
struct, mais malheureusement l'affichage fait un peu n'importe quoi.
.. figure:: ./img/logbook/noBackfaceCullingWithModel.png
:alt:
Quand je désactive le backface culling, tout s'affiche normalement, mais
quand je l'active, les deux premier ne changent pas et le dernier a des
faces qui lui manques d'un manière qui semble aléatoire.
J'imagine que c'est du au fait que j'ai essayé de mettre le code qui
s'occupe de trier les backfaces dans le struct model.
.. code:: c#
public Model GetNonBackface(Vector3 lineOfSight)
{
List newFaces = new();
foreach (var face in Faces)
{
Vector3 normal = face.Normal;
if (!normal.IsBackFace(lineOfSight))
{
newFaces.Add(face);
}
}
return new(newFaces.ToArray());
}
Il y a surement quelque chose de faux la dedans. Je continuerais demain.
.. _21042021:
21/04/2021
----------
**8h22** J'ai réglé le problème du backface culling, j'avais juste mal
adapté le code pour calculer la normale de la face.
Voici le code qui marche :
.. code:: c#
Vector3 physicalTwo = this.point2.ToPhysicalCoords();
Vector3 v0 = this.point0.ToPhysicalCoords() - physicalTwo;
Vector3 v1 = this.point1.ToPhysicalCoords() - physicalTwo;
normal = v0.Cross(v1).NormalizeOrDefault();
J'ai donc maintenant le même résultat que j'avais lors du POC, mais avec
un struct ``Model``.
.. figure:: ./img/logbook/goodBackface.png
:alt:
**10h32** J'ai mis à jour mon code de manière à ce qu'il utilise une
classe ``Picture3D`` qui déscend de ``PictureBox``. Cela me permet
d'abstraire les coordonées obtenues après la projection du cube, et les
coordonées à dessiner à l'écran. Voici à quoi ça ressemble :
.. figure:: ./img/logbook/nicePicture3D.png
:alt:
**11h40** J'ai ajouté des commentaires et je vais commencer à me
renseigner sur comment utiliser doxygen pour générer une doc technique
puis la mettre en format ``reStructuredText`` pour que je puisse y
inclure dans mon readthedocs.
**14h55** J'ai trouvé un programme qui s'appelle Doxyrest qui permet de
prendre les documents ``XML`` que Doxygen génère afin de faire une doc
en ``reStructuredText``. Le problème est que Doxygen ne semble pas aimer
les tableaux à deux dimensions qui sont dans ma classe Matrix4.
.. figure:: ./img/logbook/badDoxygen.png
:alt:
**16h00** Ne trouvant pas comment faire, j'ai posé ma question sur
`StackOverflow `__
et quelqu'un m'as donné une solution : il faut mettre à jour ``Doxygen``
à la verison 1.9.1.
.. _22042021:
22/04/2021
----------
**8h55** J'ai réorganiser les fichiers de ma documentation afin que je
puisse mettre ma documentation ``Doxygen`` dans ma documentation
technique. Pour la compiler, j'ai créer des scripts afin que tout soit
facile à a faire. Voici les étapes à suivre :
.. code:: powershell
cd docs
.\updt-doxy.bat
.\make.bat html
**10h17** J'ai fini d'écrire dans la documentation ce que j'ai fait, je
vais maintenant essayer de régler le problème de la matrice
d'homothétie.
**10h32** Je me suis rendu compte que je n'avais pas fait les calculs
pour la dernières lignes dans la multiplication de matrices, ce qui
explique pourquoi mon scaling ne marchais pas. Par exemple, pour la
première colonne, j'avais ça :
.. code:: c#
// First row
newMat[0, 0] = (left.values[0, 0] * right.values[0, 0]) +
(left.values[0, 1] * right.values[1, 0]) +
(left.values[0, 2] * right.values[2, 0]) +
(left.values[0, 3] * right.values[3, 0]);
newMat[0, 1] = (left.values[0, 0] * right.values[0, 1]) +
(left.values[0, 1] * right.values[1, 1]) +
(left.values[0, 2] * right.values[2, 1]) +
(left.values[0, 3] * right.values[3, 1]);
newMat[0, 2] = (left.values[0, 0] * right.values[0, 2]) +
(left.values[0, 1] * right.values[1, 2]) +
(left.values[0, 2] * right.values[2, 2]) +
(left.values[0, 3] * right.values[3, 2]);
Et il me manquais ça :
.. code:: c#
newMat[0, 3] = (left.values[0, 0] * right.values[0, 3]) +
(left.values[0, 1] * right.values[1, 3]) +
(left.values[0, 2] * right.values[2, 3]) +
(left.values[0, 3] * right.values[3, 3]);
.. figure:: ./img/logbook/niceScale.png
:alt:
**14h35** J'avais modifié mon code pour que les faces n'aient que 3
sommets, sauf que en faisant le code pour lire un document ``.ply``, je
me suis rendu compte que je devrait aussi faire un code qui puisse
accepter les faces à 4 sommets. Il faut donc que je remodifie ça.
A la base j'avais fait ça afin de ne pas avoir a itérer sur les faces
pour gagner des performances, du coup je me demande si je devrait pas
séparer mon struct ``Face``\ en deux structs ``Face3`` et ``Face4``.
Sauf que comme il faut que je puisse stocker les deux faces dans une
seule et même liste et que je ne sais pas comment gérer les descendance
entre les deux face, je vais juste refaire une liste.
**15h35** j'ai réussis à charger un modèle 3D au format ``.ply``. Ce
n'est pas très bien fait et a beaucoup de valeurs hard codées, mais ça
marcherais pour tous les modèles exportés par blender. Voici à quoi le
singe de blender ressemble :
.. figure:: ./img/logbook/monke.png
:alt:
.. _23042021:
23/04/2021
----------
**8h53** J'ai mis en place un moyen de charger un modèle depuis
l'application plutôt que depuis le code.
**9h20** J'ai fait quelque tests avec des modèles plus complexes, et je
me suis rendu compte que certaines faces s'affiches devant d'autres
faces. Afin de régler ce problème, je vais essayer d'implémenter
l'`algorithme du
peintre `__.
Étant donné que je fait une projection orthographique sur un plan ou un
axe est égal à 0 (par exemple X = 0 si je projette sur l'axe X), je
pense que je peut trier les polygones selon leur distance de ces axes.
**11h20** J'ai eu une discussion avec M. Bonvin et il m'a dit d'essayer
de dessiner les normales de mes faces avec une longueur qui varie en
fonction de leurs orientation en fonction de la caméra.
**14:08** J'ai fait quelque recherches pour savoir s'il possible
d'optimiser le dessin de l'image dans Windows Form et apparemment ce
n'est pas tellement possible au dela de ce que j'ai déjà fait. Sinon les
gens recommandent de passer sur GDI ou Direct3D, mais comme ce n'est pas
vraiment le but de l'application, je pense ne pas porter plus
d'attention à ce côté de l'optimisation.
**15h45** J'ai fait en sorte de pouvoir simuler la lumière en fonction
d'où les polygones font face.
.. figure:: ./img/logbook/niceLight.png
:alt:
J'ai mal structuré mon code par contre, ça ne marche que quand le
backface culling est activé. Je fixerais ça plus tard.
.. _26042021:
26/04/2021
----------
**8h33** J'ai mis à jour mon code afin que l'éclairage marche même sans
backface culling, même si je pense enlever cette option plus tard comme
elle n'apporte pas grand chose (ou peut-être je le laisserais juste pour
la démonstration).
**9h01** J'ai ajouté une option afin de pouvoir changer la couleur
d'éclairage du model.
.. figure:: ./img/logbook/redFalco.png
:alt:
**10h02** J'ai un peu modifier ma doc afin qu'elle soit mieux affichée
au format pdf.
**10h37** J'ai mis à jour la doc afin d'expliquer la compilation en
LaTeX.
**11h37** M. Bonvin est passé 1 min me demander si tout allait bien et
m'as dit qu'il serait cool de créer une classe parallélépipède rectangle
a qui on peut passer une taille et qui génère ses points en fonction de
ça et à qui on peut préciser un axe de rotation.
**12h44** En lisant le livre, je me suis rendu compte que je devais
implémenter l'inverse dans mon struct Matrix, je suis donc allé sur le
GitHub de OpenTK pour voir comment ils l'implémentent, et j'ai vu des
trucs bizarres avec des Sse et un lien vers un
`article `__
sur `cette
ligne `__.
Je vais donc lire l'article afin de mieux comprendre ce qu'il se passe
dans ce code.
De ce que j'ai compris, l'article explique juste comment calculer
l'inverse d'une matrice en C++. J'ai aussi lu `cette
question `__
sur stackoverflow et de ce que j'ai compris, Sse est un moyen d'accéder
à des méthodes optimisées pour des calculs afin de les rendre plus
rapide.
Ne voulant pas entrer dans les détails de comment calculer l'inverse
d'une matrice, je vais juste l'implémenter comme OpenTK, qui doit
surement être assez rapide.
La méthode est déclarée comme ceci :
.. code:: c#
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe void InvertSse3(Matrix4 mat)
{
}
Ce qui veut dire selon (ce
site)[https://www.dotnetperls.com/aggressiveinlining] que la méthode
sera inlinée (désolé je connais pas le verbe en français :p) quand elle
est appelée.
**13h04** Je me suis en fait souvenus que je travaillais avec des
doubles et non des float comme dans le code que je regardais. Je suis
donc allé dans l'implémentation avec des doubles, et il n'y a pas toutes
ces optimisations. Afin d'être sur que ça marche, je vais utiliser
l'implémentation qu'ils ont fait dans leur classe avec un double.
**14h20** Après avoir implémenté la méthode pour obtenir l'inverse d'une
matrice 4x4, je vais essayer de faire la rotation autour d'un axe
arbitraire.
**16h00** J'ai mis en place la méthode pour calculer l'inverse d'une
matrice. Je ne l'ai pas testée cela dit.
.. _27042021:
27/04/2021
----------
**9h01** M. Bonvin est passé vers moi et m'a conseillé de mieux séparé
ma vue de mes calculs mathématique (ce qui pourrait améliorer les
performances). Il m'a aussi dit qu'il serait bien de pouvoir afficher
directement les vecteurs normaux des faces.
**13h30** J'ai fait un premier bout de code pour séparer l'affichage.
J'ai pris la majorité de mon code qui était dans la classe
``Picture 3D`` et je l'ai mis dans une nouvelle classe ``Renderer``.
Celle-ci ne rends plus dans un ``PaintEventArgs`` mais dans un
``Bitmap``. Malheureusement ce test ne marche pas et j'ai un message
d'erreur bizarre :
.. figure:: ./img/logbook/weirdErrorBitmap.png
:alt:
Pourtant c'est un constructeur valide.
Il se trouvais que la taille de l'image n'était pas bien paramétré.
**15h02** J'ai, en gros, séparé le code de mon ``Renderer`` en 3
méthodes :
1. ``UpdateTransformation``
2. ``UpdateProjection``
3. ``Render``
``UpdateTransformation`` et ``UpdateProjection`` servent à bouger le
modèle puis le projeter. ``Render`` s'occupe ensuite de dessiner les
faces sur un ``Bitmap``.
Comme j'ai mieux séparé les calculs du dessin, je vais essayé de rendre
les deux premières méthodes asynchrones.
**15h22** J'ai maintenant un autre problème avec le ``Bitmap``, quand
j'essaie de le dessiner, j'ai la même erreur. Je dessine sur le bitmap
dans une méthode dans la classe ``Renderer``, mais j'ai une erreur dans
la classe ``Picture3D``.
.. code:: c#
Bitmap bmp = new Bitmap(Size.Width, Size.Height);
Graphics g = Graphics.FromImage(bmp);
PaintEventArgs p = new PaintEventArgs(g, e.ClipRectangle);
p.Graphics.Clear(Color.Yellow);
p.Graphics.DrawLine(Pens.Black, new Point(0, 0), new Point(200, 200));
e.Graphics.DrawImage(bmp, 0, 0);
Cela dit, le bout de code ci-dessus marche. J'imagine que c'est un
problème de thread. Car ce bout de code ne marche pas :
.. code:: c#
await renderer.UpdateTransformation();
await renderer.UpdateProjection();
renderer.Render(e);
e.Graphics.DrawImage(renderer.Bitmap, 0, 0);
.. _28042021:
28/04/2021
----------
**8h36** J'ai essayé de faire mes calculs de projection de manière
synchrone dans le constructeur afin de faire un test :
.. code:: c#
UpdateTransformation().ContinueWith((task) => UpdateProjection());
Et ça marche, j'arrive à dessiner une face.
J'imagine donc que le problème vient du bout de code au dessus avec les
``await``. Je vais donc regarder cette vidéo afin d'essayer de mieux
comprendre ce qui pourrait mal se passer :
https://www.youtube.com/watch?v=2moh18sh5p4
J'ai également essayé de faire une méthode ``UpdateAll`` dans mon
``Renderer`` :
.. code:: c#
public async Task UpdateAll(PaintEventArgs pe)
{
await UpdateTransformation();
await UpdateProjection();
Render(pe);
}
Puis, j'ai essayé de l'appeler comme ceci :
.. code:: c#
await renderer.UpdateAll(e).ContinueWith((task) => e.Graphics.DrawImage(renderer.Bitmap, 0, 0));
Sauf que j'ai toujours la même erreur de paramètre invalide.
J'ai aussi essayé comme ça :
.. code:: c#
await renderer.UpdateAll(e);
e.Graphics.DrawImage(renderer.Bitmap, 0, 0);
Mais toujours pareil.
La première vidéo ne m'ayant pas trop aidé, je vais regarder cette vidéo
: https://www.youtube.com/watch?v=il9gl8MH17s
**9h59** Cette vidéo était beaucoup plus claire. Je comprends un peu
mieux maintenant ce qu'il se passe quand on utilise le mot clé
``await``. J'imagine donc que le problème que j'ai est que exécution du
code se termine dans un autre thread que le thread UI ce qui pose un
problème. Je vais attendre le rendez-vous GMeet avec M. Bonvin à 10h30
pour lui poser des questions.
**12h10** J'ai eu une réunion avec M. Bonvin. Il m'as expliqué que je
transformais et projetais mon modèle séparément, ce qui impacte les
performances et ce n'étais pas nécessaire. Je pensais que ça l'étais à
cause du backface culling et du flat shading. Il m'as aussi dit que je
projette mal les objets. En effet, je les projettes à l'aide de matrices
de projections orthographiques, sauf que au moment de dessiner les
points projetés, je choisis quel point j'affiche comme ceci :
.. code:: c#
PointF pointf = axis switch
{
Axis.X => new((float)points[i].Y, (float)points[i].Z),
Axis.Y => new((float)points[i].X, (float)points[i].Z),
_ => points[i].ToPointF(), // Default is Z, ToPointF takes the X and Y values
};
Ce qui fait que mes matrices de projection sont inutiles, comme ce code
est équivalent à une matrice de projection. M. Bonvin m'as dit que nous
ferrons en sorte d'avoir une caméra qui peut être placée dans l'espace
jeudi.
**13h47** Il y a quelque chose que je n'ai pas compris avec les
changements fait avec M. Bonvin. Il dit que on devrait pouvoir faire
l'éclairage et le backface culling avec le modèle projeté, alors que moi
je vois la projection comme le fait "d'aplatir" la forme, ce qui fait
que toutes les faces ferait face à la caméra. C'est ce qui se passe
actuellement, visible car toutes les faces sont blanches :
.. figure:: ./img/logbook/whiteFaces.png
:alt:
Avec ce code pour la projection :
.. code:: c#
Matrix4 transform = Matrix4.CreateScale(ScaleFactor) * Matrix4.CreateRotationZ(angleZ) * projection;
// The multiplication is parallelized
transformedModel = Model * transform;
Alors que si j'enlève la projection j'ai ça :
.. figure:: ./img/logbook/goodProjection.png
:alt:
Mais ça marche quand même grâce au code pour prendre les pixels qui est
l'équivalent de la matrice de projection. Je vais donc enlever la
multiplication par la projection temporairement. Je verrais ça jeudi
avec M. Bonvin.
**15h55** J'ai ajouté la création d'une matrice de rotation autour d'un
axe. Pris sur ce code :
https://github.com/opentk/opentk/blob/master/src/OpenTK.Mathematics/Matrix/Matrix4d.cs#L643
Cela dit, je ne comprends pas encore très bien comment l'axe est défini
avec un seul vecteur3.
.. _29042021:
29/04/2021
----------
**8h34** M. Garcia nous a parlé de comment s'est passé la discussion
avec M. Domont. Je vais maintenant parler des éléments mathématiques de
mon projet dans la documentation.
**15h35** J'ai avancé toute la journée sur la documentation des éléments
mathématiques.
En lisant les explications de `ce
site `__, j'ai mieux compris le
code de rotation que j'ai pris dans le source d'OpenTK. Ce qu'ils font,
c'est une rotation autour d'un axe qui passe par l'origine.
.. _30042021:
30/04/2021
----------
**12h55** J'ai avancé toute la matinée sur la partie mathématique de la
doc. J'étais coincé dans la partie sur la rotation autour d'un axe
arbitraire dans l'espace. Ce que je ne comprenais pas, c'était comment
l'axe était définis, car le livre parle de cosinus directeurs. Grâce à
`cette vidéo `__, j'ai pu
mieux comprendre ce que c'était.
**15h37** J'ai fini la partie mathématique de la documentation. Je dois
encore corriger le français. Je vais maintenant essayer de mettre mon
logbook sur readthedocs pour le rendu de ce soir.
**15h49** Les images étaient en chemin absolu et avec des backslash et
pas juste slash, donc c'était plus long que ce que j'aurais aimé.
J'hésite à faire le logbook en reStructuredText également.
.. _03052021:
03/05/2021
----------
**8h40** J'ai commencé à implémenté la création d'une matrice de
rotation autour d'un axe arbitraire. Je me suis rendu compte que je
n'avais pas fini l'explication pour calculer les cosinus directeurs. Je
vais donc compléter ça.
**11h06** J'ai fini de coder la rotation autour d'un axe arbitraire,
mais le résultat est bizarre. On dirait le l'objet change de forme par
cette matrice, je ne sais pas si c'est mon code qui est mauvais ou la
projection qui donne ce résultat bizarre.
.. figure:: ./img/logbook/spiiin.gif
:alt:
J'ai également discuté avec M. Bonvin, il m'a expliqué ou il en était
dans l'avancée du projet de son côté (car il code une version de se
projet aussi) et m'as expliqué ce que je devrait faire ensuite :
- Afficher les normales des faces
- Afficher les axes X, Y et Z
**12h47** J'ai réglé le problème, j'avais mal déclaré la matrice de
rotation Y. Voici ce à quoi ça ressemble maintenant :
.. figure:: ./img/logbook/niceSpin.png
:alt:
**13h15** J'ai mis le renderer directement dans la form et j'ai mis
l'appel de la fonction de calcul de la frame et le paint dans deux
timers différents.
**13h55** Comme la dernière fois que j'ai essayé d'afficher les
normales, il se passe n'importe quoi
.. figure:: ./img/logbook/badNormals.gif
:alt:
**15h20** J'ai ajouté le changement de taille en fonction de l'angle
avec la caméra. ça donne ça :
.. figure:: ./img/logbook/changeSizeNormal.png
:alt:
Je ne sais toujours pas si le problème de l'affichage c'est la
projection bizarre ou mon code.
.. _04052021:
04/05/2021
----------
**12h40** Pour cause de travaux, nous n'étions pas à l'école ce matin.
**13h57** En relisant `cette
page `__,
je me suis rendu compte que j'avais pris le code pour calculer la
normale d'un triangle car ma face ne pouvait être qu'un triangle. Je
vais donc essayer avec la méthode de Newell.
**14h41** Pendant que j'implémentais la méthode de Newell, M. Bonvin est
venu m'aider. Il m'as expliqué que le problème avec mes normales venait
peut-être de comment je calcule mes normales. Je calcule le vecteur
entre les points 0, 1 et 2 et M. Bonvin m'as dit d'essayer d'y faire
avec le centre de la face. Il m'as aussi conseillé de rendre mes classes
géométries mutables.
**14h45** Faire le calcul avec le centre change la manière donc les
normales gigottes, mais elles ne sont toujours pas immobiles.
**14h48** En relisant le wiki de OpenGL, j'ai vus que le code que
j'utilisais pour calculer la formule, n'était pas exactement le même
(mais avait la même idée). Je l'ai donc changé et maintenant ça marche.
Voici mon ancien code :
.. code:: c#
Vector3 physicalTwo = this.vertices[2].ToPhysicalCoords();
Vector3 v0 = this.vertices[0].ToPhysicalCoords() - physicalTwo;
Vector3 v1 = this.vertices[1].ToPhysicalCoords() - physicalTwo;
normal = v0.Cross(v1).NormalizeOrDefault();
Et voici mon nouveau code :
.. code:: c#
Vector3 physicalZero = this.vertices[0].ToPhysicalCoords();
Vector3 v0 = this.vertices[1].ToPhysicalCoords() - physicalZero;
Vector3 v1 = this.vertices[2].ToPhysicalCoords() - physicalZero;
normal = v0.Cross(v1).NormalizeOrDefault();
Je laisse pour l'instant la ligne qui change la longueur de la normale
commentée, je verrais plus tard avec M. Bonvin si c'est ce qu'il veut.
**15h22** M. Bonvin m'as également dit que je devait faire en sorte que
ma projection se fasse de manière à ce que l'axe +Y sois vers le haut et
l'axe +Z aille vers là ou la camera regarde. J'avais déjà un bug lors du
POC ou sur l'axe Z, rien ne marchais. J'ai toujours ce problème.
.. figure:: ./img/logbook/badZ.png
:alt:
.. _05052021:
05/05/2021
----------
**11h40** J'ai passé toute la matinée à essayer de régler mon problème
de projection sur l'axe Z, sans succès. Ensuite, M. Bonvin est venu
m'apporter deux livres *Infographie I* et *II* par *Philippe Schweizer*.
*Infographie II* contient beaucoup d'informations sur comment faire du
"parentage" entre les objets 3D (comme un bras mécanique par exemple).
Je vais donc passer l'après-midi à lire ce livre.
.. _06052021:
06/05/2021
----------
**12h55** J'ai passé toute la matinée à lire le livre. Je vais
maintenant essayer de commencer mon poster.
**13h19** J'ai trouvé une police pour le titre de mon poster (Oxanium),
mais après j'ai été décourager de continuer le poster car je suis nul
dans ce qui est graphique. Je continuerais ça plus tard.
**15h20** J'ai ajouté des informations sur comment les aspects
mathématiques sont implémentés dans le code. Je ne suis pas allé dans
les détails pour l'instant, j'ai juste montré 1 ou 2 exemples de code
par concept.
J'ai pas beaucoup avancé sur le code aujourd'hui. Le fait que rien ne
marche dans mon code me démotive un peu, mais je me demande si c'est
vraiment nécessaire de continuer à tenter d'y régler. Je pourrais juste
essayer de projeter avec une matrice de projection perspective et une
caméra virtuelle et peut-être que le problème disparaitra (vus qu'il
apparait que quand on projette d'une certaine façon). Je poserais la
question à M. Bonvin demain.
.. _07052021:
07/05/2021
----------
**9h26** J'ai essayé de projeter la scène avec une projection
perspective mais ça je marche pas. C'était le code de projection
perspective que j'avais pris sur le code d'OpenTK.
.. figure:: ./img/logbook/basPerspective.png
:alt:
**10h59** J'ai convertir le code modula-2 pour faire une matrice
perspective de *Infographie II* en C# et ça marche.
.. figure:: ./img/logbook/nicePerspective.png
:alt:
Cela dit j'ai toujours mon problème.
.. figure:: ./img/logbook/problems.png
:alt:
(et ça s'affiche sur le côté je sais pas pourquoi, surement un problème
d'axe)
**15h26** J'essaie de mettre ma matrice de projection dans un classe
camera comme dans ce projet :
https://github.com/opentk/LearnOpenTK/blob/master/Common/Camera.cs.
Cette camera à une méthode pour obtenir une matrice de pour transformer
dans un espace de vue (view space) et une matrice de projection. Ce qui
fait que ma ligne pour projeter ressemble à ça :
.. code:: c#
Matrix4 transform = Matrix4.CreateScale(ScaleFactor) * Matrix4.CreateRotationX(angleX) * camera.GetViewMatrix() * camera.GetProjectionMatrix();
Malheureusement je n'arrive pas à afficher quelque chose avec cette
technique :
.. figure:: ./img/logbook/badCamera.png
:alt:
**16h03** J'ai réglé le problème mais les normales ne marchent plus
trop.
.. figure:: ./img/logbook/niceCamera.png
:alt:
J'avais mal copier le code, je devais avoir ça :
.. code:: c#
Vector4[] vectors =
{
new Vector4(x.X, y.X, z.X, 0d),
new Vector4(x.Y, y.Y, z.Y, 0d),
new Vector4(x.Z, y.Z, z.Z, 0d),
Vector4.WAxis,
};
Mais j'avais ça :
.. code:: c#
Vector4[] vectors =
{
new Vector4(x.X, y.X, z.X, 0d),
new Vector4(x.X, y.X, z.X, 0d),
new Vector4(x.X, y.X, z.X, 0d),
Vector4.WAxis,
};
.. _10052021:
10/05/2021
----------
**10h04** J'ai mis en place des mouvements de caméra, mais la rotation
vers la gauche et la droite de celle-ci ne marche pas. Aussi, après
avoir effectué une rotation, le fait d'avancer et de reculer est
inversé. J'imagine que c'est du au fait que le tutoriel que j'ai suivis
à -Z en forward plutôt que +Z. A voir comment on inverse ça.
**10h07** J'ai réglé le problème pour quand on avance. J'ai fait ça en
mettant au négatif le vecteur forward qui est calculé. C'est pas la
meilleure façon de faire ça, mais ça marche.
.. code:: c#
front = -new Vector3(
Math.Cos(pitch) * Math.Cos(yaw),
Math.Sin(pitch),
Math.Cos(pitch) * Math.Sin(yaw));
**10h10** M.Bonvin est passé me voir. Je lui ai expliqué ou j'en étais
et il m'as dit de dessiner les axes X, Y et Z. Il m'as aussi dit que je
ferais bien de documenter ou j'en suis dans mon projet et ou je parle
des problèmes que j'ai rencontré et du coup là ou je bloque en ce
moment. Je vais donc en premier lieu dessiner les axes dans la scène.
**13h37** J'ai réussi à dessiner les axes dans la scène.
.. figure:: ./img/logbook/niceAxes.png
:alt:
**14h31** J'ai toujours la rotation de gauche à droite (yaw) qui ne
marche pas. Je vais donc attaquer la documentation.
.. _11052021:
11/05/2021
----------
**9h21** J'ai réglé le problème d'affichage des faces
.. figure:: ./img/logbook/niceProjection.png
:alt:
Le problème était du au fait que j'effectuais la transformation et la
projection en même temps. En séparant ces étapes, le calcul des normales
et l'algorithme du peintre peut marcher.
Cela dit, le dessin des normales ne marche toujours pas
.. figure:: ./img/logbook/normalNeverWorks.png
:alt:
Malgré le fait que j'utilise la méthode de Newell pour calculer les
normales.
J'imagine que le problème viens du dessin comme les lumières semblent
correcte.
**12h53** J'ai réglé le problème des normales
.. figure:: ./img/logbook/goodNormalsNiceGoodNotBad.png
:alt:
Le problème venait que j'\*essayais de dessiner les normales des faces
projetées alors que je devait prendre les normales des faces non
projetées et projeter cette normale.
**14h20** J'ai mis à jour la partie problèmes rencontrés de la doc. Je
vais maintenant essayer d'avancer sur le poster.
.. _12052021:
12/05/2021
----------
**10h49** J'ajoute du contenu sur la doc ce matin.
**12h59** Je continue la doc.
**15h27** Je suis un peu coincé pour ma doc. Je sais que je devrait
changer le cahier des charge comme la direction du projet à évolué.
Cela, je ne suis plus très sur de quel est l'objectif final du projet
actuellement. Je ne peux donc pas trop avancer sur cette partie de la
doc et sur le poster. Il est également difficile de continuer la partie
mathématique de la doc, car M. Bonvin a pris les livres.
.. _14052021:
14/05/2021
----------
**16h14** J'ai passé la journée sur le poster et la documentation.
.. _17052021:
17/05/2021
----------
**9h31** J'ai passé les structs géométries en classes sauf que
maintenant quand les normales de mes faces sont piles aligné avec la
camera, la face clignote.
**13h33** Je me suis également rendu compte que certaines faces
s'affichaient alors qu'elles faisaient dos à la caméra. Je suis tombé
sur `ce post sur
stackoverflow `__
qui parle de ce problème. Je vais donc régler ça.
**14h01** J'ai rajouté une méthode ``IsClockwise`` dans la classe
``Face`` en me basant sur `ce
post `__.
**15h23** J'ai pleins de problèmes d'affichages (avec un cube à l'envers
par ex). Je pense que ça vient du fait que j'ai mal réglé les axes de
mon projet.
.. figure:: ./img/logbook/wierdBackface.png
:alt:
Cela dit ça remarche a peu près quand j'inverse le test "IsClockwise"
.. figure:: ./img/logbook/rienMarche.png
:alt:
Mais les normales se dessinent derrière.
.. figure:: ./img/logbook/normalsNotWorkingAgainWhoIsSurprisedNobody.png
:alt:
**15h53** Je ne sais pas du tout ce qui cause tout ça. Je continuerais
demain.
.. _18052021:
18/05/2021
----------
**11h02** On a eu une discussion avec M. Bonvin ou nous avons discuté de
ce que je fait avec le backface culling et il ne semble pas être
d'accord avec cette méthode. Je pense continuer à utiliser cette méthode
cela dit. Je garde aussi l'ancienne. On a aussi parlé de la disposition
des axes et de s'il fallait avoir des axes différents entre le world
space et le view space. On en est arrivé à la conclusion que ce serait
intéressant pour montrer aux experts que j'ai compris ce point là, mais
je pense pas y implémenter pour l'instant, car c'est de la complexité
inutile. Je vais juste changer le système d'axe afin que +Z aille en
direction du spectateur (on s'était mal mis d'accord sur ce point
précédemment).
**13h55** Mon algorithme du peintre ne marchais pas. C'était du au fait
que je n'utilisais pas la variable des faces triées.
.. code:: c#
// Sort the faces by depth
List sortedFaces = transformedModel.GetDepthSorted(camera.Position);
Model projected = transformedModel * projection;
if (CullingMode == CullingMode.Clockwise)
{
projected.RemoveBackface(sortedFaces);
}
**15h44** J'ai ajouté un moyen de changer le type de projection dans
l'application (perspective et orthographique). J'ai aussi un moyen de
choisir quel type de backface culling je veux (aucun, avec les normales
ou en checkant si les sommets sont dans le sens des aiguilles d'une
montre).
**16h08** Les normales s'affichent normalement.
.. figure:: ./img/logbook/goodNormalImHappy.png
:alt:
Le gros de ce qui est disponible sur l'application marche maintenant. Je
pense que demain je pourrais commencer à travailler sur les cubes qui
ont un axe de rotation arbitraire.
.. _19052021:
19/05/2021
----------
**8h28** J'ai commenté mon code.
**10h55** J'ai fini la classe ``RectangularCuboid`` (pavé droit) mais je
n'ai pas fait le parentage. Je me dis que c'est pas forcément la
meilleure façon de directement y mettre dans cette classe. Je me disais
qu'on pourrait peut-être y abstraire avec une interface, mais comme le
but de ce projet est de montré l'aspect technique de la 3D, je pense
qu'on peut se permettre d'y mettre directement dans le cuboid.
Pour la gestion des parents/enfants, chaque cuboid aura une liste
d'enfants qui eux pourront aussi avoir des enfants. Ensuite, quand une
transformation (rotation par exemple) sera appliqué à un objet, elle
sera également appliquée à chaque enfant également.
**14h51** Je réfléchissant de comment implémenter le parentage je me
suis rendu compte d'un problème. Jusqu'à maintenant j'affichais chaque
objet tout seul, donc je pouvais juste prendre les coordonnées des
sommets et les afficher tel quel. Sauf que ce système ne marche pas
quand il y a plusieurs objets. Quand je voudrais faire ça, je vais
devoir définir une position dans l'espace à chaque objet et transformer
chaque sommet afin qu'il se trouvent autour de cette position. Donc
faire passer d'un espace local à un espace monde (local space a world
space).
.. _20052021:
20/05/2021
----------
**11h02** J'ai finalement décidé de faire une classe ``Entity`` dont
``RectangularCuboid`` descend. Il faut donc adapter mon code afin qu'il
afficher une liste d'entité et non juste un model.
**15h28** J'ai réfléchis sur comment je pouvais gérer le parentage. Ce
que je pense faire c'est que pour le entités qui sont plus bas dans
l'arborescence, elle vas recevoir rotations de tous ses parents et la
sienne puis les translations. Je pense faire ça avec une fonction
récursive, mais je ne suis pas sur.
Aussi, avant j'avais une méthode qui me passais l'entité transformée
selon sa position, rotation etc, mais cette façon de faire ne marche pas
avec le parentage, je pense donc mettre une variable
``TransformedModel``, mais je ne sais pas ou mettre a jour cette
variable pour l'instant.
.. _21052021:
21/05/2021
----------
**11h40** J'ai travailler sur le parentage ce matin et M. Bonvin est
venu vers 10h30 et on a parlé de ce que j'ai fait jusqu'à maintenant. Il
se trouve que M. Bonvin voulais un système qui soit absolu alors que moi
j'ai fait un système relatif.
Sauf que j'ai déjà beaucoup avancé sur le système relatif, je vais donc
le finir et si M. Bonvin veut vraiment que je fasse le système absolu,
je le ferais.
En cherchant sur google je me suis rendu compte que ce que je faisait
s'appelle un Scene Graph : https://en.wikipedia.org/wiki/Scene_graph
**13h30** Afin de mettre a jour tous les enfants de mon graph, j'avais
fait une méthode qui prenais les informations de position du parent puis
se changeais, sauf que c'était des paramètres. Je me suis rendu compte
qu'il était plus malin d'avoir une référence au parent et de prendre ses
informations grâce à celle-ci. Aussi, cela permettrais de mettre a jour
uniquement la partie du graph qui nous intéresse (comme dans ce post :
https://stackoverflow.com/questions/8030569/3d-relative-to-absolute-transformations).
**13h41** Pour passer les paramètres, il semble que les gens rassemblent
toutes les transformations appliqué à l'objet (donc position ou
translation et rotation) dans une seule matrice
(https://stackoverflow.com/questions/56920622/how-to-get-the-absolute-position-of-an-object-relative-to-a-parent-in-a-3d-world).
Je vais donc également implémenter ça.
**14h50** J'ai finir de faire ma classe ``Entity``, il faut maintenant
que je la teste dans un cas réel, mais je me dis actuellement que il y
aura surement un problème avec l'ordre des faces (mon code ne trie que
les faces dans un model, pas dans une scène entière). Je pourrais trier
les entités en fonction de leurs distance de la caméra mais ça ne serait
pas idéal.
**15h22** En faisant mon système d'arbre, je me demandais comment je
devais gérer l'ajout d'enfants/parents. Je suis tombé sur `ce
post `__
sur stackoverflow qui donne une solution très élégante, que j'ai donc
utilisé. (J'ai maintenant vraiment fini la classe ``Entity``)
TODO : Retravailler la classe ``RectangularCuboid``.
.. _25052021:
25/05/2021
----------
Note : cette journée s'est faite à distance
**8h05** J'ai ajouté des commentaires dans les classes créés vendredi et
j'ai un peu modifier la classe ``RectangularCuboid`` pour qu'elle n'aie
que un constructeur, car je n'ai plus besoin des champs qu'elle
contenait. Cela dit, je me dis que du coup ce n'est peut-être pas
nécessaire de garder cette classe, je pourrais juste avoir une méthode
dans ma classe ``Entity`` qui pourrait être utilisée comme ça :
.. code:: c#
Entity newEntity = Entity.CreateRectangularCuboid(width, height, depth, ...);
Je verrais plus tard ce que je déciderais de faire.
**8h46** J'ai fait le code pour afficher les objets de la scène. Pour
tester j'ai mis une seule entité avec un modèle de cube pour l'instant,
mais malheureusement il apparait tout plat
.. figure:: ./img/logbook/flatCube.png
:alt:
Aussi, je me dis qu'il serait peut-être plus clean de faire une classe
``Scene`` dans laquelle j'aurais une liste d'entité et qui me donnerais
une liste de face pour le rendu plutôt qu'une liste d'entité / modèles.
Ce serait aussi mieux pour l'algorithme du peintre. Cela dit, je vais me
concentrer sur mon cube pour l'instant.
Je me fait également la réflexion que je devrait surement faire une UI
afin de pouvoir contrôler chaque entité dans le scene graph. Je sais pas
encore je m'y prendrais.
**Après-midi** J'étais malade cet après midi, je n'ai donc pas
travaillé.
.. _26052021:
26/05/2021
----------
**9h08** J'ai réglé plusieurs problèmes, déjà le premier du X qui était
inversé que j'ai depuis longtemps. Le problème venait du fait que lors
de l'affichage j'avais inversé Y comme c'est ce qu'il faut faire dans
les images vus que l'axe Y est positif en descendant. Il a fallu que je
change cette ligne de code :
.. code:: c#
// Fichier : PointFExtension.cs
// Avant
float mappedPointX = point.X.Map(mathMinX, mathMaxX, imageSize.Width, 0);
// Après
float mappedPointX = point.X.Map(mathMinX, mathMaxX, 0, imageSize.Width);
J'ai également réglé mon problème de cube plat. J'avais en fait mal
définis ma matrice de rotation combinée qui prends un vecteur en
paramètre.
**13h12** J'ai réussis à faire le parentage. Dans l'image qui suit, j'ai
fait tourner le cube du bas et celui du haut à suivis.
.. figure:: ./img/logbook/niceCubeParenting.png
:alt:
**16h02** J'ai essayé de faire un système de scène qui permettrais de me
retourner juste des faces à dessiner ce qui éviterais qu'un objet se
dessine au dessus d'un autre. Je n'ai pas fini aujourd'hui, je finirais
demain.
.. _27052021:
27/05/2021
----------
**8h56** J'ai fini le système de scène, j'ai également l'éclairage et
l'affichage des normales avec.
.. figure:: ./img/logbook/niceScene.png
:alt:
Dans cet exemple le cube du bas est parent du cube au milieu qui est
parent du cube tout en haut.
**14h26** J'ai commenté ce que j'ai fait précédemment.
.. _28052021:
28/05/2021
----------
**15h30** J'ai commencé à documenter la matrice de projection
perspective.
.. _31052021:
31/05/2021
----------
**16h10** J'ai fait toute la journée de la documentation. J'ai fini la
partie mathématique.
.. _01062021:
01/06/2021
----------
**9h58** J'ai eu un rendez-vous avec M. Bonvin. Il m'as dit que ce
serait bien de documenter le processus du début à la fin de l'affichage
d'un objet. Aussi, il m'as dit que ce serait cool que dans la
documentation pour l'exemple, je fasse une espèce de pelle mécanique
pour montrer le parentage et dans la démonstration avec les experts de
faire l'exemple avec la main.
Expliquer comment on affiche qqch
exemple devant derrière
.. _02062021:
02/06/2021
----------
**12h56** J'ai essayé de faire un système ou j'ai plusieurs scènes selon
la démo que je veux faire, sauf que maintenant mon cube est collé à la
caméra et je ne sais pas pourquoi.
.. figure:: ./img/logbook/stuckCube.png
:alt:
**13h44** J'ai réglé le problème. Il venait du fait que mon entité avait
une valeur d'homothétie de 0 par défaut. Je l'ai donc mis à 1.
**14h36** J'ai ajouté un moyen de créer un pavé droit dans le struct
``Model``.
.. _03062021:
03/06/2021
----------
**9h18** J'ai créé les modèles 3d qu'il me faut pour la démonstration de
la pelle mécanique.
**10h36** J'ai mis les modèles entre eux dans la scène.
.. figure:: ./img/logbook/backhoeNice.png
:alt:
**11h26** J'ai fini d'animer la pelle.
.. figure:: ./img/logbook/movinBackhoe.png
:alt:
**16h12** J'ai fini la démo de la main.
.. _04062021:
04/06/2021
----------
**9h17** J'ai changé l'animation de la main pour que ses doigts bougent
de manière indépendante.
**11h01** J'ai écris la partie "Étude d'opportunité" de la doc.
**15h42** J'ai fait l'analyse fonctionnelle de la doc.
.. _07062021:
07/06/2021
----------
**16h15** J'ai commencé la partie analyse organique de la doc. J'ai
notamment fait un schéma sur Figma pour expliquer les différents espaces
de coordonnées.
.. _08062021:
08/06/2021
----------
**14h06** J'ai fini de documenter l'analyse organique.
.. _09062021:
09/06/2021
----------
**14h09** J'ai écrit la conclusion de la doc.
**15h08** J'ai ajouté un modèle de falco dans la démo de la main pour montrer que mon système marche avec plusieurs objets qui ne sont pas parentés.
10/06/2021
----------
**14h00** J'ai avancé sur la documentation le matin. M. Bonvin m'as donné un retour sur la documentation et m'as dis que mon analyse organique était très laqunière.
Je vais donc essayer d'aller plus en détail dans le code.
Je ne l'avais pas fait précédemment, car je pensais que le code serait lu en même temps que cette documentation.