Handeling ALOT of bodies, how?

Oct 9, 2008 at 11:13 AM
Edited Oct 9, 2008 at 11:14 AM
In my game, i have a "pod" digging in the ground for resources. These ground fields is 54x54 pixels. I need something like 30 x 1000 of them (width / height) to act as my underground.
The performance is good with 21 x 10. But more than that slows my game down. From standard of, all ground bodies are static and disabled. They are only enabled of my pod come very close.
How can i handle so many bodies with good performance? since the bodies are disabled, is it the drawing that slows it down or the physics simulator?

I need to scroll down as the pod comes deeper into the underground, so maybe i could add/remove bodies all the time, but is that okay with so many?
Coordinator
Oct 9, 2008 at 11:32 AM
The physics simulator does not calculate anything on bodies and geoms that are disabled, so it should not be the physicssimulator that is the hotspot. You could use a profiler to see where your hotspots are.
Oct 9, 2008 at 12:23 PM
Hmm

When im adding 21 x 50 it performs with 100 fps, but with 21 x 55 it runs on 2 fps even if i don't draw any underground fields
Coordinator
Oct 9, 2008 at 12:39 PM
If you send me your project I can check it for you. I would like to know if it's the physics engine that causes this slowdown. There might be a bug somewhere.
Oct 9, 2008 at 1:08 PM
I have sent my project to you with codeplex contact system. Thx for your help
Oct 9, 2008 at 1:09 PM
whoops, uncomment the:

//pod.UpdateInvironment(undergroundFields);

under updatte :)

Coordinator
Oct 9, 2008 at 1:28 PM
Thanks Arextion. I will take a look later today if that's okay with you.
Oct 9, 2008 at 1:31 PM
No problem, thank you
Coordinator
Oct 9, 2008 at 9:35 PM

There is no problem on my computer. I have it steady at 100 fps all the time. This might also be because I have very powerful computer.

Anyways, it should not be the physics simulator that is the problem, one potential problem might be this code:

 

foreach (UGField field in undergroundFields)
{
if (AABB.Intersect(geom.AABB, field.Geom.AABB))
{
field.Body.Enabled =
true;
if (!intersectList.Contains(field))
intersectList.Add(field);
if (field.Rect.Top >= this.Rect.Bottom && ((this.Rect.Left > field.Rect.Left && this.Rect.Left < field.Rect.Right) || (this.Rect.Right < field.Rect.Right && this.Rect.Right > field.Rect.Left)))
{
if (!surfaceFields.Contains(field))
surfaceFields.Add(field);
}
}
else
{
field.Body.Enabled =
false;
if (intersectList.Contains(field))
intersectList.Remove(field);
if (surfaceFields.Contains(field))
surfaceFields.Remove(field);
}
}

Iterating all the underground fields (there is a lot) and testing intersection could be a slow operation on some computers. You might want to find a better way.

I'm just thinking here, but creating a grid might be the best way. I've drawn a picture to illustrate it. It's not very good (i'm lazy, hehe) but it illustrates the point. Motherload Grid

The grid cell size should be the size of the underground fields and a cell should contain 15-25 boxes in each. You can then calculate the current grid cell that the pod is in and activate all bodies/geoms that are in the same cell.

If we want to calcuate the current grid cell that contains the pod, we would do this:

gridCellSize = new Vector2(100,100);
podPosition = new Vector2(1249,1882);

//12.49 rounded to 12
int curPositionX = podPosition.X / cellSize.X;

//18.82 rounded to 18
int curPositionY = podPosition.Y / cellSize.Y;

so the pod would be in X=12 and Y=18 grid cell. Just activate all geoms/bodies in that grid.
I have not tested this, but it seem like it could work.

Oct 10, 2008 at 6:10 AM
How many UG fields did you test with?

For some reason, farseer uses 100% CPU on my PC all the time just when the game starts, even the demos that came with the source code.
Oct 10, 2008 at 8:14 AM
And only when the window is active
Coordinator
Oct 10, 2008 at 10:19 AM
I've just testet it on my laptop. I also get 100fps there.

I tried timing you update method and it's very fast. If I mesure it in miliseconds, it does not even register it.

The CPU is at 50% here (have dual core in laptop, so that's 100% on one core). It should only go to 100% cpu when the game window is active as I see that you have based your demo on the Farseer samples. The Update method only runs when IsActive equals true.
Oct 10, 2008 at 10:25 AM
Okay, how many underground fields did you play with?

One stupid question. How, with this code, can i scroll the camera view down. Ive looked into Matrix/viewMatrix and so on and get figure out how to do it. How can i pan down and sideways in my world?
Coordinator
Oct 10, 2008 at 1:18 PM
I played with the default amount that you defined :) I was in school before, so I only tried the game to see if there was any problems, and since you had a small amount of boxes, I could not find any problems.

I tried setting the boxes to 100x100, it took about 1 minute to load the level and it created 10002 boxes. And you are right, there is a big performance slowdown from Farseer's broad phase collider since it does some checking before doing the real work, and that checking does not take disabled geometries into account. Try switching to SweepAndPruneCollider:

in the LoadContent method:

physicsSimulator.SetBroadPhaseCollider(new SweepAndPruneCollider(physicsSimulator));

This should speed up the game a whole lot since it does a smaller amount of checking, it still lags with 10,000 geoms, but it works with 5,000 which SelectiveSweep (The default broad phase collider) does not.

I will write it down and have a look at the broad phase colliders later. Thanks for pointing this out.

I'm sorry that I can't answer your second question, I have not yet made a game that used the view matrix. I guess that view matrix only offset's the drawing positions of the textures. I've used a class called Camera2D a really long time ago, I got it from an article about side scroller games. Try searching on google.
Oct 10, 2008 at 4:53 PM
Okay, haven't tried this game on a good computer. I will try the SetBroadPhaseCollider.$0$0$0$0I thought maybe i could add just the amount of fields that are visible on the screen, and then add/remove them from the simulator as the pod flyies around. Sounds okay or totallt crazy?$0
Developer
Oct 10, 2008 at 6:18 PM
@Arextion - You might create a list big enough to hold all visible fields (geoms). If your gonna be running on the 360 you want to pool objects as much as possible. I.E. - don't create and destroy a whole bunch every frame. You should search for some standard 2D tile scrolling tutorials. I can go into a lot more detail if you need but I know there is some good tutorials out there. What you really need is your broad phase occlusion step. This will be pretty specific to your game, but not hard to implement.
Oct 10, 2008 at 8:57 PM
Here's what genbox, might have been talking about, the tutorial on ziggyware with a 2D Camera.
http://www.ziggyware.com/readarticle.php?article_id=172
Oct 10, 2008 at 9:24 PM
Hmm whats with the $0$0$0??? :D$0$0SomethingNew, yeah ive already tried that, but i couldn't get it to work with the sample demos :/