Less force at lower frame rates

Xpoint

13-09-2006 21:22:20

Hey all,
I'm trying to implant some kind of gravity source, so objects which get close to a specific point will get pulled to that point. For now, it worked great!! But I noticed that at low frame rates that force gets less strong, meaning that at to low frame rates the global scene gravity will win it from the other... (still get it?? :P )

Anyway, this is what I'm doing:
void CAreaGravityAffector::update(const float fTimestep)
{
// Get the default scene.
nxOgre::scene* pScene = CWorldManager::getSingleton().getDefaultNxOgreScene();

// Iterate through all the bodies.
nxOgre::bodyIterator bodyIt(pScene);
nxOgre::body* pBody = NULL;
while(pBody = bodyIt.next())
{
// Check if this body is static or dynamic.
// Check if this body is in the correct scene.
// Check if this body has gravity.
if(pBody->isStatic() ||
pBody->owner != pScene ||
pBody->isIgnoringGravity())
continue;

// If the body is in range, apply the forces.
Ogre::Vector3 vDistance = pBody->getGlobalPosition() - m_pSceneNode->getWorldPosition();
if(vDistance.squaredLength() <= m_fSquaredRadius)
{
float fRatio = vDistance.normalise() / m_fRadius;
float fGravity = (fRatio * m_fOuterGravity) + ((1.0f - fRatio) * m_fInnerGravity);

Ogre::Vector3 vForce = ((-vDistance) * fGravity);
pBody->addForce(vForce, NxForceMode::NX_ACCELERATION);
}
}
}

How do I fix this problem, so that forces will be the same at lower and higher frame rates?

Thanks in advance!

betajaen

14-09-2006 11:00:04

Sounds like a cool project, I wanted to do a very similar thing with magnets. Anyway, I noticed you have "fTimestep" there, but no use for it.

So if you do:

Ogre::Vector3 vForce = ((-vDistance) * fGravity) * fTimestep;

The force should be fairly the same between frames, if you want a stronger gravity "field" because effectly the force is being divided by a 100 to 1000 then just turn up fGravity.

Xpoint

14-09-2006 12:20:28

Ok, that worked! :D Didn't used that timestep because it didn't work for me, but after doing this:
Ogre::Vector3 vForce = (((-vDistance) * fGravity) * fTimestep) / (1.0f / 60.0f);
it worked nice.

vec3

14-09-2006 12:28:36

If the above advice is not sufficient then lock the framerate with:
'renderOneFrame()'.

Using the information in these threads:
http://www.ogre3d.org/phpBB2addons/view ... t=addforce
http://www.ogre3d.org/phpBB2/viewtopic. ... nt&start=0

Xpoint

14-09-2006 12:33:43

If the above advice is not sufficient then lock the framerate with:
'renderOneFrame()'.

Using the information in these threads:
http://www.ogre3d.org/phpBB2addons/view ... t=addforce
http://www.ogre3d.org/phpBB2/viewtopic. ... nt&start=0

It already works for me now. :) But locking the framerate will only be a solution if you stay at that framerate, but you can't prevent getting lower frame rates.

vec3

14-09-2006 12:51:50

Yes, I saw that it worked for you, my reply was for others with similar problems.
An added benefit for using the 'renderOneFrame()' method is that the application can run without actually rendering to screen and still be accurate in terms of its 'virtual' time (ie. the application will behave as if it is running at a certain framerate but infact is running faster to the user).

Xpoint

14-09-2006 13:00:05

I see what you mean, and I hope it will be usefull for other users. :)

I've created a video of my current progress, so if you like to see me results: Video (~17.1MB)

betajaen

14-09-2006 13:21:28

Hahaha thats my NxOgre ;)

I'm doing something incredibly similar but with magnetics using the state system.

via:
mMagenticBody->addState(STATE_MAGNET);
mIronBall->addState(STATE_MAGNETIC);


It works fairly well so far although I need to turn of the magnetic properties after it leaves a field of radius.

vec3

14-09-2006 13:29:30

Looks nice :)

Xpoint

14-09-2006 14:20:26

Hahaha thats my NxOgre ;)

I'm doing something incredibly similar but with magnetics using the state system.

via:
mMagenticBody->addState(STATE_MAGNET);
mIronBall->addState(STATE_MAGNETIC);


It works fairly well so far although I need to turn of the magnetic properties after it leaves a field of radius.

