Circular Tube ( UFO ) & Conical and Pyramidal tubes
Posted: Mon Dec 08, 2014 2:48 pm
part 1 of the tubes post are here thick and thin lines, and tubes of all shapes
part 2 making a circular tube the usual way (one mesh) , then making its material to scroll
try to go inside the tube ...
possible usages: UFO, fantasia demos, Aliens Factory, another world, ...
keys usages in the example title bar


from inside the tube
part 2 making a circular tube the usual way (one mesh) , then making its material to scroll
try to go inside the tube ...
possible usages: UFO, fantasia demos, Aliens Factory, another world, ...
keys usages in the example title bar


from inside the tube
Code: Select all
Enumeration
#Window = 500
#ground
#Camera
#Light1
#sphere
#plane
#RedMaterial
#tube
EndEnumeration
#CameraSpeed = 2
Global bands = 8 ;number of points of every ring (circle)
#Rings = 2 ;number of Rings over all the smallest tube (always 2, start ring and end ring)
Global divisions = 100
Structure vector3d
x.f
y.f
z.f
EndStructure
Structure vertex
x.f
y.f
z.f
EndStructure
Declare DrawTube (x.f, y.f,z.f, x2.f, y2.f, z2.f, Radius.f, bands)
Declare tubesCircle()
Define.f KeyX, KeyY, MouseX, MouseY
; beginning of the frenet sqaure approximation 5 procedures
Procedure vector_cross(*v1.vector3d, *v2.vector3d, *vout.vector3d)
*vout\x = (*v1\y * *v2\z) - (*v2\y * *v1\z)
*vout\y = (*v1\z * *v2\x) - (*v2\z * *v1\x)
*vout\z = (*v1\x * *v2\y) - (*v2\x * *v1\y)
EndProcedure
Procedure.f vector_magnitude(*v.vector3d)
mag.f
mag = Sqr(*v\x * *v\x + *v\y * *v\y + *v\z * *v\z)
If mag = 0:mag = 1:EndIf
ProcedureReturn mag
EndProcedure
Procedure vector_normalize (*v.vector3d)
mag.f
mag = vector_magnitude(*v)
*v\x = *v\x / mag
*v\y = *v\y / mag
*v\z = *v\z / mag
EndProcedure
Procedure vector_add (*v1.vector3d, *v2.vector3d, *vout.vector3d)
*vout\x = *v1\x + *v2\x
*vout\y = *v1\y + *v2\y
*vout\z = *v1\z + *v2\z
EndProcedure
Procedure vector_sub (*v1.vector3d, *v2.vector3d, *vout.vector3d)
*vout\x = *v1\x - *v2\x
*vout\y = *v1\y - *v2\y
*vout\z = *v1\z - *v2\z
EndProcedure
; End of the frenet sqaure approximation 5 procedures
If InitEngine3D()
;Add3DArchive(".", #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)
; Parse3DScripts()
InitSprite()
InitKeyboard()
InitMouse()
ExamineDesktops()
DesktopW = DesktopWidth(0)
DesktopH = DesktopHeight(0)
If OpenWindow(#Window, 0, 0, DesktopW, DesktopH, "W toggle wire/solid Frame ..,Space: toggle rotation.. ..mouse and arrow keys to move/ rotate the camera ")
If OpenWindowedScreen(WindowID(#Window), 0, 0, DesktopW, DesktopH, 0, 0, 0)
Parse3DScripts()
CreateCamera(#Camera, 0, 0, 100, 100)
MoveCamera(#Camera, 200, 300, 150, #PB_Absolute)
CameraLookAt(#Camera,0,0,0)
CameraBackColor(#Camera, RGB(200,255,200))
CreateMaterial(2, LoadTexture(2, "ground_diffuse.png"))
MaterialCullingMode(2, #PB_Material_NoCulling)
DisableMaterialLighting(2, #True)
ScrollMaterial(2, 0, 0, #PB_Material_Animated)
SetMaterialColor(2, #PB_Material_AmbientColor, RGB(250, 255, 0))
SetMaterialColor(2, #PB_Material_SpecularColor, RGB(255, 255, 0))
CreateMaterial(0, LoadTexture(0, "wood.jpg"))
DisableMaterialLighting(0, #True)
GetScriptMaterial(#RedMaterial, "Color/Red")
CreateLight(#Light1, RGB(255, 255, 255), 0, 100, 50)
AmbientColor(RGB(255, 255, 255))
EndIf
EndIf
EnableWorldPhysics(#True)
WorldGravity(-100)
CreateCube(#plane,1)
CreateEntity(#plane,MeshID(#plane),MaterialID(0), 0, -21, 0)
ScaleEntity(#plane, 300,1, 300)
EntityPhysicBody(#plane, #PB_Entity_StaticBody)
wireFrame = 1
tubesCircle()
CreateSphere(#sphere, 7)
CreateEntity(#sphere, MeshID(#sphere), MaterialID(#RedMaterial), 95, 10,0)
EntityPhysicBody(#sphere, #PB_Entity_SphereBody, 1,5,1)
EntityPhysicBody(#tube, #PB_Entity_StaticBody)
Tex1 = LoadTexture(#PB_Any, "MRAMOR6X6.jpg")
AddMaterialLayer(2, TextureID(Tex1), #PB_Material_Modulate)
rot=1
Repeat
Event = WindowEvent()
If ExamineMouse()
MouseX = -MouseDeltaX()/20
MouseY = -MouseDeltaY()/20
EndIf
If ExamineKeyboard()
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
If KeyboardPushed(#PB_Key_E)
x.f+0.001
ScrollMaterial(2, x, 0, #PB_Material_Fixed , 1)
EndIf
If KeyboardReleased(#PB_Key_W)
If wireFrame
MaterialShadingMode(2, #PB_Material_Wireframe)
wireFrame ! 1
Else
MaterialShadingMode(2, #PB_Material_Solid)
wireFrame ! 1
EndIf
EndIf
EndIf
x.f+0.003
ScrollMaterial(2, x, 0, #PB_Material_Fixed , 1)
RotateCamera(#Camera, MouseY, MouseX, 0, #PB_Relative)
MoveCamera(#Camera, KeyX, 0, KeyY)
RotateEntity(#tube, 0,rot,0, #PB_Relative)
ttt+1
If ttt=100 ; give the sphere a pulse every 100 loops
ApplyEntityImpulse(#sphere, 0, 200, 0, 0,1,-1)
ttt=0
EndIf
If KeyboardReleased(#PB_Key_Space)
rot ! 1
EndIf
RenderWorld()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
Else
MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
End
Procedure DrawTube (x.f, y.f,z.f, x2.f, y2.f,z2.f, Radius.f, bands)
x.f+0.00001 : y.f+0.00001 : z.f+0.00001 ; in rare cases when x,y,z where all zero:
x2.f+0.00001 : y2.f+0.00001 : z2.f+0.00001; then without adding 0.00001 will gives erroneous shape
Dim vertx.vertex(2)
lineVec.vector3d
u.f: r.f
txu.f : txv.f
x1.f = x
y1.f = y
z1.f = z
;vector of the line between start vertex and the end vertex
lineVec\x = x2 - x1
lineVec\y = y2 - y1
lineVec\z = z2 - z1
tt.f = 0
For i=0 To #Rings
x = x1 + lineVec\x * tt
y = y1 + lineVec\y * tt
z = z1 + lineVec\z * tt
tt + 1
vertx(i)\x = x
vertx(i)\y = y
vertx(i)\z = z
Next
current_point.vector3d
next_point.vector3d
T.vector3d
B.vector3d
N.vector3d
p.f
For i = 0 To #Rings-1
;center point
current_point\x = vertx(i)\x
current_point\y = vertx(i)\y
current_point\z = vertx(i)\z
;next point For Frenet square
next_point\x = vertx(i+1)\x
next_point\y = vertx(i+1)\y
next_point\z = vertx(i+1)\z
;T = P' - P
vector_sub(next_point, current_point, T)
;N = P' + P
vector_add(next_point, current_point, N)
;B = T x N
vector_cross(T, N, B)
;N = B x T
vector_cross(B, T, N)
;Normalize vectors Or Else it won't work
vector_normalize(B)
vector_normalize(N)
For j = 0 To bands
new_point_x.f
new_point_y.f
;rotate around the current point using normal rotation makes bands
new_point_x = Sin(j * (#PI*2) / bands) * RADIUS
new_point_y = Cos(j * (#PI*2) / bands) * RADIUS
;this is the coordinates of our point along the curve
x = N\x * new_point_x + B\x * new_point_y + current_point\x
y = N\y * new_point_x + B\y * new_point_y + current_point\y
z = N\z * new_point_x + B\z * new_point_y + current_point\z
MeshVertexPosition(x, y, z)
MeshVertexTextureCoordinate(txu, txv)
MeshVertexNormal(x, y, z)
txv = txv + 1/#Rings
Next
txv = 0
txu = txu + 1/bands
Next
EndProcedure
Procedure tubesCircle()
CreateMesh(#tube , #PB_Mesh_TriangleList, #PB_Mesh_Static )
For i=1 To divisions
;divide the circle Circumference to arbitrary divisions
;coordinates of a single point on the circle Circumference
X.f=X+#PI*2/divisions
Z.f=Z+#PI*2/divisions
XX.f=Cos(X)*100 ; 100 here is the radius of the big circle (big tube)
ZZ.f=Sin(Z)*100
X.f=X+#PI*2/divisions
Z.f=Z+#PI*2/divisions
XX2.f=Cos(X)*100
ZZ2.f=Sin(Z)*100
yy.f=0: yy2.f=0
Radius = 20; radius of the tube cross section (lets say thickness/2)
Bands = 8
; we gives the two adjacent points on the circle Circumference to the procedure
; which draws around every point a small circle made from arbitray divisions called bands, here it is 8
DrawTube (xx, yy, zz, xx2, yy2, zz2, Radius, Bands)
Next
v.l=0
For i = 0 To divisions+12 ;divisions is the number of circles the whole tube are made from
For j = 0 To bands - 1 ; bands is the number of divisions every small circle (tube thickness) are made
MeshFace(v,v+1,v + bands+1)
MeshFace(v + bands+1,v + bands+2,v+1 )
v + 1
Next
Next
FinishMesh(#True)
CreateEntity(#tube,MeshID(#tube),MaterialID(2) )
NormalizeMesh(#tube)
BuildMeshTangents(#tube)
EndProcedure