Makina Blog

Le blog Makina-corpus

Une randonnée en 3D grâce à BabylonJS ! Partie 2 : Le chemin


Cet article est dédié à l'explication de certains points essentiels dans le code de la première démo de Geotrek 3D. La deuxième partie explique les étapes de la création du chemin.

Article précédent partie 1 : le terrain.

La création du chemin est séparée en plusieurs étapes :

  • j'ai d'abord utilisé des sphères que j'ai drapées sur le terrain. 
  • Les points/sphères sont ensuite liés entre eux par des cylindres de même diamètre.

 

Draper les sphères

Pour draper les sphères il faut créer un rayon vertical passant par le point à draper avec Babylon.Ray(point, axe).

On teste l'intersection de ce rayon avec chaque terrain et si elle existe, on déplace la sphère à la hauteur du point d'intersection. L'inconvénient ici est que si un chemin passe sous une grotte ça ne fonctionne plus mais je doute que ce cas de figure soit dans nos données pour l'instant.

RANDO.Utils.drapePoint = function (point, dem) {
    var children = dem.getChildren();
    var ray =  new BABYLON.Ray(point, BABYLON.Axis.Y);
    for (it in children) {
        var pick = children[it].intersects(ray, true);
        if (pick.pickedPoint) {
            point.y = pick.pickedPoint.y + RANDO.SETTINGS.TREK_OFFSET;
        }
    }
};

 

 

Placer les cylindres

Une fois les sphères bien positionnées, on doit placer les cylindres. Une tâche plus compliquée qu'il n'y parait au premier abord.

Pour qu'une droite joigne 2 points, il faut :

  • que la droite passe par le milieu des 2 points 
  • si on est en 2D on a besoin que d'une seule rotation
  • si on est en 3D, 2 rotations d'axes différents sont suffisantes

Je me suis donc dis au départ bon, on va faire 2 rotations et c'est plié. Sauf que ce n'est pas si simple, il y a en effet 2 rotations à faire, mais elles ne sont pas indépendantes l'une de l'autre !

Etant débutant en 3D j'ai eu beaucoup de mal à comprendre ceci. Ce n'est qu'après quelques pages de calculs et grâce à une aide précieuse d'un stagiaire en Blender, que j'ai réussi à comprendre cette petite subtilité et faire cette fonction de placement de cylindre qui prend en paramètre un cylindre et 2 points A et B:

RANDO.Utils.placeCylinder = function (cylinder, A, B) {
    
    // Initial position at the center of the AB vector
    cylinder.position = new BABYLON.Vector3(
        (A.x+B.x)/2,
        (A.y+B.y)/2,
        (A.z+B.z)/2
    );

    // Adjust scale of cylinder
    var new_height = BABYLON.Vector3.Distance(A, B);
    var scale_y  = (cylinder.scaling.y * new_height) / cylinder.height;
    cylinder.scaling.y = scale_y;
    
    // First rotation
    var angle1 = RANDO.Utils.angleFromAxis(A, B, BABYLON.Axis.X);
    cylinder.rotate(
        BABYLON.Axis.X, 
        angle1,
        BABYLON.Space.LOCAL
    );
    
    // Second rotation
    var H = new BABYLON.Vector3(A.x,B.y,B.z);
    var angle2 = RANDO.Utils.angleFromPoints(A, B, H);
    cylinder.rotate(
        BABYLON.Axis.Z, 
        angle2, 
        BABYLON.Space.LOCAL
    );
    
    return cylinder;
};

NB:  La propriété "height" de l'objet "cylinder" n'est pas une propriété de Babylon.Mesh, je l'ai rajoutée car j'avais besoin de la hauteur initiale du cylindre.

La première rotation est calculée dans le plan Oyz et la deuxième dans le plan ABH (équivalent au plan Oyx local au cylindre). Enfin, grâce à notre cher Thalès, on sait que l'angle2 est égal à l'angle HAB.

Ci-dessous les schémas des rotations effectuées, le cylindre est représenté par le rectangle gris et les sphères sont en violet, les axes sont les axes locaux du cylindre.

 

 

 

Dans un prochain et dernier article, on parlera de l'application des textures et d'UV Mapping.

Formations associées

Formations SIG / Cartographie

Formation Leaflet

À distance (FOAD) Du 1er au 2 juillet 2024

Voir la formation

Formations SIG / Cartographie

Formation QGIS

Nantes Du 2 au 4 avril 2024

Voir la formation

Formations Front end

Formation Angular

Nantes Du 22 au 24 mai 2024

Voir la formation

Actualités en lien

Image
 randonnée-3D-BabylonJS-Part1
14/05/2014

Une randonnée en 3D grâce à BabylonJS ! Partie 3 : Les textures

Cet article est dédié à l'explication de certains points essentiels dans le code de la première démo de Geotrek 3D. La 3ème et dernière partie parle de l'application des textures sur le terrain tuilé.

Voir l'article
Image
 randonnée-3D-BabylonJS-Part1
12/05/2014

Une randonnée en 3D grâce à BabylonJS ! Partie 1 : Le terrain

Cet article est dédié à l'explication de certains points essentiels dans le code de la première démo de Geotrek 3D. La première partie est consacrée à la manière de créer un terrain tuilé en 3D grâce à BabylonJS.

Voir l'article
Image
babylonjs
03/03/2014

Affichage d'un Modèle Numérique de Terrain avec Babylon.js à partir de données PostgreSQL

Récupération et exploitation de données depuis PostGIS dans le but de visualiser un Modèle Numérique de Terrain avec Babylon.js .

Voir l'article

Inscription à la newsletter

Nous vous avons convaincus