BASIC

Author Topic: Advanced: Consistant 3d object movement at any FPS.  (Read 2604 times)

Offline Hemlos

  • To boldy go where no pixel has gone before!
  • Global Moderator
  • Prof. Inline
  • *******
  • Posts: 1618
  • Particle Hawk
    • View Profile
Hello gang,

This tutorial is written to help 3d games with consistant object movement, regardless of FPS.
Think about it, some computers are slow and things can move too slow on those screens.
Furthermore, some computer systems are fast, and will move too quickly.
So you need to regulate physical movement in 3d space.

This formula is derived from a physics paper, from a stanford university student.
In this article i found it says distance squared and time is a movement size for an instance of time.
So this got me thinking...you can move that square function around and calculate movement in 3d space :)
I tried this with good results on my 3d particle engine SpriteZ3d, which is coming along great now btw!
This is a success story and i had to share it with everyone, as this can improve any 3d game performance!

This is the magic formula i devised:

Code: GLBasic [Select]
MovementUnit = 1.0 / MAX(1.0, FPS )

I call FPS with this group of commands together, for maximum performance of the program:
Code: GLBasic [Select]
FPS = MyFPSTimer()
//Keep in mind you can only call this once per loop: FPS=MyFPSTimer()
//If you need frame time, its FrameTime%(milliseconds)
MOUSEAXIS() //here below frame time to prevent divisions by zero in your algorithms, and to make mouseaxis accurate.
SHOWSCREEN
WEND

FUNCTION MyFPSTimer: X , Y , ShowFpsBOOL  //STABLE FPS, Returns FPS
// ShowFpsBOOL print to screen option TRUE FALSE
// Usage: myfpsvalue=FPS(FALSE)
// Updates a stable FPSValue Every One Second Interval:
        STATIC TimeBuffer , FrameCount , FPSVALUE
        FrameTime = GETTIMER(); TimeBuffer = TimeBuffer + FrameTime; FrameCount = FrameCount + 1
        IF TimeBuffer > 999; TimeBuffer = TimeBuffer - 1000; FPSVALUE = FrameCount; FrameCount = 0; ENDIF
        SystemTime = SystemTime + FrameTime //total time in milliseconds
        IF ShowFpsBOOL = TRUE THEN PRINT "FPS=" + FPSVALUE, X , Y
        RETURN FPSVALUE // Returns FPS
ENDFUNCTION


 


And to use this Movement size in 3d space, you must factor it with the movement and acceleration vectors:

Code: GLBasic [Select]
//this doesnt include an acceleration algorithm, but you use it for that too.
PosX = PosX + VectorX * MovementUnit
PosY = PosY + VectorY * MovementUnit
PosZ = PosZ + VectorZ * MovementUnit
 

PosXYZ is your position matrix, and it is updated with your vector each frame.
VectorXYZ is your vector direction of movement.
Here you can apply the same formula to accelerations also, not just velocity.

And thats it!

I tested this on the particle engine, measuring the actual distance with a grid.

I tested with these parameters:
LIMITFPS -1, LIMITFPS 500, LIMITFPS 1000, LIMITFPS 1, LIMITFPS 60
ParticleCount = 1000, ParticleCount = 10, ParticleCount = 10000

And the resulting movement was identical, no matter what fps it was running!
Heres a screenshot, showing what the fountain looked like, at any frame rate:


[attachment deleted by admin]
« Last Edit: 2012-Jul-03 by Hemlos »
Volume_of_Earth(km^3) = 4/3*3.14*POW(6371.392896,3)

Offline mentalthink

  • Prof. Inline
  • *****
  • Posts: 3354
  • Integrated Brain
    • View Profile
This it´s very very interesting and extremelly powerfull!!!

Thanks Hemlos!!!  :nw: :nw:

Offline Hatonastick

  • Dr. Type
  • ****
  • Posts: 474
  • Amstrad CPC 6128
    • View Profile
Hmm this will come in handy for my game.  Thanks!
Mat. 5: 14 - 16

Android: Toshiba Thrive Tablet (3.2), Samsung Galaxy Tab 2 (4.1.2).
Netbook: Samsung N150+ Netbook (Win 7 32-bit + Ubuntu 11.10).
Desktop: Intel i5 Desktop with NVIDIA GeForce GTX 460 (Win 8.1 64-bit).