Closed GoogleCodeExporter closed 8 years ago
Here's a picture of the behavior
Original comment by bfo...@gmail.com
on 31 May 2013 at 11:26
Attachments:
The revolute limits are not meant to act like springs. If you apply large
forces to violate the limits then the solver can get stuck. Can you change your
simulation so the pole doesn't get distorted? If you want the pole to bend,
please use b2WeldJoint.
Original comment by erinca...@gmail.com
on 28 Oct 2013 at 5:52
I have springs that need to be incompressible though (think of a flexible pole
rather than an actual spring) so the weld joints aren't appropriate, and anyway
they are way too weak if the pole needs to support anything, even with a
ridiculous number of simulation steps.
I guess another joint type is needed.
If you're interested to see the use case, I have a video of the game at
http://vimeo.com/m/76771268
Original comment by bfo...@gmail.com
on 31 Oct 2013 at 12:40
Thanks, I watched the video. Looks awesome.
I'm guessing you are using many segments for a single pole.
I recommend using two segments and a single weld joint. Use quadratic
interpolation for the rendered pole. This should be quite stiff and still
produce nice curves.
The problem with the issue you filed is that I removed a hack and you want me
to add the hack back because it helped in a situation where the model isn't
stable. Lets see if we can get the model stable first.
Original comment by erinca...@gmail.com
on 31 Oct 2013 at 5:24
I already do some quadratic interpolation to keep the number of segments low,
but I can't bring it down to a single weld joint. It's a nice idea, but there
are lots of small reasons that this is not a workable approximation:
- people would notice that the collisions were not matching the pole (I promise
you, in a competitive sporting game they would be bothered by it, too)
- the pole would not allow players to 'vault' in the same way because it would
not get enough friction to launch until the entire end segment was laying flat
on the ground. Even with the friction set very high, box2D bodies do not
generate enough resistive force when sliding if there is only one point of
contact.
- players need to be able to run along each other's poles, even when they're
bent. The angle discontinuity in your suggested solution would create an
impassable barrier halfway along the pole, much of the time.
- I suspect, but am not sure, that the spring force of a single joint would
never be high enough to simulate actual pole vaulting. I suspect that when a
real pole springs back after being bent, we're seeing a superposition of force
from a large number of 'springs', which would not have the same linear force
relationship as your single spring. (But it is a long time since I got my
physics degree and that could be wrong)
To be honest, I'm not expecting you to revert the change in the code (for the
reasons you gave), and I'm also not expecting you to add a new constraint
overnight. But I think this case probably does indicate the need for a new
joint type. There will be many cases where people need joints that are
incompressible in terms of distance but stiff and flexible in terms of angle
(diving boards, thin swords, skyscrapers, etc etc) and at present we just don't
see any of these objects simulated using physics in any game, anywhere. We
can't just insist that every game fakes it with two bodies and one weld joint.
Anyway... my game works ok with the old hacked Box2D code. I don't have some
nice benefits like CCD and I did have to port over some bugfixes you applied in
later releases, but that's ok. So I'm not so much worried about this game, but
about games that myself and others will make in the future.
FWIW, I had good success with an earlier Flash prototype of this game, which
used NAPE. In that engine, you can apply a rotational constraint that doesn't
affect position, and combine it with a distance constraint (that doesn't affect
rotation). Since they are more or less orthogonal in terms of their influence
on the bodies, they don't conflict and explode. I guess I've come to see the
Box2D Revolute Joint as a higher-order constraint, and the engine is missing
the lower-order one. Call it an AngleJoint or something. The Revolute Joint is
more intuitive for beginners but there aren't many upsides for experienced guys.
Original comment by bfo...@gmail.com
on 31 Oct 2013 at 1:14
Oh, I'll also add another piece of evidence: complex self-supporting ragdolls.
I made the game CLOP (http://www.foddy.net/CLOP.html) at first using Box2D, but
then I had to abandon it and use NAPE. The horse ragdoll has enough joints that
I just couldn't get the simulation stable in Box2D. In NAPE, each joint has one
of those angle and distance constraint pairs... this way, the muscles of the
horse do not contribute to instability in the position of the body parts.
(And - I did watch the 'how do I stop my constraints exploding' session you ran
at GDC, and I'm pretty sure I wasn't just setting up or running the simulation
badly).
I hope you won't think 'well, go and use NAPE then'. Box2D is by far the more
popular and mature API, and it's on every platform and will soon be the backend
for nearly every indie game made in Unity. It's super important that it can
handle as many cases as possible.
Original comment by bfo...@gmail.com
on 31 Oct 2013 at 1:21
Good physics engine usage is just as important in games as the physics engine
itself. I recommend looking at my GDC2012 presentation on ragdolls.
https://code.google.com/p/box2d/downloads/list
If you are causing constraints to be highly violated then your model is not
suited to the quality/performance trade-off in use. You either have to increase
the solver iteration count or improve the model.
The weld joint is what you should be using. Setting the revolute limit to 0,0
is equivalent to a weld joint with 0 hertz, but less efficient. How many
segments are you using?
Did you see the walker demo in the testbed? This is quite stable. It's all in
the modeling. It would possible to create the horse with the right technique.
Look at all the stuff irresistible force has made: http://www.iforce2d.net/
Original comment by erinca...@gmail.com
on 3 Nov 2013 at 6:48
Hmm, ok. I tested it again - if I use a weld joint I can't ever seem to get it
stiff enough, even set to 0Hz, but at least it doesn't spazz out. Maybe I'll
make some tweaks to the correction code and see if I can replicate, if it will
be more efficient it's probably worth doing.
My model isn't anything crazy. It's just 12 rectangular polygons connected with
a single joint between each pair. I totally agree that good physics engine
usage is as important as the physics engine itself, but I honestly have tried
literally dozens of configurations for this game and I had very little success
so far doing things the 'right' way with weld joints.
Original comment by benn...@foddy.net
on 3 Nov 2013 at 8:46
Actually scratch that, the weld joint in 2.1.2 has the same 'handle large
detachment' code as the revolute joint, so my test doesn't prove anything. I
can't prove it in the short term, but when I was using 2.2.1 I found the weld
joints were even less stable than the revolute joints for this use case.
I'll go and try to implement the weld joints with 2.2 or 2.3 again but I'm not
at all optimistic that this is going to work.
Original comment by benn...@foddy.net
on 3 Nov 2013 at 8:50
Then maybe you want to look at the loads you place on the pole. Are they from
heavy bodies? You need to make sure the mass ratios aren't too high. The
ragdoll presentation would apply in that case.
From you forum post it looks like you have around 10 segments. Can you get away
with less?
Original comment by erinca...@gmail.com
on 3 Nov 2013 at 8:54
There is a heavy load on the end of the pole, I guess: the player. If the
player isn't heavy, he can't bend a flexible pole enough to vault with it, so
this is an 'inflexible' requirement of the design. I do understand that this is
one of the stated weaknesses in the engine though, listed right there in the
manual, so it's hardly a surprise if this generates problems. I guess my point
in starting this thread was just to say that my simulation works (with weld or
revolute joints) in 2.1.2 and it doesn't work with any revision after that.
I wound up using 12 segments. Experimenting with it just now, I found I can
increase the stiffness of the pole sufficiently to allow me to use Weld joints
if I go down to 10 segments. This is a pretty good win since I save CPU cycles
both by using Welds and by removing 2 segments. But I still suspect the model
will fail if I upgrade my Box2D above 2.1.2. I'll try it later and see.
Original comment by benn...@foddy.net
on 3 Nov 2013 at 9:29
So you made the guy heavy to distort the constraint that is supposed to be
rigid.
How about making the guy less heavy and then using a flexible weld joint (hertz
> 0)? For that pole I would use start with a hertz of around 10 and a damping
ratio of 0.2.
Original comment by erinca...@gmail.com
on 3 Nov 2013 at 10:01
Ok, part of the problem is that I'm not using the term 'rigid' the way you are.
I don't mean 'infinitely rigid' I am trying to produce a strong, but flexible
pole. The guy is heavy just like a real human being who uses his mass and
inertia to flex a pole. I used roughly realistic numbers for the density of the
various objects.
Sorry if this is frustrating from your end, I'm really not trying to be a pain.
In my earlier experiments, I found that in 2.2+ a flexible weld joint was way
too weak no matter what figures I used for the frequency and damping ratio. But
I'll make a fork with the upgraded engine and then come back with more data and
open a new issue if necessary (since this is not anything to do with the issue
I reported)
Regarding the original issue: I'm pretty sure that the post-2.2 behaviour of
the revolute joints is a problem for the engine, EVEN IF I follow your advice
and completely abandon them for the purposes of this game. They should not deal
with distortion by getting stuck in the distorted position, and then gradually
returning over the course of ten or more seconds. Or at least, I don't see the
upside of giving them this behaviour. It seems like it would generate a lot of
hard-to-debug simulations wherein a revolute joint somewhere was getting
'broken' but not in a visible or catastrophic way. If they're going to 'break'
to avoid constraint explosions, it would be better if they came properly back
to life when the constraining objects or forces were removed.
Original comment by benn...@foddy.net
on 3 Nov 2013 at 10:29
Please try all of the following with recent C++ code:
- lower the mass of the player body
- reduce the number of segments
- use a soft weld joint of with damping ratio of 0.5, hertz of 20.
- use a time step no bigger than 1/60
- use at least 20 velocity iterations
- make sure the pole is at least 2 units in length
- increase the thickness of the pole. You can do this without affecting
collision by using additional fixtures that have their collision filter set to
not collide. Make sure the mass is symmetric about the axis of the pole.
Original comment by erinca...@gmail.com
on 3 Nov 2013 at 10:45
Ok. It'll take me a little while though because of the changes to the codebase.
Original comment by benn...@foddy.net
on 4 Nov 2013 at 2:38
Closing. This is a tuning issue.
Original comment by erinca...@gmail.com
on 4 Apr 2014 at 4:22
Original issue reported on code.google.com by
bfo...@gmail.com
on 31 May 2013 at 11:13