A place to discuss everything related to Newton Dynamics.
Moderators: Sascha Willems, walaber
by 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 VideoP.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.
-

Stucuk
-
- Posts: 801
- Joined: Sat Mar 12, 2005 3:54 pm
- Location: Scotland
-
by 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
by 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.
-

Stucuk
-
- Posts: 801
- Joined: Sat Mar 12, 2005 3:54 pm
- Location: Scotland
-
by 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
by 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 AppNote: 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.
-

Stucuk
-
- Posts: 801
- Joined: Sat Mar 12, 2005 3:54 pm
- Location: Scotland
-
by 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
by 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 AppTimer 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.
-

Stucuk
-
- Posts: 801
- Joined: Sat Mar 12, 2005 3:54 pm
- Location: Scotland
-
by 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
by Stucuk » Mon Feb 02, 2009 3:50 pm
Anyone else get faster physics @ 60 updates per second?
-

Stucuk
-
- Posts: 801
- Joined: Sat Mar 12, 2005 3:54 pm
- Location: Scotland
-
by 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

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by 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.aviJulio 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?
-

Stucuk
-
- Posts: 801
- Joined: Sat Mar 12, 2005 3:54 pm
- Location: Scotland
-
by 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

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by 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)
-

Stucuk
-
- Posts: 801
- Joined: Sat Mar 12, 2005 3:54 pm
- Location: Scotland
-
by 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

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by Dave Gravel » Tue Feb 03, 2009 12:21 pm
-

Dave Gravel
-
- Posts: 801
- Joined: Sat Apr 01, 2006 9:31 pm
- Location: Quebec in Canada.
-
Return to General Discussion
Who is online
Users browsing this forum: No registered users and 11 guests