Exemple de module


Ici vous pouvez voir comment je compose un module de fenêtre pour un étage. En rouge c'est le mesh principale, celui sur lequel sera mit les différents "socket primaire". Tout les autres mesh sont les différents mesh secondaire qui viennent ce placer sur les sockets.

A terme j'aimerais une troisième couche de mesh pour approfondir encore un peu plus en détails.

Inspirations











J'aime les instances !


Quand je suis passé du full static mesh aux instances... Cela à bien soulagé les performances...
Dans l'article précédent je présentais comment je suis arrivé a faire mettre des statics mesh sur leurs emplacements respectif. Mais je n'avais qu'un seul objet possible par socket... Mon but est bien d'ajouter de la diversité dans tout les le bâtiment généré. Cela est très rare de voir un immeuble avec tout la façade exactement uniforme. Il y a toujours des petits détails qui change d'une fenêtre a une autre. Un pot de fleure sur le rebord, ou même plusieurs.... Une fenêtre peu être un peu entre ouverte ou bien grande ouverte. Tous ces petits détails font qu'un bâtiments abrite la vie ou pas, même les bâtiments de bureau de travail ont ce genre de détails...

Dans cette optique là il a fallu que je revois un peu mon code qui ne me permettait pas d'avoir plusieurs objets possible pour un même socket...



Une fois le système de structure mit en place, j'ai peu commencer à apporter un peu plus de complexité dans ma construction de building, ajouter des détails.

J'ai donc commencer a faire des test avec les "socket", le principe est asse simple. J'ajoute un "socket" sur un mesh et ensuite dans le blueprint je fais un "attach to" pour y placer un autre mesh et ainsi le second mesh ce retrouve sur la location du socket. Malheureusement dans mes tests cela fonctionnait avec des "Static Mesh" mais par soucie d'optimisation je devait utiliser des "instances" ce qui empêchait l'utilisation du node "Attach to".
Un socket est ajouté sur le mesh rouge. Je viens faire un "attach to" du cube sur le socket.

Pour contourner ce problème il a fallut que a chaque itération je récupère la position du socket et que je l'ajoute a la position du mesh qui a le socket. Cette addition de vector me donnera ma position final, celle qui sera également la position du mesh qui viendra ce positionner sur le socket.

Ici j'ai ajouté un mesh "rock" sur un "socket". Tout les meshs ici sont des instances !

A ce stade je n'ajoute qu'un socket par mesh, mais la suite fut un peu plus compliqué a mettre en place. Car mon but est bien d'avoir plusieurs socket sur un même mesh et ainsi avoir plus d'éléments qui puissent être modifié. Pour cela j'ai passé beaucoup de temps a chercher comment faire.

Puis je me suis demandé si ajouter dans ma structure une variable "Map" pouvait m'aider. Dans unreal la variable Map correspond a un dictionnaire. Il lui faut un valeur de "key" et une "value".
Je choisi donc de donner en "key" le nom du "socket" et en "value" de donner le mesh qui lui sera associé.

Il me sera facile dans le blueprint de récupérer les valeurs. A chaque itération, je regarde les sockets présent dans mon premier mesh, je fabrique une boucle a partir de cette liste de socket. Ensuite a chaque itération de socket je regarde son nom et le vais récupérer le mesh qui lui est associé dans ma variable "Map" c'est comme ca que je peu placer sur chaque socket, le mesh qui lui correspond.


Exemple de mesh avec plusieurs socket et leur mesh associé !
Dans l'image précédente j'ai rajouté dans mon code un pourcentage d'apparition. Selon la valeur que je donne pour chaque objets, ils peuvent apparaître ou non. C'est pour cela que la distribution des cubes est aléatoire sur toute la surface de mon bâtiment.



Whouaou !! Et un deuxième article arrive !!

Voici un aperçu du Blueprint qui sert a générer le rez de chaussé dans l'article précédent.


La dernière fois on en était resté à la construction des étages. Pour ce faire j'avais juste fais une boucle sur la création de mon rez de chaussé au rajoutant un offset en Z a chaque itération.

