Camera following a mesh

BlitzMax Modules Forums/MiniB3D/Camera following a mesh

I've got this method on my 'camera' type, but I really don't like how it follows the 'main' character of the game I'm writing, I'm sure there will be a better algorithm for camera 'following' the main character. This is the code I'm using right now, any suggestion will be apreciated:

	Method Update()
		Local Dist:Float
		If target = Null Then Return
		Dist = cam.EntityDistance(target)
		
		If dist>maxdistance Then
			pos.PointEntity(target)
			pos.MoveEntity(0,2,0)
		ElseIf dist<mindistance Then
			pos.PointEntity(target)
			pos.MoveEntity(0,-2,0)
		End If
		pos.RotateEntity(0,0,0,True)
		
		cam.PointEntity(target)
	End Method


Notes:
Target is the mesh that has to be followed by the camera.
Pos is a pivot that is part of the camera object, it is used to place the camera.
cam is the camera object, contained as a filed on my camera type.

This is B3D code but should work with MiniB3D. It was coded by Antony and imo is a totally cool way for having a camera follow a mesh while avoiding obstructions.

Link here : http://www.blitzbasic.com/codearcs/codearcs.php?code=1083

mmm, any miniB3D version? I've not experience on Blitz3D

Well, Since MiniB3D IS B3D for BlitzMax then you should have no problem converting the code.

some nitwit by the name of 'bradford6' posted this 5 yrs ago:
http://www.blitzbasic.com/codearcs/codearcs.php?code=97

so i went ahead and updated it for the animated robot demo


get the robot demo here:
http://www.blitzbasic.com/Community/posts.php?topic=66821

or if you already have it, drop this code in the Robot Animtest folder
Import "MiniB3D.bmx"

Strict

Local width=1024,height=768,depth=32,mode=0 ; Graphics3D width,height,depth,mode

Local cam:TCamera=CreateCamera()
CameraRange cam,.5,1500
Local camdistance:Float = 600
Local camera_mode:Int
Local camera_mode_String:String
PositionEntity cam,0,10,-100

AmbientLight 200,200,200

Local Level:TMesh=LoadMesh("media/gamelevel.b3d")
CreateOctree(level,0,3)					' create mesh octree - makes collision detection faster (MiniB3D only)

Local robot:TMesh=LoadAnimMesh("media/robotwalk.b3d")
ScaleEntity robot,0.025,0.025,0.025

Global robot_pivot:Tpivot =CreatePivot(robot) 
MoveEntity robot_pivot,0,0,camdistance		' move the pivot back a little  For follow effect

EntityType robot,1						' set ROBOT entity type to 1

Local robot_radius:Float =7.25				' set ROBOT radius as it's the source collision entity
EntityRadius robot,robot_radius
Local collsphere:Tmesh = CreateSphere(8,robot)
ScaleEntity Collsphere,robot_radius,robot_radius,robot_radius
EntityType Level,2						' set mesh entity Type To 2
Collisions 1,2,4,2							'  enable colliisons between entity type 1 and 2, with reponse 4

' used by camera code
Local mxs#=0 	;	Local mys#=0	;	Local move#=0.5
MouseXSpeed() 	;	MouseYSpeed() ' initial flush of mouse values

' used by fps code
Local old_ms=MilliSecs()	;	Local renders	 	;	Local fps

' anim stuff
Local frame:Float	,  speed:Float , yspeed:Float


' MAIN LOOP BEGIN
While Not KeyDown(KEY_ESCAPE)		

	If KeyHit(KEY_ENTER) Then DebugStop

	If KeyHit(KEY_SPACE) Then camera_mode = 1 - camera_mode
		
		If camera_mode = 0
			camera_mode_String$ = "mouse look + Arrow keys"
			mxs#=mxs#+(MouseXSpeed()/5.0)
			mys#=mys#+(MouseYSpeed()/5.0)
		
			MoveMouse width/2,height/2
			MouseXSpeed() ' flush
			MouseYSpeed() ' flush
		
			RotateEntity cam,mys#,-mxs#,0
			'PointEntity(cam,robot)
			
			If KeyDown(KEY_UP)=True Then MoveEntity cam,0,0,move#
			If KeyDown(KEY_DOWN)=True Then MoveEntity cam,0,0,-move#
		
		
			If KeyDown(KEY_LEFT)=True Then MoveEntity cam,-move#,0,0 ' move camera left
			If KeyDown(KEY_RIGHT)=True Then MoveEntity cam,move#,0,0 ' move camera right
		
		Else
				camera_mode_String$ = "smoothcam"

				smoothcam(cam,robot_pivot,robot,50,15)
		EndIf
	
	
	If KeyDown(KEY_W)  Then speed:+.009

	If KeyDown(KEY_S) Then speed:-.009


	If KeyDown(KEY_A) Then TurnEntity robot,0,1,0
	If KeyDown(KEY_D) Then TurnEntity robot,0,-1,0

	speed:* 0.99
	yspeed:-0.1
	If yspeed<-3 Then yspeed = 0
	
	MoveEntity robot,0,yspeed,-speed
	
	' manually roll the animation
	frame:+(speed)
	If frame>30 Then frame = 0
	SetAnimTime(robot,frame)
	
	UpdateWorld
	RenderWorld
	renders=renders+1
	' calculate fps
	If MilliSecs()-old_ms>=1000
		old_ms=MilliSecs()
		fps=renders
		renders=0
	EndIf

		Text 0,0,"FPS: "+String(fps)
		text 0,20,"SPACE to change Camera Mode"
		text 0,40," WASD to move ROBOT"
		text 0,60,camera_mode_String$
	Flip 
	
Wend
' MAIN LOOP END

End

Function smoothcam(camera:Tcamera,pivot:Tpivot,target:Tentity,camspeed:Float,height:Float)


	Local curx#=EntityX(camera)
	Local curz#=EntityZ(camera)
	Local cury#=EntityY(target) + height
	Local destx#=EntityX(pivot,True)
	Local destz#=EntityZ(pivot,True)
	
	
	curx#=curx#+((destx#-curx#)/camspeed)
	curz#=curz#+((destz#-curz#)/camspeed)
	

	PositionEntity camera,curx#,cury#,curz#

	PointEntity camera,target
End Function




Thanks!