IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

WebGL Discussion :

Realisation d'un globe virtuelle avec Three.js


Sujet :

WebGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Octobre 2006
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 123
    Par défaut Realisation d'un globe virtuelle avec Three.js
    Bonjour,

    Je suis sur la créa d'un globe webgl en utilisant Three.js, je rencontre des difficultés pour creer les pays sous forme de Mesh, j'ai du oublier un détail qui fera certainement la différence, j'arrive à créer un simple globe avec une texture maintenant j'aimerai créer des pays pour intéragir...

    Voici un morceau de code (le principal), pour le moment niveau rendu, j'ai des points de couleurs hazardeux qui apparaissent sur ma sphére..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    ,
      latLongToVector3:function(lat,lon,r,h){
        var phi = (lat)*Math.PI/180;
        var theta = (lon-180)*Math.PI/180;
        var x = -(r+h) * Math.cos(phi) * Math.cos(theta);
        var y = (r+h) * Math.sin(phi);
        var z = (r+h) * Math.cos(phi) * Math.sin(theta);   
        return new THREE.Vector3(x,y,z);
      },
      clearScene: function(){
       for(i=0;i<this.group-1;i++)
         this.renderer.deallocateObject(this.group[i]);
      },
      addBoundaries: function(){
        this.landsGeometries = [];
        webgl.prototype.countriesGeo.forEach(function(c){
          var geometry = new THREE.Geometry();
          geometry.name = c.name;
          c.borders.forEach(function(c){
            c.forEach(function(c){
             geometry.vertices.push(self.latLongToVector3(c.lat, c.lng, 600, 2));
           });
          geometry.faces.push(new THREE.Face3(0, 1, 2));
          geometry.mergeVertices();
          geometry.computeBoundingSphere();
          self.landsGeometries.push(geometry);
          self.scene.add(new THREE.Mesh(geometry));
          })
        });
     
      },
      testGlobe: function(){
        var geometry = new THREE.SphereGeometry(600,32,32);
        var material = new THREE.MeshPhongMaterial({
                        wireframe:true,color:0xffffff});
        this.globe = new THREE.Mesh(geometry,material);
     
        this.scene.add(this.globe);
        this.addLights();
      },
      addEarth: function(){
        this.addBoundaries();
        this.scene.add(this.group);
        this.render(function(m,o){
           var timer = Date.now() * 0.0001;
           o.light.position = o.camera.position;
           m.rotation.y += (o.tRotation - m.rotation.y)* 0.05;
           //o.clouds.rotation.z+=0.00015;
          },self.globe);
      }
    Un exemple de l'array Countries:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    {code:"LU", name:"Luxembourg", borders:[[[6.04305983,50.12805176],[6.24272013,49.90224075],[6.18628979,49.46382904],[5.89773989,49.44268036],[5.67404985,49.52947998],[5.78239012,50.09032822],[6.04305983,50.12805176],[6.04305983,50.12805176]]]}
    j'ai pas eu le temps de me familiariser avec l'API native.

    Coté traitement: Recup positions latitude, longtitude, conversion vers un vecteur 3 dimensions, injection du vecteur dans la geometry du pays concerné, création de Mesh avec la geometry correspondante .

  2. #2
    Inactif  

    Homme Profil pro
    Développeur multimédia
    Inscrit en
    Mars 2013
    Messages
    162
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur multimédia

    Informations forums :
    Inscription : Mars 2013
    Messages : 162
    Par défaut
    Le point dur dans ton programme c'est trianguler un polygone concave. Ca n'est pas une opération simple... c'est pas sûr que ta lib le fasse facilement et sans accrocs. Faudrait regarder quel algorithme Three.js utilise pour ça.

  3. #3
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 150
    Billets dans le blog
    150
    Par défaut
    Bonjour,

    Pourquoi vouloir faire les pays sous forme de mesh ? Une texture, un bump mapping ou un displacement mapping ne suffit t-il pas ?
    Si c'est pour une histoire de clic, si vous vous débrouillez à transformer le point cliquer en point sur la sphère, vous avez réussi et vous n'aurez toujours pas besoin de mesh.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  4. #4
    Membre chevronné

    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    311
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 311
    Par défaut
    Salut aimad41 !

    Avant de comprendre la 3D il te faut comprendre comment fonctionne le processus de rastérisation d’une carte graphique par un pipeline programmable (vertex et pixel shader).

    Rien ne t’impose de travailler à partir de coordonnées 3D cartésiennes orthogonales tu peux utiliser directement tes coordonnées sphériques (latitude et longitude) avec ta carte graphique en utilisant un vertex shader dédié.

    J’avais réalisé un POC permettant la rastérisation de carte marine vectoriel avec WebGL ici, la prise en charge du zoom dans mon vertex shader est bogué.
    Le voici quand même :
    Code GLSL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #define RADIUS 111319.49079327357264771338267056
    #define PI 3.1415926535897932384626433832795
    #define RAD2DEG 57.295779513082320876798154814105
    attribute vec2 Vertex;
    uniform float MetersPerPixel;
    uniform vec2 Center;
    uniform vec2 OffCenter;
    uniform vec2 HalfScreenSize;
     
    void main(void) 
    {
    	vec2 ps = vec2((Center.x - Vertex.x) * cos(Center.y/RAD2DEG + PI) * RADIUS / MetersPerPixel,
    				   (Vertex.y - Center.y)* RADIUS / MetersPerPixel);
    	gl_Position.x = (ps.x + OffCenter.x)/ HalfScreenSize.x;
    	gl_Position.y = (ps.y + OffCenter.y)/ HalfScreenSize.y;
    	gl_Position.z = 0.0;
    	gl_Position.w = 1.0; 
    }
    La définition géométrique de mes polygones sont les suivantes tous d’abord un énorme Vertex buffer regroupant tous mes sommets (coordonnées lat et long). Et ensuite une collection polygones comme ceci :
    Code JSON : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    [ {
    		Polygons : [
    			{
    				Stroke : [190, 191, 192, 193, 194, 195, 196, 197],
    				Fill : [190, 197, 196, 196, 195, 194, 193, 192, 191, 191, 190, 196, 196, 194, 193, 193, 191, 196]
    			}
    		]
    	},
    	{	
    		Polygons : [
    			{
    				Stroke : [198, 199, 200, 201],
    				Fill : [198, 201, 200, 200, 199, 198]
    			}
    		]
    	},
    	...
    ]
    Mes polygones contiennent 2 Index Buffer :
    • Stroke : contenant les indices de mes sommets et définissant le contour de mon polygone
    • Fill : contenant la séquence d’indices de mon polygone triangulé.

    Le tous rendu comme ceci :
    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    var poly = Polygons[i];
    if(poly.Fill)
    {
    	if(!poly.FillBuffer)
    	{
    		poly.FillBuffer = gl.createBuffer();
    		gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, poly.FillBuffer);
    		gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(poly.Fill), gl.STATIC_DRAW);  
    	}
    	else
    		gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, poly.FillBuffer);
     
    	gl.drawElements(gl.TRIANGLES, poly.Fill.length, gl.UNSIGNED_SHORT, 0); 
    }
     
    if(poly.Stroke)
    {
    	if(!poly.StrokeBuffer)
    	{
    		poly.StrokeBuffer = gl.createBuffer();
    		gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, poly.StrokeBuffer);
    		gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(poly.Stroke), gl.STATIC_DRAW);  
    	}
    	else
    		gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, poly.StrokeBuffer);
     
    	gl.drawElements(gl.LINE_LOOP, poly.Stroke.length, gl.UNSIGNED_SHORT, 0); 
    }
    Je n’ai pas trouvé de moyen de trianguler dans le pipeline de rendu avec WebGL, si une solution existe je suis preneur. J’ai donc triangulé mes polygones en utilisant un outil en C# :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    public static class Triangulate
    {
    	static public List<uint> ProcessIndex(List<Vector> contour)
    	{
    		int n = contour.Count;
    		if (n < 3)
    			throw new Exception("[Triangulate::ProcessIndex] ERROR - vertex count <3 !");
    		else if (n == 3) 
    			return new List<uint>(new uint[] { 0, 1, 2});
     
    		int[] V = new int[n];
     
    		/* we want a counter-clockwise polygon in V */
     
    		if (0.0 < Area(contour))
    			for (int v = 0; v < n; v++) V[v] = v;
    		else
    			for (int v = 0; v < n; v++) V[v] = (n - 1) - v;
     
    		int nv = n;
     
    		/*  remove nv-2 Vertices, creating 1 triangle every time */
    		int count = 2 * nv;   /* error detection */
    		List<uint> result = new List<uint>(count);
    		for (int m = 0, v = nv - 1; nv > 2; )
    		{
    			/* if we loop, it is probably a non-simple polygon */
    			if (0 >= (count--))
    			{
    				throw new Exception("[Triangulate::ProcessIndex] ERROR - probable bad polygon!");
     
    			}
     
    			/* three consecutive vertices in current polygon, <u,v,w> */
    			int u = v; if (nv <= u) u = 0;     /* previous */
    			v = u + 1; if (nv <= v) v = 0;     /* new v    */
    			int w = v + 1; if (nv <= w) w = 0;     /* next     */
     
    			if (Snip(contour, u, v, w, nv, V))
    			{
    				int a, b, c, s, t;
     
    				/* true names of the vertices */
    				a = V[u]; b = V[v]; c = V[w];
     
    				/* output Triangle */
    				result.Add((uint)a);
    				result.Add((uint)b);
    				result.Add((uint)c);
     
    				m++;
     
    				/* remove v from remaining polygon */
    				for (s = v, t = v + 1; t < nv; s++, t++) V[s] = V[t]; nv--;
     
    				/* resest error detection counter */
    				count = 2 * nv;
    			}
    		}
    		return result;
     
    	}
     
    	// compute area of a contour/polygon
    	static double Area(List<Vector> contour)
    	{
    		int n = contour.Count;
     
    		double A = 0.0f;
     
    		for (int p = n - 1, q = 0; q < n; p = q++)
    		{
    			A += contour[p].x * contour[q].y - contour[q].x * contour[p].y;
    		}
    		return A * 0.5f;
    	}
     
    	/*
    	 InsideTriangle decides if a point P is Inside of the triangle
    	 defined by A, B, C.
    	 */
    	static bool InsideTriangle( double Ax, double Ay,
    								double Bx, double By,
    								double Cx, double Cy,
    								double Px, double Py)
     
    	{
    		double ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
    		double cCROSSap, bCROSScp, aCROSSbp;
     
    		ax = Cx - Bx;  ay = Cy - By;
    		bx = Ax - Cx;  by = Ay - Cy;
    		cx = Bx - Ax;  cy = By - Ay;
    		apx= Px - Ax;  apy= Py - Ay;
    		bpx= Px - Bx;  bpy= Py - By;
    		cpx= Px - Cx;  cpy= Py - Cy;
     
    		aCROSSbp = ax*bpy - ay*bpx;
    		cCROSSap = cx*apy - cy*apx;
    		bCROSScp = bx*cpy - by*cpx;
     
    		return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f));
    	}
     
    	static bool Snip(List<Vector> contour,int u,int v,int w,int n,int[] V)
    	{
    		int p;
    		double Ax, Ay, Bx, By, Cx, Cy, Px, Py;
     
    		Ax = contour[V[u]].x;
    		Ay = contour[V[u]].y;
     
    		Bx = contour[V[v]].x;
    		By = contour[V[v]].y;
     
    		Cx = contour[V[w]].x;
    		Cy = contour[V[w]].y;
     
    		if (Constants.Epsilon > (((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax)))) return false;
     
    		for (p = 0; p < n; p++)
    		{
    			if ((p == u) || (p == v) || (p == w)) continue;
    			Px = contour[V[p]].x;
    			Py = contour[V[p]].y;
    			if (InsideTriangle(Ax, Ay, Bx, By, Cx, Cy, Px, Py)) return false;
    		}
     
    		return true;
    	}
     
    }

  5. #5
    Membre confirmé
    Inscrit en
    Octobre 2006
    Messages
    123
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 123
    Par défaut
    Je vais arrêter de poster sur Stackoverflow, vous êtes bien plus réactif ici

    Un plaisir de vous lire Messieurs !

    Alors pour vous répondre, je me forme encore aujourd'hui au techniques de rendu et process GPU, rasterization ect... je veux tout comprendre donc c'est un peu long

    Une mesh pour pouvoir bosser avec plus tard, pouvoir manipuler mon object ect... incluant forcement un clic sur un pays et changement de couleur au clic ect....

    Je vais me rapprocher de la dernière réponse, qui m'as l'air vraiment intéressante, je peaufine ça quand je rentre du boulot

    Merci pour l'intérêt porté aux problèmes !

    @LittleWhite Ta réponse est intéressante, question perf coté fonctionnel pas sûre, mais je vais réfléchir à cette idée, ce qui m'importe c'est vraiment d'avoir un rendu avec le plus de détails possible niveau territoire (frontières, au survol highlight le pays ect..)

    @p3ga5e Génial ! Vraiment top ! Je check ça ce soir, jte donne mes retours assez fast, mais je vais prendre le temps de bien comprendre les vertex shaders et fragment shader ! Super le rendu en tout cas !

  6. #6
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 150
    Billets dans le blog
    150
    Par défaut
    Le niveau de détails dépendra de la texture ou de l’application des textures
    Pour le moment, je ne vois pas pourquoi faire des mesh et si jamais vous maintenanez cette idée, quelle sera la taille mémoire des mesh de tous les pays à une certaine échelle ?
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Creation imprimante virtuelle avec VC++6
    Par nemo69500 dans le forum Visual C++
    Réponses: 3
    Dernier message: 21/04/2008, 10h15
  2. serveur virtuel avec oracle http server
    Par krikete dans le forum Oracle
    Réponses: 8
    Dernier message: 03/03/2007, 19h23
  3. [SOLARIS] Comment faire un lien virtuel avec unix
    Par diamonds dans le forum Solaris
    Réponses: 3
    Dernier message: 16/02/2007, 09h37
  4. Visite virtuelle avec des fichiers IVR
    Par a_me dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 04/01/2007, 16h44
  5. Réponses: 4
    Dernier message: 20/11/2005, 05h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo