schteppe / p2.js

JavaScript 2D physics library
Other
2.64k stars 330 forks source link

GridBroadphase? #199

Closed Scharnvirk closed 8 years ago

Scharnvirk commented 8 years ago

Hello,

Sorry if this is a stupid question, but I can't find the GridBroadphase class anywhere. People reference it here and there, for example: http://paulsalaets.com/posts/selecting-broadphase-p2/

Was it removed?

Anyway, I am writing a simple top-down game using threejs as a renderer, but physics will be entirely in 2D. I'd like to have two things:

P2 works perfectly for second, but struggles with first, and I thought GridBroadphase could help.

In my test setup I have 1000 objects, each with a P2 Body attached, and each body has a basic box shape. World has only gravity enabled and everything else is default; the world being updated 60 times per second.

Unfortunately, FPS is less than 10 and chrome's profiler is brutal at pointing at the issue: 7800.7 ms | 92.49 % 7805.8 ms | 92.55 % p2.min.js:24 | d.getCollisionPairs

The broadphase object's "result" array has over million elements, much like it was thinking that everything was colliding with everything. Unfortunately my browser crashes when I try to peek at this array :D

What can I do to tune P2 for large amount of objects?

Before I had my own collision detection and its broadphase did manage 60fps on that setup, but it had freezes from time to time which made me go and seek a proper 2d engine :)

P2 version I am using is the one at current master branch, browser is Chrome 47.0.2526.106 m, OS - Windows 7, CPU - i5 2400, GPU - Radeon 6950 HD 2GB.

Scharnvirk commented 8 years ago

SSSSIIIIiiiiiigh.

Sorry guys.

I forgot to initialize box shape for the body. For bodies with shapes performance gets up to 60 FPS as soon as objects unclutter a bit.

Can be closed, I guess.

Altough I'd still like to try the GridBroadphase if possible :)

psalaets commented 8 years ago

hmm looks like it was removed in version 0.7.0, see schteppe/p2.js@e90c67263d685015e374cb706f5c12b5cbfa74df

You could grab it from here and give it a try. You'll need to tweak the require() calls at the top to drop it into your project.

Scharnvirk commented 8 years ago

Thanks. Though the comment on the commit makes me believe this is not worth it ;)

schteppe commented 8 years ago

Some ideas:

I removed the grid broadphase because it was buggy and I already had enough things to do.. And the SAPBroadphase has been fast enough for most applications this far :)

Scharnvirk commented 8 years ago

Thanks.

I've already noticed the interpolation. Works very nicely, and I was quite surprised it works so nicely without any sort of additional work :)

http://epsilondynamics-wingmod.rhcloud.com/ That's what I already have so far. And I know the code is messy, I am also trying to learn ES6 (which goes through babel later on) and also got quite confused by all that "to class or not to class" debate.

Unfortunately, while on Chrome this example runs pretty much flawlessly for me, on firefox it struggles, even after bodies get out of the "clogged phase".

Anyway, next step will be a web worker, which, well, requires a total rewrite of everything. On the other hand, did anyone attempt using a webworker for p2? Will it speed things up? After all, whatever the implementation, I will have to send a huge array of data 60 or 30 times per second... and I am totally bent on projectiles affecting projectiles :D

schteppe commented 8 years ago

I get about 26 fps in firefox nightly :)

You should try disable island splitting, seems like it eats a bit of performance. When creating the world, pass islandSplit: false

There's also a lot of convex intersection going on. Consider using circles instead? And if you don't need friction, consider turning it off: world.defaultContactMaterial.friction = 0;

There's been a few worker implementations. The most serious one must be this.

jtenner commented 8 years ago

Yeah the worker implementation I created requires the use of a declarative (immutable view layer) web worker. It's really tough to implement and you have to learn a new view syntax. I'm sure it can be reduced to regular canvas 2d operations but it requires knowledge of the data and you have to make lots of assumptions.

Thanks for the mention @schteppe .

Scharnvirk commented 8 years ago

Thanks for help. Apparently just switching to spheres from boxes helps to keep firefox'es framerate to 60FPS with just some hiccups.

While I like the effect of changing angle on hit when using box shape, I don't really plan to have 1000 of box-shaped objects which can collide with each other. Bullets will be circles (at least for the game logic), and in worst case scenario I'll also disable collisions between enemy ships (or bots or whatever will it be ;p).

Interactions between bullets will be limited - enemies will have their own bullet group, player(s) - their own and bullets in one group won't collide with each other. But for now I want to prepare for the worst ;)

Disabling friction and island splitting while keeping box-shaped objects also results with more-or-less-smooth 60FPS on FF in my case.. With the usual FF-induced hiccups I also see in other webGL games.

@jtenner: my idea for worker implementation was actually not moiving phsics thread out of the game, but moving everything but the renderer. This will be useful also for multiplayer, if I happen to want one later on too ;)

Ideally the renderer will get position and velocity vectors for each "key object" along with angle and some ID, and its sole job will be, well, rendering. There will be also some purey aesthetic objects but their position will be independent of the game logic. Trails behind bullets, lights on map, things like that.

Unfortunately this requires me to rewrite everything. Fortunately, the poor thing needs it anyway :)

Big thanks again!

jtenner commented 8 years ago

@Scharnvirk I see! That's precisely what I did. I moved everything I could into the web worker by having multiple class definitions work in parallel with each other on seperate threads. The idea was that some browsers might not support Workers, so the developer codes for both scenarios (worker + no-worker) and yields a functional game no matter where it runs.

Since my view layer is declarative (tree-like should sound familiar), I can store drawing operations in an array. Since my view layer can be stored, I only have to ship physics deltas to the browser which calls the corresponding render function to create the view-tree. Note: this doesn't need to be deltas from p2 bodies, it can be from any data source.

It's very react-like, but it's not scaling yet.

Email me if you want details or are interested.

Good luck with your game!

Scharnvirk commented 8 years ago

@jtenner - thanks! I'll try implementing a basic webworker based logic/physics thread on my own and if I fail I'll ask you for help :)

@schteppe: I think this issue can be closed. I understand that the Grid broadphase was buggy and the SAP one works well enough, which I agree with. I got all the information I need and the original issue proved to be inexistent. Thanks!