That looks cool, but I won't be using the state manager for it since it is easier for me to create my own kind of system. I will use the state machine to tell that objects are magnetic though. :)

betajaen

14-09-2006 14:22:39

Well it's your code, either way yours is more like a mini-moveable non-deadly blackhole, than my ultra-strong magnetic.

But I just posted the video if you're intrested.

Xpoint

14-09-2006 14:36:06

that video looks awsome! :D Imaging that you make the same effects like that video of CellFactor: Revolution on the Ageia home page. :)

And betajaen, thanks for your great library, very easy to use!! My compliments. :wink:

Btw, I'm thinking of creating some bad ass effects for that gravity sphere so it looks like a weapon, so stay tuned. :wink:

vec3

14-09-2006 14:42:31

:D

I can only agree.

Very nice to see that the state system can be easily extended and the result so easy to use.

betajaen

14-09-2006 15:02:57

I think I just cracked gravity; there are no words except the grunts of lifting my jaw off the floor.




Watch the the video! (5 meg)

vec3

14-09-2006 15:14:40

Betajaen, do you think physX can allow this to scale up?

Where the large cube is massively larger, actual planet size, while the satellites remain small?

betajaen

14-09-2006 15:16:11

In theory yes, Wyx and I simulated collisions of planets using that scale and it worked fine, however you would get some floating point errors or rounding off at that range.

So it would be better to scale it down, although if you make it look correct people won't notice.

Xpoint

14-09-2006 18:52:30

Now the problem is reversed!!! With higher framerate the forces get weaker... Any solution for that??

Xpoint

14-09-2006 21:56:18

I think I've fixed the problem now! :D I've changed my code to this:
void CAreaGravityAffector::update(const float fTimestep)
{
// Get the default scene.
nxOgre::scene* pScene = CWorldManager::getSingleton().getDefaultNxOgreScene();

// Calculate the right timestep.
NxReal fMaxTimestep;
NxU32 dummy2;
NxTimeStepMethod dummy3;

pScene->mScene->getTiming(fMaxTimestep, dummy2, dummy3);
float fFinalTimestep = fTimestep > fMaxTimestep ? fMaxTimestep : fTimestep;

// Iterate through all the bodies.
nxOgre::bodyIterator bodyIt(pScene);
nxOgre::body* pBody = NULL;
while(pBody = bodyIt.next())
{
// Check if this body is static or dynamic.
// Check if this body is in the correct scene.
// Check if this body has gravity.
if(pBody->isStatic() ||
pBody->owner != pScene ||
pBody->isIgnoringGravity())
continue;

// If the body is in range, apply the forces.
Ogre::Vector3 vDistance = pBody->getGlobalPosition() - m_pSceneNode->getWorldPosition();
if(vDistance.squaredLength() <= m_fSquaredRadius)
{
float fRatio = vDistance.normalise() / m_fRadius;
float fGravity = (fRatio * m_fOuterGravity) + ((1.0f - fRatio) * m_fInnerGravity);

pBody->addForce(((-vDistance) * fGravity) * fFinalTimestep / fMaxTimestep, NX_ACCELERATION);
}
}
}

Just be sure the timestep doesn't get to big. The problem was that at lower framerates the force gets to large, so limit it with the max timestep. :)

betajaen

14-09-2006 22:27:08

Excellent ;)

You could base fMaxTimestep of the best frame count from Ogre so it changes dynamically.

vec3

15-09-2006 01:03:36

I can only agree again, Good going Xpoint!

Nice to see this problem solved in most ways :D

Xpoint

15-09-2006 13:54:03

One more video of this: video (~5MB)
It shows the same, but now those balls are just as heavy as the gravitional balls, wich gives a funny effect. :wink: Next thing for me will be implanting magnets, but that will be done next week because I'll be gone for the weekend.

betajaen

15-09-2006 13:58:16

Haha, very nice. I'd be intrested to see your full code of it all, perhaps it could be a prefab?

I sort of messed up the magnet code in NxOgre and can't get it back like I had before, still working on it though, but I'm on a break and working on the opposite - Explosions.

Xpoint

15-09-2006 14:39:45

There isn't realy more code to show exept for that function. :) But I'll look if I can create a prefab for it next week. I'll be gone till sunday now, so good luck with your magnets. :wink:

Cya.

Toby

18-09-2006 12:59:15

Very cool effect.

Xpoint

19-09-2006 22:28:16

Currently busy with other things, so not sure if I can work on that prefab.. :x Anyway, I'll let you know. :)