Force/Impulse timebase

chunky
Posts: 145
Joined: Tue Oct 30, 2007 9:23 pm

Re: Force/Impulse timebase

Post by chunky »

I'm downloading that version [2.65b2] now.
]

I'm still getting results where the simulation seems to go a lot faster at lower framerates than it does at high framerates. I'm trying to see if it's my main loop just losing time somewhere.

Thank-you very much,
Gary
dbrank0
Posts: 6
Joined: Thu Nov 15, 2007 8:54 am

Re: Force/Impulse timebase

Post by dbrank0 »

I tried out this beta, too. Forces now work as expected, so I no longer have to use gravity. :> Thanks.
Also by inscreasing number of maximum timesteps in stepSimulation, as chunky pointed out, I think my problems with simulation being dependent on framerate, are solved.
But there is one thing, I did not notice in 2.64. As I start game (resources being loaded and all) framerate considerably drops for first few seconds, and then it suddenly returns to 'normal'. With Bullet 2.64 this didn't happen.
Cleanrock
Posts: 7
Joined: Tue May 01, 2007 6:23 pm

Re: Force/Impulse timebase

Post by Cleanrock »

Erwin Coumans wrote:I agree that with the internal substeps, it is better to clear out the user force _after_ all substeps completed. It will be fixed for next release (2.65).

Other physics SDKs, like Havok and Ageia also clear out the force after the simulation step I think, but I need to verify.
Thanks for the feedback,
Erwin
Seems a minor mistake was done when fixing this.
clearForces() shall only be called when simulation steps have been performed. I moved the clearForces() to the end of the if(numSimulationSubSteps) block :

Code: Select all

if (numSimulationSubSteps)
{
  saveKinematicState(fixedTimeStep);

  applyGravity();

  //clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
  int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps;

  for (int i=0;i<clampedSimulationSteps;i++)
  {
    internalSingleStepSimulation(fixedTimeStep);
    synchronizeMotionStates();
  }

  clearForces();
} 
RobW
Posts: 33
Joined: Fri Feb 01, 2008 9:44 am

Re: Force/Impulse timebase

Post by RobW »

I outlined some determinism bugs to do with force application in this thread, which could be pertinent in this discussion:

http://www.bulletphysics.com/Bullet/php ... nism#p8730
Cleanrock
Posts: 7
Joined: Tue May 01, 2007 6:23 pm

Re: Force/Impulse timebase

Post by Cleanrock »

after reading ur post i realize its more complicated than i first thought, but my change makes things more deterministic in my "usage" of bullet, i only apply forces when simulation steps

i think u have to synch ur external force applications with actual sim steps
ill think about it and get back if i come up with something good
DannyChapman
Posts: 84
Joined: Sun Jan 07, 2007 4:29 pm
Location: Oxford, England
Contact:

Re: Force/Impulse timebase

Post by DannyChapman »

Erwin Coumans wrote: Other physics SDKs, like Havok and Ageia also clear out the force after the simulation step I think, but I need to verify.
Whatever other SDKs do... the idea of clearing the force after each simulation step has never made sense to me for two reasons:

1. The force is quite clearly "owned" by the client, not the physics engine (the physics engine may have its own force calculations, but these will not go through the public API) - if the client sets a value, it's simply not the physics engine's place to mess around with it.

2. If the force gets cleared automatically after each simulation step there's really no difference, apart from a constant scaling factor, between force and impulse so long as the timestep remains constant. Consequently client programmers who don't really quite get the idea of when to use force and when to use impulse mix the two up... and then there's a horrible mess to clear up when the timestep needs to be changed. The more difference in the API between the two the better - e.g. setForce and applyImpulse.

I can it would be hard to change this and maintain backwards compatibility, but...

- Danny
chunky
Posts: 145
Joined: Tue Oct 30, 2007 9:23 pm

Re: Force/Impulse timebase

Post by chunky »

What danny says makes a lot of sense. I actually am running into problems trying to figure out how and when to apply forces to my system, and in the end I stuck with rigidbody->setGravity() to maintain constant force on a body over time, when it would make a lot more sense to just apply a force and have it stay there until I change it.

One question is, how do you deal with clearing forces and adding new ones? Do you typically just have a clear-all-forces call and then reapply them? What if I have four forces acting on a body and I want to remove one of them, but don't have the values of the forces as they were originally applied?

