A beginners romp into Farseer 3.0

Apr 8, 2010 at 9:19 PM

First a haiku:

Farseer three point oh,

your testbed looks so stunning,

Plus, performance gains!

So anyway, I've decided to take the plunge and start fiddling with the ultimate goal to convert an existing project over.  I thought it might be useful if I shared some of my experiences for any other beginners (I'm a dummy, as you'll see) and ask questions as I go.  For experienced programmers this may be annoying, so feel free to skip (although your input would be appreciated).

The first challenge is grasping the MKS.  According to the March Update, "You must either scale the physics world to match your pixel-based code or write code that uses a smaller orthographic viewport."  Again, I'm a dummy, so the latter suggestion is very confusing.  Lets make that the first question:

  • Use a smaller orthogra-wuh viewport huh say what now?

Wikipedia has a fascinating but hard to connect to programming entry on orthographic projection.  And the Windows Tech forums include an interesting discussion between XNA greats Gravelyn and Hargreaves regarding orthographic matrices.  But really, I'm very much in the dark on what's being suggested here.  My general approach to the viewport has been to use a camera class and transformation matrices to zoom, pan, rotate, etc.  Does "use a smaller orthographic viewport" mean zoom out? 

Lets skip to the "scale the physics world" approach, which seems more intuitive.

Reviewing Box2D tutorials, it seems most people use a scale of 30. Next question:

  • What are the upsides/downsides to using a larger or smaller scale? 

oranjoose posted a helpful down and dirty test program for farseer 3.0 in the March update. At first I thought he was using a scale of 30 in disguise because of this: 

new PolygonShape(PolygonTools.CreateRectangle(15 / SCALE, 5 / SCALE), 1f)

He mentions that the PNG he's using is a 30 x 10 png and the SCALE variable is 15f, so it looks like the rectangle is 1 x .34 meters and the actual scale is 30.  But I was forgetting that CreateRectangle() wants half the width and height.  (Why?)

Anyway, I decide to skin a physics world item with something from the pixel world.  To do this, I fiddle with the ShapeEditingTest in the testbed.  It has a square that it defines as 4 meters by 4 meters.  The testbed isn't ideal to start skinning because it has no calls to a draw method, but after some hacking I snuck one in.  I pass the _body position and rotation to the spritebatch.draw() method and encounter a few strange things.  Apparently, the body's rotation is the opposite of the spritebatch rotation.  Next question,

  • Why is the body's rotation the opposite of the spritebatch rotation?

Course the fix here is easy.  Negative _body.Rotation to the draw method solves it, but still i'm curious what's happening.  (Does this mean on my list of tasks for migrating an existing project, all angular velocities must be flipped?)  Something strange is happening, but I can't see the difference.  Also note, oranjoose's example does not have this issue--rotation is rotation--but neither his example nor the ShapeEditingTest.cs make any references to rotation that seem unusual.  Incidentally, it may be unfair to pose this question without posting code.  The code is ShapeEditingTest.cs, unaltered, except for a draw method with -_body.Rotation passed to it.

Next comes positioning.  Oranjoose's example does an interesting thing, using two functions StoW and WtoS (for Screen to World and World to Screen), which divide by the scale or multiply by it respectively, so he can position the object in the first instance using screen positions.  For positioning the sprite he uses a rectangle target, updated in the update() to the position of the body times the scale.  When I do this in the ShapeEditingTest I get the up is down, down is up problem, because Y can be higher in the "world" as it moves up, instead of lower as spritebatch conceptualizes it.  As Mattbettcher pointed out, the testbed is laid out with the X,Y coordinate zero at the center:

So next question:

  • How do you properly map a position which may be positive or negative in the physics model to a spritebatch position?

Having posed the question, I'm realizing that it's not as if spritebatch positioning doesn't also allow for positive or negative, I'm just not used to a viewport approaching it this way.  Why is having higher Y values for the draw rectangle in Oranjoose's example making the object move up instead of down, but not so in the shapeeditingtest?

Right around now I press the zoom button while running the application and realize I haven't been taking this into account in the slightest.  So it looks like if I'm ever going to position a sprite on that box, I'll have to run a transformation matrix into the spritebatch.  Makes sense, but man, from a beginner perspective, there's a lot to learn here.  Lets end with another Haiku:

Farseer three point oh,

Kicking my ass to Sunday,

"Far" from getting it.

 

 

 

Developer
Apr 9, 2010 at 2:58 AM

Ok, it seems most of your questions are graphics related.

1. Projection - this is the method the computer uses to show you 3D data on a 2D screen.

  • Orthographic projection - basically this type of projection simply ignores the Z of all the vertices projected with it. This is used in 2D games most often.
  • Perspective projection - this type of projection divides the X and Y components of the vertices by the Z component. It is most often used in 3D games.

