Seeing# in C#-Apps einbinden

In den letzten Wochen habe ich mich darauf konzentriert, Möglichkeiten zu schaffen, um Seeing# leichter in C# Apps einbinden zu können – völlig egal ob diese am Desktop oder als Windows Universal App laufen. Ziel ist, dass die Einbindung in allen Fällen möglichst einfach und möglichst ähnlich durchgeführt werden kann. Zu diesem Zweck habe ich die verschiedenen Steuerelemente für WPF und Universal Apps modifiziert, so gibt es jetzt in WPF einen eigenen Xaml-Namespace. Der größere Punkt ist aber eine Einführung eines Komponenten-Systems, mit dem man bereits im Xaml verschiedene Aspekte der 3D-Anzeige zusammenbauen kann. Beispielweise, welche Objekte dargestellt werden sollen und wie die Bedienung der Kamera funktionieren soll.

Ohne viel drum herum zu schreiben sieht das für eine einfache 3D-Anzeige mit Kamera-Steuerung in WPF folgendermaßen aus:

<Window x:Class="SeeingSharp.WpfComponentTest.MainWindow"
        xmlns:ssharpMulti="https://www.rolandk.de//wp/seeingsharp/multimedia"  
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:SeeingSharp.WpfComponentTest"
        mc:Ignorable="d"
        Icon="Assets/Logo.ico"
        Title="Seeing# WPF Components Test" Height="350" Width="525">
    <Grid>
        <ssharpMulti:SeeingSharpRendererElement>
            <ssharpMulti:FocusedPointCameraComponent
                CameraDistanceMin="3" 
                CameraDistanceMax="10"
                CameraDistanceInitial="5"/>
            <ssharpMulti:SimpleCenteredCubeComponent />
        </ssharpMulti:SeeingSharpRendererElement>
    </Grid>
</Window>

Das Ergebnis ist ein WPF-Fenster mit einem schlichten 3D-Würfel und einer Kamera, die auf Maus- und Tastatur-Eingaben reagiert und entsprechend um den Würfel kreist. Die drei Eigenschaften der Klasse FocusedPointCameraComponent beschreiben, wie weit die Kamera vom 3D-Objekt entfernt sein kann. Der „fokussierte Punkt“ wird nicht gesetzt und ist somit 0, also die Ursprungskoordinate im 3D-Raum.

wpf-component-test

Für Windows Universal Apps sieht das sehr ähnlich aus, nur das man hier die Namensräume nicht ganz so schön anpassen kann, wie in Wpf:

<Page
    x:Class="SeeingSharp.UniversalComponentTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:SeeingSharp.UniversalComponentTest"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:ssharpView="using:SeeingSharp.Multimedia.Views"
    xmlns:ssharpComp="using:SeeingSharp.Multimedia.Components"
    mc:Ignorable="d">

    <ssharpView:SeeingSharpRenderPanel>
        <ssharpComp:FocusedPointCameraComponent
                CameraDistanceMin="3" 
                CameraDistanceMax="10"
                CameraDistanceInitial="5"/>
        <ssharpComp:SimpleCenteredCubeComponent />
    </ssharpView:SeeingSharpRenderPanel>
</Page>

Eine Komponente ist nichts anderes als eine Klasse, die ein paar Methoden implementiert. Die obigen sind bereits im Standard von Seeing# enthalten, können also direkt so verwendet werden. Die Komponente SimpleCenteredCubeComponent beispielsweise ist folgendermaßen umgesetzt:

public class SimpleCenteredCubeComponent 
    : SceneComponent<SimpleCenteredCubeComponent.PerSceneContext>
{
    protected override PerSceneContext Attach(SceneManipulator manipulator, ViewInformation correspondingView)
    {
        PerSceneContext context = new PerSceneContext();

        NamedOrGenericKey resCubeGeometry = manipulator.AddGeometry(new CubeType());
        context.CubeObject = manipulator.AddGeneric(resCubeGeometry);
        context.CubeObject.Color = Color4.RedColor;

        return context;
    }

    protected override void Detach(SceneManipulator manipulator, ViewInformation correspondingView, PerSceneContext context)
    {
        manipulator.Remove(context.CubeObject);
    }

    //*********************************************************************
    //*********************************************************************
    //*********************************************************************
    public class PerSceneContext
    {
        public GenericObject CubeObject;
    }
}

Die Komponenten für die Kamera-Steuerung sind dagegen schon etwas größer, aber auch nicht wirklich komplex. Das Coding dazu kann man sich direkt auf Github [1] anschauen.

Verweise
[1] = …b.com/RolandKoenig/SeeingSharp/tree/master/SeeingSharp.Multimedia/Components/_Input

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.