Logbook¶
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.
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.
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.
public Model GetNonBackface(Vector3 lineOfSight)
{
List<Face> 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.
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 :
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.
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 :
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.
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.
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 :
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 :
// 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 :
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]);
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 Faceen 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 :
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.
J’ai mal structuré mon code par contre, ça ne marche que quand le backface culling est activé. Je fixerais ça plus tard.
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.
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 :
[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.
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 :
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 :
UpdateTransformationUpdateProjectionRender
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.
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 :
await renderer.UpdateTransformation();
await renderer.UpdateProjection();
renderer.Render(e);
e.Graphics.DrawImage(renderer.Bitmap, 0, 0);
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 :
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 :
public async Task UpdateAll(PaintEventArgs pe)
{
await UpdateTransformation();
await UpdateProjection();
Render(pe);
}
Puis, j’ai essayé de l’appeler comme ceci :
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 :
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 :
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 :
Avec ce code pour la projection :
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 :
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.
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.
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.
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.
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 :
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
15h20 J’ai ajouté le changement de taille en fonction de l’angle avec la caméra. ça donne ça :
Je ne sais toujours pas si le problème de l’affichage c’est la projection bizarre ou mon code.
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 :
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 :
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.
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.
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.
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.
10h59 J’ai convertir le code modula-2 pour faire une matrice perspective de Infographie II en C# et ça marche.
Cela dit j’ai toujours mon problème.
(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 :
Matrix4 transform = Matrix4.CreateScale(ScaleFactor) * Matrix4.CreateRotationX(angleX) * camera.GetViewMatrix() * camera.GetProjectionMatrix();
Malheureusement je n’arrive pas à afficher quelque chose avec cette technique :
16h03 J’ai réglé le problème mais les normales ne marchent plus trop.
J’avais mal copier le code, je devais avoir ça :
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 :
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,
};
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.
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.
14h31 J’ai toujours la rotation de gauche à droite (yaw) qui ne marche pas. Je vais donc attaquer la documentation.
11/05/2021¶
9h21 J’ai réglé le problème d’affichage des faces
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
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
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.
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.
14/05/2021¶
16h14 J’ai passé la journée sur le poster et la documentation.
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.
Cela dit ça remarche a peu près quand j’inverse le test « IsClockwise »
Mais les normales se dessinent derrière.
15h53 Je ne sais pas du tout ce qui cause tout ça. Je continuerais demain.
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.
// Sort the faces by depth
List<Face> 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.
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.
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).
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.
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.
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 :
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
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é.
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 :
// 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.
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.
27/05/2021¶
8h56 J’ai fini le système de scène, j’ai également l’éclairage et l’affichage des normales avec.
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.
28/05/2021¶
15h30 J’ai commencé à documenter la matrice de projection perspective.
31/05/2021¶
16h10 J’ai fait toute la journée de la documentation. J’ai fini la partie mathématique.
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
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.
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.
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.
11h26 J’ai fini d’animer la pelle.
16h12 J’ai fini la démo de la main.
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.
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.
08/06/2021¶
14h06 J’ai fini de documenter l’analyse organique.
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.
22h00 J’ai continué la doc.
11/06/2021¶
9h45 Finalisation de la doc et rendu.