the first demo is animating sine tube with physics body and sphere inside the tube. the example is essentially the same as setmeshdata.pb in the purebasic distributions but with tubes instead of the 2D flag
to let the sphere fit inside the hollow tube we need to CreateEntityBody for the tube continuously, but i choose once every 4 times (you can change it from line 197:
Code: Select all
If tot = 4
CreateEntityBody(1, #PB_Entity_StaticBody , 1, 1, 1)
if you don't want to play with physics just comment the all CreateEntityBody in the code and then it is okay in all PB versions
note that using CreateEntityBody continuously is unofficial
better to try the animation with physics in PB 5.43/44
Code: Select all
DisableDebugger
#CameraSpeed = 0.5
#NUM_BANDS = 16 ;number of points every circle (band) on the tube made from
#BAND_RAD = 0.5 ;tube thickness
Structure vector3d
x.f
y.f
z.f
EndStructure
Global next_point.vector3d
Global current_point.vector3d
Global T0.vector3d
Global N0.vector3d
Global B0.vector3d
;procedures used with (Frenet method) to position a point perpendicular to a point on a 2D CURVE
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
Define.f KeyX, KeyY, MouseX, MouseY
Global rot = 1
Global rings, tot
Global.f AngleVague, WaveFrequency, WavePeriodX, WavePeriodZ, WaveAmplitude
WaveFrequency=2 ;=waves/second
WavePeriodX =4 ;=1/Wave length
WavePeriodZ =6 ;=1/Wave length
WaveAmplitude=2; try 0.2
Global Dim TubeData.PB_MeshVertex(0)
Declare UpdateMatrix()
Global Dim vertex.vector3d(0)
Declare MakeTube (Bands.l,BandRadius.f)
Declare AnimateTube (Bands.l,BandRadius.f)
Quit.b = #False
ExamineDesktops()
OpenWindow(3, 0, 0, DesktopWidth(0), DesktopHeight(0), "tubes , W toggle Wire/Solid Frame. ...mouse + arrow keys: to move / rotate the Camera. ...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;Initialize environment
InitEngine3D()
InitSprite()
InitMouse()
OpenWindowedScreen(WindowID(3), 0, 0, DesktopWidth(0), DesktopHeight(0), 0, 0, 0)
InitKeyboard()
;SetFrameRate(60)
Add3DArchive(".", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts",#PB_3DArchive_FileSystem)
Parse3DScripts()
CreateLight(0,RGB(255,255,255),-100,40,30)
AmbientColor(RGB(100,100,100))
CreateCamera(0, 0, 0, 100, 100)
MoveCamera(0, 0, 0, 75)
CameraLookAt(0, 0, 0, 0)
CameraBackColor(0, RGB(255,240,240))
GetScriptMaterial(3, "Scene/GroundBlend")
CreatePlane(3, 100, 100, 5, 5, 5, 5)
CreateEntity(3,MeshID(3),MaterialID(3), 0, -10, 0)
;EntityRenderMode(3, 0)
CreateEntityBody(3, #PB_Entity_BoxBody, 0, 1, 1)
CreateMaterial(0, LoadTexture(0, "MRAMOR6X6.jpg")) ;"terrain_texture.jpg"
MaterialCullingMode(0, #PB_Material_NoCulling)
MaterialShadingMode(0, #PB_Material_Wireframe)
DisableMaterialLighting(0, #True)
CreateMaterial(2, LoadTexture(2, "Geebee2.bmp"))
MaterialCullingMode(2, #PB_Material_NoCulling)
CreateMesh(1, #PB_Mesh_TriangleList, #PB_Mesh_Static ) ; mesh to make the Tube
SetMeshMaterial(1, MaterialID(0))
MakeTube (#NUM_BANDS, #BAND_RAD )
CreateEntity(1, MeshID(1),MaterialID(0), 0, 4, 0)
ScaleEntity(1,3,3,3)
CreateEntityBody(1, #PB_Entity_StaticBody, 5, 0.4, 1)
GetMeshData(1,0, TubeData(), #PB_Mesh_Vertex | #PB_Mesh_Normal, 0, MeshVertexCount(1,0)-1)
CreateSphere(2,1)
CreateEntity(2, MeshID(2),MaterialID(2), 14, 4, 30)
CreateEntityBody(2, #PB_Entity_SphereBody, 1, 0.1, 5)
ExamineKeyboard()
;WorldDebug(#PB_World_DebugEntity)
;WorldDebug(#PB_World_DebugBody)
Repeat
Repeat
Event = WindowEvent()
Until Event = 0
If ExamineMouse()
MouseX = -MouseDeltaX() * #CameraSpeed * 0.3
MouseY = -MouseDeltaY() * #CameraSpeed * 0.3
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
If KeyboardReleased(#PB_Key_W)
If w
MaterialShadingMode(0, #PB_Material_Wireframe)
Else
MaterialShadingMode(0, #PB_Material_Solid)
EndIf
w!1
EndIf
If KeyboardReleased(#PB_Key_Space) ; drop a sphere
sphere = CreateEntity(#PB_Any, MeshID(2),MaterialID(2), 16, 4, 30)
CreateEntityBody(sphere, #PB_Entity_SphereBody, 1, 0.1, 5)
EndIf
MoveCamera (0, KeyX, 0, KeyY)
RotateCamera(0, MouseY, MouseX, 0, #PB_Relative)
; Waves
UpdateMatrix() ; to animate the tube
AngleVague = AngleVague+WaveFrequency ; for the animation equation
RenderWorld()
FlipBuffers()
title$="FPS = "+Str(Engine3DStatus(#PB_Engine3D_CurrentFPS ))+" __ rendered triangles = "+Str(Engine3DStatus(#PB_Engine3D_NbRenderedTriangles ))
title$ + "....'Space': drop a sphere "+".... 'W' toggle Wire/Solid Frame "+"... Mouse+keys: Camera"
SetWindowTitle(3, title$ )
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape)
Quit = #True
EndIf
Until Quit = #True Or Event = #PB_Event_CloseWindow
Procedure UpdateMatrix()
Protected.l a, b, c
i=0
x.f = -6 :i = 0
While x <= 6
vertex(i)\y=Sin(Radian((AngleVague+i*WavePeriodX+i*WavePeriodZ)))*WaveAmplitude
i + 1
x+0.1
Wend
;to make less impact on the 3D engine we do CreateEntityBody every 4 times, the best is every loop but with big impact especialy on versions >= 5.50
tot+1
If tot = 4
CreateEntityBody(1, #PB_Entity_StaticBody , 1, 1, 1)
tot=0
EndIf
AnimateTube(#NUM_BANDS, #BAND_RAD)
EndProcedure
Procedure MakeTube (Bands.l, BandRadius.f)
x.f: y.f: z.f
txu.f : txv.f
x = -6 :i = 0
While x <= 6
ReDim vertex.vector3d(i)
vertex(i)\x = x
vertex(i)\y = Sin(x); we will modify this value contineously during the animation procedure
vertex(i)\z = 10 ; we will TransforMesh the mesh Later by -10 to center it
i + 1 ; so it rotate around itself and not in orbit
x + 0.1
Wend
rings = i-1
;Debug rings
For i = 0 To rings-1
;center point
current_point\x = vertex(i)\x
current_point\y = vertex(i)\y
current_point\z = vertex(i)\z
;next point (For Frenet square method)
next_point\x = vertex(i+1)\x
next_point\y = vertex(i+1)\y
next_point\z = vertex(i+1)\z
;T = P' - P
vector_sub(next_point, current_point, T0)
;N = P' + P
vector_add(next_point, current_point, N0)
;B = T x N
vector_cross(T0, N0, B0)
;N = B x T
vector_cross(B0, T0, N0)
;Normalize vectors Or Else it won't work
vector_normalize(B0)
vector_normalize(N0)
For j = 0 To bands - 0
new_point_x.f
new_point_y.f
;rotate around the current point using normal rotation to makes a band (ie a circle around the point on the 2D curve)
new_point_x = Sin(j * 2 * #PI / bands) * #BAND_RAD
new_point_y = Cos(j * 2 * #PI / bands) * #BAND_RAD
;this is the corrected coordinates of our point in the band (the circle) (we need 16 points to make a circle)
x = N0\x * new_point_x + B0\x * new_point_y + current_point\x
y = N0\y * new_point_x + B0\y * new_point_y + current_point\y
z = N0\z * new_point_x + B0\z * new_point_y + current_point\z
MeshVertexPosition(x, y, z)
MeshVertexTextureCoordinate(txu, txv)
MeshVertexNormal(x, y, z)
txv = txv + 1/bands ; for texturing
Next
txv = 0
txu = txu + 1/bands ; for texturing
Next
v.l
For i = 0 To rings - 1
For j = 0 To bands - 1
MeshFace(v,v+1,v + bands+1)
MeshFace(v + bands+1,v + bands+2,v+1 )
v + 1
Next
Next
FinishMesh(1)
UpdateMeshBoundingBox(1)
NormalizeMesh(1)
EndProcedure
Procedure AnimateTube (Bands.l, BandRadius.f)
;we just make use of the contineously changing array vertex(i)\x|y|z to calculate -->
;the coordinates of TubeData(pnt)\x|y|z With SetMeshData To animate the Tube Mesh
pnt = 0
x.f: y.f: z.f
txu.f : txv.f
For i = 0 To rings-1 ; number of rings is known from the MakeTube procedure
;center point
current_point\x = vertex(i)\x
current_point\y = vertex(i)\y
current_point\z = vertex(i)\z
;next point (For Frenet square method)
next_point\x = vertex(i+1)\x
next_point\y = vertex(i+1)\y
next_point\z = vertex(i+1)\z
;T = P' - P
vector_sub(next_point, current_point, T0)
;N = P' + P
vector_add(next_point, current_point, N0)
;B = T x N
vector_cross(T0, N0, B0)
;N = B x T
vector_cross(B0, T0, N0)
;Normalize vectors Or Else it won't work
vector_normalize(B0)
vector_normalize(N0)
For j = 0 To bands - 0
new_point_x.f
new_point_y.f
;rotate around the current point using normal rotation to makes a band (ie a circle around the point on the 2D curve)
new_point_x = Sin(j * 2 * #PI / bands) * #BAND_RAD
new_point_y = Cos(j * 2 * #PI / bands) * #BAND_RAD
;this is the corrected coordinates of our point in the band (the circle) (we need 16 points to make a circle)
x = N0\x * new_point_x + B0\x * new_point_y + current_point\x
y = N0\y * new_point_x + B0\y * new_point_y + current_point\y
z = N0\z * new_point_x + B0\z * new_point_y + current_point\z
TubeData(pnt)\x = x
TubeData(pnt)\y = y
TubeData(pnt)\z = z
pnt + 1
Next
Next
SetMeshData(1, 0, TubeData(), #PB_Mesh_Vertex | #PB_Mesh_Normal, 0, MeshVertexCount(1,0)-1)
;UpdateMeshBoundingBox(1)
EndProcedure
Code: Select all
#CameraSpeed = 0.2
#NUM_BANDS = 16 ;number of points every circle (band) on the tube made from
#BAND_RAD = 0.7 ;tube thickness
Define.f KeyX, KeyY, MouseX, MouseY
Global rot = 1
Global rings
Global NbX = #NUM_BANDS
Global NbZ
Structure vector3d
x.f
y.f
z.f
EndStructure
Global next_point.vector3d
Global current_point.vector3d
Global T0.vector3d
Global N0.vector3d
Global B0.vector3d
;procedures used with (Frenet method) to position a point perpendicular to a point on a 2D CURVE
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
Global Dim vertex.vector3d(0)
Declare MakeTube (Bands.l,BandRadius.f)
Quit.b = #False
ExamineDesktops()
OpenWindow(3, 0, 0, DesktopWidth(0), DesktopHeight(0), "tubes , 'W' toggle wire/solid Frame ... 'space' rotate/stop. ...mouse + arrow keys to move the Camera. ...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;Initialize environment
InitEngine3D()
InitSprite()
InitMouse()
OpenWindowedScreen(WindowID(3), 0, 0, DesktopWidth(0), DesktopHeight(0), 0, 0, 0)
InitKeyboard()
;SetFrameRate(60)
Add3DArchive(".", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures", #PB_3DArchive_FileSystem)
CreateLight(0,RGB(255,255,255),-100,40,30)
AmbientColor(RGB(100,100,100))
CreateCamera(0, 0, 0, 100, 100)
MoveCamera(0, 0, 0, 35,#PB_Absolute)
CameraLookAt(0, 0, 0, 0)
CreateMaterial(0, LoadTexture(0, "MRAMOR6X6.jpg")) ;"ground_diffuse.png"
MaterialCullingMode(0, #PB_Material_NoCulling)
;MaterialShadingMode(0, #PB_Material_Wireframe)
DisableMaterialLighting(0, #True)
CreateMesh(1, #PB_Mesh_TriangleList, #PB_Mesh_Static )
SetMeshMaterial(1, MaterialID(0))
MakeTube (#NUM_BANDS, #BAND_RAD )
NormalizeMesh(1)
FinishMesh(1)
UpdateMeshBoundingBox(1)
CreateEntity(1, MeshID(1), MaterialID(0))
CreateLine3D(10,-15,0,0,RGB(255,0,0), 15,0,0,RGB(255,0,0))
CreateLine3D(11,0,-15,0,RGB(255,0,0), 0,15,0,RGB(255,0,0))
ExamineKeyboard()
Repeat
Repeat
Event = WindowEvent()
Until Event = 0
If ExamineMouse()
MouseX = -MouseDeltaX() * #CameraSpeed * 0.5
MouseY = -MouseDeltaY() * #CameraSpeed * 0.5
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
If KeyboardReleased(#PB_Key_W)
If w
MaterialShadingMode(0, #PB_Material_Solid)
Else
MaterialShadingMode(0, #PB_Material_Wireframe)
EndIf
w!1
EndIf
If KeyboardReleased(#PB_Key_Space) ; rotate left
rot! 1
EndIf
;RotateEntity(1,0,1*rot,0, #PB_Relative)
RotateEntity(1, 0, 0.5*rot, 0, #PB_Relative)
MoveCamera (0, KeyX, 0, KeyY)
RotateCamera(0, MouseY, MouseX, 0, #PB_Relative)
RenderWorld()
FlipBuffers()
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape)
Quit = #True
EndIf
Until Quit = #True Or Event = #PB_Event_CloseWindow
Procedure MakeTube (Bands.l, BandRadius.f)
Protected.f x, y, z, a1, b1, n1
txu.f : txv.f
angle.f = 0: incr.f = 0.01
i = 0
a1 = 0.2: b1.f=0.8 : n1=10: x=0
While angle <= 2*#PI
x=(a1*Sin(n1*angle)+b1)*Cos(angle)
y=(a1*Sin(n1*angle)+b1)*Sin(angle)
z=a1*Cos(n1*angle)
vertex(i)\x = x*10; 10 is the amplification
vertex(i)\y = y*10
vertex(i)\z = z*10
i + 1
angle + incr
ReDim vertex.vector3d(i)
Wend
; another one point for the Ferret procedure (to calculate the last ring)
ReDim vertex.vector3d(i+1)
x=(a1*Sin(n1*angle)+b1)*Cos(angle)
y=(a1*Sin(n1*angle)+b1)*Sin(angle)
z=a1*Cos(n1*angle)
vertex(i)\x = x*10
vertex(i)\y = y*10
vertex(i)\z = z*10
rings = i
NbZ = rings
;Debug rings
For i = 0 To rings
;center point
current_point\x = vertex(i)\x
current_point\y = vertex(i)\y
current_point\z = vertex(i)\z
;next point (For Frenet square method)
next_point\x = vertex(i+1)\x
next_point\y = vertex(i+1)\y
next_point\z = vertex(i+1)\z
;T = P' - P
vector_sub(next_point, current_point, T0)
;N = P' + P
vector_add(next_point, current_point, N0)
;B = T x N
vector_cross(T0, N0, B0)
;N = B x T
vector_cross(B0, T0, N0)
;Normalize vectors Or Else it won't work
vector_normalize(B0)
vector_normalize(N0)
For j = 0 To bands
new_point_x.f
new_point_y.f
;rotate around the current point using normal rotation to makes a band (ie a circle around the point on the 2D curve)
new_point_x = Sin(j * 2 * #PI / bands) * #BAND_RAD
new_point_y = Cos(j * 2 * #PI / bands) * #BAND_RAD
;this is the corrected coordinates of our point in the band (the circle) (we need 16 points to make a circle)
x = N0\x * new_point_x + B0\x * new_point_y + current_point\x
y = N0\y * new_point_x + B0\y * new_point_y + current_point\y
z = N0\z * new_point_x + B0\z * new_point_y + current_point\z
MeshVertexPosition(x, y, z)
MeshVertexTextureCoordinate(txu, txv)
MeshVertexNormal(x, y, z)
txv = txv + 1/bands
Next
txv = 0
txu = txu + 1/bands
Next
Protected.l a, b, c, Nb
Protected.w P1, P2, P3, P4
Nb=NbX+1
NbZ = rings
;Debug NbZ
For b=0 To NbZ-2
For a=0 To NbX-1
P1=a+(b*Nb)
P2=P1+1
P3=a+(b+1)*Nb
P4=P3+1
MeshFace(P3, P2, P1)
MeshFace(P2, P3, P4)
Next
Next
EndProcedure
Code: Select all
#CameraSpeed = 0.5
#NUM_BANDS = 16 ;number of points every circle (band) on the tube made from
#BAND_RAD = 0.7 ;tube thickness
Define.f KeyX, KeyY, MouseX, MouseY
Global rot = 1
Global rings
Global NbX = #NUM_BANDS
Global NbZ
Structure vector3d
x.f
y.f
z.f
EndStructure
Global next_point.vector3d
Global current_point.vector3d
Global T0.vector3d
Global N0.vector3d
Global B0.vector3d
;procedures used with (Frenet method) to position a point perpendicular to a point on a 2D CURVE
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
Global Dim vertex.vector3d(0)
Declare MakeTube (Bands.l,BandRadius.f)
Quit.b = #False
ExamineDesktops()
OpenWindow(3, 0, 0, DesktopWidth(0), DesktopHeight(0), "tubes , 'Space': rotate/stop. ...mouse + arrow keys to move the Camera. ...'W' Wire/Solid Frame", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;Initialize environment
InitEngine3D()
InitSprite()
InitMouse()
OpenWindowedScreen(WindowID(3), 0, 0, DesktopWidth(0), DesktopHeight(0), 0, 0, 0)
InitKeyboard()
;Add3DArchive(".", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
CreateLight(0,RGB(255,255,255),-100,40,30)
AmbientColor(RGB(100,100,100))
CreateCamera(0, 0, 0, 100, 100)
MoveCamera(0, 0, 15, 20)
CameraLookAt(0, 0, -10, 0)
CreateMaterial(0, LoadTexture(0, "MRAMOR6X6.jpg"))
MaterialCullingMode(0, #PB_Material_NoCulling)
;MaterialShadingMode(0, #PB_Material_Wireframe)
DisableMaterialLighting(0, #True)
CreateMesh(1, #PB_Mesh_TriangleList, #PB_Mesh_Static )
SetMeshMaterial(1, MaterialID(0))
MakeTube (#NUM_BANDS, #BAND_RAD )
NormalizeMesh(1)
FinishMesh(1)
UpdateMeshBoundingBox(1)
CreateEntity(1, MeshID(1), MaterialID(0))
RotateEntity(1, 90,0,0)
ExamineKeyboard()
y.f
Repeat
Repeat
Event = WindowEvent()
Until Event = 0
If ExamineMouse()
MouseX = -MouseDeltaX() * #CameraSpeed * 0.5
MouseY = -MouseDeltaY() * #CameraSpeed * 0.5
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
If KeyboardReleased(#PB_Key_W)
If w
MaterialShadingMode(0, #PB_Material_Solid)
Else
MaterialShadingMode(0, #PB_Material_Wireframe)
EndIf
w!1
EndIf
If KeyboardReleased(#PB_Key_Space) ; rotate left
rot! 1
EndIf
RotateEntity(1,0,0,0.2*rot, #PB_Relative)
MoveCamera (0, KeyX, 0, KeyY)
RotateCamera(0, MouseY, MouseX, 0, #PB_Relative)
RenderWorld()
FlipBuffers()
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape)
Quit = #True
EndIf
Until Quit = #True Or Event = #PB_Event_CloseWindow
Procedure MakeTube (Bands.l, BandRadius.f)
Protected.f a1, b1, x, y, z
radius.f: incr.f=0.1: up.f
txu.f : txv.f
i = 0:angle.f
a1 = 0.4: b1=0.5
While angle <= 6*#PI
radius = a1 + b1*angle
x = radius * Cos(angle)
y = radius * Sin(angle)
vertex(i)\x = x
vertex(i)\y = y
vertex(i)\z = up
i + 1
ReDim vertex.vector3d(i)
angle + incr
up.f + 0.1 ; for expanding into z direction from the 2D curve
Wend
;another one point for the Ferret procedure (to calculate the last ring)
ReDim vertex.vector3d(i+1)
radius = a1 + b1*angle
x = radius * Cos(angle)
y = radius * Sin(angle)
vertex(i)\x = x
vertex(i)\y = y
vertex(i)\z = up
rings = i
NbZ = rings
;Debug rings
For i = 0 To rings
;center point
current_point\x = vertex(i)\x
current_point\y = vertex(i)\y
current_point\z = vertex(i)\z
;next point (For Frenet square method)
next_point\x = vertex(i+1)\x
next_point\y = vertex(i+1)\y
next_point\z = vertex(i+1)\z
;T = P' - P
vector_sub(next_point, current_point, T0)
;N = P' + P
vector_add(next_point, current_point, N0)
;B = T x N
vector_cross(T0, N0, B0)
;N = B x T
vector_cross(B0, T0, N0)
;Normalize vectors Or Else it won't work
vector_normalize(B0)
vector_normalize(N0)
For j = 0 To bands - 0
new_point_x.f
new_point_y.f
;rotate around the current point using normal rotation to makes a band (ie a circle around the point on the 2D curve)
new_point_x = Sin(j * 2 * #PI / bands) * #BAND_RAD
new_point_y = Cos(j * 2 * #PI / bands) * #BAND_RAD
;this is the corrected coordinates of our point in the band (the circle) (we need 16 points to make a circle)
x = N0\x * new_point_x + B0\x * new_point_y + current_point\x
y = N0\y * new_point_x + B0\y * new_point_y + current_point\y
z = N0\z * new_point_x + B0\z * new_point_y + current_point\z
MeshVertexPosition(x, y, z)
MeshVertexTextureCoordinate(txu, txv)
MeshVertexNormal(x, y, z)
txv = txv + 1/bands
Next
txv = 0
txu = txu + 1/bands
Next
Protected.l a, b, c, Nb
Protected.w P1, P2, P3, P4
Nb=NbX+1
NbZ = rings
;Debug NbZ
For b=0 To NbZ-2
For a=0 To NbX-1
P1=a+(b*Nb)
P2=P1+1
P3=a+(b+1)*Nb
P4=P3+1
MeshFace(P3, P2, P1)
MeshFace(P2, P3, P4)
Next
Next
EndProcedure