Slick Forums

Discuss the Slick 2D Library
It is currently Thu Aug 16, 2018 4:44 am

All times are UTC




Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: Sat Oct 04, 2008 4:04 am 
Offline

Joined: Sat Oct 04, 2008 3:58 am
Posts: 99
I'm using phys2d in a platformer (modeled after the platformer demo, thanks btw), but the overhead of phys2d is crazy. The game become unplayable (1 frame per ~30 seconds) at around 30 objects. It's a bit concerning to see my framerates into the FramesPerMinute rating when running two quad core Xeons :shock:

Is there any way to reduce the overhead of the physics engine? I don't mind sacrificing the physics quality of some of my less interesting objects if I can make a solid impact on the CPU use. I can blindly replace a bunch of objects with statics if it comes down to it, but I can't really do that for enemies and 30's a pretty tight cap for what I had in mind :twisted:


Top
 Profile  
 
 Post subject:
PostPosted: Sat Oct 04, 2008 10:30 am 
Offline
Site Admin
User avatar

Joined: Thu Jan 01, 1970 12:00 am
Posts: 3143
Options for optimizing are pretty limited. You can change the way the collision space is resolved using a CollisionStrategy. You can bring down the overhead per frame by changing the number of steps or the steps size using the World constructor and/or the length of the step passed into World.step().

However, given the hardware you're running on I can't believe it's either of those things causeing the problem. Could you post a figurative example of what you're doing (i.e. the game loop? and what FPS you were running at without phys2d step())

It'd also be interesting to know how many bodies are actually colliding at any given moment and what shapes they're using.

Probably the best option is to move to JBox2D however, they're focus was very much keeping the garbage to a minimum and it scales pretty well to those cases.

Kev

PS. Anyone interested in help me bring a Phys2D like API over the top of JBox2D? Maybe this would give us the best of both worlds.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Oct 04, 2008 3:40 pm 
Offline

Joined: Sat Oct 04, 2008 3:58 am
Posts: 99
It's pretty simple right now.

Collision Listener
Code:
world.addListener(new CollisionListener() {
         public void collisionOccured(CollisionEvent event)
         {
            Entity a, b;
            a = ((Entity)event.getBodyA().getUserData());
            b = ((Entity)event.getBodyB().getUserData());
            
            if(a != null && b != null) // Entity collision
            {
               a.touched(b);
               b.touched(a);
            }
            else // Collided with something else, probably the environment
            {
               if(a != null)
                  a.touched();
               else
                  if(b != null)
                     b.touched();
            }
         }
      });

Environment logic loop
Code:
   public void update(int delta) {
      boolean first = true;
      
      totalDelta += delta;
      while (totalDelta > stepSize) {
         world.step(stepSize * 0.01f);
         totalDelta -= stepSize;

         if (first) {
            first = false;
            for (int i=0;i<entities.size();i++) {
               entities.get(i).preUpdate(delta);
            }
         }
         
         for (int i=0;i<entities.size();i++) {
            Entity e = entities.get(i);
            if(e.isDestroyed())
            {
               if(e.getBody() != null)
                  world.remove(e.getBody());
               entities.remove(i);
            } else
               e.update(stepSize);
         }
      }

Beyond that, there aren't any really interesting changes. Just a bunch of rather vanilla classes to flesh out objects, and a modified map reader to read maps generated by TileStudio (as well as place entities into the map based on this data). My test entities are all based off AbstractEntity, do I'm not even using anything expensive like onGroundImpl()

What seems to kill it is stacking bodies (such as crates). They don't seem to rest if they're touching other bodies, which means the physics engine is constantly chugging away trying to calculate things that really don't need to be done. All of my entities are 32x32 boxes (to match the 32x32 tile map)

FPS with step() is < 1, to the point where the game pretty much hangs after the fourth frame. Core CPU use is 100%

FPS without step is a solid 60. Core CPU use ~13%

I've tried removing my collisionlistener and it doesn't really affect performance in any positive way. I've also made sure all of my bodies canRest().
The only thing that relieves the CPU use is converting everything to statics.

I can get core CPU use down to around 50 at a step size of 50, but its not viable.


Last edited by FireSlash on Sat Oct 04, 2008 6:54 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Sat Oct 04, 2008 6:43 pm 
Offline

Joined: Sat Oct 04, 2008 3:58 am
Posts: 99
I went ahead and write a quick check to swap out my statics with regular bodies when they're hit, but I can't seem to tweak the velocity right for the intial collision. It's either so little it doesn't register, or so much the objects are nearly shot through walls regardless of what they're hit with.

Code:
// Recreate static bodies into normal ones
            if(event.getBodyA().isStatic() && (a != null))
            {
               Body stat = event.getBodyA();
               Body nonStatic = new Body((DynamicShape)stat.getShape(), a.getMass());
               nonStatic.setPosition(stat.getPosition().getX(), stat.getPosition().getY());
               
               Vector2f vec = new Vector2f(stat.getVelocity());
               vec.scale(-1);
               nonStatic.adjustVelocity(vec);
               nonStatic.adjustVelocity((Vector2f) stat.getPosition());
               
               world.remove(a.getBody());
               world.add(nonStatic);
               a.setBody(nonStatic);
               nonStatic.collided(event.getBodyB());
            }
            if(event.getBodyB().isStatic() && (b != null))
            {
               Body stat = event.getBodyB();
               Body nonStatic = new Body((DynamicShape)stat.getShape(), b.getMass());
               nonStatic.setPosition(stat.getPosition().getX(), stat.getPosition().getY());
               
               Vector2f vec = new Vector2f(stat.getVelocity());
               vec.scale(-1);
               nonStatic.adjustVelocity(vec);
               nonStatic.adjustVelocity((Vector2f) stat.getPosition());
               
               world.remove(b.getBody());
               world.add(nonStatic);
               b.setBody(nonStatic);
               nonStatic.collided(event.getBodyA());
            }

If I can get this working, between that, a quick disable check, and some other tweaks, I think I can make this usable. JBox2D might be faster, but I'd rather avoid re-writing all of the classes I've written thus far :?


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 05, 2008 2:02 am 
Offline

Joined: Sat Oct 04, 2008 3:58 am
Posts: 99
Moved to jbox2d. For anyone looking to do the same with the platformer example, you'll need to check out the SVN copy for the Polygon class that can convert concave objects (such as the world static bodies) into a series of convex ones.

The version in their current release is broken

Things to consider before switching:
  • phys2d seems to be more accurate as far as keeping bodies solid. JBox has a weird quirk where bodies can 'sink' into each other if a route above it isn't readily available, such as a stack of boxes.
  • phys2d's API is a lot easier to use, and the naming is more logical (Ignoring the affected/effected typo :wink: ). jbox2d has a lot of 'gotcha's. Such as the polygon vertex ordering has to be CCW (Trust me. It HAS to be :shock:)
  • jbox2d is FAST :!:
  • phys2d seems to be somewhat more accurate. jbox2d's settling seems unnatural at times. I also saw more randomized results with jbox2d than what phys2d produced.
  • Both engines have their quirks.

In conclusion:
Phys2d - Easier to use, more accurate
jbox2d - Friggin fast.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Oct 05, 2008 6:56 am 
Offline
Site Admin
User avatar

Joined: Thu Jan 01, 1970 12:00 am
Posts: 3143
Thanks thats a really good overview of the two - thanks for posting back with it.

Kev


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group