mardi 14 juillet 2020

X-Plane - Quelques courses

Parce qu'il fallait bien profiter des soldes, je me suis lâché, et j'ai ajouté deux avions dans le hangar. Tout d'abord, le déjà classique A321 de Toliss, avec lequel je compte bien faire quelques procédures de panne moteur et autres joyeusetés (voir à ce sujet les excellents tutos de FalconEye), mais également du trans-atlantique: la variante LR de l'A321 peut faire jusqu'à 4000 nautiques, alors qu'un Paris New-York est légèrement au dessus des 3000 nautiques. Pour Los Angeles et pour Pékin, ce sera un peu plus tendu. Mais n'ayez crainte ! Flight Factor va sortir la mise à jour de son A350 sous peu.

Mais revenons à nos agneaux. Je tiens donc dans mes petites mains potelées l'Eclipse 550 NG, modélisé par Aerobask. C'est une très belle bête, qui se pilote gentiment, et qui a une avionique tout à fait intéressante en la personne du Garmin GTN 750, écran tactile, les plans de vol en deux coups de cuillère à pot, sympa. Histoire de coller à l'histoire et d'accompagner notre ex-Premier ministre, j'ai fait un petit vol depuis Le Bourget jusqu'à l'aéroport du Havre.

Voici donc la bête, en extérieur et en intérieur. Je sense que cet avion va remplacer le Cirrus Vision SF50 dans mon cœur pour les petits vols sans prétentions !

Manche et manette Airbus - Ils l'ont fait !

Contre toute attente (en tous cas la mienne !), Thrustmaster a sorti une réplique du manche et de la manette des gaz de l'Airbus A320. Apparemment, ça vient juste de sortir, c'est plutôt cool, et plutôt bien reçu par la communauté. Les revues du manche sur Youtube sont bonnes. La manette des gaz, ce n'est pas encore pour tout de suite car juste en précommande, mais elle est belle comme tout. L'ensemble semble viser le milieu de gamme et les simuleux faisant beaucoup de liner.

C'est intéressant de voir que ce genre de matos voit le jour maintenant. Je suppose que la venue très prochaine de Flight Simulator 2020 n'y est pas pour rien ! Ce n'est probablement pas suffisant pour me faire lâcher mon Warthog Hotas, qui ne joue pas dans la même gamme, mais c'est hyper tentant.

vendredi 3 juillet 2020

Minage d'astéroïdes

Mon vaisseau spatial de classe VERMINE, pour VÉhicule de Reconnaissance et MINage dans l'Espace, commence à prendre forme. Je me suis inspiré de bateaux cargos, et j'ai tenté d'ajouter une touche suffisamment spatiale à la chose, avec des gros moteurs fluo, et des antennes sur le toit. Le tout est beaucoup trop propre : je vais devoir travailler pour donner un aspect buriné à la chose.

