Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Thema wird beschrieben, wie Transformationen auf 3D-Modelle im Windows Presentation Foundation (WPF)-Grafiksystem angewendet werden. Mit Transformationen kann der Entwickler Modelle neu positionieren, ändern und neu ausrichten, ohne die Basiswerte zu ändern, die sie definieren.
3D-Koordinatenraum
3D-Grafikinhalte in Windows Presentation Foundation (WPF) werden in einem Element gekapselt, Viewport3Ddas an der zweidimensionalen Elementstruktur teilnehmen kann. Das Grafiksystem behandelt Viewport3D als zweidimensionales visuelles Element wie viele andere in Windows Presentation Foundation (WPF). Viewport3D fungiert als Fenster – ein Viewport – in einer dreidimensionalen Szene. Genauer gesagt ist es eine Oberfläche, auf der eine 3D-Szene projiziert wird. Obwohl Sie Viewport3D mit anderen 2D-Zeichnungsobjekten im selben Szenendiagramm verwenden können, können Sie 2D- und 3D-Objekte nicht innerhalb eines Viewport3D-Objekts interpenetieren. In der folgenden Diskussion ist der beschriebene Koordinatenbereich im Viewport3D-Element enthalten.
Das Windows Presentation Foundation (WPF)-Koordinatensystem für 2D-Grafiken sucht den Ursprung oben links auf der Renderingoberfläche (in der Regel der Bildschirm). Im 2D-System gehen positive x-Achsenwerte nach rechts und positive Y-Achsenwerte nach unten. Im 3D-Koordinatensystem befindet sich der Ursprung jedoch in der Mitte des Bildschirms, wobei positive x-Achsenwerte nach rechts verlaufen, positive y-Achsenwerte hingegen nach oben. Positive z-Achsenwerte verlaufen vom Ursprung aus nach vorne in Richtung des Betrachters.
Koordinatensystemvergleich
Der durch diese Achsen definierte Raum ist der stationäre Referenzrahmen für 3D-Objekte in Windows Presentation Foundation (WPF). Wenn Sie Modelle in diesem Raum erstellen und Lichter und Kameras erstellen, um sie anzuzeigen, ist es hilfreich, diesen stationären Referenzrahmen oder "Weltraum" vom lokalen Referenzrahmen zu unterscheiden, den Sie für jedes Modell erstellen, wenn Sie Transformationen darauf anwenden. Denken Sie auch daran, dass Objekte im Weltraum je nach Licht- und Kameraeinstellungen völlig anders aussehen oder gar nicht sichtbar sind, aber die Position der Kamera ändert nicht die Position von Objekten im Weltraum.
Transformieren von Modellen
Wenn Sie Modelle erstellen, haben sie eine bestimmte Position in der Szene. Um diese Modelle in der Szene zu verschieben, sie zu drehen oder ihre Größe zu ändern, ist es nicht praktisch, die Scheitelpunkte zu ändern, die die Modelle selbst definieren. Stattdessen wenden Sie Transformationen wie in 2D auf Modelle an.
Jedes Modellobjekt verfügt über eine Transform Eigenschaft, mit der Sie das Modell verschieben, neu ausrichten oder die Größe des Modells ändern können. Wenn Sie eine Transformation anwenden, werden alle Punkte des Modells effektiv durch den von der Transformation angegebenen Vektor oder Wert versetzt. Mit anderen Worten, Sie haben den Koordinatenbereich transformiert, in dem das Modell definiert ist ("Modellraum"), aber Sie haben die Werte, aus denen die Geometrie des Modells besteht, im Koordinatensystem der gesamten Szene ("Weltraum") nicht geändert.
Übersetzungstransformationen
3D-Transformationen erben von der abstrakten Basisklasse Transform3D; dazu gehören die affinen Transformationsklassen TranslateTransform3D, ScaleTransform3Dund RotateTransform3D. Das Windows Presentation Foundation (WPF)-3D-System bietet auch eine MatrixTransform3D Klasse, mit der Sie dieselben Transformationen in präziseren Matrixvorgängen angeben können.
TranslateTransform3D Verschiebt alle Punkte in der Model3D-Anweisung in die Richtung des Offsetvektors, den Sie mit den OffsetX, OffsetYund OffsetZ eigenschaften angeben. Bei einem Vertex eines Würfels bei (2,2,2) würde ein Offsetvektor von (0,1.6,1) diesen Vertex (2,2,2) auf (2,3.6,3) verschieben. Der Eckpunkt des Würfels befindet sich weiterhin bei (2,2,2) im Modellbereich, aber jetzt hat der Modellbereich seine Beziehung zum Weltkoordinatenraum geändert, sodass (2,2,2) im Modellbereich (2,3.6,3) im Weltkoordinatenraum ist.
Übersetzung mit Offset
Die folgenden Codebeispiele zeigen, wie eine Übersetzung angewendet wird.
<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>
Skalierungstransformationen
ScaleTransform3D ändert die Skalierung des Modells durch einen angegebenen Skalierungsvektor mit Bezug auf einen Mittelpunkt. Geben Sie eine einheitliche Skalierung an, die das Modell um denselben Wert in den Achsen X, Y und Z skaliert, um die Größe des Modells proportional zu ändern. Wenn Sie z. B. die TransformationsScaleXScaleY- und ScaleZ Eigenschaften auf 0,5 halbieren, wird die Größe des Modells halbiert. Durch Festlegen der gleichen Eigenschaften auf 2 wird die Skalierung in allen drei Achsen verdoppelt.
ScaleVector-Beispiel
Durch Angeben einer nicht einheitlichen Skalierungstransformation – einer Skalierungstransformation, deren X-, Y- und Z-Werte nicht alle gleich sind – können Sie dazu führen, dass ein Modell in einer oder zwei Dimensionen gestreckt oder kontraktiert wird, ohne dass sich dies auf die anderen Auswirkt. Zum Beispiel würde die Einstellung ScaleX auf 1, ScaleY auf 2 und ScaleZ auf 1 dazu führen, dass sich das transformierte Modell in der Höhe verdoppelt, aber entlang der X- und Z-Achse unverändert bleibt.
Standardmäßig bewirkt ScaleTransform3D, dass Scheitelpunkte über den Ursprung (0,0,0) erweitert oder kontraktiert werden. Wenn das Modell, das Sie transformieren möchten, nicht vom Ursprungspunkt ausgeht, wird das Modell nicht "am Platz" skaliert, wenn es vom Ursprung aus skaliert wird. Stattdessen verschiebt und skaliert sich das Modell, wenn seine Scheitelpunkte mit dem Skalierungsvektor multipliziert werden.
Skalierungscenter (Beispiel)
Um ein Modell "vor Ort" zu skalieren, geben Sie die Mitte des Modells an, indem Sie die ScaleTransform3D-Eigenschaften CenterX, CenterY und CenterZ festlegen. Dadurch wird sichergestellt, dass das Grafiksystem den Modellraum skaliert und anschließend auf das angegebene Point3D zentriert. Wenn Sie das Modell hingegen am Ursprung aufgebaut und einen anderen Mittelpunkt angegeben haben, können Sie erwarten, dass das Modell vom Ursprung weg verschoben wird.
Drehungstransformationen
Sie können ein Modell in 3D auf verschiedene Weise drehen. Eine typische Drehtransformation gibt eine Achse und einen Drehwinkel um diese Achse an. Mit der RotateTransform3D-Klasse können Sie ein Rotation3D mit seiner Rotation-Eigenschaft definieren. Anschließend geben Sie die Axis- und Angle-Eigenschaften für die Rotation3D an, in diesem Fall ein AxisAngleRotation3D, um die Transformation zu definieren. In den folgenden Beispielen wird ein Modell um 60 Grad um die Y-Achse gedreht.
<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>
Hinweis:Windows Presentation Foundation (WPF) 3D ist ein rechtshändiges System, d. h., ein positiver Winkelwert für eine Drehung führt zu einer Drehung gegen den Uhrzeigersinn über die Achse.
Achsenwinkeldrehungen gehen von einer Drehung um den Ursprung aus, wenn für die Eigenschaften CenterX, CenterY und CenterZ von RotateTransform3D kein Wert angegeben ist. Wie bei der Skalierung ist es hilfreich, daran zu denken, dass die Drehung den gesamten Koordinatenbereich des Modells transformiert. Wenn das Modell nicht über den Ursprung erstellt wurde oder zuvor übersetzt wurde, kann die Drehung den Ursprung "pivotieren", anstatt an Ort und Stelle zu drehen.
Drehung mit neuer Mitte angegeben
Um das Modell "an Ort" zu drehen, geben Sie die tatsächliche Mitte des Modells als Drehmittelpunkt an. Da Geometrie in der Regel über den Ursprung modelliert wird, können Sie am häufigsten das erwartete Ergebnis einer Gruppe von Transformationen erzielen, indem Sie zuerst die Größe des Modells (skalieren) und dann die Ausrichtung (drehen) und schließlich an die gewünschte Position verschieben (übersetzen).
Beispiel für Drehung
Achsenwinkeldrehungen funktionieren gut für statische Transformationen und einige Animationen. Ziehen Sie jedoch in Betracht, ein Würfelmodell um 60 Grad um die X-Achse zu drehen, und dann 45 Grad um die Z-Achse. Sie können diese Transformation als zwei diskrete affine Transformationen oder als Matrix beschreiben. Es kann jedoch schwierig sein, eine auf diese Weise definierte Drehung reibungslos zu animieren. Obwohl die anfangs- und endenden Positionen des Modells, die von beiden Ansätzen berechnet werden, gleich sind, sind die zwischengeschalteten Positionen des Modells rechnerisch unsicher. Quaternionen stellen eine alternative Methode zum Berechnen der Interpolation zwischen Dem Anfang und Ende einer Drehung dar.
Eine Quaternion stellt eine Achse im 3D-Raum und eine Drehung um diese Achse dar. Beispielsweise kann eine Quaternion eine Achse (1,1,2) und eine Drehung von 50 Grad darstellen. Die Stärke von Quaternions bei der Bestimmung von Drehungen liegt in den beiden Operationen, die Sie ausführen können: Komposition und Interpolation. Die Zusammensetzung von zwei Quaternionen, die auf eine Geometrie angewendet werden, bedeutet: "Die Geometrie zunächst um Achse2 mit Drehung2 zu drehen und danach um Achse1 mit Drehung1." Mithilfe der Komposition können Sie die beiden Drehungen der Geometrie zu einer einzigen Rotation kombinieren, die durch eine einzelne Quaternion dargestellt wird. Da die Quaternion-Interpolation einen reibungslosen und vernünftigen Weg von einer Achse und Ausrichtung zu einer anderen berechnen kann, können Sie zwischen dem Original und der zusammengesetzten Quaternion interpolieren, um einen reibungslosen Übergang von einer zur anderen zu erzielen, sodass Sie die Transformation animieren können. Bei Modellen, die Sie animieren möchten, können Sie ein Ziel Quaternion für die Drehung angeben, indem Sie eine QuaternionRotation3D für die Rotation Eigenschaft verwenden.
Verwenden von Transformationssammlungen
Beim Erstellen einer Szene ist es üblich, mehrere Transformationen auf ein Modell anzuwenden. Fügen Sie der Children Auflistung der Transform3DGroup Klasse Transformationen hinzu, um Transformationen zu gruppieren, um sie bequem auf verschiedene Modelle in der Szene anzuwenden. Häufig empfiehlt es sich, eine Transformation in mehreren verschiedenen Gruppen wiederzuverwenden, sodass Sie ein Modell wiederverwenden können, indem Sie auf jede Instanz einen anderen Satz von Transformationen anwenden. Beachten Sie, dass die Reihenfolge, in der die Transformationen der Auflistung hinzugefügt werden, erheblich ist: Transformationen in der Auflistung werden von der ersten zur letzten angewendet.
Animieren von Transformationen
Die 3D-Implementierung von Windows Presentation Foundation (WPF) nimmt an dem gleichen Timing- und Animationssystem wie 2D-Grafiken teil. Mit anderen Worten: Um eine 3D-Szene zu animieren, animieren Sie die Eigenschaften ihrer Modelle. Es ist möglich, Eigenschaften von Grundtypen direkt zu animieren, aber in der Regel ist es einfacher, Transformationen zu animieren, die die Position oder Darstellung von Modellen ändern. Da Transformationen sowohl auf Model3DGroup Objekte als auch auf einzelne Modelle angewendet werden können, ist es möglich, einen Satz von Animationen auf die Kinder einer Model3D-Gruppe und einen anderen Satz von Animationen auf eine Gruppe von Objekten anzuwenden. Hintergrundinformationen zum Windows Presentation Foundation(WPF)-Zeitsteuerungs- und Animationssystem finden Sie unter Animation Überblick und Storyboard Überblick.
Wenn Sie ein Objekt in Windows Presentation Foundation (WPF) animieren möchten, erstellen Sie eine Zeitachse, definieren Sie eine Animation (die im Laufe der Zeit eine Änderung des Eigenschaftswerts ist), und geben Sie die Eigenschaft an, auf die die Animation angewendet werden soll. Diese Eigenschaft muss eine Eigenschaft eines FrameworkElements sein. Da alle Objekte in einer 3D-Szene direkte Unterelemente von Viewport3D sind, gelten die Eigenschaften, auf die Sie mit jeder Animation abzielen möchten, als Eigenschaften des Viewport3D. Es ist wichtig, den Eigenschaftspfad für die Animation sorgfältig festzulegen, da die Syntax umständlich sein kann.
Angenommen, Sie möchten ein Objekt an Ort und Stelle drehen, aber auch eine schwingende Bewegung ausführen, um mehr von dem Objekt freizulegen. Sie können eine RotateTransform3D auf das Modell anwenden und die Achse ihrer Drehung von einem Vektor auf einen anderen animieren. Das folgende Codebeispiel veranschaulicht die Anwendung einer Vector3DAnimation auf die Axis-Eigenschaft der Rotation3D der Transformation, vorausgesetzt, dass RotateTransform3D eine von mehreren Transformationen ist, die mit einer TransformGroup auf das Modell angewendet werden.
//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
Verwenden Sie eine ähnliche Syntax, um andere Transformationseigenschaften zum Verschieben oder Skalieren des Objekts zu verwenden. Sie können z. B. eine Point3DAnimation auf die Eigenschaft ScaleCenter einer Skalentransformation anwenden, damit ein Modell seine Form sanft verzerrt.
Obwohl in den vorherigen Beispielen die Eigenschaften GeometryModel3Dtransformiert werden, ist es auch möglich, die Eigenschaften anderer Modelle in der Szene zu transformieren. Durch das Animieren von Übersetzungen, die auf Light-Objekte angewendet werden, können Sie beispielsweise bewegende Licht- und Schatteneffekte erstellen, die das Aussehen Ihrer Modelle erheblich ändern können.
Da Kameras auch Modelle sind, ist es auch möglich, Kameraeigenschaften zu transformieren. Sie können zwar das Aussehen der Szene verändern, indem Sie die Kameraposition oder die Flächenabstände transformieren — tatsächlich die gesamte Szenenprojektion — beachten Sie jedoch, dass viele der auf diese Weise erzielten Effekte für den Betrachter möglicherweise nicht so viel "visuellen Sinn" ergeben wie Transformationen, die auf die Position der Modelle in der Szene angewendet werden.
Siehe auch
.NET Desktop feedback