Tracking a Camera Thru 3d

Blitz3D Forums/Blitz3D Programming/Tracking a Camera Thru 3d

danjo(Posted 2005) [#1]
I have been thinking of ways to do an effect, whereas the camera moves thru a level, on a preset route, arriving at a final destination, (or looping).
the camera route, will go around corners, and it will also turn on its pivot, (slowly angling toward its new direction as it gets there).
i have some different ways to takcle this, but i wouldnt mind other peoples ideas on how they would do this.

someways i thought about is set a target, and point your camera pivot at it until it collides, where it then sets the target at its next location, and so on.
another way, may be to have a data field set of start points, end points, tracking speed, and camera directions.

before i go too deeply into a method, i would like to hear if anyone else may have a straightforward way. the camera will simply follow a set path, and face set directions along the way, arriving at the end.


danjo(Posted 2005) [#2]
i found Rims, recording and playback of an entity, and it seems to be the "idiots" way of doing this. i will adjust some settings, and the files it saves can be then called back to replay the recorded cam movment.


Ross C(Posted 2005) [#3]
You could have way points, kept in an array.

dim waypoint(30,2) ; 30 waypoints, 2nd dimention: 0 = x, 1 = y, 2 = z


Then have a pivot travel in front of the camera, and always point the camera at the pivot. Move the pivot towards the waypoints. Move the camera towards the pivot. The camera should curve round the waypoints smoothly. I rather use types for the waypoints however. I'll knock together an example.


Ross C(Posted 2005) [#4]
Ok, here it is :o) I used arrays, as it's slightly easier to do i think. Comments in code, based on the above statement :o)

Graphics3D 800,600
SetBuffer BackBuffer()

Global camera = CreateCamera()
Global camera_pivot = CreateSphere() ; the pivot the camera will follow. SPHERE so you can see whats happening
Global light = CreateLight()


; set up some cubes, to see the camera moving properly
Dim scene(20)

For loop = 0 To 20
	scene(loop) = CreateCube()
	PositionEntity scene(loop),Rnd(-40,40),Rnd(-30,30),Rnd(-60,60)
	EntityColor scene(loop),Rnd(0,255),Rnd(0,255),Rnd(0,255)
Next


Global max_waypoints = 10 ; set the max waypoint number. You'll need to have enough data statements!
Dim waypoint(max_waypoints,2) ; dimention the array. 2 is for the 3 co-ords. 0 = x, y = 1, z= 2
For loop = 0 To max_waypoints
	Read waypoint(loop,0) ; read in the X co-ord
	Read waypoint(loop,1) ; read in the Y co-ord
	Read waypoint(loop,2) ; read in the X co-ord
Next


Global current_waypoint = 0 ; the current waypoint number
Global waypoint_marker = CreateSphere();Pivot() ; changed to a sphere, so you can see whats happening

;position the waypoint marker at the current waypoint number.
PositionEntity waypoint_marker,waypoint(current_waypoint,0),waypoint(current_waypoint,1),waypoint(current_waypoint,2)


While Not KeyHit(1)


	UpdateWorld
	update_camera(0.2)
	RenderWorld
	Flip
Wend
End


; function to make the pivot follow the waypoints and the camera follow the pivot
Function update_camera(speed#)
	
	
	PointEntity camera_pivot,waypoint_marker; point the camera pivot at the current waypoint marker
	MoveEntity camera_pivot,0,0,speed ; move the camera pivot ta a constant speed towards the marker
	PointEntity camera,camera_pivot ; point the camera at the camera pivot
	MoveEntity camera,0,0,EntityDistance#(camera,camera_pivot) / ((1/speed)*10); move the camera towards the pivot,
																			   ;based on the distance between the two for smooth movement

	If EntityDistance#(camera_pivot,waypoint_marker) < 1.2 Then ; if the camera pivot is close to the marker
		current_waypoint = current_waypoint + 1 ; increment the waypoint number
		If current_waypoint > max_waypoints Then ; if this causes it to exceed the max number of waypoints then
			current_waypoint = 0 ; set to back to 0 to loop the waypoints
		End If
		; BELOW, position the waypoint marker at the current (recently moved on ABOVE) waypoint position
		; using the values read into the array
		PositionEntity waypoint_marker,waypoint(current_waypoint,0),waypoint(current_waypoint,1),waypoint(current_waypoint,2)
	End If
	
End Function

;data for the waypoint positions

Data 0  ,10 ,10
Data 10 ,20 ,20
Data 30 ,5  ,30
Data 20 ,12 ,27
Data 10 ,12 ,-5
Data -10,23 ,-10
Data -30,-10,17
Data 30 ,0  ,6
Data 10 ,27 ,-26
Data 20 ,8  ,20
Data -20,0  ,0