Page 1 of 1

fill the tank with Balls

Posted: Wed Jul 16, 2014 10:44 am
by applePi
then rotate the tank to let the balls flow at once to the ground
notes:1- it is too important to tilt the tank slightly so the balls will not accumulate vertically at the beginning: RotateEntity(#cyl, 0,0,1)
2- we have done illegal slight move for a static object (the tank), this will not move the tank but its purpose is to give the balls some action (that is cheating the engine and utilizing illegal action for our benefit, the tank can be considered as vibrating internally when we do this)
3- i have found that the balls with radius 0.3 is the best for this example. radius 0.2 works. but radius 0.1 will penetrate the tank walls. so we can check different tank meshes with different thickness to see what is more suitable for a specific spheres.
Image
Image

tested using PureBasic 5.30 beta 7

Code: Select all

#CameraSpeed = 1
#cyl = 200
#ball = 210
#mat = 220
#ballsReflector = 230

Global Dim ball(1000)
Global ballNum
Define.f KeyX, KeyY, MouseX, MouseY

ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "....Space to throw balls,...... Z to rotate the Tank, ............ mouse and arrow keys to move the cam  ", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

;Initialize environment
InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()

OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0)-4, 0, 0, 0)
    
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures/",#PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Scripts",#PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Packs/desert.zip", #PB_3DArchive_Zip)
  Parse3DScripts()
  
  
  ; transparent Texture from example CreateTextureAlpha.pb in Purebasic 3D folder
    CreateTexture(#mat, 256, 256)
      StartDrawing(TextureOutput(#mat))
      DrawingMode(#PB_2DDrawing_AllChannels | #PB_2DDrawing_AlphaBlend)
      Box(0, 0, 256, 256, RGBA(0, 0, 0, 255))
      Box(0, 0, 256, 256, RGBA(100, 255, 0, 70)) 
      ;Circle(127, 127, 50, RGBA(0, 0, 0, 0))
      StopDrawing()
      CreateMaterial(#mat, TextureID(#mat))
      MaterialBlendingMode(#mat, #PB_Material_AlphaBlend)
      MaterialCullingMode(#mat, #PB_Material_NoCulling)
      DisableMaterialLighting(#mat, 1)
      
    WorldShadows(#PB_Shadow_Modulative, -1, RGB(127, 127, 127))
    
    ;Materials
    CreateMaterial(0, LoadTexture(0, "Wood.jpg"))
    GetScriptMaterial(1, "SphereMap/SphereMappedRustySteel")
    CreateMaterial(2, LoadTexture(2, "Dirt.jpg"))
    GetScriptMaterial(3, "Scene/GroundBlend")
    MaterialBlendingMode(0, #PB_Material_AlphaBlend)
    MaterialCullingMode(0, #PB_Material_NoCulling )
    DisableMaterialLighting(0, 1)

        
    ; create the Tank
    CreateCylinder(#cyl,3,10,2,0,0) ; "2" specify a square tank look the Docs.
    CreateEntity(#cyl, MeshID(#cyl), MaterialID(#mat), 0,9.5,0)
    RotateEntity(#cyl, 0,0,1)
    EntityPhysicBody(#cyl, #PB_Entity_StaticBody, 1, 0.1, 1)
    
    ; create the Balls
    CreateSphere(#ball, 0.3 )
    For i = 0 To 1000
    ball(i) = CreateEntity(#PB_Any, MeshID(#ball),#PB_Material_None)
    MoveEntity(ball(i), 0,14,0, #PB_Absolute)
    Next
        
    ; Camera
    ;
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, -30, 20, -20, #PB_Absolute)
    CameraLookAt(0, 0 , 0  , 0)
    
    ; Skybox
    ;
    SkyBox("desert07.jpg")
    
    ; Light
    ;
    CreateLight(0, RGB(255, 255, 255), 100, 800, -500)
    AmbientColor(RGB(20, 20, 20))
    CreateCube(#ballsReflector,1)
    CreateEntity(#ballsReflector, MeshID(#ballsReflector),MaterialID(0),0,15,0)
    ScaleEntity(#ballsReflector, 3,1,3)
    EntityPhysicBody(#ballsReflector, #PB_Entity_StaticBody, 1, 0.1, 1)
    
    ;ground
    CreateEntity(3,MeshID(#ballsReflector),MaterialID(3), 0, 0, 0)
    ScaleEntity(3,40,2,40)
    EntityRenderMode(3, 0) 
    EntityPhysicBody(3, #PB_Entity_StaticBody, 1, 1, 1)
    MoveEntity(#cyl,0,0.5,0) ; just a cheat to make the tank vibrating internaly to keep the balls busy and active a little
    
    
    Repeat
        
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
      EndIf
      ExamineKeyboard()
      If KeyboardPushed(#PB_Key_Space) ; throwing balls by giving it physical properties
      If done = 0
      ballNum+1
      If ballNum = 1000: done = 1:  EndIf
      
      EntityPhysicBody(ball(ballNum),#PB_Entity_SphereBody,1,0.5,1)
      ;DisableEntityBody(ball(ballNum), 0)
      EndIf 
      EndIf
    
             
        If KeyboardPushed(#PB_Key_Z)
         
          RotateEntity(#cyl, 0,0,2,#PB_Relative)
         For i=1 To 1000
            DisableEntityBody(ball(i),0)
          Next
          MoveEntity(#cyl,0,3,0) ; a cheat, look line 90
        EndIf
          
        
        If KeyboardPushed(#PB_Key_Left)
          KeyX = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = #CameraSpeed
        Else
          KeyX = 0
        EndIf
        
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = #CameraSpeed
        Else
          KeyY = 0
        EndIf
      
      
      MoveCamera  (0, KeyX, 0, KeyY)
      RotateCamera(0,  MouseY, MouseX, 0, #PB_Relative)
      
      RenderWorld()

      FlipBuffers()
      Repeat
    event = WindowEvent()
    If event = #PB_Event_CloseWindow
      quit = #True
    EndIf
  Until event = 0 Or quit = #True
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
 End

Re: fill the tank with Balls

Posted: Wed Jul 16, 2014 11:07 am
by IdeasVacuum
As always, great work applePi. Very interesting to learn that a cylinder can be given flat walls. 8)

Re: fill the tank with Balls

Posted: Wed Jul 16, 2014 1:09 pm
by djes
Nice example ! There's a duplicate InitSprite(), it throws an error here.
Also, this kind of program shows that physics could (and will) be nice, but it still isn't really realistic, I think...

Re: fill the tank with Balls

Posted: Wed Jul 16, 2014 1:51 pm
by applePi
thanks IdeasVacuum and djes , the code is corrected for the double InitSprite.
in fact i have surprised it works. just in the morning i have used the Bridge.pb example as a framework to test this tank/balls demo. when i was rotating the tank the balls go outside the tank and even they stay in the air without falling on the ground. then after redesigning the dimensions of the whole screen it works. so it is possible that dimensioning the scene are important for the Bullet engine to work correctly.

Edit:: now i found it, if we throw the balls, and then we stay stationary a few seconds, the trying to rotate the tank, the ball will go through the tank walls.
so we should make the balls active from the beginning to prevent such phenomena.
i will find a way and will correct the code.
Edit2: added this line MoveEntity(#cyl,0,0.5,0) before the loop to keep the balls active by the cheat i talked about above. it does not work to use DisableEntityBody(ball(ballNum), 0) for the balls in line 106

Re: fill the tank with Balls

Posted: Wed Jul 16, 2014 2:06 pm
by STARGÅTE
program crashed!

I think because, you have a opened window, but no window event handling.
So insert a WindowEvent()

Re: fill the tank with Balls

Posted: Wed Jul 16, 2014 2:19 pm
by DK_PETER
Nice example applePi.

I've modified your code a bit..
The EntityAngularFactor() seems to keeps the balls inside.

Edit: EntityAngularFactor() was not enough -
Added ApplyEntityImpulse(ball(ballNum), 0.1, 1, 0.1,0,16,0) <--this works too

Code: Select all

#CameraSpeed = 1
#cyl = 200
#ball = 210
#mat = 220
#ballsReflector = 230

Global Dim ball(1000)
Global ballNum
Define.f KeyX, KeyY, MouseX, MouseY

ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "....Space to throw balls,...... XZ to rotate the Tank, ............ mouse and arrow keys to move the cam  ", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

;Initialize environment
InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()

OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0)-4, 0, 0, 0)
   
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures/",#PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Scripts",#PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Packs/desert.zip", #PB_3DArchive_Zip)
  Parse3DScripts()
 
 
  ; transparent Texture from example CreateTextureAlpha.pb in Purebasic 3D folder
    CreateTexture(#mat, 256, 256)
      StartDrawing(TextureOutput(#mat))
      DrawingMode(#PB_2DDrawing_AllChannels | #PB_2DDrawing_AlphaBlend)
      Box(0, 0, 256, 256, RGBA(0, 0, 0, 255))
      Box(0, 0, 256, 256, RGBA(100, 255, 0, 70))
      ;Circle(127, 127, 50, RGBA(0, 0, 0, 0))
      StopDrawing()
      CreateMaterial(#mat, TextureID(#mat))
      MaterialBlendingMode(#mat, #PB_Material_AlphaBlend)
      MaterialCullingMode(#mat, #PB_Material_NoCulling)
      DisableMaterialLighting(#mat, 1)
     
    WorldShadows(#PB_Shadow_Modulative, -1, RGB(127, 127, 127))
   
    ;Materials
    CreateMaterial(0, LoadTexture(0, "Wood.jpg"))
    GetScriptMaterial(1, "SphereMap/SphereMappedRustySteel")
    CreateMaterial(2, LoadTexture(2, "Dirt.jpg"))
    GetScriptMaterial(3, "Scene/GroundBlend")
    MaterialBlendingMode(0, #PB_Material_AlphaBlend)
    MaterialCullingMode(0, #PB_Material_NoCulling )
    DisableMaterialLighting(0, 1)

       
    ; create the Tank
    CreateCylinder(#cyl,3,10,2,0,0) ; "2" specify a square tank look the Docs.
    CreateEntity(#cyl, MeshID(#cyl), MaterialID(#mat), 0,9.5,0)
    RotateEntity(#cyl, 0,0,1)
    EntityPhysicBody(#cyl, #PB_Entity_StaticBody, 1, 0.1, 1)
   
    ; create the Balls
    CreateSphere(#ball, 0.3 )
    For i = 0 To 1000
    ball(i) = CreateEntity(#PB_Any, MeshID(#ball),#PB_Material_None)
    MoveEntity(ball(i), 0,14,0, #PB_Absolute)
    Next
       
    ; Camera
    ;
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, -30, 20, -20, #PB_Absolute)
    CameraLookAt(0, 0 , 0  , 0)
   
    ; Skybox
    ;
    SkyBox("desert07.jpg")
   
    ; Light
    ;
    CreateLight(0, RGB(255, 255, 255), 100, 800, -500)
    AmbientColor(RGB(20, 20, 20))
    CreateCube(#ballsReflector,1)
    CreateEntity(#ballsReflector, MeshID(#ballsReflector),MaterialID(0),0,15,0)
    ScaleEntity(#ballsReflector, 3,1,3)
    EntityPhysicBody(#ballsReflector, #PB_Entity_StaticBody, 1, 0.1, 1)
   
    ;ground
    CreateEntity(3,MeshID(#ballsReflector),MaterialID(3), 0, 0, 0)
    ScaleEntity(3,40,2,40)
    EntityRenderMode(3, 0)
    EntityPhysicBody(3, #PB_Entity_StaticBody, 1, 1, 1)
   
           
    Repeat
       Repeat:ev=WindowEvent():Until ev=0
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
      EndIf
      ExamineKeyboard()
      If KeyboardPushed(#PB_Key_Space) ; throwing balls by giving it physical properties
      If done = 0
      ballNum+1
      If ballNum = 1000: done = 1:  EndIf
      EntityPhysicBody(ball(ballNum),#PB_Entity_SphereBody,1,0.5,1)
      EntityAngularFactor(ball(ballNum),Random(1,0),Random(1,0),Random(1,0))
      ApplyEntityImpulse(ball(ballNum), 0.1, 1, 0.1,0,16,0)
      EndIf
      EndIf
             
        If KeyboardPushed(#PB_Key_Z)
          RotateEntity(#cyl, 0,0,2,#PB_Relative)
        EndIf
        If KeyboardPushed(#PB_Key_X)
          RotateEntity(#cyl, 0,0,-2,#PB_Relative)
        EndIf

        If KeyboardPushed(#PB_Key_Left)
          KeyX = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = #CameraSpeed
        Else
          KeyX = 0
        EndIf
       
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = #CameraSpeed
        Else
          KeyY = 0
        EndIf
     
     
      MoveCamera  (0, KeyX, 0, KeyY)
      RotateCamera(0,  MouseY, MouseX, 0, #PB_Relative)
     
      RenderWorld()

      FlipBuffers()
     
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
   
 End

Re: fill the tank with Balls

Posted: Wed Jul 16, 2014 2:30 pm
by applePi
@stargate , i have added the WindowEvent(), hope it works
@DK_PETER , i am still find the balls escape the tank walls. do this test: throw about 20 balls, then stay calm for 10 seconds, then rotate the Tank, i see the ball escape. i remember the EntityAngularFactor are usefull but i forgot it completely.
look Edit2 above, i have used the illegal cheat, and it seems works. test it please. i changed the code a little
thanks

Re: fill the tank with Balls

Posted: Wed Jul 16, 2014 2:36 pm
by DK_PETER
applePi wrote:@stargate , i have added the WindowEvent(), hope it works
@DK_PETER , i am still find the balls escape the tank walls. do this test: throw about 20 balls, then stay calm for 10 seconds, then rotate the Tank, i see the ball escape. i remember the EntityAngularFactor are usefull but i forgot it completely.
look Edit2 above, i have used the illegal cheat, and it seems works. test it please. i changed the code a little
thanks
@applePi
Yes it works :-) Even if you add the reverse rotation, they stay inside.

Re: fill the tank with Balls

Posted: Wed Jul 16, 2014 5:03 pm
by applePi
i found a Legal solution from here http://www.purebasic.fr/english/viewtop ... =4&t=58942 , it is an advice from comtois to falsam to use DisableEntityBody(entity,0)
i haven't used it correctly above. but here when we rotate the tank there is a loop to activate all the balls DisableEntityBody(ball(i),0) in line 115 when we press Z to rotate the tank. i have waited several minutes and when everything are stationary and calm , then rotating the tank are successfully pushes the spheres.
the new code below, and deleting the illegal code, but note that some small free energy vibrations using my cheat are not bad, we can use the 2 methods together.
we can later do fine tunning the code to activate only the real balls which are inside the tank

Code: Select all

#CameraSpeed = 1
#cyl = 200
#ball = 210
#mat = 220
#ballsReflector = 230

Global Dim ball(1000)
Global ballNum
Define.f KeyX, KeyY, MouseX, MouseY

ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "....Space to throw balls,...... Z to rotate the Tank, ............ mouse and arrow keys to move the cam  ", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

;Initialize environment
InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()

OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0)-4, 0, 0, 0)
    
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures/",#PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Scripts",#PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Packs/desert.zip", #PB_3DArchive_Zip)
  Parse3DScripts()
  
  
  ; transparent Texture from example CreateTextureAlpha.pb in Purebasic 3D folder
    CreateTexture(#mat, 256, 256)
      StartDrawing(TextureOutput(#mat))
      DrawingMode(#PB_2DDrawing_AllChannels | #PB_2DDrawing_AlphaBlend)
      Box(0, 0, 256, 256, RGBA(0, 0, 0, 255))
      Box(0, 0, 256, 256, RGBA(100, 255, 0, 70)) 
      ;Circle(127, 127, 50, RGBA(0, 0, 0, 0))
      StopDrawing()
      CreateMaterial(#mat, TextureID(#mat))
      MaterialBlendingMode(#mat, #PB_Material_AlphaBlend)
      MaterialCullingMode(#mat, #PB_Material_NoCulling)
      DisableMaterialLighting(#mat, 1)
      
    WorldShadows(#PB_Shadow_Modulative, -1, RGB(127, 127, 127))
    
    ;Materials
    CreateMaterial(0, LoadTexture(0, "Wood.jpg"))
    GetScriptMaterial(1, "SphereMap/SphereMappedRustySteel")
    CreateMaterial(2, LoadTexture(2, "Dirt.jpg"))
    GetScriptMaterial(3, "Scene/GroundBlend")
    MaterialBlendingMode(0, #PB_Material_AlphaBlend)
    MaterialCullingMode(0, #PB_Material_NoCulling )
    DisableMaterialLighting(0, 1)

        
    ; create the Tank
    CreateCylinder(#cyl,3,10,2,0,0) ; "2" specify a square tank look the Docs.
    CreateEntity(#cyl, MeshID(#cyl), MaterialID(#mat), 0,9.5,0)
    RotateEntity(#cyl, 0,0,1)
    EntityPhysicBody(#cyl, #PB_Entity_StaticBody, 1, 0.1, 1)
    
    ; create the Balls
    CreateSphere(#ball, 0.3 )
    For i = 0 To 1000
    ball(i) = CreateEntity(#PB_Any, MeshID(#ball),#PB_Material_None)
    MoveEntity(ball(i), 0,14,0, #PB_Absolute)
    Next
        
    ; Camera
    ;
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, -30, 20, -20, #PB_Absolute)
    CameraLookAt(0, 0 , 0  , 0)
    
    ; Skybox
    ;
    SkyBox("desert07.jpg")
    
    ; Light
    ;
    CreateLight(0, RGB(255, 255, 255), 100, 800, -500)
    AmbientColor(RGB(20, 20, 20))
    CreateCube(#ballsReflector,1)
    CreateEntity(#ballsReflector, MeshID(#ballsReflector),MaterialID(0),0,15,0)
    ScaleEntity(#ballsReflector, 3,1,3)
    EntityPhysicBody(#ballsReflector, #PB_Entity_StaticBody, 1, 0.1, 1)
    
    ;ground
    CreateEntity(3,MeshID(#ballsReflector),MaterialID(3), 0, 0, 0)
    ScaleEntity(3,40,2,40)
    EntityRenderMode(3, 0) 
    EntityPhysicBody(3, #PB_Entity_StaticBody, 1, 1, 1)
       
    
    Repeat
        
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
      EndIf
      ExamineKeyboard()
      If KeyboardPushed(#PB_Key_Space) ; throwing balls by giving it physical properties
      If done = 0
      ballNum+1
      If ballNum = 1000: done = 1:  EndIf
      
      EntityPhysicBody(ball(ballNum),#PB_Entity_SphereBody,1,0.5,1)
      DisableEntityBody(ball(ballNum), 0)
      EndIf 
      EndIf
    
             
        If KeyboardPushed(#PB_Key_Z)
         
          RotateEntity(#cyl, 0,0,2,#PB_Relative)
          
          For i=1 To 1000
            DisableEntityBody(ball(i),0)
          Next
          
        EndIf
          
        
        If KeyboardPushed(#PB_Key_Left)
          KeyX = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = #CameraSpeed
        Else
          KeyX = 0
        EndIf
        
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = #CameraSpeed
        Else
          KeyY = 0
        EndIf
      
      
      MoveCamera  (0, KeyX, 0, KeyY)
      RotateCamera(0,  MouseY, MouseX, 0, #PB_Relative)
      
      RenderWorld()

      FlipBuffers()
      Repeat
    event = WindowEvent()
    If event = #PB_Event_CloseWindow
      quit = #True
    EndIf
  Until event = 0 Or quit = #True
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
 End

Re: fill the tank with Balls

Posted: Thu Jul 17, 2014 7:45 am
by Bananenfreak
Hmm, I don´t know, but is there something wrong with OGREs spleepbehavior?
Inactive balls should get active if they get an impulse, force or in any way energy.
I think here´s an problem. It´s only a guess...

What I mean is: Statistically objects (A) in sleepmode fall through other objects (B) or These objects (B) can pass object A without response.
I think there could be something incorrect with threads or so...

Re: fill the tank with Balls

Posted: Thu Jul 17, 2014 8:56 am
by applePi
Bananenfreak, in line 105 in the latest code above replace the line:
DisableEntityBody(ball(ballNum), 0) with
SetEntityAttribute(ball(ballNum), #PB_Entity_LinearSleeping,0)
and the balls stay active for ever. the doc says:
#PB_Entity_LinearSleeping : Change the minimum linear velocity value under which the entity will be sleeping. and the minimum here is 0 and there is no |velocity| value under it, so the balls keeps active. test it. the help file have many other adjustments for other purposes:
http://www.purebasic.com/documentation/ ... ibute.html
i think this will solve the DK_PETER test in the past to rotate a big ground space and he found that the ball sink in the ground (somewhere in the forum), but now it will not sink using DisableEntityBody(ball, 0) or SetEntityAttribute(ball(ballNum), #PB_Entity_LinearSleeping,0)
it seems to me SetEntityAttribute are more realistic than DisableEntityBody(ball, 0), try it
so the user have the choice.
about the question why not the 1000 balls stay active from the beginning without additional code? the answer could be: why not giving the user the choice ? but this is only a controversy from me, since when we enable the physics then certainly we want the balls on the scene active always

Re: fill the tank with Balls

Posted: Thu Jul 17, 2014 1:47 pm
by Bananenfreak
If physicobjects are active whole time there could be in higher powerconsumption...

Re: fill the tank with Balls

Posted: Fri Jul 18, 2014 11:52 am
by DK_PETER
applePi wrote:i found a Legal solution from here http://www.purebasic.fr/english/viewtop ... =4&t=58942 , it is an advice from comtois to falsam to use DisableEntityBody(entity,0)
@applePi.
Actually...there is no 'legal' way to obtain the desired result, when using a moving/rotating object with the #PB_Entity_StaticBody attached.
For it to work, we must apply a VERY small rotational value (Below f.ex 2 or 3). Go above a value of 3 and the balls spews out on all sides (Both in yours and mine solution).
There are no real solution to the problem as the object we're trying to animate is defined with a static property. In a 'real' example, which would require a somewhat
faster rotational/movable (both ways) animation, the static object is completely useless for anything other than a'hmmm.. a glued position in space.
The only viable option, which should work, is creating several static objects and use them to 'hinge' an object(container) with the f. ex. #PB_Entity_BoxBody property attached.

Re: fill the tank with Balls

Posted: Fri Jul 18, 2014 2:28 pm
by applePi
you are right DK_PETER , the static should be static, even i'm not sure if the word "static" exclude rotation or not. but since the static object rotation works partially we can use it in specific projects with low speeds , note that if you want to increase the speed of the pot you should increase the balls radius so not to penetrate the walls. i don't have a thick pot to try it to see the effect of thickness.
there is a requests before for the compound objects , look here http://www.purebasic.fr/english/viewtop ... 62#p442673
http://purebasic.fr/english/viewtopic.p ... it=concave
and other places. in the future it could be part of AttachEntityObject() function so all the attached objects can have a dynamic concave structure.

if we opened the Engine3D.dll with some text editor we can see this
?0GImpactConcaveShape@...
just a superficial note. without a comment.
but look that "btCompoundShape" are in bullet, but it is not clear that it is available also in Ogre implementation of bullet http://www.ogre3d.org/tikiwiki/OgreBullet

michael from mp3d have implemented some weak form (but working) of compound objects , i have used it to make a working pendulum with escape mechanism like found in the real pendulum clock (just needs tick tack sound) look here http://forums.purebasic.com/english/vie ... =engine+3D
i refer to that example to show the benefits of implementing compound objects.

Re: fill the tank with Balls

Posted: Thu Oct 20, 2016 11:14 am
by applePi
the above example in PB 5.50
my purpose is to show the usage of #PB_Entity_LinearDamping
since many users noticed that the balls continue to move.
but using :
SetEntityAttribute(ball(ballNum), #PB_Entity_LinearDamping, 0.3)
make the balls stop before falling out of the world
instead of 0.3 try 1 and the balls can't fall from the generator
0 will let it move continuously
note: don't fill the tank too much since your computer will slow down
Edit:i have tried a cylinder (filling it from inside) by 300 balls and the fps was 30, while with the tube it is 20 (this is when the containers are filled) , this is natural due to the complexity of the tube , so i will try later a container made from 4 boxes attached together and the fps may be better.

instructions: use PB 5.50, space to fill the tank, Z to rotate the tank

Code: Select all

#CameraSpeed = 1
Enumeration
#cyl = 200
#ball
#mat
#ballsReflector
#base
EndEnumeration

Global Dim ball(1000)
Global ballNum
Define.f KeyX, KeyY, MouseX, MouseY

ExamineDesktops()
OpenWindow(0, 0, 0, DesktopWidth(0), DesktopHeight(0), "....Space to throw balls,.. Z to rotate the Tank, ...mouse and arrow keys to move the cam  ", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

;Initialize environment
InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()

OpenWindowedScreen(WindowID(0), 0, 0, DesktopWidth(0), DesktopHeight(0)-4, 0, 0, 0)
    
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures/",#PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Scripts",#PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Packs/desert.zip", #PB_3DArchive_Zip)
  Parse3DScripts()
  
  
  ; transparent Texture
    CreateTexture(#mat, 256, 256)
      StartDrawing(TextureOutput(#mat))
      DrawingMode(#PB_2DDrawing_AllChannels | #PB_2DDrawing_AlphaBlend)
      Box(0, 0, 256, 256, RGBA(0, 0, 0, 255))
      Box(0, 0, 256, 256, RGBA(100, 255, 0, 70)) 
      
      StopDrawing()
      CreateMaterial(#mat, TextureID(#mat))
      MaterialBlendingMode(#mat, #PB_Material_AlphaBlend)
      MaterialCullingMode(#mat, #PB_Material_NoCulling)
      DisableMaterialLighting(#mat, 1)
      
    WorldShadows(#PB_Shadow_Modulative, -1, RGB(127, 127, 127))
    
    CreateLine3D(0, 0, 0, 0, RGB(255,   0,   0), 10,  0,  0, RGB(255,   0,   0))  ; Axis X
    CreateLine3D(1, 0, 0, 0, RGB(  0, 255,   0),  0, 10,  0, RGB(  0, 255,   0))  ; Axis Y
    CreateLine3D(2, 0, 0, 0, RGB(  0,   0, 255),  0,  0, 10, RGB(  0,   0, 255))  ; Axis Z
    
    ;Materials
    CreateMaterial(0, LoadTexture(0, "Wood.jpg"))
    GetScriptMaterial(1, "SphereMap/SphereMappedRustySteel")
    CreateMaterial(2, LoadTexture(2, "Dirt.jpg"))
    GetScriptMaterial(3, "Scene/GroundBlend")
    MaterialBlendingMode(0, #PB_Material_AlphaBlend)
    MaterialCullingMode(0, #PB_Material_NoCulling )
    DisableMaterialLighting(0, 1)
    
            
    ; create the Tank
    CreateTube(#cyl, 4, 3, 10, 4, 16) ; "4" specify a square tank
    TransformMesh(#cyl, 0, 10, 0, 1,1,1, 0,0,0)
    UpdateMeshBoundingBox(#cyl)
    CreateEntity(#cyl, MeshID(#cyl), MaterialID(#mat), 0,-5,0)
    CreateCylinder(#base,3,1,4,16,1)
    CreateEntity(#base, MeshID(#base), MaterialID(0), 0,0,0)
    Global tank = CreateEntity(#PB_Any,0,0)
    AddSubEntity(tank, #cyl, #PB_Entity_StaticBody) ; we add the concave geometry of the tube
    AddSubEntity(tank, #base, #PB_Entity_ConvexHullBody)
    MoveEntity(tank, 10,5,0)
    CreateEntityBody(tank, #PB_Entity_CompoundBody, 0, 0.5, 1)
        
    ; create the Balls
    CreateSphere(#ball, 0.3 )
    For i = 0 To 300
     ball(i) = CreateEntity(#PB_Any, MeshID(#ball),#PB_Material_None)
     MoveEntity(ball(i), 10,14,0, #PB_Absolute)
    Next
    
    
    ; Camera
    ;
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, -30, 25, -20, #PB_Absolute)
    CameraLookAt(0, 0 , 5  , 0)
    
    ; Skybox
    ;
    SkyBox("desert07.jpg")
    
    ; Light
    ;
    CreateLight(0, RGB(255, 255, 255), 100, 800, -500)
    AmbientColor(RGB(20, 20, 20))
    CreateCube(#ballsReflector,1)
    CreateEntity(#ballsReflector, MeshID(#ballsReflector),MaterialID(0),10,15,0)
    ScaleEntity(#ballsReflector, 3,1,3)
    CreateEntityBody(#ballsReflector, #PB_Entity_StaticBody, 1, 0.1, 1)
    
    ;ground
    CreateEntity(3,MeshID(#ballsReflector),MaterialID(3), 0, -5, 0)
    ScaleEntity(3,40,2,40)
    EntityRenderMode(3, 0) 
    CreateEntityBody(3, #PB_Entity_StaticBody, 1, 1, 1)
          
    a$=" ........Space To throw balls,..... Z To rotate the Tank, ...mouse And arrow keys To move the cam"
    Repeat
      Repeat
        Until WindowEvent() = 0
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
      EndIf
      ExamineKeyboard()
      If KeyboardPushed(#PB_Key_Space) ; throwing balls by giving it physical properties
      If done = 0
      ballNum+1
      If ballNum = 1000: done = 1:  EndIf
      
      CreateEntityBody(ball(ballNum),#PB_Entity_SphereBody,1,0.5,Random(1))
      DisableEntityBody(ball(ballNum), 0)
      SetEntityAttribute(ball(ballNum), #PB_Entity_LinearDamping, 0.3)
      EndIf 
      EndIf
    
             
        If KeyboardPushed(#PB_Key_Z)
         
          RotateEntity(tank, 0,0,1,#PB_Relative)
                    
        EndIf
          
        
        If KeyboardPushed(#PB_Key_Left)
          KeyX = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = #CameraSpeed
        Else
          KeyX = 0
        EndIf
        
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = #CameraSpeed
        Else
          KeyY = 0
        EndIf
      
      SetWindowTitle(0, "FPS = "+Str(Engine3DStatus(#PB_Engine3D_CurrentFPS ))+a$)
      MoveCamera  (0, KeyX, 0, KeyY)
      RotateCamera(0,  MouseY, MouseX, 0, #PB_Relative)
      
      RenderWorld()

      FlipBuffers()
      Repeat
    event = WindowEvent()
    If event = #PB_Event_CloseWindow
      quit = #True
    EndIf
  Until event = 0 Or quit = #True
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
 End