You can download the source code for my WPF / Physics demo here.  Here’s a very brief overview…

Most of the action takes place in World.xaml and its codebehind file.  It uses an ItemsControl bound to an ObservableCollection, with a DataTemplate for each body class.  Here’s the ItemsControl:

<ItemsControl ItemsSource="{Binding}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
          <Canvas/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

The ItemsControl has its ItemsSource bound to the current DataContext.  The default item container is replaced with a Canvas to allow drawing objects to be positioned anywhere.  Here are a couple of the DataTemplates I’ve got:

<DataTemplate DataType="{x:Type local:RectangleBody}">
    <Rectangle Width="{Binding Width}" Height="{Binding Height}" Fill="#80FF0000" Stroke="#80000000" StrokeThickness="0.01" RenderTransformOrigin="0.5, 0.5">
        <Rectangle.RenderTransform>
            <MatrixTransform Matrix="{Binding DisplayMatrix}"/>
        </Rectangle.RenderTransform>
    </Rectangle>
</DataTemplate>

<DataTemplate DataType="{x:Type local:PolygonBody}">
    <Polygon Points="{Binding Points}" Fill="#80808000" Stroke="#80000000" StrokeThickness="0.01">
        <Polygon.RenderTransform>
            <MatrixTransform Matrix="{Binding DisplayMatrix}"/>
        </Polygon.RenderTransform>
    </Polygon>
</DataTemplate>

RectangleBody and PolygonBody are a couple of custom classes wrapping Newton primitives.  DisplayMatrix is a property that returns a 2D transformation matrix based on the 3D matrix calculated by the Newton engine.  Whenever Newton adjusts the matrix it raises an event.  I catch this and call my PropertyChanged delegate (see the INotifyPropertyChanged interface for details).

Why the ridiculously thin (0.01) StrokeThickness I hear you ask?  I’ve got a fairly good explanation for that (scaling from physical world coordinates to display coordinates), but I’ll wait until someone asks before I try to explain myself…

Anyway, take a look at the source and fire some questions at me.  I’m still amazed how little WPF code & markup it needed to get this going.

Thanks again to Flylio for writing a great C# Newton Dynamics wrapper, which is now even better since I ironed out some bugs and replaced its XNA dependency with a WPF one!

About these ads