Gary (-;
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Force/Impulse timebase

Post by AlexSilverman »

In light of this discussion, it seems to make sense to split addForce() into addInstantaneousForce() and addConstantForce(). I can see the need for both, and I think making two distinct functions removes some ambiguity in the matter. I typically think of a force to be added as an instantaneous thing, such as a strike with a hammer or something, rather than a push that occurs over time, but that's probably in part because I haven't run into an API yet that deals with forces in any way other than this. Regardless, I can see one possible implementation boiling down to something like this

Code: Select all

void addInstantaneousForce(force) { addForce(force); }
void addConstantForce(force) { setGravity(getGravity() + force); }
at which point I kinda question the need for it, as it seems to have become a question of semantics rather than functionality, but maybe I'm oversimplifying :)

- Alex
chunky
Posts: 145
Joined: Tue Oct 30, 2007 9:23 pm

Re: Force/Impulse timebase

Post by chunky »

void addConstantForce(force) { setGravity(getGravity() + force); }
Except then you can't remove the force if you don't hold it's old value.

It seems like just borrowing the gravity code wouldn't work out - you'd need to store the old value, and put it back when forces are cleared. Except then it's possible that the programmer may have changed the gravity separately from adding forces, and now you have other problems. Additionally gravity acts independant of mass, which this code doesn't account for.

I think it'd be a lot better to have a whole separate codepath for constant forces added.

Gary (-;
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Force/Impulse timebase

Post by AlexSilverman »

Gary,

I would make the argument that holding on to a copy of each constant force separately feels like something that belongs more in whatever Bullet wrapper a project uses, rather than a part of Bullet itself. It seems to have a lot more to do with the logic of the project rather than a general purpose feature. Just my opinion :)
chunky wrote:you'd need to store the old value, and put it back when forces are cleared
The method by which gravity is applied to a body isn't subject to the force being cleared. Each rigid body maintains its own gravity vector, which is added to the cumulative total force acting on it each simulation step, so it doesn't really get cleared in the same sense as other forces added with addForce() do. The cumulative force vector is indeed cleared, but the objects gravity vector is persistent, and readded each frame, which is in effect what you point out would need to be done.
chunky wrote:Additionally gravity acts independant of mass
I'm not sure what you mean. Given my understanding of how Bullet handles forces each simulation step, the user adds whatever forces they like in between steps, then Bullet adds the gravity vector to the body's accumulated force vector. Next, the linear velocity is calculated using by (accumulated force) * (inverse mass) * (time delta). Is there more to this than I understand?

- Alex
chunky
Posts: 145
Joined: Tue Oct 30, 2007 9:23 pm

Re: Force/Impulse timebase

Post by chunky »

AlexSilverman wrote:Gary,

I would make the argument that holding on to a copy of each constant force separately feels like something that belongs more in whatever Bullet wrapper a project uses, rather than a part of Bullet itself. It seems to have a lot more to do with the logic of the project rather than a general purpose feature. Just my opinion :)
Aye, probably. But you still need an accumulator and a subtractor, essentially a list and a bunch of vector adds. Someone has to implement it, and it'd be the same code [or almost the same] for every person out there. So, yes, I agree that it's not central to a physics engine, but it does seem like a useful utility for a physics engine to provide.

Not that I even have multiple forces acting right now in my game, of course...
AlexSilverman wrote:
chunky wrote:you'd need to store the old value, and put it back when forces are cleared
The method by which gravity is applied to a body isn't subject to the force being cleared. Each rigid body maintains its own gravity vector, which is added to the cumulative total force acting on it each simulation step, so it doesn't really get cleared in the same sense as other forces added with addForce() do. The cumulative force vector is indeed cleared, but the objects gravity vector is persistent, and readded each frame, which is in effect what you point out would need to be done.
Except the code that you pasted above, adding a constant force actually modifies that persistent gravity vector.
AlexSilverman wrote:
chunky wrote:Additionally gravity acts independant of mass
I'm not sure what you mean. Given my understanding of how Bullet handles forces each simulation step, the user adds whatever forces they like in between steps, then Bullet adds the gravity vector to the body's accumulated force vector. Next, the linear velocity is calculated using by (accumulated force) * (inverse mass) * (time delta). Is there more to this than I understand?
Again, I was just looking at the code you posted - the force would need a mass divisor [multiplier?] before adding it to the gravity.

