Mi ha sempre affascinato l'idea di creare in modo abbastanza semplice oggetti 3D con WPF. La cosa che mi è sempre servita è un controllo per la visualizzazione di grafici a barre o simili.
Vediamo come crearne uno in WPF.
Per prima cosa ci serve conoscere alcune nozioni base della visualizzazione di oggetti 3D in WPF.
1) Tutto quello che deve essere visualizzato con una rappresentazione 3D dei dati deve essere inserito all'interno di un Viewport3D. Immaginatelo come un contenitore di oggetti che vivono in un mondo 3D.
2) Occorre definire alcune luci per "illuminare" i nostri oggetti
3) Occorre definire una telecamera per "riprendere" i nostri oggetti e visualizzarli sul nostro monitor. Saremo così come di registi sulla scena di un film.
Non entrerò nel dettaglio di come creare una scena 3D perchè Andrea nei suoi prossimi post spiegherà bene come è strutturato un ambiente 3D in WPF.
Nel nostro caso gli esempi dovrebbero bastare. ( Se non bastassero chiedete pure )
Definiamo tutto questo
[code language="xml"]
<Viewport3D Name="mainViewport" ClipToBounds="True">
<Viewport3D.Camera>
<PerspectiveCamera
FarPlaneDistance="150"
LookDirection="-10,-6,-10"
UpDirection="0,3,0"
NearPlaneDistance="1"
Position="20,20,20"
FieldOfView="70" />
</Viewport3D.Camera>
....
</Viewport3D>
[/code]
Con il tag <Viewport3D.Camera> definiamo come deve essere posizionata la nostra camera, Con l'attributo position la posizioniamo nel punto x=20, y=20, z=20 e con l'attributo LookDirection gli diciamo che deve essere puntata verso il punto x=-10, y=-6, z=-10. In pratica quarda verso l'origine ma un pochino più in alto dell'origine.
Definiamo una luce e quindi modifichiamo il nostro codice in questo modo:
[code language="xml"]
<Viewport3D Name="mainViewport" ClipToBounds="True">
<Viewport3D.Camera>
<PerspectiveCamera
FarPlaneDistance="150"
LookDirection="-10,-6,-10"
UpDirection="0,3,0"
NearPlaneDistance="1"
Position="20,20,20"
FieldOfView="70" />
</Viewport3D.Camera>
....
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight
Color="White"
Direction="-5,-5,-10" />
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
[/code]
Il ModelVisual3D è un oggetto renderizzabile all'interno del mondo 3D, contiene gli oggetti più semplici e definisce come questi debbano comportarsi nei confronti del mondo 3D. Il modelVisual3D permette di applicare agli oggetti 3D alcune traformazioni come traslazioni e rotazioni rispetto all'origine. E' un contenitore di primitive.
Inseriamo nel Content di questo oggetto la nostra luce.
Iniziamo ad inserire nel nostro mondo 3D alcune primitive. Tutte le primitive vanno messe all'interno della proprietà ModelVisual3D.Children. Quindi il nostro codice cambierà nella forma seguente:
[code language="xml"]
<Viewport3D Name="mainViewport" ClipToBounds="True">
<Viewport3D.Camera>
<PerspectiveCamera
FarPlaneDistance="150"
LookDirection="-10,-6,-10"
UpDirection="0,3,0"
NearPlaneDistance="1"
Position="20,20,20"
FieldOfView="70" />
</Viewport3D.Camera>
<ModelVisual3D>
<ModelVisual3D.Children>
</ModelVisual3D.Children>
<ModelVisual3D.Content>
<DirectionalLight
Color="White"
Direction="-5,-5,-10" />
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
[/code]
Un'ultima cosa che dobbiamo aggiugere è la posizione del nostro ModelVisual3D rispetto al ViewPort3D.
Quindi inseriamo alcune trasformate che posizioneranno il nostro oggetto in un punto differente dal punto x=0, y=0, z=0.
E gia che ci siamo prepariamo il nostro ModelVisual3D ad essere sottoposto ad altre trasformazioni.
[code language="xml"]
<Viewport3D Name="mainViewport" ClipToBounds="True">
<Viewport3D.Camera>
<PerspectiveCamera
FarPlaneDistance="150"
LookDirection="-10,-6,-10"
UpDirection="0,3,0"
NearPlaneDistance="1"
Position="20,20,20"
FieldOfView="70" />
</Viewport3D.Camera>
<ModelVisual3D>
<ModelVisual3D.Transform>
<Transform3DGroup>
<Transform3DGroup.Children>
<Transform3DCollection >
<ScaleTransform3D ScaleX="1" ScaleY="1" ScaleZ="1" />
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D Axis="0 1 0" Angle="0" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
<TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0" />
</Transform3DCollection>
</Transform3DGroup.Children>
</Transform3DGroup>
</ModelVisual3D.Transform>
<ModelVisual3D.Children>
</ModelVisual3D.Children>
<ModelVisual3D.Content>
<DirectionalLight
Color="White"
Direction="-5,-5,-10" />
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>
[/code]
Il nostro ModelVisual3D è pronto per contenere oggetti di base epuò anche essere posizionato, traslato e ridimensionato a nostro piacimento attraverso le trasformate 3D che abbiamo inserito nell'attributo ModelVisual3D.Transform
Il nostro mondo virtuale 3D è pronto. il Viewport può essere inserito all'interno di qualunque controllo WPF 2D.
Chiaramente se ce lo mettiamo adesso non vedremo niente perchè non c'è nulla da renderizzare.