ROBOTICA

video
immagini
papers
progettati
costruiti
toolbox
vrml
simulatori

links

 

Papers
meccanica
sistemi
documents

Capitolo 30° Il nodo ElevationGrid Capitolo 32°

In questa lezione esaminiamo uno degli ultimi nodi che riguardano aspetti geometrici.

Il nodo ElevationGrid consente di descrivere terreni particolarmente realistici imponendo diverse altezze in diversi punti.

Fino a questo punto nel tutorial, quando ci siamo trovati di fronte alla necessita' di definire il terreno su cui si trova l'osservatore abbiamo sempre fatto ricorso ad un semplice piano. Con il nodo ElevationGrid possiamo definire terreni complessi come si vuole, da aguzze montagne a dolci colline.

Ovviamente se il tipo di navigazione e' WALK l'osservatore verra' mantenuto sul terreno e ne seguira' quindi i diversi andamenti mano a mano che si sposta.

La sintassi del nodo ElevationGrid e' abbastanza semplice. Qui di seguito esamino quanto ci serve; per informazioni piu' dettagliate vi rimando direttamente alle specifiche.

ElevationGrid {  field  SFFloat creaseAngle 0  field
  SFInt32 xDimension 0  field SFFloat xSpacing  0.0  field
  SFInt32 zDimension  0 field  SFFloat zSpacing  0.0  field
  MFFloat height  []  eventIn  MFFloat  set_height }

Il nodo ElevationGrid viene usato, come per Cone, Box, Sphere o altri nodigia' visti, dopo il campo geometry nel nodo Shape.

Vediamo i singoli campi. Il primo campo indica l'angolo al di sotto del quale il browser provvede ad effettuare uno smooth shading. Di solitoimposto un valore piuttosto alto (espresso in radianti) in modo da avere delletransizioni dolci tra un poligono e l'altro; questo consente di raggiungeregradi di realismo piu' elevati.

Per definire un terreno con altezze diverse si deve specificare una grigliadi valori in modo che il browser provveda poi ad interpolare le altezze sulle varie posizioni. Le dimensioni della griglia di valori vengonospecificate dai campi xDimension e zDimension.

Lo spazio che intercorre tra i punti della griglia viene settato tramite i parametri xSpacing e zSpacing. Ponendo i punti molto distanziati si avrannotendenzialmente delle transizioni piu' lente che non ponendo dei valori ravvicinati (il tutto dipendo poi anche dai valori delle altezze fornite ovviamente).

Il campo height e' una matrice bidimensionale (MFFloat) di valori. In praticasi specificano tutte le altezze dei vari punti della griglia.

Un generico punto (i,j) nella griglia avra' dunque le seguenti coordinate:

P[i,j].x = xSpacing * iP[i,j].y =
height[i + j * zDimension]P[i,j].z =
zSpacing * j0 < j < xDimension   e  0 < j < zDimension

Infine, l'ultimo campo, set_height serve per modificare i valori delle altezzea run-time in modo da poter avere elevationgrids animate.

Prima di passare ad un piccolo esempio, faccio notare come sia arduo pensare di definire delle griglie a mano editandole direttamente... Per ottenere discreti effetti si dovrebbe ricorrere ad array di dimensioni non piccole.E quando si ha a che fare con circa 400 altezze (una banale griglia di 20 X 20) procedere a mano con l'inserimento diventa improponibile. Sarebbe dunque meglio ricorrere a tools esterni. Per quanto mi riguarda ho utilizzato direttamente un piccolo generatore automatico che mi ero scritto in C per la realizzazione di un Voxel.

Fornisco qui di seguito un esempio di utilizzo di questo nodo. In questo caso data la semplicita' della griglia ho creato a mano la mappa e poi l'ho scalata in modo da avere l'effetto che desideravo.Si puo' notare come si ottenga un effetto piu' che dignitoso utilizzando pochi nodi e con una dimensione abbastanza limitata... Per rendere piu' realistico il mondo (che dovrebbe rappresentare un'isola rocciosa in mezzo al mare... essendo un'isola era ovvio ;) ) ho mappato una texture sullaelevation grid.

#VRML V2.0 utf8
# isola rocciosa
NavigationInfo {
 headlight FALSE
}
DirectionalLight {
 direction -.2 -.4 -.5 
}
Viewpoint {
 position 24 2 200
}
Background {
        skyAngle [1.3 1.57 3.14]
        skyColor [.6 .6 1, .5 .5 1, .8 0 0, .5 .5 1]
        groundAngle [1 1.57]
        groundColor [.3 .3 1, .4 .4 1, .5 .5 1]
}
Collision {
 children [
  Transform {
   scale 1.5 2.8 1.5
 children [
  Shape {
  appearance Appearance {
  material Material { diffuseColor .8 .5 0 }
  texture ImageTexture { url "../textures/marmi/stones.jpg" }
     }
     geometry ElevationGrid {
      creaseAngle 6
      xDimension 16
      zDimension 20
      xSpacing 3
      zSpacing 3
height [
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, 1, 5, 4, 3, 3, 4, 2, 5, 6, 4, 3, 1, 0,
 0, 0, 1, 1, 6, 7, 7, 6, 8, 5, 6, 4, 3, 3, 1, 0,
 0, 0, 0, 1, 5, 8, 9, 10, 8, 5, 7, 5, 4, 2, 1, 0,
 0, 0, 0, 0, 4, 7, 10, 11, 9, 9, 7, 6, 3, 2, 1, 0,
 0, 0, 1, 0, 5, 10, 12, 13, 10, 10, 8, 9, 4, 3, 1, 0,
 0, 1, 2, 2, 7, 10, 15, 16, 15, 11, 9, 8, 5, 2, 1, 0,
 0, .8, 2, 2, 6, 10, 14, 15, 15, 12, 8, 8, 5, 1, 0, 0,
 0, .5, 1, 1, 6, 8, 13, 13, 12, 10, 6, 6, 4, 1, 0, 0,
 0, 0, 0, 1, 5, 5, 11, 10, 12, 6, 4, 4, 2, 1, 0, 0,
 0, 0, 0, 0, 3, 4, 7, 9, 10, 5, 3, 2, 1, 0, 0, 0,
 0, 0, 0, 1, 0, 3, 5, 6, 8, 5, 2, 1, 0, 0, 0, 0,
 0, .3, 1, 0, 0, 1, 3, 4, 4, 3, 1, 0, 0, 0, 0, 0, 
 -.1, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, .2, .5, .2, 0, .1, .2, .3, .2, .2, 0, 0, 0, 0,
 -.1, 0, -.5, 0, .3, .1, .2, .3, .1, .2, .1, .1, 0, .1, 0, 0,
 -.12, -.15, -.07, 0, .1, 0, -.2, -.2, 0, .1, 0, 0, -.2, 0,
 -.2, -.2,
 -.2, -.6, -.2, -.2, -.2, -.2, -.2, -.2, -.2, -.2, -.2,
 -.2, -.2, -.2, -.2, -.2, 
 ]
     }
    }
   ]
  }
 ]
}
# definisco qui il mare. Un semplice piano azzurro.
Collision {
 children [
  Transform {
   translation 0 -.2 0 
   children [
    Shape {
     appearance Appearance {
      material Material { diffuseColor .5 .5 1 }
     }
     geometry IndexedFaceSet {
      coord Coordinate {
       point [-2000 0 -2000, -2000 0 2000, 2000 0 2000, 2000 0 -2000]
      }
      coordIndex [0, 1, 2, 3, -1]
     }
    }
   ]
  }
 ]
}

Isola rocciosa