schteppe / p2.js

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

Chain stability (Constraints demo) #268

Open kroko opened 7 years ago

kroko commented 7 years ago

Hi,

In the Constraints demo and Island Solver the ball chain gets very unstable on stretching, even at ~1.8x resting chain length. Is there a way and if yes, how to counter that?

Thanks!


Offt: I started doing project using Matter.js and on last step before it's done discovered unexpected behaviour, that really puts all the work done into trash. So I have to look for and rewrite everything using different engine (don't have time to try to learn the reasons and fix Matter, and if i did, maybe my unexpected is that's the way it is from maintainers standpoint, dunno yet), real schade. p2 looks most promising, but I do have "chain" in the project, that user will be able to stretch extremely, thus this question.

schteppe commented 7 years ago

Hi, how about using a small maxForce on the DistanceConstraint? You could also use less stiffness. Experiment with those parameters and you should be fine:)

kroko commented 7 years ago

May I ask yet another question? :) Is there a way to turn buoyancy off. It seems there is no built in way to get that any dynamic object dos not sink in static surfaces when user drags, even with ContactMaterial (haven't gone through ContactEquation though). As example - in all demos with mouse interactivity it is possible to drag dynamic bodies into static ones. Sure there could be manual checking and repositioning on each loop (for all dynamic bodies -> for all static bodies -> get dynamic body AABB, get static body AABB (AABB can be done only on simple shapes), calculate if they overlap, if yes, calculate correction vector and manually move -> loop multiple times, because correction for one static body might have pushed dynamic body into another static body near by), but this is a no go for scenes with multiple static and dynamic bodies scattered around. buoyancy is fun!, just, IMHO one expects shapes to impenetrable by default from a physengine, sinking in is extra, unless the engine has specific style/artistic take on physics :)

schteppe commented 7 years ago

Of course :) Yes, just make the dragging force smaller. If you use a DistanceConstraint, then you can again use the .setMaxForce(maxForce) method. If the contact force from the static surface is a couple of times larger than the mouse drag force, then you should be good.

kroko commented 7 years ago

1) I might have understood your answer if I would manage mouse events manually (on mousedown doing manual hittest for all bodies and if hit, then adding constraint to the body; on mousemove moving the constraint, on mouseup removing the constraint). Ok, tried using RevoluteConstraint where i can set maxForce for mouse ev. However I cannot get to the point, where I can grab something, move it so that object follows absolutely and instantly where the mouse is (meaning considerable max force), meanwhile not be able not to sink-drag into objects. But probably this is more about my inability to understand yet how the lib works from the examples.

2) DistanceConstraint is too much manual labor (well, if all shapes in the world, both static and dynamic would be circles then maaaaybe). :)

3) I cannot find a way to do it automatically (that is, without managing mouse manually as in 1st point). Imho ContactMaterial and its props will not help here, would it? http://jsbin.com/japomuj/2/edit?js,output

schteppe commented 7 years ago
  1. Yes, this is how the mouse constraint works in the p2 demos. Unfortunately there's no way to get a "follows absolutely and instantly" constraint. You could use a 2x smaller time step and it would become 2x better, but the performance would be 2x worse as well. This is just how constraints work, they are not "instant". The box2d manual says: "Many users have tried to adapt the mouse joint for game play. Users often want to achieve precise positioning and instantaneous response. The mouse joint doesn’t work very well in that context. You may wish to consider using kinematic bodies instead.". This means that you should implement your own "constraint", which handles all movement and collisions when dragging using the mouse. It's a bit of work, but it would enable "instant dragging". This library may be useful (see demo).
  2. Too much manual labour? Anyway, a revolute should be good :)
  3. Not sure what you mean here... Automatically? Automatically as in using the built in stuff in the p2.Renderer ?
kroko commented 7 years ago

1) By instant I don't mean instantly instant, inertia is still there of course. :) But for it to be reasonably instant the maxForce has to be considerably high to move the body due its own inertia as well as Fg. And having this maxForce to be so big that the system is reasonably instant introduces again that i can push dynamic bodies that I interact with into static bodies, thing that I want to avoid and that the question is about.

2) By DistanceConstraint I thought you are suggesting to manually add distance constraints to all bodies within the system. Did I misunderstood you? If no, n bodies mean n(n-1)/2 constraints in general situation, or if there are a dynamic and b static bodies and i do only for dynamic-static pairs, then there are a*b constraints that needs to be managed. A lot in a decent physics universe. :) Distance constraints have to be recalculated on each step, bodies are not circles where only radius matters (no body rotation). Think of needing to calculate quadrilateral touching ground plane in arbitrary angle, I need to calculate distance constraint on every step taking account body geometry and angle and setting distance constraint accordingly, plus it might be hitting multiple static bodies at the same time... what about complex convex/concave shapes or combinatory shapes.

3) By automatically I mean 'by not managing mouse, hittests etc myself', can I manage automatically the situation where user is not able to drag bodies into static. As in jsbin example - I do not manage mouse constraint myself there (as in 1st point), but I am able to grab and move stuff around due to built in mouse interaction (but dynamic bodies sink into static ones, that I'd like to avoid).

schteppe commented 7 years ago

Ok, then I understand :) Did you try using less gravity (or even turning off gravity for the body when mousedragging)? That may give you some more parameter tweaking space.

I see now that the Renderer code makes it difficult to tweak the maxForce for its mouse constraint, I should fix this...

Yes, sorry. I meant using a DistanceConstraint for constraining the bodies to the mouse, instead of using a RevoluteConstraint. But you could use either, it doesn't really matter I think.