Draw a cylinder from x1,y1,z1 to x2,y2,z2 Part 2

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

Draw a cylinder from x1,y1,z1 to x2,y2,z2 Part 2

Post by applePi »

part 1 of connecting any 2 points with a cylinder is here http://www.purebasic.fr/english/viewtop ... 9&p=484465 it depends on trigonometry to do that trick
but we can use the purebasic own functions to do this trick such as EntityLookAt, look Comtois have used this method here: http://www.purebasic.fr/english/viewtop ... 15#p392148
if you don't want the physics then you can remove the lines 72+134

Code: Select all

MoveEntity(Compound, 20, 10, -10, #PB_Absolute) 
CreateEntityBody(Compound, #PB_Entity_CompoundBody ) 
and then it will rotate around 0,0,0 , look the comments
press Z/X to change the view from top or from the side
needs PB 5.60

Code: Select all

InitEngine3D()
InitKeyboard()
InitSprite()
InitMouse()

Declare cylinderFromTo(x1.f,y1.f,z1.f, x2.f,y2.f,z2.f)
Define.f KeyX, KeyY, MouseX, MouseY
Global Window, Event
Global x1.f, y1.f, z1.f, x2.f, y2.f, z2.f
Global camera, quit
Global Texture, Material
#cameraSpeed = 2

ExamineDesktops()
DesktopW = DesktopWidth(0)
DesktopH = DesktopHeight(0)
OpenWindow(0,0,0,DesktopW, DesktopH,"arrows and mouse to move/rotate the camera .... .. Z/X  scene from above/normal ",#PB_Window_ScreenCentered| #PB_Window_MinimizeGadget | #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0),0,0,DesktopW, DesktopH)

Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)

Parse3DScripts()

;SkyBox("desert07.jpg")

AmbientColor(RGB(150, 150, 150))

CreateLight(#PB_Any,RGB(170, 170, 150), 700, 100, 600)
WorldShadows(#PB_Shadow_Additive)

CreateMaterial(5, LoadTexture(5, "soil_wall.jpg"))
MaterialCullingMode(5, #PB_Material_NoCulling)

CreateMaterial(7, LoadTexture(7, "Geebee2.bmp"))
MaterialCullingMode(7, #PB_Material_NoCulling)


 CreateLine3D(#PB_Any, 0, 0.2, 0, RGB(255,   0,   0), 60,  0.2,  0, RGB(255,   0,   0))  ; Axis X
 CreateLine3D(#PB_Any, 0, 0, 0, RGB(  0, 255,   0),  0, 60,  0, RGB(  0, 255,   0))  ; Axis Y
 CreateLine3D(#PB_Any, 0, 0.2, 0, RGB(  0,   0, 255),  0,  0.2, 60, RGB(  0,   0, 255))  ; Axis Z
        
Camera = CreateCamera(#PB_Any, 0, 0, 100, 100)
MoveCamera(Camera, 20, 20, 60, #PB_Absolute)
CameraLookAt(Camera,  5,10,0)
CameraBackColor(Camera, RGB(150,150,100))

;Ground
Material = CreateMaterial(#PB_Any, TextureID(LoadTexture(#PB_Any, "snow_1024.jpg")))
MaterialCullingMode(Material, #PB_Material_NoCulling)

Entity = CreateEntity(#PB_Any, MeshID(CreatePlane(#PB_Any, 1000, 1000, 100, 100, 10, 10)), MaterialID(Material))
CreateEntityBody(Entity, #PB_Entity_StaticBody, 1, 0.5, 10)

CreateCylinder(0, 0.5, 10)
TransformMesh(0, 0,0,-5, 1,1,1,90,0,0)
UpdateMeshBoundingBox(0)

Global Compound = CreateEntity(#PB_Any,0,0) ; the construction which will encompass all cylinders

;If we want the construction To rotate around itself correctly and not in orbit then
;we must construct it around the origin 0,0,0 and after that we move it to any place 
cylinderFromTo(-10,0.5,-10, 10,0.5,-10)
cylinderFromTo(-10,0.5,10, 10,0.5,10)
cylinderFromTo(-10,0.5,-10, -10,0.5,10)
cylinderFromTo(10,0.5,-10, 10,0.5,10)

cylinderFromTo(-10,0.5,-10, 0,20,0)
cylinderFromTo(-10,0.5,10,  0,20,0)
cylinderFromTo(10,0.5,-10,  0,20,0)
cylinderFromTo(10,0.5,10,   0,20,0)

MoveEntity(Compound, 20, 10, -10, #PB_Absolute)

Repeat
  Repeat   
    Event  = WindowEvent()
  Until Event = 0
      
      If ExamineMouse()
        MouseX = -MouseDeltaX()/10
        MouseY = -MouseDeltaY()/10
      EndIf
                
      If ExamineKeyboard()
        
      ;moving the camera ================================================
        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
        
    If KeyboardPushed (#PB_Key_Escape)
     Break
   EndIf
   If KeyboardPushed(#PB_Key_Z)
     MoveCamera(Camera, 10, 100, 10, #PB_Absolute)
     CameraLookAt(Camera,  0,0,0)
   ElseIf KeyboardPushed(#PB_Key_X)
     MoveCamera(Camera, 20, 20, 60, #PB_Absolute)
     CameraLookAt(Camera,  5,10,0)
   EndIf
   RotateEntity(Compound, 0,0.5,0, #PB_Relative)
   
   RotateCamera(camera, MouseY, MouseX, 0, #PB_Relative)
   MoveCamera(camera, KeyX, 0, KeyY)
     
      RenderWorld()
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1

    End
    
    Procedure cylinderFromTo(x1.f,y1.f,z1.f, x2.f,y2.f,z2.f)
     cyl = CreateEntity(#PB_Any, MeshID(0), MaterialID(7))
     MoveEntity(cyl,x1,y1,z1)
     EntityLookAt(cyl, x2,y2,z2) 
     distance.f = Sqr(Pow((x2-x1),2)+Pow((y2-y1),2)+Pow((z2-z1),2))
     ScaleEntity(cyl,1,1,distance/10, #PB_Absolute)
     AddSubEntity(Compound, cyl, #PB_Entity_CylinderBody) 
     CreateEntityBody(Compound, #PB_Entity_CompoundBody ) 
    EndProcedure
    
    
    
here is a toy :a cylinder will follow the sphere wherever she go, stretching or contracting as necessary, the sphere is rotating around the 0,0,0 but the cylinder first side is located at x1=-5:y1=10:z1=-3 so it will stretch or contract while following the sphere.
press Z/X to change the view from top or from the side

Code: Select all

InitEngine3D()
InitKeyboard()
InitSprite()
InitMouse()

Define.f KeyX, KeyY, MouseX, MouseY
Global Window, Event
Global x1.f, y1.f, z1.f, x2.f, y2.f, z2.f
Global camera, quit
Global Texture, Material
#cameraSpeed = 2

ExamineDesktops()
DesktopW = DesktopWidth(0)
DesktopH = DesktopHeight(0)
OpenWindow(0,0,0,DesktopW, DesktopH,"arrows and mouse to move/rotate the camera. ... . .Z/X scene from above/side ",#PB_Window_ScreenCentered| #PB_Window_MinimizeGadget | #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0),0,0,DesktopW, DesktopH)

Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)

Parse3DScripts()

;SkyBox("desert07.jpg")
AmbientColor(RGB(150, 150, 150))

CreateLight(#PB_Any,RGB(170, 170, 150), 700, 100, 600)
WorldShadows(#PB_Shadow_Additive)

CreateMaterial(5, LoadTexture(5, "soil_wall.jpg"))
MaterialCullingMode(5, #PB_Material_NoCulling)

CreateMaterial(6, LoadTexture(6, "ground_diffuse.png"))
MaterialCullingMode(6, #PB_Material_NoCulling)
;MaterialBlendingMode(6, #PB_Material_AlphaBlend)
;SetMaterialColor(6, #PB_Material_DiffuseColor, RGBA(255, 255, 255, 120))

CreateMaterial(7, LoadTexture(7, "Geebee2.bmp"))
MaterialCullingMode(7, #PB_Material_NoCulling)


 CreateLine3D(#PB_Any, -30, 0.2, 0, RGB(255,   0,   0), 30,  0.2,  0, RGB(255,   0,   0))  ; Axis X
 CreateLine3D(#PB_Any, 0, 0, 0, RGB(  0, 255,   0),  0, 30,  0, RGB(  0, 255,   0))  ; Axis Y
 CreateLine3D(#PB_Any, 0, 0.2, -30, RGB(  0,   0, 255),  0,  0.2, 30, RGB(  0,   0, 255))  ; Axis Z
        
Camera = CreateCamera(#PB_Any, 0, 0, 100, 100)
MoveCamera(Camera, 5, 10, 60, #PB_Absolute)
CameraLookAt(Camera,  0,10,0)

;Ground
Material = CreateMaterial(#PB_Any, TextureID(LoadTexture(#PB_Any, "snow_1024.jpg")))
MaterialCullingMode(Material, #PB_Material_NoCulling)

Entity = CreateEntity(#PB_Any, MeshID(CreatePlane(#PB_Any, 1000, 1000, 100, 100, 10, 10)), MaterialID(Material))
CreateEntityBody(Entity, #PB_Entity_StaticBody, 1, 0.5, 10)

Global.f x1, y1, z1, x2, y2, z2
x1=-5:y1=10:z1=-3
Global.f x2,y2,z2
x2=20:y2 = 20: z2=20
  Global cyl = CreateCylinder(#PB_Any, 0.5, 10)
  Global cylinder = CreateEntity(#PB_Any, MeshID(cyl), MaterialID(7))
  ;we shift the cylinder center to its first side by -5
  TransformMesh(cyl, 0,0,-5, 1,1,1,90,0,0)
  MoveEntity(cylinder,x1,y1,z1)
  EntityLookAt(cylinder, x2,y2,z2) 
  distance.f = Sqr(Pow((x2-x1),2)+Pow((y2-y1),2)+Pow((z2-z1),2))
  ScaleEntity(cylinder,1,1,distance/10, #PB_Absolute)
  
  UpdateMeshBoundingBox(cyl)
  Global sph = CreateSphere(#PB_Any, 2)
  Global sphere = CreateEntity(#PB_Any, MeshID(sph), MaterialID(6),x2,y2,z2)
  sphere2 = CreateEntity(#PB_Any, MeshID(sph), MaterialID(6),x1,y1,z1)
  ScaleEntity(sphere2, 0.4, 0.4, 0.4)
  
Repeat
  Repeat   
    Event  = WindowEvent()
  Until Event = 0
      
      If ExamineMouse()
        MouseX = -MouseDeltaX()/10
        MouseY = -MouseDeltaY()/10
      EndIf
                
      If ExamineKeyboard()
        
      ;moving the camera ================================================
        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
        
    If KeyboardPushed (#PB_Key_Escape)
     Break
   EndIf
   If KeyboardPushed(#PB_Key_Z)
     MoveCamera(Camera, 10, 100, 10, #PB_Absolute)
     CameraLookAt(Camera,  0,0,0)
   ElseIf KeyboardPushed(#PB_Key_X)
     MoveCamera(Camera, 20, 20, 60, #PB_Absolute)
     CameraLookAt(Camera,  5,10,0)
   EndIf
        
    angle.f+0.01
    angleY.f + 0.05
    ; move the sphere in zigzaging circular orbit
    ; and so the cylinder will look at that position
    x2 = Sin(angle)*10: y2 = 10+Sin(angleY)*3: z2 = Cos(angle)*10
    MoveEntity(sphere, x2, y2, z2, #PB_Absolute)
    distance.f = Sqr(Pow((x2-x1),2)+Pow((y2-y1),2)+Pow((z2-z1),2))
    ScaleEntity(cylinder,1,1,distance/10, #PB_Absolute)
    EntityLookAt(cylinder, x2,y2,z2)
     
     RotateCamera(camera, MouseY, MouseX, 0, #PB_Relative)
     MoveCamera(camera, KeyX, 0, KeyY)
     
      RenderWorld()
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1

    End
    
    
Last edited by applePi on Mon Jul 10, 2017 8:09 am, edited 1 time in total.
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Draw a cylinder from x1,y1,z1 to x2,y2,z2 Part 2

Post by DK_PETER »

Thanks applePi.
Using EntityLookAt is a neat trick. :wink:
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Post Reply