CylinderFromTo(cylRadius, x1, y1, z1, x2, y2, z2)
cylinders is better than thin unnoticeable lines
before we do that we need to know:
1- the distance between the two points
2- make a cylinder = that distance
3- shift the cylinder rotational center to one of its edges using the TransformMesh(...) function
4-create an entity from that cylinder mesh and move it to the first point, the new center of the cylinder will be on the first point (remember we shifted the cylinder center to the cylinder base)
5- now what we need is to apply trigonometry rules to rotate the cylinder twice: horizontal and vertical until it fits between the 2 points
the code is documented
i have used this picture to imagine the situation:


if you find errors or have another version of the code please post and thanks in advance.
tested with PB5.42 beta4 windows xp/32
Code: Select all
Declare CylinderFromTo(cylRadius.f, x1.f, y1.f, z1.f, x2.f, y2.f, z2.f)
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
Global cyl, sphereOrNot=1
#cameraSpeed = 0.5
ExamineDesktops()
DesktopW = DesktopWidth(0)
DesktopH = DesktopHeight(0)
OpenWindow(0,0,0,DesktopW, DesktopH,"press 'Space' to stop/rotate the camera ",#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)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Packs/desert.zip", #PB_3DArchive_Zip)
Add3DArchive(#PB_Compiler_Home+"examples/3d/Data/Packs/Sinbad.zip", #PB_3DArchive_Zip)
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, "Geebee2.bmp"))
MaterialCullingMode(5, #PB_Material_NoCulling)
CreateMaterial(6, LoadTexture(6, "clouds.jpg"))
MaterialCullingMode(6, #PB_Material_NoCulling)
CreateLine3D(0, 0, 0.2, 0, RGB(255, 0, 0), 10, 0.2, 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.2, 0, RGB( 0, 0, 255), 0, 0.2, 10, RGB( 0, 0, 255)) ; Axis Z
Camera = CreateCamera(#PB_Any, 0, 0, 100, 100)
MoveCamera(Camera, 0, 20, 50, #PB_Absolute)
CameraLookAt(Camera, 0,10,0)
;Ground
Material = CreateMaterial(#PB_Any, TextureID(LoadTexture(#PB_Any, "snow_1024.jpg")))
Entity = CreateEntity(#PB_Any, MeshID(CreatePlane(#PB_Any, 1000, 1000, 100, 100, 10, 10)), MaterialID(Material))
Fog(RGB(139, 100, 19), 1, 100, 200)
Euclid = CreateEntity(#PB_Any, MeshID(LoadMesh(#PB_Any, "Sinbad.mesh")), #PB_Material_None, 0, 5, -25)
For i=1 To 12 ; read the data for points with spheres on
Read.f x1: Read.f y1: Read.f z1: Read.f x2: Read.f y2: Read.f z2
CylinderFromTo(0.3, x1, y1, z1, x2, y2, z2)
Next
sphereOrNot=0
For i=1 To 4 ; read data for points without spheres on it
Read.f x1: Read.f y1: Read.f z1: Read.f x2: Read.f y2: Read.f z2
CylinderFromTo(0.7, x1, y1, z1, x2, y2, z2)
Next
Global camRot=1
Repeat
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_CloseWindow
End
EndSelect
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 KeyboardReleased (#PB_Key_Space)
camRot !1
EndIf
If camRot
count.f + 0.003
MoveCamera(camera, Sin(count) * 60, 15, Cos(count) * 60, #PB_Absolute)
CameraLookAt(camera,0,5,0)
Else
RotateCamera(camera, MouseY, MouseX, 0, #PB_Relative)
MoveCamera(camera, KeyX, 0, KeyY)
EndIf
RenderWorld()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
End
Procedure CylinderFromTo(cylRadius.f, x1.f, y1.f, z1.f, x2.f, y2.f, z2.f)
CreateLine3D(3, 0, 0, 0, RGB( 140, 250, 255), x2, y2, z2, RGB( 140, 250, 255))
NbBaseSegments = 16
; the lenght of the cylinder = distance between the 2 points
cylLenght.f = Sqr((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1))
CreateCylinder(5,cylRadius,cylLenght, NbBaseSegments, 2,0)
;change the cylinder rotation center from its center to its edge
TransformMesh(5, cylLenght/2,0,0,1,1,1, 0, 0,90)
UpdateMeshBoundingBox(5)
CreateEntity(cyl, MeshID(5), MaterialID(5), x1, y1, z1)
If sphereOrNot ; just to draw or not to draw spheres over the points
sphere = CreateSphere(#PB_Any, 1)
CreateEntity(#PB_Any, MeshID(sphere), MaterialID(6), x1, y1, z1)
secondPoint = CreateEntity(#PB_Any, MeshID(sphere), MaterialID(6), x2, y2, z2)
EndIf
angleSin.f=(y2-y1)/cylLenght ; to find the vertical angle needed for cylinder vertical rotation
angle.f = Degree(ASin(angleSin))
angXZ.f = ATan2(x2-x1, z2-z1) ; horizontal angle between x and the projection of the line between the 2 points over the plane
angXZ = Degree(angXZ)
RotateEntity(cyl, 0,-angXZ, 0, #PB_Absolute)
RotateEntity(cyl, 0,0, angle, #PB_Relative)
cyl+1
EndProcedure
DataSection
points:
Data.f -10,1,10, 10,1,10
Data.f 10,1,10, 10,1,-10
Data.f 10,1,-10, -10,1,-10
Data.f-10,1,-10, -10,1,10
Data.f 10,22,10, 10,22,-10
Data.f 10,22,-10, -10,22, -10
Data.f -10,22,-10, -10,22,10
Data.f -10,22,10, 10,22,10
Data.f 10,1,10, 10,22,10
Data.f 10,1,-10, 10,22,-10
Data.f -10,1,-10, -10,22,-10
Data.f -10,1,10, -10,22,10
Data.f -5,6,10, 5,6,10
Data.f 5,14,10, -5,14,10
Data.f 2.5,14,10, -5,6,10
Data.f -4.0,10,10, 1.5,10,10
EndDataSection