Je me suis complètement lâché sur le "glare" (l'éblouissement ?), avec le bleu des moteurs et le blanc du reflet du soleil sur la coque qui provoquent de grands halos de lumière. Mais on est épique ou on ne l'est pas.

dimanche 21 juin 2020

Dans l'espace

Je suis d'une humeur très spatiale, ces temps-ci. Voici deux rendus, tout d'abord d'une planète de type Saturne, avec des anneaux de gaz et de roche, et ensuite d'un astéroïde construit sur le même modèle que ceux de l'anneau, mais avec plus de détails.

L’astéroïde est fait à partir d'un cube très lourdement subdivisé, auquel on a ajouté un modificateur "displace" avec une texture Voronoi. Tout d'abord, on créé une texture avec une taille assez élevée, afin d'avoir un objet avec pas trop d'arêtes, qui soit bien découpé. Ensuite, l'on peut ajouter des détails. Je trouve que le 4ème niveau de poids donne un effet particulièrement intéressant. Et finalement, on rajoute une texture normale avec un bête bruit très détaillé.

Pour le fond étoilé, voici mes nœuds "world". Je créé une texture de bruit très fine, que je passe à travers une color ramp pour ne garder que des points éparpillés. Voici mes étoiles. Ensuite, j'aimerais bien leur donner des couleurs différentes, alors je créé une autre texture de bruit, fine aussi, mais moins, histoire que des étoiles proches aient des teintes proches, parce que pourquoi pas, et je la passe à travers une color ramp qui contient toutes les teintes qui m'intéressent : du rouge, du jaune, du blanc, du bleu. Ensuite, je combine ces deux textures à travers un nœud "hue saturation value", pour utiliser les couleurs de la deuxième texture, mais avec la luminosité contrôlée par la première texture. Et voilà, des étoiles gentiment colorées !

Notez également dans la deuxième image, un "glare" assez fort, contrôlé via le compositeur, et qui donne un aspect "spatial". Les lumières sont fortes (100 000 W pour la lumière mon soleil) pour avoir de beaux contrastes.

L'on notera à quel point on peut faire de fort jolies choses avec Eevee : c'est typiquement le genre de scènes où ce moteur temps réel donne de très belles choses. En revanche, quelques tests d'animation montrent ses limites: avec une forme compliquée comme celle de mon astéroïde, les ombres sont finalement assez imprécises, ce qui n'est pas gênant pour une image seule, mais provoque des sauts intempestifs quand elles sont animées.

Maintenant, reste à améliorer les vaisseaux, et à animer le tout un minimum, histoire de profiter des jeux de lumière.

jeudi 11 juin 2020

C++14 - std::string_view veut jouer avec std::set

Petite expérience du matin (chagrin ?) : Comment faire un find sur un std::set en utilisant string_view ?

Revenons en arrière. Tout d'abord, qu'est-ce que std::string_view, et pourquoi voudrait-on l'utiliser pour faire un find ?

Vous avez peut-être remarqué que l'objet std::string est loin d'être gratuit. Non seulement les copies peuvent être chères (modulo COW et SSO, m'enfin bref), mais en plus le reste du monde conspire contre nous entre les chaînes codées en dur qui sont des const char *, et de nombreuses bibliothèques ne veulent pas en entendre parler. Voyez par exemple cette recherche dans un std::set : en passant un paramètre const char *, il se cache en fait la construction d'un objet std::string, et donc une allocation.

#include <set>
#include <string>
#include <iostream>

#include <stdlib.h>

int number_of_allocs = 0;

void* operator new(std::size_t size) {
  ++number_of_allocs;
  void *p = malloc(size);
  if(!p) throw std::bad_alloc();
  return p;
}

void* operator new  [](std::size_t size) {
  ++number_of_allocs;
  void *p = malloc(size);
  if(!p) throw std::bad_alloc();
  return p;
}

void* operator new  [](std::size_t size, const std::nothrow_t&) throw() {
  ++number_of_allocs;
  return malloc(size);
}
void* operator new   (std::size_t size, const std::nothrow_t&) throw() {
  ++number_of_allocs;
  return malloc(size);
}


void operator delete(void* ptr) throw() { free(ptr); }
void operator delete (void* ptr, const std::nothrow_t&) throw() { free(ptr); }
void operator delete[](void* ptr) throw() { free(ptr); }
void operator delete[](void* ptr, const std::nothrow_t&) throw() { free(ptr); }

int main()
{
  std::cout << number_of_allocs << std::endl;
  
  std::set<std::string> str({"a", "b", "c"});
  
  std::cout << number_of_allocs << std::endl;
  
  // Longue chaine pour éviter le SSO
  str.find("abceuhaoeuhaotuhaoutnohusaocamhamknomhucra,huh");
  
  std::cout << number_of_allocs << std::endl;

  return 0;
}

La punition est immédiate, le programme affiche 0, 3 et 4, parce que la chaîne dans le find a été convertie en std::string et a provoqué une allocation.

Si l'on s'amuse plutôt à passer un std::string_view, dans ce cas, le programme ne compile pas, car il n'y a pas de création implicite de std::string d'après une std::string_view.

  str.find(std::string_view("abceuhaoeuhaotuhaoutnohusaocamhamknomhucra,huh"));

Entre en scène la nouvelle surcharge de la fonction find, datant du C++14, qui prend un paramètre template qui doit être comparable avec une clé "de manière transparente", sans conversion nécessaire. Ah ah! Pile ce qu'il nous faut. Il faut juste donner au std::set un comparateur transparent, comme std::less, et cela fonctionne.

[...]
int main()
{
  std::cout << number_of_allocs << std::endl;
  
  std::set<std::string, std::less<> > str({"a", "b", "c"});
  
  std::cout << number_of_allocs << std::endl;
  
  str.find(std::string_view("abceuhaoeuhaotuhaoutnohusaocamhamknomhucra,huh"));
  
  std::cout << number_of_allocs << std::endl;

  return 0;
}

Victoire, le programme affiche 0, 3, 3, et a donc économisé l'allocation ! Mieux encore, la version où l'on passe juste la chaîne en const char * a également économisé son allocation, le std::string_view n'étant là que pour empêcher la conversion implicite.

Première conclusion : ajoutez des std::less<> à vos std::set et std::map prenant des chaînes !

Deuxième conclusion : pensez à creer un comparateur manuel si vous faites ce genre de magie avec vos propres objets

Troisème conclusion : passez à C++20 pour faire la même chose avec std::unordered_set et std::unordered_map. Je vous en recauserai peut-être quand j'aurai mis à jour mon compilo.

Références:
https://en.cppreference.com/w/cpp/string/basic_string_view
https://en.cppreference.com/w/cpp/container/unordered_set/find
https://stackoverflow.com/questions/9927856/how-to-use-operator-new-to-count-number-of-times-of-dynamic-memory-allocation
https://stackoverflow.com/questions/35525777/use-of-string-view-for-map-lookup

jeudi 7 mai 2020

Lanternes en vidéo

Une lanterne posée sur le sol, c'est rigolo, mais une lanterne qui tombe du plafond, c'est encore mieux ! Voici un rendu rapide (enfin, c'était la modélisation qui était rapide, le rendu, lui, a quand même pris 6 heures) de la lanterne du post précédent qui chute et rebondit sur le sol. Il a suffi de laisser faire le moteur physique de Blender, et le tour était joué. On admirera les effets de lumière sur le sol quand la lanterne le percute.

Une lanterne

Petite scène rapide avec une lanterne. C'était finalement beaucoup plus facile que prévu : simplement se mettre une petite loupiote dans le cube (aïe !) et utiliser pour le cube un shader translucide coloré. Le tour est joué !

Il y a probablement moyen d'en faire une vidéo...