Posted this on some obscure thread on general physics engine stuff, just thought i would add it here for future reference and with a search-able topic and some example code.
The Phy timing commands are somewhat cryptic in the help files, but with some experimenting and luck i came up with this method (and some looking over the NVidia boards plus SDK)
Both the fixed timing commands have to be used in conjunction every loop,
passing in the frame Elapsed and Duration time:
Phy Set Fixed Timing Elapsed
Phy Set Timing Duration,8,0
The code shows a tray with a ball rolling down to stop at the center, should be pretty consistent test circumstances.
For every run more iterations are added to a work loop so the FPS will drop, the time it takes to reach the bottom should be pretty much the same.
The time the ball takes to reach the bottom is recored and the last fifteen times are displayed.
Should give something like 14-15 seconds every time. The Physics solver can act up on extreme high or low FPS though but thats to be expected.
The timing/average function method is not my invention, i borrowed it from code posted by the eminent DarkCoder.
Remove the comment from the "Elapsed = Average(..." for more consistent Elapsed values.
Interestingly a zero Elapsed value passed in to the fixed timing commands now and then does not matter. The engine seems to make an average itself.
Global Elapsed as float
Global Duration as float
Global OldTime as Double Integer
Global Fps as integer
` to save timescores
Type TimeScoresType
AtRun as integer
Time as integer
FPS as integer
EndType
Global Dim TimeScores() as TimeScoresType
Global Dim AverageElapsed(60) as Float
Global AveragePointer as integer
Global MaxAverageArray as integer
MaxAverageArray = Array Count(AverageElapsed(0))
Set Display Mode 800 , 600 , 32, 0 , 0 , 0 ` No screen refresh sync.
`Set Display Mode 800 , 600 , 32, 1 , 0 , 0 ` Sync to screen refresh
Sync On
Autocam Off
` Start Physics multithreaded.
PhyxRunMode=Physx()
Phy Start PhyxRunMode,0,1
` Update full needed, according to the documentation.
Phy Update 0
Position Camera 0,60,-130
Point Camera 0,0,0
` Make a bowl (cone) and flatten it, also we invert it as cones are culled not showing the inner polygons.
Make Object Cone 2, 200
Set Object Cull 2 , 0 ` For safety we cull it so we can see the cone from below if we loose track with the mouselook.
Scale Object 2 , 100,-30,100
Phy Make Rigid Body Static Mesh 2
`Starts=1
Do
` Get frame times
GetFrameTimes()
` Collect physics data
Phy Update 1
` The timings.
` Interestingly enugh, an Elapsed value of zero passed in here now and then does not matter.
` The timer() command can be too slow on faster machines giving an occasional zero Elapsed.
Phy Set Fixed Timing Elapsed
Phy Set Timing Duration,8,0 ` Increase timesteps (second parameter) for faster physics with standard gravity, with 8 we get a pretty realistic motion.
` The two commands below tried separately instead of "Phy Set Timing Duration,8,0" should give the same results.
`Phy Set Timing Duration,1,0
`Phy Set Auto Fixed Timing
` Info.
Text 0,0, "Screen Fps():" + str$( screen fps() ) + ", Calculated FPS:" + str$(Fps)
Text 0,20, " Elapsed:" + str$(Elapsed) + " Duration:" + str$(Duration)
` End run condition checks
if BallRolling=1
` Check if the ball has stopped at the bottom of the tray
lvx# = Phy get rigid body linear velocity x( 1 )
lvy# = Phy get rigid body linear velocity y( 1 )
lvz# = Phy get rigid body linear velocity z( 1 )
speedvector#=sqrt((lvx# * lvx#) + (lvy# * lvy# ) + (lvz# * lvz#))` ^ (0.5)
if speedvector#<0.1
` Ball has stopped, delete the ball for the next run and prepare a new run.
` Try checking for 0.0. Though extreme extents on Fps low and high gives poor physics solver results so a speedvector# of zero is sometimes not reached.
RunEnd=timer()
BallRolling=0
Phy Delete Rigid Body 1
Delete Object 1
` Increase the number of ball starts, add to the increment for faster results.
inc Starts, 2
endif
endif
` End run scores
if RunEnd>0
` We have reached the ball stop, add timescores to the timscore array.
inc AtRunNow
BallRolling=0
Array Insert At Top TimeScores(0)
TimeScores(0).AtRun = AtRunNow
TimeScores(0).Time = RunEnd-RunStart
TimeScores(0).FPS = screen fps()
if Array Count(TimeScores(0))>15
Array Delete Element TimeScores(0), Array Count(TimeScores(0))
endif
else
` If the ball is still rolling display the previous fifteen timescores.
if Array Count(TimeScores(0))>=0
for i=0 to Array Count(TimeScores(0))
Text 1,20+(20*(i+1)), "Ball Run " + Str$(TimeScores(i).AtRun) + ":" + str$(TimeScores(i).Time ) + "ms, FPS: " + str$(TimeScores(i).FPS)
next
endif
endif
` Initiate and restarts
if Spacekey() and BallRolling=0
` Start the test run.
StartBallcycle=1
endif
if StartBallcycle=0
text 0,60, "Press Spacebar to start"
endif
if StartBallcycle=1 and BallRolling=0
` Initiate the ball and set it in motion on a new run.
BallRolling=1
Make Object Sphere 1, 5
Position Object 1, 90,40,0
Phy Make Rigid Body Dynamic Sphere 1
Phy Add Rigid Body Local Force 1,0,0,20,2
RunEnd=0
RunStart=timer()
endif
` Add more and more for the program to do between frames.
For i = 0 to 1000*Starts
a=sqrt(i)
next i
` Physics update
Phy Update 0
`MoveCamera()
Sync
Loop
Function GetFrameTimes()
` Timings, Elapsed And Duration is needed for the Physics timings.
Elapsed = (Timer()-OldTime)
OldTime = Timer()
`Elapsed = Averages(Elapsed) ` Uncomment to get more consistent Elapsed timings.
Duration = Elapsed * .001
Fps = Int(1000/Elapsed)
Endfunction
Function Averages(InElapsed as Float)
` If we have very high FPS we can get some averages for the Elapsed time.
Local OutElapsed as float
inc AveragePointer
if AveragePointer > MaxAverageArray
AveragePointer =0
endif
AverageElapsed(AveragePointer)=InElapsed
for i = 0 to MaxAverageArray
OutElapsed = OutElapsed + AverageElapsed(i)
Next i
OutElapsed = OutElapsed/(MaxAverageArray+1)
Endfunction OutElapsed
Function MoveCamera()
camspeed# = .1 * Elapsed
if upkey() or downkey()
move camera (upkey()-downkey())*camspeed#
endif
turnspeed# =.1*Elapsed
rotate camera wrapvalue(camera angle X()+(mousemoveY()*turnspeed#)),wrapvalue(camera angle Y()+(mousemoveX()*turnspeed#)),0
Endfunction
Edit, lost a paragraph in the initial editing
Regards