NewtonUpdate

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

NewtonUpdate

Postby Stucuk » Sun Feb 01, 2009 2:07 pm

Im wondering what the correct amount of times to update newton per second to get realistic looking physics. Calling NewtonUpdate() 60 times a second seems too slow, a value between 120-180 seems more realistic.

- 1/120 Vs 1/60 Video
- 1/120 Vs 1/180 Video

P.S the timestep part of the NewtonUpdate() procedure is still useless in 2.0?
Last edited by Stucuk on Mon Feb 02, 2009 10:58 pm, edited 1 time in total.
User avatar
Stucuk
 
Posts: 801
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Re: NewtonUpdate

Postby agi_shi » Sun Feb 01, 2009 2:17 pm

Something doesn't look right, are your forces and everything correct? I use a 1.0 / 60.0 time step and it looks very realistically fast, none of that slow-motion physics stuff you see in most games.
agi_shi
 
Posts: 263
Joined: Fri Aug 17, 2007 6:54 pm

Re: NewtonUpdate

Postby Stucuk » Sun Feb 01, 2009 2:28 pm

Gravity is set to -9.8. Mass is 10 and 5, tho mass doesn't effect the speed they are falling at. (Changing gravity does, tho i don't want unrealistic gravity values)

Code: Select all
procedure TNewtonObject.ApplyForceAndTorque;
var
 force : TVec3;
begin
 if not Assigned(FBody) then Exit;
 force := MultiplyVector(FGravity,GetMass);
 NewtonBodySetForce(FBody, @force[0]);
end;


FTimeSlice is 1/120 or 1/60 or 1/180 depending on which world it is.
Code: Select all
procedure TNewtonWorld.Update(FrameTime : TNPrecision);
Var
 UpdateTime : TNPrecision;
begin
 if not FEnabled then Exit;
 UpdateTime := 1/60; // this is the update timestamp

 FLastFrameTime := FLastFrameTime + FrameTime;
 If FLastFrameTime > 1 then
 FLastFrameTime := 1;
 If FLastFrameTime >= FTimeSlice then
 Repeat
   NewtonUpdate(FWorld, UpdateTime);
   FLastFrameTime := FLastFrameTime - FTimeSlice;
 Until (FLastFrameTime < FTimeSlice);
end;


Note: Framerate is always above 180 (Average is about 1300 on my pc)
Last edited by Stucuk on Sun Feb 01, 2009 5:06 pm, edited 1 time in total.
User avatar
Stucuk
 
Posts: 801
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Re: NewtonUpdate

Postby agi_shi » Sun Feb 01, 2009 4:01 pm

I use this:
Code: Select all
game loop
{

    accumulatedTime = accumulatedTime + deltaTime

    while accumulatedTime >= (1.0 / 60.0)
    {
        NewtonUpdate(world, 1.0 / 60)
        accumulatedTime = accumulatedTime - (1.0 / 60.0)
    }
}

Which seems to be the same as your code, except my physics happen faster than your 180 FPS video, even though I run mine at 60 FPS ...
agi_shi
 
Posts: 263
Joined: Fri Aug 17, 2007 6:54 pm

Re: NewtonUpdate

Postby Stucuk » Sun Feb 01, 2009 4:35 pm

Everything in the simulation is set to the default values, the rendering is what newton's view of the world is (NewtonWorldForEachBodyInAABBDo(), NewtonCollisionForEachPolygonDo()). Apart from the ApplyForceandTorque callback and the Update procedures there isn't rearly anything else that is interacting with newton after the objects have been created. So i got no clue how you could get a faster world with the same amount of NewtonUpdate() calls.

- Test App

Note: The timer class im using uses QueryPerformanceFrequency() and QueryPerformanceCounter() to work out the precise time, so the FrameTime passed to the Update procedure is the correct time.
User avatar
Stucuk
 
Posts: 801
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Re: NewtonUpdate

Postby agi_shi » Sun Feb 01, 2009 5:21 pm

The one on the far right in the demo is 2x slower than my 60 FPS simulation. Are you sure your timings are in seconds? Not sure what to tell you.
agi_shi
 
Posts: 263
Joined: Fri Aug 17, 2007 6:54 pm

Re: NewtonUpdate

Postby Stucuk » Sun Feb 01, 2009 6:48 pm

Yes its a double storing the time in seconds. Iv modifyed the test app so that each world has its own timer, the timer i use doubles as a means to work out the FPS. Each world's update was modifyed to refresh its timer when NewtonUpdate() is called. On average (As FPS fluctuates its imposible for it to perfectly do 1/60, 1/120 or 1/180) its doing the right updates (The UPS labels show the current updates per second averaged over 3 seconds (Or less if 3 seconds hasn't passed)).

- Test App

Timer Unit Source Code:
Code: Select all
unit TimerUnit;

{
 TimerUnit
 Started: Unknown (Added to DNW on 30 Jan 2009)
 By: Stuart "Stucuk" Carey

 If you make changes to this unit please list them below including your name.
 I.E 17 Dec 2008 (Stucuk):  Started Application

 --Changes--
}

interface

Const IntervalVal = 10;
      FrameSliceN = 3*IntervalVal-1;

type TTimerSystem = class(TObject)
  private
    FFrequency : int64;
    FoldTime   : int64;    // last system time
  public
    TotalTime  : double; // time since app started
    FrameTime  : double; // time elapsed since last frame
    Frames     : Cardinal;
    FrameSlices: Array [0..FrameSliceN] of Cardinal;
    FramesSec  : double;
    constructor Create;
    Procedure Refresh;
    function GetFPS : integer;
    procedure ClearAverages;
    function GetAverageFPS : integer;
  end;

var
 TimerSystem : TTimerSystem;

implementation

uses windows;

constructor TTimerSystem.Create;
begin
  FramesSec := 0;
  Frames    := 0;
  QueryPerformanceFrequency(FFrequency); // get high-resolution Frequency
  QueryPerformanceCounter(FoldTime);
  Refresh;
  ClearAverages;
end;

Procedure TTimerSystem.Refresh;
var tmp : int64;
    t2  : double;
    x   : Byte;
begin
  QueryPerformanceCounter(tmp);
  t2        := tmp-FoldTime;
  frameTime := t2/FFrequency;
  TotalTime := TotalTime + frameTime;
  FoldTime  := tmp;

  inc(Frames);

  FramesSec := FramesSec + frameTime;
  if FramesSec >= 1/IntervalVal then
  begin
   FramesSec  := FramesSec - 1/IntervalVal;
   for x := FrameSliceN downto 1 do
   FrameSlices[x] := FrameSlices[x-1];
   FrameSlices[0] := Frames;
   Frames     := 0;
  end;
end;

function TTimerSystem.GetFPS : integer;
begin
  result := Round(1 / frameTime);
end;

procedure TTimerSystem.ClearAverages;
var
 X : Byte;
begin
 Frames     := 0;
 FramesSec  := 0;
 for x := 0 to FrameSliceN do
 FrameSlices[x] := 0;
end;

// Get AverageFPS for last 3 seconds or less if not enough data!
function TTimerSystem.GetAverageFPS : integer;
var
 X,
 FT  : Byte;
 FV  : Cardinal;
begin
 FT := 1;
 FV := 0;
 for x := 1 to FrameSliceN do
 begin
  if FrameSlices[x] > 0 then
  inc(FT);
  inc(FV,FrameSlices[x]);
 end;
 result := Round((FrameSlices[0] + FV) / (FT/IntervalVal));
end;

begin
 TimerSystem := TTimerSystem.Create;
end.
User avatar
Stucuk
 
Posts: 801
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Re: NewtonUpdate

Postby agi_shi » Sun Feb 01, 2009 7:38 pm

Hm. Well, that's very weird, I'm honestly stumped :|
agi_shi
 
Posts: 263
Joined: Fri Aug 17, 2007 6:54 pm

Re: NewtonUpdate

Postby Stucuk » Mon Feb 02, 2009 3:50 pm

Anyone else get faster physics @ 60 updates per second?
User avatar
Stucuk
 
Posts: 801
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Re: NewtonUpdate

Postby Julio Jerez » Mon Feb 02, 2009 6:21 pm

have you set the drag coeficeint to zero when you create the bodies?

also you cna do a test but using the expresion

y = y0 + v0 * t + 0.5 G * t^2

then you can set a body to free fall and run it a diffrent frequncy, the you can mesude how mu teh simulation is off for teh theorical value.
you let if you for two or three secunds and measure the value at the end o fteh time.
the you check teh two values

dy = y - y0 - v0 * t - 0.5 G * t^2

dy = BodyGetPosit at the begin - BodyGetPosit at the end
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: NewtonUpdate

Postby Stucuk » Mon Feb 02, 2009 7:30 pm

Julio Jerez wrote:have you set the drag coeficeint to zero when you create the bodies?


Setting NewtonBodySetLinearDamping() and NewtonBodySetAngularDamping() to 0.0001 doesn't do much to the speed that objects fall(1/60 still looks slow).

- Drag.avi
- NoDrag.avi

Julio Jerez wrote:also you cna do a test but using the expresion

y = y0 + v0 * t + 0.5 G * t^2

then you can set a body to free fall and run it a diffrent frequncy, the you can mesude how mu teh simulation is off for teh theorical value.
you let if you for two or three secunds and measure the value at the end o fteh time.
the you check teh two values

dy = y - y0 - v0 * t - 0.5 G * t^2

dy = BodyGetPosit at the begin - BodyGetPosit at the end


What does y0 mean? I assume v0 is velocity, t for time, g for gravity?
User avatar
Stucuk
 
Posts: 801
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Re: NewtonUpdate

Postby Julio Jerez » Mon Feb 02, 2009 8:11 pm



on these videos are you stepint teh simulation by teh same amount of time?

but this I mean

the simulation tah run at 60 fps is twice as fast as teh simulation tha runt at 120 fps
to make teh equal you will need to do

Update (1/120);
Update (1/120);

for each

update (1/60)

am I write?
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: NewtonUpdate

Postby Stucuk » Mon Feb 02, 2009 11:08 pm

Julio Jerez wrote:


on these videos are you stepint teh simulation by teh same amount of time?

but this I mean

the simulation tah run at 60 fps is twice as fast as teh simulation tha runt at 120 fps
to make teh equal you will need to do

Update (1/120);
Update (1/120);

for each

update (1/60)

am I write?


The 60 fps one is on the right on the first video, its slower. The actual NewtonUpdate() procedure is being sent a value of 1/60. The only difference between the different worlds is how meny times the NewtonUpdate() procedure is called, on the left in the first video NewtonUpdate(World,1/60) is called 120 times per second, the one on the right it is called 60 times per second. In the latter videos the 60 updates per second world is on the left.

The 120 one is like the code below:
Code: Select all
    accumulatedTime = accumulatedTime + deltaTime

    while accumulatedTime >= (1.0 / 120.0)
    {
        NewtonUpdate(world, 1.0 / 60)
        accumulatedTime = accumulatedTime - (1.0 / 120.0)
    }


The 60 one is like the code below:
Code: Select all
    accumulatedTime = accumulatedTime + deltaTime

    while accumulatedTime >= (1.0 / 60.0)
    {
        NewtonUpdate(world, 1.0 / 60)
        accumulatedTime = accumulatedTime - (1.0 / 60.0)
    }


Note: I screwed up the links in the first post, the 2nd video link was the same as the first, fixed now)
User avatar
Stucuk
 
Posts: 801
Joined: Sat Mar 12, 2005 3:54 pm
Location: Scotland

Re: NewtonUpdate

Postby Julio Jerez » Tue Feb 03, 2009 12:08 am

in teh fiorst loop
accumulatedTime = accumulatedTime + deltaTime

Code: Select all
    while accumulatedTime >= (1.0 / 120.0)
    {
        NewtonUpdate(world, 1.0 / 60)
        accumulatedTime = accumulatedTime - (1.0 / 120.0)
    }


should not be

Code: Select all
accumulatedTime = accumulatedTime + deltaTime

    while accumulatedTime >= (1.0 / 120.0)
    {
      // her 1/120
        NewtonUpdate(world, 1.0 / 120)
        accumulatedTime = accumulatedTime - (1.0 / 120.0)
    }
Julio Jerez
Moderator
Moderator
 
Posts: 12426
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: NewtonUpdate

Postby Dave Gravel » Tue Feb 03, 2009 12:21 pm

You search a nice physics solution, if you can read this message you're at the good place :wink:
OrionX3D Projects & Demos:
https://orionx3d.sytes.net
https://www.facebook.com/dave.gravel1
https://www.youtube.com/user/EvadLevarg/videos
User avatar
Dave Gravel
 
Posts: 801
Joined: Sat Apr 01, 2006 9:31 pm
Location: Quebec in Canada.

Next

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 8 guests