Results 1 to 3 of 3

Thread: pressing key once are not instantaneous

  1. #1

    pressing key once are not instantaneous

    of course it is not instantaneous but i want to convey something.
    while trying a program called modelviewer http://psch.thinbasic.com/forum/inde...prev_next=prev
    i come across a situation that pressing move key once as fast as we can are not compatible with the x=x+0.001 as an example, and the object will move more than what we intended by x=x+0.001.
    after visualizing the issue i think that the loop go across the "If GetAsyncKeyState(%VK_D) Then x = x + 0.001"" tens or even hundreds of times before the old man heavy finger release his (fast!!) press on the key so the x advanced more and more than intended.
    so if we insert a SLEEP function to allow the heavy finger to move up from the key then the x will increased approximately more precisely, and this depends on the speed of your cpu.
    like this:
    If GetAsyncKeyState(%VK_W) Then
    Sleep(30)
    LightZ -= 0.005
    EndIf
    i have found that Petr suggested using sleep before in a bug reported by me http://www.thinbasic.com/community/p...r=all#note2163 but i forget it completely.
    also i have found recently a very great function TBGL_GetWindowKeyOnce wich are absolutley precise but you can use it only step by step like this:
    If TBGL_GetWindowKeyOnce( hWnd, %VK_W ) Then
    'TBGL_ResetKeyState()
    'Sleep(delay)
    LightZ -= 0.005
    EndIf
    suitable for moving /rotating models and figures precisely.
    if you have added :
    TBGL_ResetKeyState()
    Sleep(delay)
    then it will function like the GetAsyncKeyState/TBGL_GetAsyncKeyState with SLEEP.
    the attached example are extracted from the modelviewer mentioned above and manipulated to reflect the issue.
    use W,S to move the ball more precisely through the triangle.
    use A,D to move the ball horizontally (not precisely)
    use <,> to rotate the triangle
    i placed the figure in this specific orientation to ask Petr an intuitive question :if there is a hope that the ball when penetrate the triangle can leave a hole in the figure in which we can see through it and whats behind.
    i have attached with_tiger_skin2 it is originally posted by Petr in the famous waterpatch example to show that the ball almost will go tear the skin and make a hole in it ,but we can't display a hole since the model are already loaded. for more info look "3D curves texturing between mathematica and thinbasic"

    P.S: i have an idea to make a hole at run time,this is to deal with the object as in the physical world, composed from many smaller objects (such as molecules). and collectively it is making the whole bigger object.
    now if a ball penetrate this big object it is simply erase some smaller objects in its path. we just distroy those smaller objects.
    i will investigate this approach. even it is possibly a cpu heavy task.
    Attached Files Attached Files
    Last edited by zak; 26-01-2012 at 16:00.

  2. #2
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,129
    Rep Power
    732
    Hi Zak,

    thanks for sharing your discoveries!

    I would add one more advice, which makes possible to not use SLEEP at all, and still have full control.

    The approach with:
    ' -- This results in increasing x by 0.1 once per FRAME
    x = x + 0.1
    
    Has the general problem of being too dependant on performance on given machine.

    If the script runs at 60FPS, holding the key for 1 second will make the object moved by 0.1 * 60 = 6 units

    If the script runs at 1000FPS (yes, it is possible), holding the key for 1 second will make the object moved by 0.1 * 1000 = 100 units.

    If we take unit as meter, it is difference of 6 meters vs. 100 meters... quite a lot

    The approach used for example in computer games, or other application, is performance synchronised movement.

    This very simple technique consists in measuring the actual time the frame took to render, and scaling the movement by this.

    You can achieve this by measuring the time one frame takes to render on your own, for example using the new cTimer class, or HiResTimer_Get commands.

    Even simpler is to use build in TBGL_GetFrameRate function, which will return a number reporting how many frames per second the loop can run.

    There is simple relation between these two, where:
    timeSpentRenderingFrame = 1 / frameRate ' -- in seconds

    frameRate = 1 / timeSpentRenderingFrame ' -- in frames per second
    The second approach can be applied quite simply in two steps:
    - retrieving the current frame rate once per render cycle:
    frameRate = TBGL_GetFrameRate
    
    - scaling the movement by this value:
    ' -- This means holding the key will result in movement of 0.1 meter per second
    x = x + 0.1 / frameRate
    
    This approach is independent on PC performance, and will most likely result in the same speed of movement across different PCs.
    I wrote "most likely", because the measurement works with 1 frame old data, so in case the frame rate changes a lot, it can introduce slight imprecision. This can be filtered out by using more advanced math mechanisms (various filters, using average and so on).

    I modified the first example to demonstrate this and slightly modernised the used commands. The movement is now done in way it occurs at 1 m/s and the rotations at 90 degrees/second, but this can be of course tuned as you wish:
      Uses "TBGL" 
      
      Dim hWnd     As DWord 
      Dim Distance As Single = 3
      Dim Rot_Y    As Single = 45
        
      hWnd = TBGL_CreateWindowEx("move the light: z_coord:WS     xy_coord: DA,     rotate: arrow keys >,<", 640, 480, 32, %TBGL_WS_WINDOWED) 
      TBGL_ShowWindow 
      
      Dim LightX, LightY, LightZ As Single
      LightX = 0: LightY = 1:LightZ = 0
      
      TBGL_UseLighting TRUE
      TBGL_UseLightSource %GL_LIGHT0, TRUE
      TBGL_SetLightParameter %GL_LIGHT0, %TBGL_LIGHT_DIFFUSE, 1, 1, 1, 1 
      TBGL_SetLightParameter %GL_LIGHT0, %TBGL_LIGHT_POSITION, LightX, LightY, LightZ, 0
    
      TBGL_ResetKeyState() ' Resets ESC key status before checking 
      
      Dim frameRate As Double
        
      While TBGL_IsWindow(hWnd)
      
        frameRate = TBGL_GetFrameRate
         
        TBGL_ClearFrame
        
          ' Camera settings      
          TBGL_Camera 0, Distance, Distance, 0, 0, 0 
          
          TBGL_Rotate Rot_Y, 0, 1, 0                                                    
          TBGL_SetLightParameter %GL_LIGHT0, %TBGL_LIGHT_POSITION, LightX, LightY, LightZ, 0
          
          TBGL_Color 255, 255, 255
          TBGL_Box 0.5, 0.5, 0.5      
                      
          TBGL_PushMatrix               
              TBGL_Color 255, 128, 0
              TBGL_Translate LightX, LightY, LightZ
              TBGL_Sphere 0.1           
          TBGL_PopMatrix
        
        tbgl_DrawFrame 
    
        If TBGL_GetWindowKeyState(hWnd, %VK_RIGHT)  Then Rot_Y -= 90/FrameRate  ' 90 degrees/second
        
        If TBGL_GetWindowKeyState(hWnd, %VK_LEFT)   Then Rot_Y += 90/FrameRate
            
        If TBGL_GetWindowKeyState(hWnd, %VK_W)      Then
          LightZ -= 1/FrameRate ' 1 meter/second
        EndIf  
        
        If TBGL_GetWindowKeyState(hWnd, %VK_S)      Then
          LightZ += 1/FrameRate ' 1 meter/second
        EndIf
        If TBGL_GetWindowKeyState(hWnd, %VK_A)      Then LightX -= 1/FrameRate  ' 1 meter/second
        If TBGL_GetWindowKeyState(hWnd, %VK_D)      Then LightX += 1/FrameRate  ' 1 meter/second
        
        If TBGL_GetWindowKeyState(hWnd, %VK_P)      Then LightY += 1/FrameRate  ' 1 meter/second
        If TBGL_GetWindowKeyState(hWnd, %VK_L)      Then LightY -= 1/FrameRate  ' 1 meter/second
        
        If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While 
    
      Wend 
    
      TBGL_DestroyWindow
    

    Petr
    Last edited by Petr Schreiber; 26-01-2012 at 21:37.
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  3. #3
    Hi Petr
    thanks for the detailed description of the Framerate usage, now i can see why you have used it in your original modelview example, and i havn't used it.
    indeed i have tried my examples on two computers one slow and the other speedier and they are different in the speed they present the move/rotation. but using the framerate they are almost approximately the same.
    thanks

Members who have read this thread: 0

There are no members to list at the moment.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •