Gears

Everything related to 3D programming
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Gears

Post by applePi »

Gears, using the latest PB 5.50 beta 1. with the new type #PB_Entity_CompoundBody for the CreateEntityBody function which make us able to design and simulate mechanical machines. this is just a show case , a more precise movements is possible
press Z/X to apply torque force to the left gear. if gears teeth stuck give some push to the right gear by pressing Space
some notes after the code
Image

Code: Select all

;
; ------------------------------------------------------------
;
;   PureBasic - CompoundBody
;
;    (c) Fantaisie Software
;
; ------------------------------------------------------------
;

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"

#CameraSpeed = 1

Define.f KeyX, KeyY, MouseX, MouseY


If InitEngine3D()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/"              , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures"  , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Models"    , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts"    , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/GUI"        , #PB_3DArchive_FileSystem)
    Parse3DScripts()
    
    ;WorldDebug(#PB_World_DebugBody)
        
    ;-------------------------------
    ; create  material
    CreateMaterial(1, LoadTexture(1, "wood.jpg"))
    SetMaterialColor(1, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
    ; 
    CreateMaterial(2, LoadTexture(2, "dirt.jpg"))
    SetMaterialColor(2, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
    
    CreateMaterial(3, LoadTexture(3, "clouds.jpg"))
    SetMaterialColor(3, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
    
    CreateMaterial(4, LoadTexture(4, "r2skin.jpg"))
    
    ;-------------------------------
    CreateCube(1, 2)
    CreateSphere(3, 1)
    CreateEntity(1, MeshID(1),MaterialID(1),  0, 0, 0)
    CreateEntity(2, MeshID(1),MaterialID(1),  0, 0, 0.1)
    RotateEntity(2, 0,0,45, #PB_Absolute)
    Global Compound = CreateEntity(#PB_Any,0,0)
    AddSubEntity(Compound, 1, #PB_Entity_BoxBody) 
    AddSubEntity(Compound, 2, #PB_Entity_BoxBody)
    DisableDebugger
    CreateEntityBody(Compound, #PB_Entity_CompoundBody, 1, 0.4, 0.5)
    EnableDebugger
        ;-------------------------------
 
    CreateEntity(3, MeshID(1),MaterialID(3),  0, 0, 0)
    CreateEntity(4, MeshID(1),MaterialID(3),  0, 0, 0)
    CreateEntity(5, MeshID(1),MaterialID(3),  0, 0, 0.1)
    RotateEntity(4, 0,0,30, #PB_Absolute)
    RotateEntity(5, 0,0,60, #PB_Absolute)
    Comp2 = CreateEntity(#PB_Any,0,0)
    AddSubEntity(Comp2, 3, #PB_Entity_BoxBody) 
    AddSubEntity(Comp2, 4, #PB_Entity_BoxBody)
    AddSubEntity(Comp2, 5, #PB_Entity_BoxBody)
    DisableDebugger
    CreateEntityBody(Comp2, #PB_Entity_CompoundBody, 1, 0.4, 0.4)
    EnableDebugger
    
    ;Ground
    ;
    Ground = CreateEntity(#PB_Any, MeshID(1), MaterialID(2), 0, -7, 0)
    ScaleEntity(Ground, 40, 0.4, 40)
    CreateEntityBody(Ground, #PB_Entity_StaticBody)
        
    GenericJoint(4,EntityID(Ground), 0, 4, 0,EntityID(Compound), 0, 0, 0)
    SetJointAttribute(4, #PB_Joint_NoLimit, 0, 5)
    ;SetJointAttribute(4, #PB_Joint_LowerLimit, 1, 5) 
    ;SetJointAttribute(4, #PB_Joint_UpperLimit, 200, 5) 
    ;SetJointAttribute(4, #PB_Joint_Damping, 0.001, 5)
    GenericJoint(5,EntityID(Ground), 2.6, 4, 0,EntityID(Comp2), 0, 0, 0)
    SetJointAttribute(5, #PB_Joint_NoLimit, 0, 5)
    
     ; camera
    CreateCamera(0, 0, 0, 100, 100, #True)
    MoveCamera(0,1.5,-2,10, #PB_Absolute)
    
    ; GUI
    OpenWindow3D(0, 0, 0, 50 , 10 , "")
    HideWindow3D(0,1)
    ShowGUI(128, 1) ; Display the GUI, semi-transparent and display the mouse cursor
    SetWindowTitle(0, "PureBasic-3D Demos ....  Press Z/X to apply torque to the left Gear")
    
    Repeat
      Screen3DEvents()
      
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
        InputEvent3D(MouseX(), MouseY(),0)
        BodyPick(CameraID(0), MouseButton(#PB_MouseButton_Left), MouseX(), MouseY(), 1)
      EndIf
    
      If ExamineKeyboard()
        
        If KeyboardPushed(#PB_Key_Z)
          ApplyEntityTorque(Compound, 0, 0, 25)
          ElseIf KeyboardPushed(#PB_Key_X)
            ApplyEntityTorque(Compound, 0, 0, -25)
            ElseIf KeyboardPushed(#PB_Key_Space) ; in case gears teeth stuck
            ApplyEntityImpulse(comp2, -0.2, 0, 0, 0, 10,0)
   
        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
        
      EndIf
      
      MoveCamera  (0, KeyX, 0, KeyY)
      RotateCamera(0,  MouseY, MouseX, 0, #PB_Relative)
      
      RenderWorld()
      
      FlipBuffers()
      
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
  EndIf
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf

End
Note: it seems the Damping (#PB_Joint_Damping) is active if we use it with #PB_Joint_EnableSpring for the Generic Joint, and not to the rotational objects with generic Joints. disable the body and joint of the right gear and uncomment line 85:
SetJointAttribute(4, #PB_Joint_Damping, 0.001, 5)
it does not have any effect on damping the left Gear rotation, it will keep running for ever
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Gears

Post by applePi »

more about compound entity, something like a turbine.
seems there is a way to get damping behavior for the rotational objects, is to give it a spring feature but with very low stiffness and damping zero, so it will not rotate forever. (and the spring will not damaged)

Note: there is a visual effect like that when you look at a rotating fan.
operations instructions on the title bar
inspect the scene with mouse and arrow keys

Image

Code: Select all

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"

#CameraSpeed = 0.4

Define.f KeyX, KeyY, MouseX, MouseY

If InitEngine3D()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/"              , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures"  , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Models"    , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts"    , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/GUI"        , #PB_3DArchive_FileSystem)
    Parse3DScripts()
    
    ;WorldDebug(#PB_World_DebugBody)
        
    ;-------------------------------
    ; create  material
    CreateMaterial(1, LoadTexture(1, "axes.png"))
    ;RotateMaterial(1, -70, #PB_Material_Fixed)
    SetMaterialColor(1, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
    ; 
    CreateMaterial(2, LoadTexture(2, "snow_1024.jpg"))
    SetMaterialColor(2, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
    
    CreateMaterial(3, LoadTexture(3, "clouds.jpg"))
    SetMaterialColor(3, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
    
    CreateMaterial(4, LoadTexture(4, "r2skin.jpg"))
    
    ;-------------------------------
;construction of a gear with 18 teeth
ang=40 ; the angle wanted for every tooth of the gear
CreateCylinder(50, 1, 0.5)
CreateEntity(50, MeshID(50),MaterialID(1),  0, 0, 0)
RotateEntity(50, 90,0, 0, #PB_Absolute)
CreateCube(1, 1)

Global Compound = CreateEntity(#PB_Any,0,0)

For i=1 To 18
angle.f+20
x.f = Cos(Radian(angle)): z.f = Sin(Radian(angle))
CreateEntity(i, MeshID(1),MaterialID(3),  x, z, 0)
ScaleEntity(i, 1, 0.05, 0.4)

ang+20
RotateEntity(i, 0,0, ang, #PB_Absolute)
AddSubEntity(Compound, i, #PB_Entity_BoxBody) 
Next

AddSubEntity(Compound, 50, #PB_Entity_CylinderBody) 
CreateEntityBody(Compound, #PB_Entity_CompoundBody, 1, 0.4, 0.5)

;-----------------------------------------
    ;Ground
    ;
    Ground = CreateEntity(#PB_Any, MeshID(1), MaterialID(2), 0, -7, 0)
    ScaleEntity(Ground, 40, 0.4, 40)
    CreateEntityBody(Ground, #PB_Entity_StaticBody)
    
    GenericJoint(4,EntityID(Ground), 0, 5, 0,EntityID(Compound), 0, 0, 0)
    SetJointAttribute(4, #PB_Joint_EnableSpring, #True, 5)
    SetJointAttribute(4, #PB_Joint_Stiffness, 5, 5)
    SetJointAttribute(4, #PB_Joint_Damping, 0.0, 5)
    
     ; camera
    CreateCamera(0, 0, 0, 100, 100, #True)
    MoveCamera(0,0,-2,5, #PB_Absolute)
    
    ; GUI
    OpenWindow3D(0, 0, 0, 50 , 10 , "")
    HideWindow3D(0,1)
    ShowGUI(128, 1) ; Display the GUI, semi-transparent and display the mouse cursor
    SetWindowTitle(0, "PureBasic-3D Demos ...Press 'space': to drop stones ... Z/X to apply torque to the Turbine, ... ")
    
  #stone = 30
  Global Dim stone(1000)
  CreateCube(#stone, 0.1)
  For i = 1 To 1000
  stone(i) = CreateEntity(#PB_Any, MeshID(#stone),#PB_Material_None)
  Next

    Repeat
      Screen3DEvents()
      
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.1
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.1
        InputEvent3D(MouseX(), MouseY(),0)
        BodyPick(CameraID(0), MouseButton(#PB_MouseButton_Left), MouseX(), MouseY(), 1)
      EndIf
    
      If ExamineKeyboard()
        
        If KeyboardPushed(#PB_Key_Z)
          ApplyEntityTorque(Compound, 0, 0, 25)
          ;ApplyEntityTorqueImpulse(Compound, 0, 0, 1)

          ElseIf KeyboardPushed(#PB_Key_X)
            ApplyEntityTorque(Compound, 0, 0, -25)
            
          EndIf
          
    If KeyboardReleased(#PB_Key_Space); throw cubes over the gear
      stn+1
      If stn > 1000: stn=1: EndIf
      MoveEntity(stone(stn), 1,1,0)
      CreateEntityBody(stone(stn),#PB_Entity_BoxBody,1)
    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
        
      EndIf
      
      MoveCamera  (0, KeyX, 0, KeyY)
      RotateCamera(0,  MouseY, MouseX, 0, #PB_Relative)
      
      RenderWorld()
      
      FlipBuffers()
      
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
  EndIf
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf

End
User avatar
Bananenfreak
Enthusiast
Enthusiast
Posts: 519
Joined: Mon Apr 15, 2013 12:22 pm

Re: Gears

Post by Bananenfreak »

Really cool examples. Thank you for sharing it with us :)

I played a while with the turbine, started it in idle running then part load and full load :D
Image
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Gears

Post by IdeasVacuum »

Brilliant stuff as usual applePi. Not sure how far your car will go with gears made out of slices of toast.......
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Gears

Post by applePi »

Thanks Bananenfreak and IdeasVacuum
Not sure how far your car will go with gears made out of slices of toast
we can use a real gear such as made from modeling software. i have made some tests and it seems we can use real gears if we use #PB_Entity_StaticBody) as a guidance for the AddSubEntity function to follow the cavities and holes of the object
example:

Code: Select all

LoadMesh(6, "gear_lwo.mesh")
CreateEntity(6, MeshID(6),MaterialID(6),  0, 0, 0)
Global Gear2 = CreateEntity(#PB_Any,0,0)
AddSubEntity(Gear2, 6, #PB_Entity_StaticBody)
it can interact with gears made by adding usual convex compound objects, but i can't make it interact with a gear made the same way (#PB_Entity_StaticBody). but this formula works:
compound -> (real + compound)-> real gear
here the white and green gears is real ("gear_lwo.mesh")
you need this free gear downloaded from turbosquid and converted to ogre mesh
http://wikisend.com/download/360042/gear_lwo.mesh

the only difficulty is to position objects so not to collide when the generic joints attracted them to the designed positions. i will wait for the docs of the addSubEntity
Image

use Z/X keys to rotate the left gear (by applying torque), this rotations will transfered to all gears
use space to apply force to the big white gear
mouse and arrow keys to move the camera

needs PB 5.50 beta 2 , and the model http://wikisend.com/download/360042/gear_lwo.mesh save it in the same folder as the code
Update:
as refered to in http://purebasic.fr/english/viewtopic.p ... 78#p489709 , we have disabled collision for all gears during the construction, and when we enter the main loop we enable it again after every thing fits in place after 1 second or so.
needs PB 5.50 beta 2

Code: Select all

;
;
;
; ------------------------------------------------------------
;
;   PureBasic - CompoundBody
;
;    (c) Fantaisie Software
;
; ------------------------------------------------------------
;

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"

#CameraSpeed = 0.4

Define.f KeyX, KeyY, MouseX, MouseY


If InitEngine3D()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    Add3DArchive("."    , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/"              , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures"  , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Models"    , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts"    , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/GUI"        , #PB_3DArchive_FileSystem)
    Parse3DScripts()
    
    ;WorldDebug(#PB_World_DebugBody)
        
    ;-------------------------------
    ; create  material
    CreateMaterial(1, LoadTexture(1, "wood.jpg"))
    SetMaterialColor(1, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
    ; 
    GetScriptMaterial(2, "Color/Green")
    SetMaterialColor(2, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
    
    CreateMaterial(3, LoadTexture(3, "clouds.jpg"))
    SetMaterialColor(3, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
    
    CreateMaterial(4, LoadTexture(4, "ground_diffuse.png"))
    GetScriptMaterial(5, "Color/Red")
    CreateMaterial(6, LoadTexture(6, "snow_1024.jpg"))
    CreateMaterial(7, LoadTexture(7, "soil_wall.jpg"))
    
    ;-------------------------------
    
    ;the first left gear
    ;CreateCylinder(#Mesh, Radius.f, Height.f [, NbBaseSegments, NbHeightSegments, CloseTop])
    CreateCylinder(1, 1.5, 1 , 3, 1, 1)
    CreateEntity(1, MeshID(1),MaterialID(3),  0, 0, 0)
    RotateEntity(1, 0,90,90, #PB_Absolute)
    CreateEntity(2, MeshID(1),MaterialID(3),  0, 0, 0)
    RotateEntity(2, 0,90,90, #PB_Absolute)
    RotateEntity(2, 0,40,0, #PB_Relative)
    CreateEntity(3, MeshID(1),MaterialID(3),  0, 0, 0.1)
    RotateEntity(3, 0,90,90, #PB_Absolute)
    RotateEntity(3, 0,80,0, #PB_Relative)
    
    
    Global Gear1 = CreateEntity(#PB_Any,0,0)
    AddSubEntity(Gear1, 1, #PB_Entity_ConvexHullBody) 
    AddSubEntity(Gear1, 2, #PB_Entity_ConvexHullBody)
    AddSubEntity(Gear1, 3, #PB_Entity_ConvexHullBody)
    CreateEntityBody(Gear1, #PB_Entity_CompoundBody, 1, 0.4, 1)
    SetEntityAttribute(Gear1, #PB_Entity_DisableContactResponse, 1) ;disable collision
   
    ;-------------------------------
    
    LoadMesh(6, "gear_lwo.mesh")
    Global Gear2 = CreateEntity(#PB_Any,0,0)
    CreateEntity(6, MeshID(6),MaterialID(6),  0, 0, 0)
    ScaleEntity(6, 2,2,2)
    CreateCylinder(7, 0.5, 3 ) ; the blue axes
    CreateEntity(7, MeshID(7),MaterialID(3),  0, 0, 0) ; add axes (does not have a real job)
    RotateEntity(7,90,0,0)
    
    ;the component of red smaller gear which will attached later to the big white gear
    CreateCylinder(8, 0.7, 1 , 3, 1, 1) ; triangular cylinder
    For i=8 To 10 ; create tria cylinders entities from 8 to 10
      CreateEntity(i, MeshID(8),MaterialID(5),  0, 0, 2)
      RotateEntity(i, 90,90+rot,0, #PB_Absolute)
      rot+40 ; 360/9 = 40
      AddSubEntity(Gear2, i, #PB_Entity_ConvexHullBody) 
    Next
    
    AddSubEntity(Gear2, 6, #PB_Entity_StaticBody) ; the white gear passed as dynamic concave geometry
    AddSubEntity(Gear2, 7, #PB_Entity_CylinderBody)
    AddSubEntity(Gear2, 8, #PB_Entity_ConvexHullBody)
    AddSubEntity(Gear2, 9, #PB_Entity_ConvexHullBody)
    AddSubEntity(Gear2, 10, #PB_Entity_ConvexHullBody)
    CreateEntityBody(Gear2, #PB_Entity_CompoundBody, 5, 0.4, 1)
    SetEntityAttribute(Gear2, #PB_Entity_DisableContactResponse, 1); disable collision
    
    CreateEntity(11, MeshID(6),MaterialID(2),  0, 0, 0) ;another entity from the gear: "gear_lwo.mesh"
    Global Gear3 = CreateEntity(#PB_Any,0,0) ; the green gear
    AddSubEntity(Gear3, 11, #PB_Entity_StaticBody)
    CreateEntityBody(Gear3, #PB_Entity_CompoundBody, 5, 0.4, 1)
    SetEntityAttribute(Gear3, #PB_Entity_DisableContactResponse, 1); disable collision
           
    ;Ground
    Ground = CreateCube(#PB_Any, 1)
    Ground = CreateEntity(#PB_Any, MeshID(Ground), MaterialID(4), 0, -7, 0)
    ScaleEntity(Ground, 40, 0.4, 40)
    CreateEntityBody(Ground, #PB_Entity_StaticBody)
        
    GenericJoint(4,EntityID(Ground), -0.1, 4, 0,EntityID(Gear1), 0, 0, 0)
    SetJointAttribute(4, #PB_Joint_NoLimit, 0, 5)
    GenericJoint(5,EntityID(Ground), 3.1, 4, 0,EntityID(Gear2), 0, 0, 0)
    SetJointAttribute(5, #PB_Joint_NoLimit, 0, 5)
    
    GenericJoint(6,EntityID(Ground), 4.7, 4, 2,EntityID(Gear3), 0, 0, 0)
    SetJointAttribute(6, #PB_Joint_NoLimit, 0, 5)
    
     ; camera
    CreateCamera(0, 0, 0, 100, 100, #True)
    MoveCamera(0,0,-2,10, #PB_Absolute)
    CameraLookAt(0,1.5,-2,0)
    CreateLight(1, RGB(255,255,255), 0, 5, 10)
    
    
    ; GUI
    OpenWindow3D(0, 0, 0, 50 , 10 , "")
    HideWindow3D(0,1)
    ShowGUI(128, 1) ; Display the GUI, semi-transparent and display the mouse cursor
    SetWindowTitle(0, "PureBasic-3D Demos ....  Press Z/X to apply torque to the left Gear")
    
    tm.f = ElapsedMilliseconds(); we need to wait 1 second for the whole gears construction to fit together before enabling the collison again
    
    Repeat
      Screen3DEvents()
      
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.2
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.2
        InputEvent3D(MouseX(), MouseY(),0)
        BodyPick(CameraID(0), MouseButton(#PB_MouseButton_Left), MouseX(), MouseY(), 1)
      EndIf
    
      If ExamineKeyboard()
        
        If KeyboardPushed(#PB_Key_Z)
          ApplyEntityTorque(Gear1, 0, 0, 25)
          ElseIf KeyboardPushed(#PB_Key_X)
            ApplyEntityTorque(Gear1, 0, 0, -25)
            ElseIf KeyboardPushed(#PB_Key_Space) ; in case gears teeth stuck
            ApplyEntityImpulse(Gear2, -0.2, 0, 0, 0, 10,0)
   
        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
        
      EndIf
      
      MoveCamera  (0, KeyX, 0, KeyY)
      RotateCamera(0,  MouseY, MouseX, 0, #PB_Relative)
      
      RenderWorld()
      
      FlipBuffers()
      
      If twoseconds = 0 
      tm2.f = ElapsedMilliseconds()
      If (tm2-tm) >= 1000 ; after 1 second enable the collison
        ;enable the collision for all the entities
        SetEntityAttribute(Gear1, #PB_Entity_DisableContactResponse, 0)
        SetEntityAttribute(Gear2, #PB_Entity_DisableContactResponse, 0)
        SetEntityAttribute(Gear3, #PB_Entity_DisableContactResponse, 0)
        twoseconds =1 
        
      EndIf
    EndIf
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
  EndIf
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf

End
;-------------------------------------------------------------------------------------
here the gears are attached not to the static ground but to a movable rectangular block, you can move the block (the car) by keys V/B. the purpose is to prove that all the construction can move even 2 of its components passed to AddSubEntity() with #PB_Entity_StaticBody
needs also the same gear model from the link above ( http://wikisend.com/download/360042/gear_lwo.mesh )

Image

Code: Select all

;
;
; ------------------------------------------------------------
;
;   PureBasic - CompoundBody
;
;    (c) Fantaisie Software
;
; ------------------------------------------------------------
;

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"

#CameraSpeed = 1

Define.f KeyX, KeyY, MouseX, MouseY


If InitEngine3D()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    Add3DArchive("."    , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/"              , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures"  , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Models"    , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts"    , #PB_3DArchive_FileSystem)
    Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/GUI"        , #PB_3DArchive_FileSystem)
    Parse3DScripts()
    
    ;WorldDebug(#PB_World_DebugBody)
        
    ;-------------------------------
    ; create  material
    CreateMaterial(1, LoadTexture(1, "wood.jpg"))
    SetMaterialColor(1, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
    ; 
    GetScriptMaterial(2, "Color/Green")
    SetMaterialColor(2, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
    
    CreateMaterial(3, LoadTexture(3, "clouds.jpg"))
    SetMaterialColor(3, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
    
    CreateMaterial(4, LoadTexture(4, "ground_diffuse.png"))
    GetScriptMaterial(5, "Color/Red")
    CreateMaterial(6, LoadTexture(6, "snow_1024.jpg"))
    CreateMaterial(7, LoadTexture(7, "soil_wall.jpg"))
    
    ;-------------------------------
    
    ;the first left gear
    ;CreateCylinder(#Mesh, Radius.f, Height.f [, NbBaseSegments, NbHeightSegments, CloseTop])
    CreateCylinder(1, 1.5, 1 , 3, 1, 1)
    CreateEntity(1, MeshID(1),MaterialID(3),  0, 0, 0)
    RotateEntity(1, 0,90,90, #PB_Absolute)
    CreateEntity(2, MeshID(1),MaterialID(3),  0, 0, 0)
    RotateEntity(2, 0,90,90, #PB_Absolute)
    RotateEntity(2, 0,40,0, #PB_Relative)
    CreateEntity(3, MeshID(1),MaterialID(3),  0, 0, 0.1)
    RotateEntity(3, 0,90,90, #PB_Absolute)
    RotateEntity(3, 0,80,0, #PB_Relative)
    
    
    Global Gear1 = CreateEntity(#PB_Any,0,0)
    AddSubEntity(Gear1, 1, #PB_Entity_ConvexHullBody) 
    AddSubEntity(Gear1, 2, #PB_Entity_ConvexHullBody)
    AddSubEntity(Gear1, 3, #PB_Entity_ConvexHullBody)
    CreateEntityBody(Gear1, #PB_Entity_CompoundBody, 1, 0.4, 1)
    SetEntityAttribute(Gear1, #PB_Entity_DisableContactResponse, 1) ; we will enable it again later
    
    ;0000000000000000000000000000000000000000000000000000000000000000   
    ; the component of red smaller gear which will attached later to the big white gear
    
    LoadMesh(6, "gear_lwo.mesh")
    Global Gear2 = CreateEntity(#PB_Any,0,0)
    CreateEntity(6, MeshID(6),MaterialID(6),  0, 0, 0)
    ScaleEntity(6, 2,2,2)
    CreateCylinder(7, 0.5, 3 ) ; the blue axes
    CreateEntity(7, MeshID(7),MaterialID(3),  0, 0, 0) ; add axes (does not have a real job)
    RotateEntity(7,90,0,0)
        
    ;the component of red smaller gear which will attached later to the big white gear
    CreateCylinder(8, 0.7, 1 , 3, 1, 1) ; triangular cylinder
    For i=8 To 10 ; create tria cylinders entities from 8 to 10
      CreateEntity(i, MeshID(8),MaterialID(5),  0, 0, 2)
      RotateEntity(i, 90,90+rot,0, #PB_Absolute)
      rot+40 ; 360/9 = 40
      AddSubEntity(Gear2, i, #PB_Entity_ConvexHullBody) 
    Next
        
    AddSubEntity(Gear2, 6, #PB_Entity_StaticBody) ;the white gear passed as dynamic concave geometry
    AddSubEntity(Gear2, 7, #PB_Entity_CylinderBody)
    AddSubEntity(Gear2, 8, #PB_Entity_ConvexHullBody)
    AddSubEntity(Gear2, 9, #PB_Entity_ConvexHullBody)
    AddSubEntity(Gear2, 10, #PB_Entity_ConvexHullBody)
    CreateEntityBody(Gear2, #PB_Entity_CompoundBody, 5, 0.4, 1)
    SetEntityAttribute(Gear2, #PB_Entity_DisableContactResponse, 1)
    
    CreateEntity(11, MeshID(6),MaterialID(2),  0, 0, 0) ;another entity from the gear: "gear_lwo.mesh"
    Global Gear3 = CreateEntity(#PB_Any,0,0)
    AddSubEntity(Gear3, 11, #PB_Entity_StaticBody)
    CreateEntityBody(Gear3, #PB_Entity_CompoundBody, 5, 0.4, 1)
    SetEntityAttribute(Gear3, #PB_Entity_DisableContactResponse, 1)
    
           
    ;car
    car = CreateCube(#PB_Any, 1)
    car = CreateEntity(#PB_Any, MeshID(car), MaterialID(4), 0, -7, 0)
    ScaleEntity(car, 15, 0.4, 15)
    CreateEntityBody(car, #PB_Entity_BoxBody, 20, 0, 1)
            
    GenericJoint(4,EntityID(car), -0.1, 3, 0,EntityID(Gear1), 0, 0, 0)
    SetJointAttribute(4, #PB_Joint_NoLimit, 0, 5)
    GenericJoint(5,EntityID(car), 3.1, 3, 0,EntityID(Gear2), 0, 0, 0)
    SetJointAttribute(5, #PB_Joint_NoLimit, 0, 5)
    
    GenericJoint(6,EntityID(car), 4.7, 3, 2,EntityID(Gear3), 0, 0, 0)
    SetJointAttribute(6, #PB_Joint_NoLimit, 0, 5)
    
    ;Ground
    Ground = CreateCube(#PB_Any, 1)
    Ground = CreateEntity(#PB_Any, MeshID(Ground), MaterialID(7), 0, -8, 0)
    ScaleEntity(Ground, 70, 0.4, 70)
    CreateEntityBody(Ground, #PB_Entity_StaticBody)
    
    ; camera
    CreateCamera(0, 0, 0, 100, 100, #True)
    MoveCamera(0,0,-2,30, #PB_Absolute)
    CameraLookAt(0,1.5,-2,0)
    CreateLight(1, RGB(255,255,255), 0, 5, 10)
    
    
    ; GUI
    OpenWindow3D(0, 0, 0, 50 , 10 , "")
    HideWindow3D(0,1)
    ShowGUI(128, 1) ; Display the GUI, semi-transparent and display the mouse cursor
    SetWindowTitle(0, "PureBasic-3D Demos ....  Press Z/X to apply torque to the left Gear...'space' rotate white Gear")
    
    tm.f = ElapsedMilliseconds(); we need to wait 2 seconds for the whole gears construction to fit together before enabling the collison again
    Repeat
      Screen3DEvents()
      
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
        InputEvent3D(MouseX(), MouseY(),0)
        BodyPick(CameraID(0), MouseButton(#PB_MouseButton_Left), MouseX(), MouseY(), 1)
      EndIf
    
      If ExamineKeyboard()
        
        If KeyboardPushed(#PB_Key_Z)
          ApplyEntityTorque(Gear1, 0, 0, 25)
          ElseIf KeyboardPushed(#PB_Key_X)
            ApplyEntityTorque(Gear1, 0, 0, -25)
            ElseIf KeyboardPushed(#PB_Key_Space) ; in case gears teeth stuck
              ApplyEntityImpulse(Gear2, -0.2, 0, 0, 0, 10,0)
            ElseIf KeyboardPushed(#PB_Key_B) 
              ApplyEntityImpulse(car, 5, 0, 0, 0, 0,0)
            ElseIf KeyboardPushed(#PB_Key_V)
              ApplyEntityImpulse(car, -5, 0, 0, 0, 0,0)
   
        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
        
      EndIf
      
      MoveCamera  (0, KeyX, 0, KeyY)
      RotateCamera(0,  MouseY, MouseX, 0, #PB_Relative)
      
      RenderWorld()
      
      FlipBuffers()
      
      If twoseconds = 0
      tm2.f = ElapsedMilliseconds()
      If (tm2-tm) >= 2000
        SetEntityAttribute(Gear1, #PB_Entity_DisableContactResponse, 0)
        SetEntityAttribute(Gear2, #PB_Entity_DisableContactResponse, 0)
        SetEntityAttribute(Gear3, #PB_Entity_DisableContactResponse, 0)
        twoseconds =1    
      EndIf
    EndIf
    
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
  EndIf
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf

End
Last edited by applePi on Wed Sep 14, 2016 2:29 pm, edited 11 times in total.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Gears

Post by IdeasVacuum »

Really excellent applePi, I don't know how you code this stuff so fast.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: Gears

Post by applePi »

IdeasVacuum , in the latest code above the final entities (gear1,gear2, gear3) fight for one second before they settle down and behave. but this is not acceptable, i remember the SetEntityAttribute #PB_Entity_DisableContactResponse
so the solution is to disable collision immediately after we make CreatEntityBody for every gear. and in the main loop we wait the necessary milliseconds and then enable the collision again. it is strange purebasic have things we think first we will never use it but later we discover it is necessary.
the latest code above updated. in rare cases when the collision disabled it happened one tooth is inside other one and when the collision enabled again the gear stuck, but usually they repel each other and behave correctly.
also i think there is a logical error in using #True or #False with SetEntityAttribute(Gear1, #PB_Entity_DisableContactResponse, #True[#False])
Post Reply