schteppe / p2.js

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

Most efficient body-to-world-only collision configuration? #211

Closed Scharnvirk closed 8 years ago

Scharnvirk commented 8 years ago

Hello,

I apologize if this is not the right place to ask questions.

Anyway... what would be the most efficient (fastest?) implementation of a physics system which has a class of objects which interact only with the world (walls only, top-view style) and nothing else, but also has some more complex objects?

I need thousands of them. For now I have this config: this.gravity = [0, 0]; this.islandSplit = false; this.applyDamping = false; this.applyGravity = false; this.applySpringForces = false; this.defaultContactMaterial.friction = 0;

Unfortunately, performance gain between this and "default" World object is minimal. Like, 1400 objects before FPS drop occurs to 1500 objects with all these options on. And I need many more objects.

For bodies, I use a circle with radius of 3 and walls are four boxes of 5x400 dimensions.

Changing collisionMasks/gropus doesn't seem to affect performance.

For now I am using full 60fps speed because I also need to combat lag, but surprisingly, reducing this to 30 does not add that much performance. Maybe from 1400 to 1800 at best, so it is not worth it.

I even tried disabling event emitting but its effect is also neglible.

What I try to achieve are simple tiny sparks, lots of them, but which don't go through walls. They should bounce, but if they just disappear it will be acceptable.

I was even wondering if I shouldn't do that calculations in the shader which renders them, but I will have very serious trouble with sending world config (walls positions and such). Plus my GLSL skills are at "draw-a-pixel" level for now ;)

If there is no other option, I can build second webworker dedicated only for these objects (and walls), but this will hamper performance as communication between workers and main thread is very costly - even with typed arrays.

Current "stress-test": http://epsilondynamics-wingmod.rhcloud.com/

Thanks in advance!

schteppe commented 8 years ago

Hi,

This is the only place to ask questions, so you're in the right place :)

I think that you should try to get a GLSL version running, if you want maximum performance. If you did everything in screen space, you wouldn't need to provide the scene geometry data to the shader. However, a GLSL version couldn't provide you with collision callbacks back to the CPU - but maybe that's OK...

This is a 3D version - everything running on the GPU: https://www.youtube.com/watch?v=rto0G05nzZo

A 2D version would be interesting to implement :)

If you go the p2.js way you should probably cut down on the number of particles. The CPU can only handle so much. And then I would implement a custom Broadphase that would which bodies are walls and particles. This could probably speed up the p2.js broadphase quite a bit.

Scharnvirk commented 8 years ago

Yeah, I am sure that GPU is the best way to go, but unfortunately it would take ages for me. JS with webworkers, promises and asynchronousness is ultra-easy compared to GLSL stuff :)

What I was thinking was somehow reducing amount of things p2 has to calculate. In fact, what I'd need for one class of particles, would be just checking if they overlap some rectangles... hm.

I did not think of it before, but in this case, naive one-phase collision detection might actually be the fastest way. I'll check it.