Pour la suite, comme je distingue bien le rez de chaussée et les étages, il me faut des modules spécifiques pour les étages. Ici, je choisi donc des modules de 800*400 unité pour le rez de chaussée et de 800*300 pour les étages.
J'utilise le blueprint "Structure" afin de gérer mes variables, que ce soit mes différents mesh de rez de chaussée, d'étages, de toit... Au début pour effectuer mes offset, je récupérais les informations de bounding box de mes mesh, mais cela n'avait pas trop d’intérêt et faisait du calcul supplémentaire. C'est pourquoi j'ai rajouté une variable vector pour le rez de chaussé et une pour les étages qui me permettent de rentrer directement les informations de bounding box sans devoir les calculer.
Une structure pour générer un batiment


Le blueprint de structure facilite grandement les choses et me font gagner beaucoup de temps. En effet, quand je me suis lancé sur le blueprint j'allais récupérer tous mes mesh grâce à un path(chemin d’accès) mais cela demander beaucoup trop de node et pouvais facilement me faire faire des erreurs.
C'est en regardant la vidéo de "Ammobox Studio" que j'ai vu cette manière de faire:


Après pas mal de travail sur le blueprint j'ai réussi a obtenir mon rez de chaussée et mes étages avec différents mesh. Pour bien me rendre compte lors du développement que tout fonctionne bien j'ai mis des shader différents en désaturant la couleur pour les étages.



Rattrapage d'informations :)

Génération du Rez de Chaussée

Je mis prend un peu tard pour commencer mon carnet de bord mais j'avais besoins de temps pour commencer mon algorithme sur Unreal Engine. Je suis passé par plusieurs stade, je me suis d'abord demandé comment je pourrais organiser mon code pour que l'on puisse utiliser l'outils pour toute sorte de bâtiments. 
J'ai donc divisé mes façades en plusieurs parties, a la verticale dans un premiers temps on retrouve en premier lieux les fondations puis les rez de chaussée, les étages et le toit. Pour ce qui est des modules horizontal on peu découper le rez de chaussée peu être composé de modules "Porte", "Fenêtre", "Mur vide" et les "Coins". Ce sera en partie les même chose pour les étages avec le module de "Porte" en moins. 
Je me suis donc en premier lieux attaquer au Rez de chaussée. Pour ce faire il fallait que je puisse placer correctement mes modules, notamment grâce au bounding box. Elles me permettent de récupérer les dimensions du module en X, Y et Z. Je peu donc placer le prochain module en fonction du premier. Pour ce faire j'utilise également les splines, l'idée est de donner une coordonner en X a cette spline, quand la coordonner devient plus grande que celle de la bounding boxe du module, je place un second module a la suite.

Il a fallu que je laisser un peu d'amplitude a cette distance car il y avait des valeur a 3 chiffres après la virgule donc dans certains cas le module suivant n'était pas poser.

Le processus de génération est donc le suivant :
  • Je commence par enregistrer les différentes coordonnées dans des listes ( 4 en tout, une pour chaque côté).
  • Ensuite je transfère ces listes vers des listes de travail dans lesquelles je pourrais supprimer au fur à mesure des données.
  • A cette étape, pour chaque côté je créer des nouvelles listes, une pour chaque type de module(porte, mur vide, fenêtre,...) afin de leur attribuer des coordonnées aléatoire prit dans la liste de travail. 
  • Grace aux listes créé juste avant, je peux donc placer mes modules facilement.
Génération des étages avec un test sur l'utilisation des sockets

Une fois le rez de chaussée terminé pour sa première version j'ai fais un peu de rangement dans mes Blueprint en faisant des fonctions réutilisable. A la suite j'ai donc pu facilement dupliquer la fonction du rez de chaussée pour faire les étages afin de tester la verticalité sachant qu'il y aura pas mal de changement dans la fonction des étages. Mais cela ma permis de me rendre compte que j'avais fais une erreur avec les "StaticMesh", cela faisait ramer pas mal, j'ai donc remplacer les "StaticMesh" par des "instancedStaticMesh" en prenant soins de désactiver les shadows, les collisions afin de libérer de la puissance de calcule. Ces deux options seront géré par un mesh placer au milieu du building et qui sera scaler a la même taille que le building, c'est donc le mesh qui fera la collision et l'ombre porté du building.