WPF Physics Source

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!

39 Comments

  1. Ok, so about that ridiculously thin (0.01) StrokeThickness… It’s because I’m defining the shapes with the same units I’m representing the bodies in the ‘physical’ world (meters), and scaling the whole scene up to display units with a RenderTransform. This scales the StrokeThickness up by the same amount… Is that a lame excuse? :o)

    Reply

  2. That was loads of fun but there seems to a performance limit when you add a huge number of sprites.

    Does the video use Microsoft Physics Illustrator? If that app had an export to xaml function that could be pretty cool for creating basic technical animations in xaml.

    Reply

  3. The performance does suffer but that’s to be expected (I’ve not looked yet if it’s the physics engine choking or WPF). I’m sure there are optimizations that could be made :o)

    Physics Illustrator doesn’t have an XAML export (that I’m aware of); could be interesting if it did. The source is freely available though, so I’m thinking about adapting some of its design / stroke-handling ideas.

    Before that I was probably going to make the bodies draggable during the animation (just as an excuse to play more with WPF).

    Reply

  4. Hi, I’m really curious and I found this page through a google search. Did you manage to get Newton Dynamics working in XNA Game Studio Express? And if so do you think you could let me know how to use the wrapper in a GSE project? If you could e-mail me back that would be great, thanks.

    Reply

  5. Hi Chris,

    Awesome blog and super cool demos. In fact, you’ve inspired me to work on a 2D game I’ve been thinking about for a while. To that end, I would like to use some of your code (it’s excellent and would save me a lot of time), but in the likely event that I:
    a) Finish the game and
    b) Miraculously find a way to make money from it,
    I don’t want to be in a sticky licensing situtation.
    So, my natural question to you is, what is the licensing agreement for your source code? I see Newton has a pretty liberal license, any chance your code uses the same license? Or MIT license or ZLib license (same as bullet engine)? Any of those would be great. GNU and some of the others are pretty prohibitive so I’m hoping (pretty please!) that you won’t choose one of those.

    I see someone else had the same question. Please let us know.
    Thanks for the great blog,
    Mike.

    Reply

  6. Sam – I’m sure it’d be possible to get Newton working in GSE, but it’d only work on a PC. It should be possible to test it easily enough (create a new project in GSE and drag the files in?). I’m prepared to be wrong though!

    Reply

  7. Mike – You can assume my code uses the same license as Newton (or Flylio’s wrapper which my demo also depends on). To be honest the real work is done in Flylio’s code (NewtonWrapper); he did the hard work of figuring out the interop to Newton’s DLLs. Other than a few bugs I fixed, it’s pretty much unchanged from his site (except to remove the XNA dependency and replace it with a WPF one).

    Don’t forget there’s also the fully managed BulletX library my later demos use. If you want to deploy on Silverlight or Xbox you’ll need all the managed code you can get 🙂

    Let me know if you have any problems with my code; I’ll help any way I can.

    Reply

  8. Awesome, thanks Chris! I really appreciate it.

    Have you tried (had any luck with) using Newton CollisionTrees? I can’t seem to get them to work using the wrapper.

    Reply

  9. Mike – I’ve not tried using them (I don’t even know what they do :)). It’s quite possible there’s a bug in the NewtonWrapper somewhere; it’s worth taking a look at the Newton header files and comparing the datatypes to what the wrapper is expecting. Pay particular attention if the wrapper uses sizeof() or passes an array in any form (the bugs I already found/fixed were like that).

    Reply

  10. Mike – When debugging, just keep this chant in your head: “Newton is solid and works for everyone else” 🙂 That only leaves the wrapper and my code to wade through. It possible there’s a bug in Newton itself, but I bet it’s highly unlikely at this stage.

    Reply

  11. Okay, that’s good advice. I have found some minor tweaks I’ve had to make to the wrapper myself (regarding the same issues you mentioned). So the problem is probably along the same lines. I shall forge on and presevere.

    P.S. Your code has been rock-solid… no problems.

    Reply

  12. Mike – Can you let me know what bugs you find/fix in the wrapper? Would be good to keep my code up to date.

    Maybe it’s time I added the source to CodePlex again 🙂

    Reply

  13. Sure, here goes:
    1. Fixed InvokeContactBegin return value handling in CMaterialPhysics (was hardcoded to 1… you need to be able to return 0 if you want to ignore material contacts).
    2. There are a number of properties imported in BodyManipulation.cs that refer to ref float[] (examples: NewtonBodyGetVelocity, NewtonBodyGetTorque, etc). These needed to be changed to just float[] (get rid of the ref) in order to work. Also made the corresponding change in CBody.cs.
    3. CJointBallSocket.cs -> NewtonConstraintCreateBall passes m_Handle in the call to Newton.NewtonConstraintCreateBall. It needs to pass m_World.Handle.

    I think that covers it for actual “bugs”. I made some other tweaks to expose/cleanup properties I needed but I don’t think they qualify as mandatory.

    Reply

  14. Man, I cannot for the life of me get Collision trees to work. Picture the car in your demo rolling down a concave ramp. I’m trying to use collision trees to create the ramp (Newton doesn’t like concave surfaces so you have to simulate them by chaining together a bunch of convex collisions). Anyway, I think I have to throw in the towel on this one. I have the ramp mostly working using CCollisionComplexPrimitives.CreateCompound but there is an undesirable side effect of random “bumpiness” along the ramp’s surface. I was told (on the Newton forums) that collision trees should fix this, but alas, it appears as though I’m not smart enough for to make them work. Anyway, if you find yourself bored (and are itching for some frustration) I’d be thrilled to learn you actually got collision trees to work (I noticed Flyio’s original wrapper samples use them but the download I found is just .cs files… no project or solution included so I wasn’t able to actually run it).

    Cheers,
    Mike.

    Reply

  15. Mike – Sorry to hear of problems 😦 Do the bumps correspond to the vertices along the surface? (as if they’re connected with flat lines).

    I’ll take a look at it, but not sure when yet (my time is stretched pretty thin right now). I’ll let you know if/when I figure it out 🙂 Let me know if you make any more progress on it.

    Thanks!
    Chris.

    Reply

  16. Hey Chris,

    The vertices are connected with flat lines (very short line segments). I’ve created the ramp’s compound collision by drawing 2 parrallel arcs (half circles) and then connecting 2 points from the inner arc to 2 points from the outer arc (so each sub-collision is a small trapezoid… note: I also tried tessellating with triangles instead of trapezoids and got the same behavior). As I said, this seems to work pretty well except for the occassional, random bounce upward (it’s as though there are some unseen potholes in my ramp… it does not behave like you would expect if it were just transitioning from one flat line to another… it behaves like it hit something sticking up… in fact increasing the number of points per arc (thus shortening the length of each flat line) actually makes the side-effect worse). Shrug.

    How has your experience with the Managed Bullet Library been? Do you find it easier to use than Newton? Have you done anything with compound or concave surfaces with it? I wonder if it would be worth it trying to switch engines. It would be a lot of work and I think I can live with the behavior I have now, but if you strongly endorse the Bullet library I’ll strongly consider taking the plunge.

    Mike.

    Reply

  17. Mike – Unfortunately I don’t know enough about the innards of the engine to offer much help 😦 It might be worth contacting the NewtonDynamics guys to see if it’s likely to be an engine glitch (although their site hasn’t been updated recently).

    I’d definitely recommend Bullet; it seems more capable than Newton (with apparent support for non-convex collisions). Unfortunately I’ve not had time to kick it around as much as I’d like. It might be worth grabbing one of my other demos (the Silverlight 1.1 Physics one clamps to 2D) and see how easy/difficult it is to get more complex stuff in there. It includes a ‘Vehicle’ class like Newton too, so porting might not be too difficult.

    Here’s how to get BulletX working with WPF or Silverlight:
    1) Download the source for my ‘3D XBAP Physics’ or ‘Silverlight 1.1 Physics’ demos, you’ll find a wrapper assembly called CJC.XnaToWpf (or similar).
    2) Get the latest BulletX source from http://www.codeplex.com/xnadevru/Release/ProjectReleases.aspx?ReleaseId=1278 and add a project reference to XnaToWpf; you should be able to remove the XNA reference completely (XnaToWpf just mimics the main math classes from XNA).

    Also, the Xnadev.ru guys have some other projects you might find useful: http://www.codeplex.com/xnadevru

    Hope this helps! Let me know what you decide.

    Chris

    Reply

  18. Hey Chris!

    I have a beta version of the game I’ve been working on (which leverages some of your code) now available. I’d love for you to check it out, but I don’t want to post the url anywhere until I’ve had a chance to work out the kinks. Can I send you an email? Or can you email me and I’ll respond with the link?

    Thanks for the great blog and awesome samples,
    Mike.

    Reply

  19. Hi Chris!! Thanks for this excellent demo. Have you tried something similar but with draggable objects? How easy do you think it could be?. I’ve seen some newton dragging samples but I’m not too sure if they could be translated to the .net wrapper completely, mainly b/c I don’t understand clearly how to translate screen coords to world coords. That newton samples also use worldraycast to figure out (i think) if the mouse is over an object. In wpf I think this is not necessary since we have the onmouse events.

    Thanks a lot and keep the excellent work!!!

    Reply

  20. Great demo, thanks Chris! I really appreciate it too.

    I tried to put an InkCanvas with its EditMode property set to “Select” around the ItemControls element, but it failed to select any shape. Only a small canvas element seems to be selected at the center of the form each time I click an object. Any idea / suggestion ?

    Reply

  21. Hello,

    I’m surprised and very happy to see that someone used my wrapper!

    I’ll hope it was usefull !!

    @PLUS2009!

    Flylio.

    Reply

  22. Chris,
    How can I move those objecs ‘bodies’ with the mouse? I tried to play with the Matrix of the objects, but nothing.

    Reply

  23. Alex – I’d need to look at the code to be sure (it’s been a while) but I’m pretty sure you need to apply a force to the body you want to move. You could also take a look at the “move platforms” code; pretty sure that just jiggles the matrices a bit… Let me know how it goes 🙂

    Reply

  24. And one else, when the objects complete their movement, they are frozen…I cannot manipulate…Do I need to set something?

    Reply

  25. Alex – Take a look at the SetPlatforms method in Bodies.cs (although looking at it now, it’s probably not much use). Instead try calling the AddForce method on the body you want to move, giving it a Vector3D of the direction you want it to move (imaginary force pushing it from the opposite side). Let me know if it works!

    Reply

  26. Alex – The Newton engine has an optimization where it stops calculating body movement when it thinks they’re stationary (they can still be moved by other collisions of course). You might need to dig around in the code a little to find how to override that (again, just applying a force to the body may be sufficient).

    Reply

  27. Hi Chris,
    I am working on a similar project in wpf physics for my univercity and i was wondering if you could upload your source code once again in order to get some help.

    Thanks in advance
    Stelios

    Reply

      1. Thank you very much Chris!I am a beginner in wpf and i was thinking if you could give me a little more help.I have manage to create an inkcanvas in which i draw some shapes.I can also draw forces on that shapes and see them animate (simple translate animation).
        My problem is how i can make them collide with each other?Is there any animation handler in wpf which will allow me to chech for collisions when my shape moves pixel by pixel?Or am i going to the wrong direction?
        I would appreciate any kind of help you can give me because i m stuck for many days at this problem trying to find a solution.

        Thank again
        Stelios

    1. SteliosD – It’s usually best to have a clear separation between the rendering (WPF / whatever) and the physics world. Define the objects using whatever primitives are provided by the physics engine you’re using, then figure out the rendering later. An example might be if you’re animating a sphere; many physics engines might provide a sphere primitive, which is typically much faster for it to manipulate than a series of vertices on a polygon (since it has a known radius etc, it can perform very simple bounds checks). When you’re ready to render, use the current object positions and orientations from the physics engine and render that however you want in WPF. For a 3D sphere you’ll want to build a bunch of polygons for it (as few or as many as you like; even though the physics engine is dealing with a perfect sphere, your rendering can take whatever shortcuts it likes to improve performance etc), then apply rotation and translation transforms to get it in the right place. If you’re just rendering a 2D object (a shape, image or whatever) it’s essentially the same; just apply rotation and translation transforms and you’re done.

      Another benefit of separating the physics from the rendering is frame-rate / performance independence. You can typically update the physics world far more often than refresh the screen. Most of the physics demos I’ve written cheat a little by running everything on the main thread. When WPF wants to render a new frame (in CompositionTarget.Rendering) you tell the physics engine to update, usually providing it with a time interval since the last update. But ideally you could update the physics world on a different thread, then snapshot its state each time WPF wants to render a frame. Obviously you’d need to make sure it’s thread-safe, but that’s pretty easy.

      Hope this helps.

      Reply

      1. So Chris lets see if i get this right.For example if i have two circles on my canvas first i should calculate the point where they ‘re going to collide and where they’re going to end up next and then do all the rendering?I thought it would be easier to check for collisions when for example TranslateTransform.XProperty changes but i don’t know how to check when it happens.
        The reason i asked for your source code before was that i couldn’t find any physics library for wpf and i was hoping to find something in the Newton’s library of yours.Will this be usable for me and if so how can i import it to my program?

        I apologize for taking you so much time.If i ‘m annoying you i wont make any further questions.

        Thank you once again
        Stelios

Leave a comment