the new function CameraFollow are splendid, some of other programming languages will sell such a function on a DVD as a special grand addon product .
CameraFollow(#Camera, ObjectID, Angle, Height, Distance, RotationPercent, PositionPercent [, Mode])
i don't understand fully the last three values. but here is the camera follow a sphere inside a helical tube http://www.purebasic.fr/english/viewtop ... 36&t=56642 the values are experimental and it is at the end of the trip the camera begins to vibrate, also i have reduced the gravity so to prolong the trip and to reduce the camera vibration . just focus on the CameraFollow since the tube construction are discussed in the above link
Code: Select all
#manyPi = 10 * #PI ;PI For rotation
#NUM_RINGS = 360
;#NUM_RINGS = 70
#NUM_BANDS = 32
;#RING_RAD = 2.0
#BAND_RAD = 0.5 ; thickness of the tube
#plane = 9
#ball = 10
Global stop = 1
Global.f rot = 1
Structure vector3d
x.f
y.f
z.f
EndStructure
Declare DrawTube (Rings.l, Bands.l, BandRadius.f)
Quit.b = #False: wire = 1
ExamineDesktops()
OpenWindow(3, 0, 0, DesktopWidth(0), DesktopHeight(0), " W to toggle wire/solid Frame", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;Initialize environment
InitEngine3D()
InitSprite()
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)
CreateMaterial(1, LoadTexture(1, "clouds.jpg"))
CreatePlane(#plane, 10, 10, 1, 1, 1, 1)
CreateEntity (#plane, MeshID(#plane), MaterialID(1))
MoveEntity(#plane,0,-3,0)
EntityPhysicBody(#plane, #PB_Entity_StaticBody)
CreateLight(0,RGB(255,255,255),-100,40,30)
AmbientColor(RGB(100,100,100))
CreateCamera(0, 0, 0, 100, 100)
MoveCamera(0, 0, 4, 30)
;CameraLookAt(0, 0, 2, 0)
RotateCamera(0, -15, 0, 0)
tex=CreateTexture(#PB_Any, 128, 128)
StartDrawing(TextureOutput(tex))
DrawingMode(#PB_2DDrawing_AlphaBlend)
Box(0, 0, 256, 256, RGBA(255, 100, 0, 255))
StopDrawing()
mat=CreateMaterial(#PB_Any, TextureID(tex))
CreateMaterial(0, LoadTexture(0, "terrain_texture.jpg"))
;CreateMaterial(0, LoadTexture(0, "wood.jpg"))
;CreateMaterial(0, LoadTexture(0, "MRAMOR6X6.jpg"))
MaterialCullingMode(0, #PB_Material_NoCulling)
;MaterialBlendingMode(0, #PB_Material_AlphaBlend)
DisableMaterialLighting(0, 1)
CreateMesh(1, #PB_Mesh_TriangleList, #PB_Mesh_Static )
SetMeshMaterial(1, MaterialID(0))
DrawTube (#NUM_RINGS, #NUM_BANDS, #BAND_RAD)
NormalizeMesh(1)
FinishMesh(1)
CreateEntity(1, MeshID(1), MaterialID(0))
MoveEntity(1,0,4,-2)
EntityPhysicBody(1, #PB_Entity_StaticBody ,0.1)
RotateEntity(1,90,250,0)
CreateSphere(#ball,2)
CreateEntity(#ball,MeshID(#ball),MaterialID(mat) )
ScaleEntity(#ball, 0.05,0.05,0.05)
MoveEntity(#ball, -0.3,4,-1.1)
EntityPhysicBody(#ball, #PB_Entity_SphereBody ,1,0.01,2)
y.f
ExamineKeyboard()
WorldGravity(-2)
Repeat
Event = WindowEvent()
If KeyboardReleased(#PB_Key_W)
If wire=1
MaterialShadingMode(0, #PB_Material_Wireframe)
wire = 0
ElseIf wire = 0
MaterialShadingMode(0, #PB_Material_Solid)
wire = 1
EndIf
EndIf
;CameraFollow(#Camera, ObjectID, Angle, Height, Distance, RotationPercent, PositionPercent [, Mode])
CameraFixedYawAxis(0, 1 )
CameraFollow(0, EntityID(#ball) , 0, EntityY(#ball)+0.2 ,1, 1, 0.02, #True )
RenderWorld()
FlipBuffers()
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape)
Quit = #True
EndIf
Until Quit = #True Or Event = #PB_Event_CloseWindow
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
Procedure DrawTube (Rings.l, Bands.l, BandRadius.f)
x.f: y.f: z.f
op.f = 1
txu.f : txv.f
For i = 0 To rings + 1
current_point.vector3d
next_point.vector3d
T.vector3d
B.vector3d
N.vector3d
p.f
;center point
p = op * i * #manyPi / rings
current_point\x = Cos(p)
current_point\y = Sin(p)
current_point\z = 0.2 * p
;next point For Frenet square
p = op * (i + 1) * #manyPi / rings
next_point\x = Cos(p)
next_point\y = Sin(p)
next_point\z = 0.2 * p
;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 - 1
new_point_x.f
new_point_y.f
;rotate around the current point using normal rotation makes bands
new_point_x = Sin(j * 2*#PI / bands) * #BAND_RAD
new_point_y = Cos(j * 2*#PI / bands) * #BAND_RAD
;this is the coords 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/bands
Next
txv = 0
;txu = txu + 1/rings
txu = txu + 1/bands
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
EndProcedure


