PARIS BUBBLES

Le développement de cette démonstration webgl nous a fait revenir à l’objet initial qui nous a lancé dans la création de SPACEGOO, à savoir l’affichage de contenus multimédia, typiquement 2D, dans un contexte 3D. Ici le contexte 3D permet une expérience de navigation plus douce, qui n’est pas hachée par les clics sur les liens hypertextes.

Le contraste entre la 2D et la 3D créé un effet intéressant, et met en valeur le contenu 2D par effet de perspective. Cette mise en valeur est enrichie par les transitions entre la couleur et le noir et blanc.

Cette démonstration nous a pris 4 jours de développement à 2, et on est très satisfait du résultat produit. Par rapport à nos autres démonstrations nous introduisons des éléments nouveaux, notamment le positionnement d’éléments CSS en synchronisation avec la scène Webgl. Le déploiement du contenu est également innovant : au début il sort de la bulle où chaque contenu est emballé dans un carré, et ces carrés sont de tailles décroissantes et positionnés dans un rectangle dont le rapport hauteur/largeur vaut le nombre d’or ( vous trouverez plus d’informations sur cette disposition ici : http://en.wikipedia.org/wiki/Fibonacci_number ). Puis il se dispatche sur l’écran de sorte à ne pas trop se chevaucher.

Cette présentation rend particulièrement bien avec un écran tactile de grande taille.

Le lien vers la démo est ici : http://www.spacegoo.com/bubbles

Pour les non compatibles, voici la démo :

bubbles.ogv
Runtime
1:25
Compteur de vues
460

New webgl demo : Tiananmen 1989

En ces temps où le contrôle de la liberté d’expression est plus que jamais un sujet à la mode, notamment grâce aux révolutions arabes et aux dernières révélations de wikileaks sur les entreprises occidentales ayant vendu des technologies de surveillance électronique à des dictatures ( http://wikileaks.org/the-spyfiles.html ), nous dévoilons notre nouvelle démo webgl consistant en un espace dédié à la liberté d’expression.

Avant d’aborder les aspects techniques de cette démonstration, je vais me permettre une rapide digression par rapport au sujet principal de ce blog, sur les évènements historiques l’ayant inspiré.

A partir du 15 Septembre 1989, un important mouvement populaire se forme sur la place Tiananmen, à Pékin. Ce mouvement est mené essentiellement par des étudiants, des intellectuels et des ouvriers. Ces deniers demandent des réformes politiques et démocratiques. Bien que ce mouvement soit totalement pacifique, le gouvernement communiste chinois met en place la loi martiale le 20 mai. A partir du 4 Juin, l’armée populaire ouvre le feu sur la foule. Le nombre de morts n’a pas été évalué avec certitude, et oscille entre plusieurs centaines et quelque milliers.

En Juin 1989, un manifestant  se place sur le chemin d’une colonne de chars, sur l’avenue Chang’An, qui borde la place Tiananmen au nord. Si l’identité de cet homme n’est pas connue, cette image est mondialement célèbre de par son puissant symbolisme.

Actuellement, même si la Chine n’est plus celle de Mao, elle reste une dictature communiste où la liberté d’expression est contrôlée et où les médias sont censurés. Leur outil de censure de l’Internet, le GFW (pour the Greate FireWall )  ne cesse de se perfectionner : il filtre le contenu des paquets lisibles, bloque les proxies, effectue du DNS poisoning, relentit les connexions HTTPS et de nombreux VPN, ….

Notre démonstration fige cet instant historique, et transforme ce symbole de la répression en un lieu de liberté d’expression. Tout internaute peut peindre et coller des images sur les chars, sur le sol ou sur le monument à la gloire des héros du communisme. Les modifications peuvent être sauvegardées sur le serveur de sorte à les partager.

Au niveau technique, les maillages ont été exportés de Blender. Les intersections se font via un octree créé à l’exportation de Blender, et non plus au chargement en javascript comme dans notre précédente démo Cadillac Ranch . Le serveur recréé le processus de création effectué côté client avec GD, la librairie de gestion d’images de PHP.

La démonstration est disponible ici : http://www.spacegoo.com/tiananmen

Et la vidéo capture d’écran pour les non compatibles webgl (profitez de Noël pour changer de PC ) :

Tiananmen 3D
Runtime
2:25
Compteur de vues
398

 

Pavages de Penrose

Pour notre future démo, nous nous sommes intéressés aux pavages de Penrose.
Il s’agit de pavages non-périodiques du plan construits à partir de règles locales. Ainsi, contrairement aux pavages classiques périodiques qu’on peut voir par exemple dans les mosaïques de l’Alhambra, ceux-ci ne possèdent aucune règle qui permet de déduire l’ensemble du dessin par une suite finie de rotations/translations.
En résultent des motifs surprenants et très beaux.
D’un point de vue scientifique, ils servent à étudier les quasi-cristaux, notamment pour déterminer leurs figures de diffraction. Alain connes s’en sert également comme d’un exemple privilégié pour illustrer sa géométrie non-commutative.

Nous allons décrire un algorithme pour construire de tels pavages à partir de triangles d’or. Un triangle d’or est un triangle isocèle dont le grand côté est \varphi fois plus long que le petit côté. Il n’en existe que deux types :
On définit alors une procédure de découpage de ces triangles. Partant de l’un ou l’autre cas, on le coupe en deux suivant la méthode suivante :

  • A gauche :  \lVert SR\rVert = \lVert RQ \rVert ou de manière équivalente : S = (2-\varphi)*P + (\varphi - 1)*Q
  • A droite :  \lVert RP\rVert = \lVert RS \rVert   ou de manière équivalente : S = (\varphi - 1)*Q + (2-\varphi)*R

Les triangles générés par un tel découpage sont également des triangles d’or, ce qui permet de réiterer la procédure. Il faut noter qu’à chaque subdivision, on a le choix entre une division « à gauche » ou « à droite », ce qui permet de générer autant de façon de paver le plan que nécéssaire.
Nous avons fait le choix d’une méthode particulière, qui génère de beaux pavages, et en voici l’algorithme, en pseudo-code de type javascript, avec une gestion manuelle de la pile de récursion, pour éviter de la faire exploser à l’éxécution :

// lvl donne le nombre de subdivisions
penrose = function(lvl) {
var Q = [100, 100];
var R = [100, 500];
var P = [716, 300];
// lvl désigne la distance qui sépare le triangle de la subdivision maximale autorisée
var root = Triangle(P, Q, R, "aigu", lvl);
var stack = [];

stack.push(root);
// Tant que la pile de triangle non-subdivisés est non-vide :
while (stack.length > 0) {
var zde = stack.pop ();
if (zde.prof <= 1) { // cas terminal
zde.draw ();
}
else {
// split renvoie le point S suivant la procédure décrite plus haut
var S = zde.split ();
if (zde.style === "aigu") {
stack.push(Triangle(zde.R, S, zde.Q, "aigu", zde.prof-2));
stack.push(Triangle(S, zde.P, zde.R, "obtus", zde.prof-1));
}
else {
stack.push(Triangle(zde.R, zde.P, S, "aigu", zde.prof-1));
stack.push(Triangle(S, zde.P, zde.Q, "obtus", zde.prof-2));
}
}
}
}

Ce code termine puisqu’à chaque étape, on ne génère que des triangles dont la profondeur est strictement inférieure au triangle courant et que le cas terminal ne renvoie rien.

Nous l’avons utilisé en javascript en dessinant un tel triangle découpé avec 16 niveaux de profondeurs :

La démo est disponible ici :http://www.spacegoo.com/penrose

Héritage en Javascript

Le javascript est aujourd’hui largement utilisé sur le Web. Tous les navigateurs implémentent leur moteur javascript, et il est évidemment le langage incontournable quand il s’agit d’utiliser WebGL ou WebCL.

Il est présenté comme un langage objet, mais ses capacités à ce niveau restent nativement limitées. Notamment, l’héritage n’est pas prévu. Lorsqu’on développe une application conséquente, l’héritage est pourtant un facteur indispensable pour réduire la quantité de code et donc les coûts de développement d’une application.

Il existe plusieurs méthodes pour contourner cette faiblesse du langage, et nous allons vous en présenter une, qui est à notre avis la plus souple et la plus élégante. Selon la terminologie de Douglas Crockford, il s’agit d’un pattern d’héritage « fonctionnel ». Rien ne vaut un exemple, alors en voici un :


var motherClass = function (spec) {
var that = {}; // création de l'objet retourné
that.get_name = function () { // "virtual" method
}
return that;
}

var daughterClass = function (spec) {
spec.name = spec.name || "";
var that = motherClass(spec); // l'héritage est ici : on initialise l'objet retourné en utilisant le constructeur de la classe mère
that.get_name = function () { // on spécifie le code de la méthode "virtuelle" mère
return "daughterClass : " + spec.name;
}
return that;
}

var instance = daughterClass({name: "daughter"}); // instanciation
console.log(instance.get_name ());

daughterClass : daughter 

On peut alors spécifier plusieurs classes héritant de « motherClass ».
Une autre classe pourrait par exemple être :

var daughterClass2 = function (spec) {
spec.name = spec.name || "";
var that = motherClass(spec); //héritage ici!
that.get_name = function () { // et respecification de l'interface
return "daughterClass2 : " + spec.name;
}
that.special_to_this_class = function () { // methode specifique à la classe daughterClass2
return "special";
}
return that;
}

Et on peut alors utiliser cela dans un même tableau (c’est un avantage du non-typage javascript) :


var tab = [];
tab[0] = daughterClass({name: "1"});
tab[1] = daughterClass2({name: "2"});

for (var i = 0 ; i < 2 ; ++i) { console.log(tab[i].get_name ()); }

daughterClass : 1
daughterClass2: 2

Après cela il ne tient qu’à vous d’enrichir les méthodes pour obtenir ce que vous voulez!

PS : notez que dans ces classes, on ne peut accéder aux attributs autrement qu’avec la méthode get. C’est un forme d’encapsulation des données!

Welcome to SPACEGOO BEACH

A défaut de pouvoir partir sur une plage des tropiques pour contempler un océan bleu turquoise, nous avons recréé en partie ce genre de paradis sur spacegoo.com.
Ainsi notre dernière démo webgl, SPACEGOO BEACH, est une simulation d’océan.

La surface de l’eau est représentée par une surface maillée de façon plus resserrée au centre, sur laquelle sont appliquées deux textures : celle du ciel et la texture du fond. Pour calculer les coordonnées UV relatives à l’application de ces textures, nous utilisons les lois de Descartes dans les shaders via les fonctions refract et reflect.

Les vagues sont représentées par une superposition de 10 ondes sinusoïdales. Leurs paramètres sont liées via des lois empiriques que l’on peut trouver sur cet article de wikipédia.

Cliquez ici pour lancer la démo

Pour les non compatibles webgl, qui n’ont pas profité des promotions de la rentrée pour s’acheter un nouvel ordinateur, voici la vidéo capture d’écran :

SPACEGOO beach
Runtime
1:01
Compteur de vues
10,470