Panoramica delle trasformazioni 3D
Questo argomento descrive come applicare trasformazioni ai modelli 3D nel sistema grafico Windows Presentation Foundation (WPF). Le trasformazioni consentono allo sviluppatore di riposizionare, ridimensionare e riorientare i modelli senza modificare i valori di base che li definiscono.
Spazio delle coordinate 3D
Il contenuto grafico 3D in Windows Presentation Foundation (WPF) viene incapsulato in un elemento, Viewport3D, che può partecipare alla struttura di elementi bidimensionali. Il sistema grafico considera Viewport3D come elemento visivo bidimensionale come molti altri in Windows Presentation Foundation (WPF). Viewport3D funziona come finestra, ovvero un riquadro di visualizzazione, in una scena tridimensionale. In modo più accurato, si tratta di una superficie su cui viene proiettata una scena 3D. Sebbene sia possibile usare Viewport3D con altri oggetti di disegno 2D nello stesso grafo della scena, non è possibile interpenetrare oggetti 2D e 3D all'interno di un Viewport3D. Nella discussione seguente lo spazio delle coordinate descritto è contenuto nell'elemento Viewport3D.
Il sistema di coordinate Windows Presentation Foundation (WPF) per la grafica 2D individua l'origine in alto a sinistra della superficie di rendering (in genere lo schermo). Nel sistema 2D, i valori positivi dell'asse x procedono verso destra e i valori positivi dell'asse y procedono verso il basso. Nel sistema di coordinate 3D, l'origine si trova al centro dello schermo, con valori positivi dell'asse x che procedono verso destra, quelli dell'asse y verso l'alto, e quelli dell'asse z che si avvicinano dall'origine verso il visualizzatore.
CoordSystem-1
Confronto dei sistemi di coordinate
Lo spazio definito da questi assi è la cornice di riferimento fissa per gli oggetti 3D in Windows Presentation Foundation (WPF). Mentre si costruiscono modelli in questo spazio e si creano luci e fotocamere per visualizzarli, è utile distinguere questo sistema di riferimento fisso, o "spazio mondo", dal sistema di riferimento locale creato per ogni modello quando si applicano trasformazioni ad esso. Ricorda anche che gli oggetti nello spazio globale potrebbero apparire completamente diversi, o non essere affatto visibili, a seconda delle impostazioni della luce e della fotocamera, ma la posizione della fotocamera non modifica la posizione degli oggetti nello spazio globale.
Trasformazione di modelli
Quando si creano modelli, hanno una posizione specifica nella scena. Per spostare tali modelli nella scena, ruotarli o modificarne le dimensioni, non è pratico modificare i vertici che definiscono i modelli stessi. Al contrario, proprio come in 2D, si applicano trasformazioni ai modelli.
Ogni oggetto modello ha una proprietà Transform con cui è possibile spostare, riorientare o ridimensionare il modello. Quando si applica una trasformazione, si sfalsano in modo efficace tutti i punti del modello in base a qualsiasi vettore o valore specificato dalla trasformazione. In altre parole, è stato trasformato lo spazio delle coordinate in cui è definito il modello ("spazio del modello"), ma non sono stati modificati i valori che costituiscono la geometria del modello nel sistema di coordinate dell'intera scena ("spazio globale").
Trasformazioni di traduzione
Le trasformazioni 3D ereditano dalla classe base astratta Transform3D; tra cui le classi di trasformazione affine TranslateTransform3D, ScaleTransform3De RotateTransform3D. Il sistema 3D di Windows Presentation Foundation (WPF) fornisce anche una classe MatrixTransform3D che consente di specificare le stesse trasformazioni in operazioni di matrice più concise.
TranslateTransform3D sposta tutti i punti nel Model3D nella direzione del vettore di offset specificato con le proprietà OffsetX, OffsetYe OffsetZ. Ad esempio, dato un vertice di un cubo in (2,2,2), un vettore di offset di (0,1,6,1) sposta tale vertice (2,2,2) in (2,3,6,3). Il vertice del cubo è ancora (2,2,2) nello spazio del modello, ma ora che la relazione dello spazio del modello con lo spazio globale è cambiata, (2,2,2) nello spazio del modello è diventato (2,3.6,3) nello spazio globale.
Traduzione con offset
Negli esempi di codice seguenti viene illustrato come applicare una traduzione.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<DockPanel>
<Viewbox>
<Canvas Width="600" Height="201">
<!-- The Viewport3D provides a rendering surface for 3-D visual content. -->
<Viewport3D Name="MyAnimatedObject"
ClipToBounds="True" Width="600" Height="150"
Canvas.Left="0" Canvas.Top="10">
<!-- Defines the camera used to view the 3D object. -->
<Viewport3D.Camera>
<PerspectiveCamera x:Name="myPerspectiveCamera" Position="0,0,2" LookDirection="0,0,-1"
FieldOfView="60" />
</Viewport3D.Camera>
<!-- The ModelVisual3D children contain the 3D models -->
<Viewport3D.Children>
<!-- This ModelVisual3D defines the light cast in the scene. Without light, the
3D object cannot be seen. -->
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color="#FFFFFF" Direction="-0.612372,-0.5,-0.612372" />
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<GeometryModel3D>
<!-- The geometry specifes the shape of the 3D plane. In this case, a flat sheet is created. -->
<GeometryModel3D.Geometry>
<MeshGeometry3D
TriangleIndices="0,1,2 3,4,5 "
Normals="0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 "
TextureCoordinates="0,0 1,0 1,1 1,1 0,1 0,0 "
Positions="-0.5,-0.5,0.5 0.5,-0.5,0.5 0.5,0.5,0.5 0.5,0.5,0.5 -0.5,0.5,0.5 -0.5,-0.5,0.5 " />
</GeometryModel3D.Geometry>
<!-- The material specifies the material applied to the plane. In this case it is a linear gradient.-->
<GeometryModel3D.Material>
<MaterialGroup>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<SolidColorBrush Color="Cyan" Opacity="0.3"/>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</MaterialGroup>
</GeometryModel3D.Material>
<!-- The Transform specifies how to transform the 3D object. The OffsetX property is animated
in the Storyboard below. -->
<GeometryModel3D.Transform>
<TranslateTransform3D x:Name="myTranslateTransform3D" OffsetX="0" OffsetY="0" OffsetZ="0" />
</GeometryModel3D.Transform>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D.Children>
<!-- Trigger the TranslateTransform3D animation when the 3D object loads. -->
<Viewport3D.Triggers>
<EventTrigger RoutedEvent="Viewport3D.Loaded">
<BeginStoryboard>
<Storyboard>
<!-- This animation animates the OffsetX property of the TranslateTransform3D. -->
<DoubleAnimation
Storyboard.TargetName="myTranslateTransform3D"
Storyboard.TargetProperty="OffsetX"
To="-0.8"
AutoReverse="True" RepeatBehavior="Forever" />
<!-- If you want to animate OffsetY and/or OffsetZ, create similar DoubleAnimations
respectively. -->
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Viewport3D.Triggers>
</Viewport3D>
</Canvas>
</Viewbox>
</DockPanel>
</Page>
Trasformazioni di scala
ScaleTransform3D modifica la scala del modello in base a un vettore di scala specificato con riferimento a un punto centrale. Specificare una scala uniforme, che ridimensiona il modello in base allo stesso valore negli assi X, Y e Z, per modificare le dimensioni del modello in modo proporzionale. Ad esempio, impostando le proprietà della trasformazione ScaleX, ScaleYe ScaleZ su 0,5, si dimezzano le dimensioni del modello; impostando le stesse proprietà su 2, si raddoppia la scala in tutti e tre gli assi.
Esempio di ScaleVector
Specificando una trasformazione di scalabilità non uniforme, ovvero una trasformazione della scala i cui valori X, Y e Z non sono tutti uguali, è possibile che un modello venga esteso o contratto in una o due dimensioni senza influire sugli altri. Se ad esempio si imposta ScaleX su 1, ScaleY su 2 e ScaleZ su 1, il modello trasformato viene raddoppiato in altezza, ma rimane invariato lungo gli assi X e Z.
Per impostazione predefinita, ScaleTransform3D determina l'espansione o il contratto dei vertici sull'origine (0,0,0). Se il modello che si desidera trasformare non viene estratto dall'origine, tuttavia, il ridimensionamento del modello dall'origine non ridimensiona il modello "sul posto". Al contrario, quando i vertici del modello vengono moltiplicati per il vettore di scala, l'operazione di scala avrà l'effetto di tradurre il modello e ridimensionarlo.
Esempio del centro di scalabilità
Per ridimensionare un modello "sul posto", specificare il centro del modello impostando le proprietà CenterX, CenterYe CenterZ di ScaleTransform3D. In questo modo il sistema grafico ridimensiona lo spazio del modello e lo trasla per centrarlo sul Point3Dspecificato. Viceversa, se il modello è stato compilato sull'origine e si specifica un punto centrale diverso, ci si aspetta di vedere il modello spostato lontano dall'origine.
Trasformazioni di rotazione
È possibile ruotare un modello in 3D in diversi modi. Una trasformazione di rotazione tipica specifica un asse e un angolo di rotazione attorno a tale asse. La classe RotateTransform3D consente di definire un Rotation3D con la relativa proprietà Rotation. Si specificano quindi le proprietà Axis e Angle di Rotation3D, in questo caso un AxisAngleRotation3D, per definire la trasformazione. Negli esempi seguenti un modello viene ruotato di 60 gradi attorno all'asse Y.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" >
<DockPanel>
<Viewbox>
<Canvas Width="321" Height="201">
<!-- The Viewport3D provides a rendering surface for 3-D visual content. -->
<Viewport3D Name="MyAnimatedObject"
ClipToBounds="True" Width="150" Height="150"
Canvas.Left="0" Canvas.Top="10">
<!-- Defines the camera used to view the 3D object. -->
<Viewport3D.Camera>
<PerspectiveCamera x:Name="myPerspectiveCamera" Position="0,0,2" LookDirection="0,0,-1"
FieldOfView="60" />
</Viewport3D.Camera>
<!-- The ModelVisual3D children contain the 3D models -->
<Viewport3D.Children>
<!-- Two ModelVisual3D define the lights cast in the scene. Without light, the
3D object cannot be seen. Also, the direction of the lights affect shadowing. -->
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color="#FFFFFF" Direction="-0.612372,-0.5,-0.612372" />
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight Color="#FFFFFF" Direction="0.612372,-0.5,-0.612372" />
</ModelVisual3D.Content>
</ModelVisual3D>
<ModelVisual3D>
<ModelVisual3D.Content>
<GeometryModel3D>
<!-- The geometry specifes the shape of the 3D plane. In this case, a flat sheet is created. -->
<GeometryModel3D.Geometry>
<MeshGeometry3D
TriangleIndices="0,1,2 3,4,5 "
Normals="0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 "
TextureCoordinates="0,0 1,0 1,1 1,1 0,1 0,0 "
Positions="-0.5,-0.5,0.5 0.5,-0.5,0.5 0.5,0.5,0.5 0.5,0.5,0.5 -0.5,0.5,0.5 -0.5,-0.5,0.5 " />
</GeometryModel3D.Geometry>
<!-- The material specifies the material applied to the plane. In this case it is a linear gradient.-->
<GeometryModel3D.Material>
<MaterialGroup>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
<LinearGradientBrush.GradientStops>
<GradientStop Color="Yellow" Offset="0" />
<GradientStop Color="Red" Offset="0.25" />
<GradientStop Color="Blue" Offset="0.75" />
<GradientStop Color="LimeGreen" Offset="1" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</MaterialGroup>
</GeometryModel3D.Material>
<!-- The Transform specifies how to transform the 3D object. The properties of the
Rotation object are animated causing the 3D object to rotate and "wobble" (see Storyboard below).-->
<GeometryModel3D.Transform>
<RotateTransform3D>
<RotateTransform3D.Rotation>
<AxisAngleRotation3D x:Name="myAngleRotation" Axis="0,3,0" Angle="40" />
</RotateTransform3D.Rotation>
</RotateTransform3D>
</GeometryModel3D.Transform>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D.Children>
<!-- Trigger the rotation animation when the 3D object loads. -->
<Viewport3D.Triggers>
<EventTrigger RoutedEvent="Viewport3D.Loaded">
<BeginStoryboard>
<Storyboard>
<!-- This animation animates the Angle property of the AxisAngleRotation3D
making the 3D object rotate from -60 degrees to 60 degrees. -->
<DoubleAnimation
Storyboard.TargetName="myAngleRotation"
Storyboard.TargetProperty="Angle"
From="-60" To="60" Duration="0:0:4" AutoReverse="True" RepeatBehavior="Forever"/>
<!-- This animation animates the Axis property of the AxisAngleRotation3D
making the 3D wobble as it rotates. -->
<Vector3DAnimation
Storyboard.TargetName="myAngleRotation"
Storyboard.TargetProperty="Axis"
From="0,3,0" To="1,0,1" Duration="0:0:4" AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Viewport3D.Triggers>
</Viewport3D>
</Canvas>
</Viewbox>
</DockPanel>
</Page>
Nota: Windows Presentation Foundation (WPF) 3D è un sistema destrorso, il che significa che un valore di angolo positivo per una rotazione comporta una rotazione in senso antiorario sull'asse.
Le rotazioni dell'angolo dell'asse presuppongono la rotazione sull'origine se non viene specificato un valore per le proprietà CenterX, CenterYe CenterZ in RotateTransform3D. Come per il ridimensionamento, è utile ricordare che la rotazione trasforma l'intero spazio delle coordinate del modello. Se il modello non è stato creato intorno all'origine o è stato tradotto in precedenza, la rotazione potrebbe avvenire intorno all'origine anziché ruotare sul proprio asse.
Rotazione con nuovo centro specificato
Per ruotare il modello "sul posto", specificare il centro effettivo del modello come centro di rotazione. Poiché la geometria è in genere modellata sull'origine, è possibile ottenere più spesso il risultato previsto di un set di trasformazioni ridimensionando prima il modello (ridimensionandolo), quindi impostandone l'orientamento (ruotandolo) e infine spostandolo nella posizione desiderata (traducendola).
Esempio di rotazione
Le rotazioni dell'angolo dell'asse funzionano bene per le trasformazioni statiche e alcune animazioni. È tuttavia consigliabile ruotare un modello di cubo di 60 gradi attorno all'asse X, quindi 45 gradi intorno all'asse Z. È possibile descrivere questa trasformazione come due trasformazioni affine discrete o come matrice. Tuttavia, potrebbe essere difficile animare senza problemi una rotazione definita in questo modo. Anche se le posizioni iniziali e finali del modello calcolate da entrambi gli approcci sono le stesse, le posizioni intermedie prese dal modello sono incerte dal punto di vista computazionale. I quaternioni rappresentano un modo alternativo per calcolare l'interpolazione tra l'inizio e la fine di una rotazione.
Un quaternione rappresenta un asse nello spazio 3D e una rotazione attorno a tale asse. Ad esempio, un quaternione potrebbe rappresentare un asse (1,1,2) e una rotazione di 50 gradi. La potenza dei quaternioni nella definizione delle rotazioni deriva dalle due operazioni che è possibile eseguire su di esse: composizione e interpolazione. La composizione di due quaternioni applicati a una geometria implica "ruotare la geometria intorno all'asse2 con rotazione2, quindi ruotarla attorno all'asse1 con rotazione1". Mediante la composizione, è possibile combinare le due rotazioni sulla geometria per ottenere un singolo quaternione che rappresenta il risultato. Poiché l'interpolazione di quaternioni può calcolare un percorso fluido e ragionevole da un asse e un orientamento all'altro, è possibile interpolare dall'originale al quaternione composto per ottenere una transizione graduale tra i due, consentendo di animare la trasformazione. Per i modelli che si desidera animare, è possibile specificare la destinazione Quaternion per la rotazione usando un QuaternionRotation3D per la proprietà Rotation.
Uso delle raccolte di trasformazioni
Quando si compila una scena, è comune applicare più trasformazioni a un modello. Aggiungere trasformazioni alla raccolta Children della classe Transform3DGroup per raggruppare convenientemente le trasformazioni da applicare a vari modelli nella scena. Spesso è utile riutilizzare una trasformazione in diversi gruppi, in gran parte del modo in cui è possibile riutilizzare un modello applicando un set diverso di trasformazioni a ogni istanza. Si noti che l'ordine in cui le trasformazioni vengono aggiunte alla raccolta è significativa: le trasformazioni nella raccolta vengono applicate da prima all'ultima.
Animazione delle trasformazioni
L'implementazione 3D di Windows Presentation Foundation (WPF) partecipa allo stesso sistema di temporizzazione e animazione della grafica 2D. In altre parole, per animare una scena 3D, animare le proprietà dei relativi modelli. È possibile animare direttamente le proprietà delle primitive, ma in genere è più facile animare le trasformazioni che modificano la posizione o l'aspetto dei modelli. Poiché le trasformazioni possono essere applicate agli oggetti Model3DGroup e ai singoli modelli, è possibile applicare un set di animazioni agli elementi figlio di un Model3Dgroup e un altro set di animazioni a un gruppo di oggetti. Per informazioni di base sul sistema di temporizzazione e animazione di Windows Presentation Foundation (WPF), vedere Panoramica delle animazioni e Panoramica degli storyboard.
Per animare un oggetto in Windows Presentation Foundation (WPF), creare una sequenza temporale, definire un'animazione (che è effettivamente una modifica di un valore della proprietà nel tempo) e specificare la proprietà a cui applicare l'animazione. Questa proprietà deve essere una proprietà di un FrameworkElement. Poiché tutti gli oggetti in una scena 3D sono elementi figlio di Viewport3D, le proprietà a cui si applica qualsiasi animazione da applicare alla scena sono proprietà associate a quelle di Viewport3D. È importante determinare attentamente il percorso della proprietà per l'animazione, perché la sintassi può essere verbosa.
Si supponga di voler ruotare un oggetto sul posto, ma anche di applicare un movimento oscillante per esporre di più l'oggetto alla vista. È possibile scegliere di applicare un RotateTransform3D al modello e animare l'asse di rotazione del modello, cambiandolo da un vettore a un altro. L'esempio di codice seguente illustra l'applicazione di un Vector3DAnimation alla proprietà Axis della proprietà Rotation3D della trasformazione, presupponendo che RotateTransform3D sia una delle diverse trasformazioni applicate al modello con un TransformGroup.
//Define a rotation
RotateTransform3D myRotateTransform = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 1));
'Define a rotation
Dim myRotateTransform As New RotateTransform3D(New AxisAngleRotation3D(New Vector3D(0, 1, 0), 1))
Vector3DAnimation myVectorAnimation = new Vector3DAnimation(new Vector3D(-1, -1, -1), new Duration(TimeSpan.FromMilliseconds(5000)));
myVectorAnimation.RepeatBehavior = RepeatBehavior.Forever;
Dim myVectorAnimation As New Vector3DAnimation(New Vector3D(-1, -1, -1), New Duration(TimeSpan.FromMilliseconds(5000)))
myVectorAnimation.RepeatBehavior = RepeatBehavior.Forever
Usare una sintassi simile per impostare come destinazione altre proprietà di trasformazione per spostare o ridimensionare l'oggetto. Ad esempio, è possibile applicare un Point3DAnimation alla proprietà ScaleCenter in una trasformazione di scala per far sì che un modello deformi la forma in modo uniforme.
Anche se gli esempi precedenti trasformano le proprietà di GeometryModel3D, è anche possibile trasformare le proprietà di altri modelli nella scena. Animando le traduzioni applicate agli oggetti Light, ad esempio, è possibile creare effetti luce e ombreggiatura mobili che possono modificare notevolmente l'aspetto dei modelli.
Poiché anche le fotocamere sono modelli, è possibile trasformare anche le proprietà della fotocamera. Anche se è certamente possibile modificare l'aspetto della scena trasformando la posizione della fotocamera o le distanze del piano, in effetti trasformando l'intera proiezione della scena, si noti che molti degli effetti che si ottengono in questo modo potrebbero non rendere tanto "senso visivo" al visualizzatore come trasformazioni applicate alla posizione o alla posizione dei modelli nella scena.
Vedere anche
- Panoramica della grafica 3D
- Panoramica delle trasformazioni
- esempio di trasformazioni 2D
.NET Desktop feedback