2. Using custom projections with SpriteBatch.

  • This can be tricky as SpriteBatch only accepts a View transformation matrix.
  • In XNA 4.0 this seems to be super easy, but I will get back to you on that.

3. Scaling the physics world.

  • This is actually somewhat counter-intuitive for all but the inexperienced eye.
  • It is much easier to use an orthographic projection then to scale manually.
  • Remember - the physics engine wants stuff in Meters, the graphics card could care less. So keeping all your units at the same scale pays off when debugging and porting.

4. Why is SpriteBatch rotation opposite.

  • Because it uses an offset orthographic projection set to the size of the game window. (I can explain in detail if you need)

5. Easiest way to fix all these problems.

  • Don't use SpriteBatch when using XNA 3.1 (I think it will be fine with 4.0).
  • Instead draw textured Quads.
  • Wait for my new Sample Framework.

I hope some of this helps. I didn't want to go into to much detail as this is a physics engine forum not a graphics forum, but please still feel free to ask any questions you have. What I would recommend is to read a book on 3D programming basics. This should help you understand what all the different Matrix's do and how to leverage them to your benefit.

Thank you for being to detailed in you questions, that really helps me understand where new users will have difficulty switching to the new engine/framework.

Apr 9, 2010 at 8:21 PM

@ Matt:  Thank you for the detailed response.  I'm going to begin my adventure into textured Quads today.  Like others, I'm eagerly awaiting the new sample framework.  I'm very appreciative of the hard work you guys are doing.  So thanks again!

Apr 19, 2010 at 10:53 AM

I'm trying to compile the FP3 under tartoise automatic SVN, but i have big problems : i get some heavy error and, despite all the samples i have read about, i only see a Demo1 wich won't compile because of some _rectangleBody not defined and some non existing PhysicWorld.Add() ...

Am I doing something wrong or the project is still under heavy changes? I read many enthusiastic comments so i wanted to check that out

Apr 19, 2010 at 3:36 PM

Remove the simlesamplesxna project.

Apr 19, 2010 at 5:43 PM
Edited Apr 19, 2010 at 5:53 PM

As we can consider this the "official" farseer 3.0 porting thread (nice haikus), I will add my questions here :)

How can I disable fixtures? I need to enable and disable a fixture depending on my character's state (crouch or standed).

Also, if someone can give an example of drawing the game world using spritebatch that be combined with the debug view, would be much appreciated :S

Developer
Apr 19, 2010 at 10:03 PM
Eversor: The SimpleSampleXNA project is undergoing heavy changes. Simply delete it and everything else should work. Pnikosis: You shouldn't need to disable/enable fixtures. Just remove and add them. Remember to cache the fixtures so no garbage collection occurs. Drawing with SpriteBatch in an orthographic view port is a bitch in XNA 3.1. The code looks terrible. I have been trying to solve this for some time now, but I may give up soon. I had written a replacement for SpriteBatch called QuadRenderer. All SpriteBatch does is render quads. Only problem is it doesn't like anything other then pixel based scales. My class QuadRenderer was around twice as fast as SpriteBatch and supported frame based animation but was to complex for the samples (it had like 4 methods, but you could just skip the frame based animation stuff and then it only had 2). I have lost a lot of my time and desire to complete the samples. The testbed project is complete and shows everything needed, the old fancy white blocks may never return.
Apr 20, 2010 at 7:28 AM

Thanks Matt for the answer! I though that removing and adding fixtures in the world would affect the performance, my mistake.

About the SpriteBatch and your QuadRenderer method solution... Awwww... :( I'd love to help on this one, but I really suck specially in graphics programming :/

Apr 20, 2010 at 10:03 AM

I made a class to achieve a similar thing to QuadRender for my 2.5D XNA game based on Farseer 2.1.x (Square Off). I've posted it here in case it will help anyone. Use at your own risk! The code is a bit convoluted and lacks a few features that I never got around to adding. Features it does have though:

  • Batches your geometries, optionally transforming them individually with matrices
  • It's not really a quad renderer as it just takes arrays of VertexPositionTextureColor and batches them.
  • Splits batches by texture, minimising draw calls to effectively 1 per texture (unless you have really large batches)
  • Supports triangle lists and triangle strips (handy for drawing smooth paths)

 

Apr 20, 2010 at 5:00 PM

The problem I have, is that I'm using other effects that use the spritebatch (particles, and other effects), so I'm not sure how to integrate all of this :S

Developer
Apr 20, 2010 at 11:11 PM

Pnikosis:

You should be able to use Roonda's code (very much like my QuadRender class, but no frame based animation support) and simply replace all your SpriteBatch calls with his RenderBatch. The main difference is that your quad will no longer be automatically created for you. I might get some time this weekend to write some code to help you out that is a little simpler then Roonda's.

Apr 21, 2010 at 7:27 AM

Thanks Matt (and thanks Roonda) :)