Page 1 of 1

inside a Tube trip . CameraFollow example

Posted: Thu Oct 03, 2013 3:13 pm
by applePi
what it looks like to be inside a tube ? !!
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
  

Re: inside a Tube trip . CameraFollow example

Posted: Thu Oct 03, 2013 4:04 pm
by IdeasVacuum
Love it! 8)

Re: inside a Tube trip . CameraFollow example

Posted: Thu Oct 03, 2013 7:10 pm
by davido
Very nice!

Re: inside a Tube trip . CameraFollow example

Posted: Thu Oct 03, 2013 8:08 pm
by Samuel
That's a very cool example. I haven't had the time to work with CameraFollow() yet, but it looks like it's a very handy feature.

Re: inside a Tube trip . CameraFollow example

Posted: Sat Oct 05, 2013 6:39 pm
by Comtois
applePi wrote:CameraFollow(#Camera, ObjectID, Angle, Height, Distance, RotationPercent, PositionPercent [, Mode])
i don't understand fully the last three values.
RotationPercent and PositionPercent are linear interpolation.
If Mode = #False you will have to call CameraLookAt() after CameraFollow().

try this

Code: Select all

CameraFollow(0, EntityID(#ball) , 0, EntityY(#ball)+0.2 ,1, 0.01, 0.02, #True )  

Re: inside a Tube trip . CameraFollow example

Posted: Sat Oct 05, 2013 7:05 pm
by applePi
thanks Comtois for the explanation
the new value makes me drive inside the tube exactly.