Tutorial-Serie: WPF 3D Picture Cube – Animation Teil 3

3D WPF Würfel AnimationNachdem wir im zweiten Teil unseren 3D-Würfel erstellt haben, wollen wir ihn nun im WPF-3D-Raum animieren. Hierfür nutzen wir sogenannte From/To/By-Animationen sowie AxisAngleRotation3D-Objekte, um Rotationen durchzuführen und ein TranslateTransform3D-Objekt, um den Cube mit VB.NET (sollte für C#-Entwickler kein Problem darstellen) durch den Raum wandern zu lassen.

Zunächst fügen wir im XAML-Code das Menü hinzu und setzen die Kamerasicht wieder zurück, sodass wir frontal auf den Würfel schauen.

       <Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300" AllowsTransparency="False" WindowStyle="ThreeDBorderWindow" >

        <Grid>
        <Grid.Background>
            <LinearGradientBrush StartPoint="0 0" EndPoint="1 1">
                <GradientStop Color="Aqua" Offset="0"/>
                <GradientStop Color="BlueViolet" Offset="1"/>
            </LinearGradientBrush>
        </Grid.Background>
            <DockPanel
  Width="Auto"
  VerticalAlignment="Stretch"
  Height="Auto"
  HorizontalAlignment="Stretch"
  Grid.ColumnSpan="1"
  Grid.Column="0"
  Grid.Row="0"
  Margin="0,0,0,0"
  Grid.RowSpan="1">
            <StackPanel>
           <Border BorderThickness="2" BorderBrush="Gray">
                <StackPanel>
                    <StackPanel.Background>
                        <LinearGradientBrush>
                            <GradientStop Color="AliceBlue" Offset="0"/>
                            <GradientStop Color="BlueViolet"  Offset=".3"/>
                            <GradientStop Color="Aqua"   Offset=".7"/>
                            <GradientStop Color="AliceBlue" Offset="1"/>
                        </LinearGradientBrush>
                    </StackPanel.Background>

                        <StackPanel Margin="10">

                            <Button Name="Cube" Click="Cube_Click">Cube</Button>
                            <Button Name="btnRotateX" Click="btnRotateX_Click">Rotate X</Button>
                            <Button Name="btnRotateY" Click="btnRotateY_Click">Rotate Y</Button>
                            <Button Name="btnRotateZ" Click="btnRotateZ_Click">Rotate Z</Button>
                            <Button Name="btnTransZ" Click="btnTransZ_Click">Transl. Z</Button>

                            <Button Name="btnClose" Click="btnClose_Click">Close</Button>

                        </StackPanel>

                </StackPanel>
            </Border>
                </StackPanel>
                <Viewport3D Name="mainViewport" ClipToBounds="True">
                    <Viewport3D.Camera>
                       <PerspectiveCamera x:Name="cam" Position="0,0,4" LookDirection="0,0,-3.5" ></PerspectiveCamera>
                    </Viewport3D.Camera>

                    <ModelVisual3D>
                        <ModelVisual3D.Content>
                            <DirectionalLight
	    Color="White"
	    Direction="0,0,-1" />
                        </ModelVisual3D.Content>

                </ModelVisual3D>
                </Viewport3D>
            </DockPanel>
        </Grid>

</Window>

Dann fügen wir im VB.NET-Code die fehlenden Event-Subs hinzu, in dem wir das jeweilige Steuerelement oben links auswählen und dann rechts die richtigen Events wählen.

Nun Erzeugen wir eine neue Sub „PaintCube“ und schieben den gesamten Code aus dem zweiten Teil dieses WPF Tutorials, der unseren Würfel beschreibt, in diese Sub.

Um die Lage und Postion des Würfels im 3D-Raum zu ändern, benötigen wir nun vier neue private Objekte. Zur Vereinfachung nenne ich sie mal Positionnierungs-Objekte:

    Private RotationX As New AxisAngleRotation3D(New Vector3D(1, 0, 0), 0)
    Private RotationY As New AxisAngleRotation3D(New Vector3D(0, 1, 0), 0)
    Private RotationZ As New AxisAngleRotation3D(New Vector3D(0, 0, 1), 0)
    Private TranslateZ As New TranslateTransform3D

Ein AxisAngleRotation3D-Objekt stellt eine 3D-Drehung mit einem angegebenen Winkel um eine angegebene Achse dar.
Ein TranslateTransform3D-Objekt verschiebt ein Objekt im dreidimensionalen x-y-z-Raum.

Im zweiten Teil fügen wir ja die Model3DGroup dem ModelVisual3D hinzu, um dieses dann als Kind des Viewports hinzufügen. Bevor wir aber letzteres tun, erzeugen wir ein Transform3DGroup- Objekt, fügen diesem unsere vier neuen Positionnierungs-Objekte hinzu und weisen diese dann unserer Transform-Property des Models zu:

        Dim transformGroup As New Transform3DGroup

        transformGroup.Children.Add(New RotateTransform3D(RotationX))
        transformGroup.Children.Add(New RotateTransform3D(RotationY))
        transformGroup.Children.Add(New RotateTransform3D(RotationZ))
        transformGroup.Children.Add(TranslateZ)
        Model.Transform = transformGroup

Und erst jetzt weisen wir das Model dem Viewport zu:

Me.mainViewport.Children.Add(Model)

Jetzt haben wir unserem Würfel die Fähigkeit gegeben Ihre Position und Lage im 3D-Raum zu ändern. Jetzt müssen wir nur noch dafür sorgen, dass er es auch tut.

Kommen wir also zum Animieren unseres Objektes! Hierzu benötigen wir zunächst den Namespace für die Animation:

Imports System.Windows.Media.Animation

Das Animieren ist im Grund ganz einfach. Wir verändern die Postion und die Lage des Würfels während eines Zeitablaufes immer stärker. Hierfür nutzen wir die sogenannten Basis-Animationen (auch From/To/By-Animationen genannt).
Wir definieren in unserem Fall ein Objekt vom Typ DoubleAnimimation (weil die Werte, die wir verändern Double sind) und weisen den Properties From und To zu von welchem Wert zu welchem Wert er sich verändern soll.
Außerdem bestimmen wir darüber noch die Laufzeit, Wiederholungen usw.
Anschließend übergeben wir dieses Animations-Objekt der BeginAnimation – Eigenschaft unseres Positionsierungsobjektes und geben dabei an, was animiert werden soll.

Zum besseren Verständnis sehen wir hier nun, wie dies Animations-Deklaration für unsere Bewegung entlang der Z-Achse aussieht:

        Dim transAnimationZ As New DoubleAnimation
        transAnimationZ.Duration = TimeSpan.Parse("0:0:4")
        transAnimationZ.From = -1.5
        transAnimationZ.To = 3.5
        transAnimationZ.AutoReverse = True
        transAnimationZ.AccelerationRatio = 0.1
        transAnimationZ.DecelerationRatio = 0.1
        transAnimationZ.RepeatBehavior = New RepeatBehavior(2)
        TranslateZ.BeginAnimation(TranslateTransform3D.OffsetZProperty, transAnimationZ)

Die Rotationen sehen alle ähnlich aus. Hier die Routine für die X-Drehung:

        Dim rotateAnimationX As New DoubleAnimation
        rotateAnimationX.Duration = TimeSpan.Parse("0:0:4")
        rotateAnimationX.From = -180
        rotateAnimationX.To = 180
        rotateAnimationX.AutoReverse = True
        rotateAnimationX.AccelerationRatio = 0.1
        rotateAnimationX.DecelerationRatio = 0.1
        rotateAnimationX.RepeatBehavior = New RepeatBehavior(2)

        RotationX.BeginAnimation(AxisAngleRotation3D.AngleProperty, rotateAnimationX)

Wenn Ihr nun die Hauptroutine PaintCube im Click-Event Cube-Buttons aufruft, sowie die verschiedenen Animations-Routinen hinter den jeweils anderen Buttons, dann sollte Eure Animation wie im Video des ersten Teils des WPF Tutorials laufen.

Ach ja, den Close-Befehl solltet ihr natürlich auch hinter dem Close-Button packen 😉

Me.Close()

Viel Spaß!

kick it on dotnet-kicks.de

Comments
  1. Benny
  2. anakkecil
  3. Martin Bollin
  4. Carsten Seifert
  5. daGrossa
  6. Carsten Seifert