Infinite loop when applying a force to a rested body?

Jan 2, 2011 at 7:24 AM
Edited Jan 2, 2011 at 9:02 AM

When I add a force either through AddForce or AddLinearImpulse to a body that isn't moving there's a good chance farseer will get stuck looping here:

 

for (;;)
                    {
                        // Use a mix of the secant rule and bisection.
                        float t;
                        if ((rootIterCount & 1) != 0)
                        {
                            // Secant rule to improve convergence.
                            t = a1 + (target - s1) * (a2 - a1) / (s2 - s1);
                        }
                        else
                        {
                            // Bisection to guarantee progress.
                            t = 0.5f * (a1 + a2);
                        }

                        float s = fcn.Evaluate(indexA, indexB, t);

                        if (Math.Abs(s - target) < tolerance)
                        {
                            // t2 holds a tentative value for t1
                            t2 = t;
                            break;
                        }

                        // Ensure we continue to bracket the root.
                        if (s > target)
                        {
                            a1 = t;
                            s1 = s;
                        }
                        else
                        {
                            a2 = t;
                            s2 = s;
                        }

                        ++rootIterCount;
                        ++TOIRootIters;

                        if (rootIterCount == 50)
                        {
                            break;
                        }
                    }

Any ideas why?

I just verified this also happens with setting linear velocities as well. The loop isn't infinite so much so it takes a very long time to complete and doesn't produce desirable results, it's almost guaranteed to happen if I try this on all the actors at once, like so:

for (int i = 0; i < world.Actors.Count; i++)
            {
                Vector2 dir = Vector2.One;
                dir.Normalize();

                if (world.Actors[i].BodyState == JabActor.BodyType.DYNAMIC)
                {
                    world.Actors[i].LinearVelocity += (dir);
                }
            }

Coordinator
Jan 2, 2011 at 12:52 PM

It should not get stuck as the rootIterCount == 50 line will prevent the loop from running more than 50 times.

Are you scaling your world to the MKS unit system?

Jan 2, 2011 at 3:14 PM
Genbox wrote:

It should not get stuck as the rootIterCount == 50 line will prevent the loop from running more than 50 times.

Are you scaling your world to the MKS unit system?

You're almost definitely right on the loop, it's just that everytime I break it stops in that loop.

Every 100 pixels in the screen (at 1:1 scale) is '1 unit' in Farseer, if that's correct?

Coordinator
Jan 2, 2011 at 3:19 PM

The problem might be somewhere else then. The TOI loop might just be the place it uses the most time. Would it be possible for you to send me the project? I've seen this problem once before while working with Box2D and it was due to an object being added to the world multiple times. I would have to take a look at the stack trace to figure out where the problem comes from.

Jan 2, 2011 at 3:39 PM

Yeah that wouldn't be a problem, where should I send it?

Coordinator
Jan 2, 2011 at 3:50 PM
Click on my username and click contact. I will reply with my email.
>
Jan 2, 2011 at 4:40 PM

Oh cool, I just send you a message with a link to download the source files.

Coordinator
Jan 6, 2011 at 11:06 PM

This has been resolved and was due to a NaN float being applied as force on bodies.