I guess the code was mostly an example so it seems a bit silly to poke holes in it

Gary (-;
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Force/Impulse timebase

Post by AlexSilverman »

Gary,
chunky wrote:adding a constant force actually modifies that persistent gravity vector
That's true that it was just quickly written example code, but I am still confused :) Adding a constant force does modify the persistent gravity vector, and that's kind of the point, isn't it? I mean, gravity is a constant force, and you're just adding more to it, as I see it.
chunky wrote:the force would need a mass divisor [multiplier?] before adding it to the gravity
Also, isn't the mass of the object being taken into account in the btRigidBody::integrateVelocities() method? I don't understand why you would need a mass divisor/multiplier additional to that.

Finally, I was thinking about the vector of applied constant forces you mention, and it seems to me that more than just a vector of forces would be necessary in a lot of cases. For example, imagine a character wearing a rocket pack on a (constantly and uniformly :) ) windy day. One could have typical gravity, the wind force, and the rocket force all affecting the character at the same time. If the rocket is only on for three seconds, at the end of that three seconds, how would you know which force to remove from the accumulator if you don't know the value of the force when it was added? Personally I would prefer a force and a pointer to the object that added it, which then presents problems if that object is "nature" as with the wind, which might not have an applicator, such as a rocket pack. I'll admit that this is a pretty specific example, but unless you're removing forces below/above some threshold, I think the need to know where a force came from would come up pretty often. But then again, this is me thinking in gameplay terms, which I'm not terribly good at :)

Please feel free to explain any of this as you might to a 3rd grader :)

- Alex
chunky
Posts: 145
Joined: Tue Oct 30, 2007 9:23 pm

Re: Force/Impulse timebase

Post by chunky »

That's true that it was just quickly written example code, but I am still confused Adding a constant force does modify the persistent gravity vector, and that's kind of the point, isn't it? I mean, gravity is a constant force, and you're just adding more to it, as I see it.
Hm. Lemme rephrase it all:
1) create a body. Call body->setGravity(vector) to describe the gravity that will always be affecting that body henceforth.
2) Apply a constant force to that body. Call body->setGravity(vector + body->getGravity)
3) time passes...
4) Now you have to remove the force from the body and leave it only acting under the gravity you initially set on it

What do you do?
I don't understand why you would need a mass divisor/multiplier additional to that.
Because my brain has a "accelleration under gravity is constant" thing going on. The constant force applied by gravity varies with mass, while a programmer applying a constant force is attempting to apply a constant force, not one that varies on other body parameters.
If the rocket is only on for three seconds, at the end of that three seconds, how would you know which force to remove from the accumulator if you don't know the value of the force when it was added?
I think you & I are asking the same question, just using different words to do it.
Please feel free to explain any of this as you might to a 3rd grader
Well, with every passing message that I post here, the odds become greater that it's actually me that's misunderstanding something...

Gary (-;
AlexSilverman
Posts: 141
Joined: Mon Jul 02, 2007 5:12 pm

Re: Force/Impulse timebase

Post by AlexSilverman »

Hmmm. I get the whole constant acceleration thing, but let me try to explain why I think that gravity in Bullet is a force (where the user doesn't need to account for mass) rather than a constant acceleration (where the user does need to account for mass). A rigid body interprets the gravity vector thusly.

Velocity = Gravity * (Inverse Mass * Delta Time)

Treating gravity as a force (where F = ma, and a is in m/(s*s)), the mass falls away, and the acceleration turns into a velocity. If gravity is treated as an acceleration, then this equation no longer works.
chunky wrote:I think you & I are asking the same question, just using different words to do it.
I agree. I understand the problem, but I think that the solution we both see is slightly different. It seems to me that whatever the solution, there needs to be some mechanism for associating a force in the accumulator with whatever object/body it was that added that force. To me, a force is identified by how strong it is (eg: 150 Newtons) and some other datapoint related to what imparts it (eg: the jet pack). If you don't know the first part, you need to know the other.
chunky wrote:Well, with every passing message that I post here, the odds become greater that it's actually me that's misunderstanding something...
I think it's both of us, or neither of us :)

- Alex
mitul002
Posts: 1
Joined: Tue May 05, 2009 6:14 pm

Re: Force/Impulse timebase

Post by mitul002 »

The post is very useful. Thanks for sharing.

simulation emprunt immobilier
Post Reply