Moving parented camera with collisions

Blitz3D Forums/Blitz3D Beginners Area/Moving parented camera with collisions

Mac M(Posted 2003) [#1]
When I assing the parent of my camera to the collision level I can move the entire level (or rotate), and the camera moves with it. But if I apply gravity to the camera, it falls to the bottom, logically, but it pass through the map and keeps falling. Shouldn't the camera move with the level and conserve it's relative position to the map, and consecuently the collision data? How can I fix this? Thanks.


Ross C(Posted 2003) [#2]
Set up collisions between the camera and the level then. Or a'm i away the wrong way here :)


Mac M(Posted 2003) [#3]
Collisions are all in order. Camera stands on the level floor and all collisions work fine until I move/rotate the level. Then the level moves, and the camera with the same movement, but collision with floor is gone.


Ross C(Posted 2003) [#4]
Mmmmm, could you post some code plz?


Mac M(Posted 2003) [#5]
Just the Gargoyle FPS in samples\si\fps directory modified with my problem. 'A' key raises all entities. 'Z' key to lower.

; * FPS sample.
; * Program code by Simon Harrison (si@...).
; * Gargoyle model by Adam Gore.

; Graphics values
Const width=640,height=480,depth=16								

; Collision type values
Const type_camera=1,type_blood=2	; Source 
Const type_scenery=3,type_ladders=4	; Destination

; Camera position, angle values
Global cam_x#,cam_z#,cam_pitch#,cam_yaw#						; Current
Global dest_cam_x#,dest_cam_z#,dest_cam_pitch#,dest_cam_yaw#	; Destination

; CameraPick value
Global picked

; Set display mode
Graphics3D width,height,depth
SetBuffer BackBuffer()

; Create global pivot parent of ALL entities
Global all;
all=CreatePivot()

; Create collision sphere that represents the player camera
Global collision_sphere=CreateSphere(8,all)
PositionEntity collision_sphere,10,10,10
EntityRadius collision_sphere,7.5
EntityType collision_sphere,type_camera

; Set up camera, child of collision_sphere
Global camera=CreateCamera(collision_sphere)
CameraRange camera,1,600

; Set up lights
AmbientLight 191,191,191						
Global light=CreateLight(all)
LightColor light,31,31,31
RotateEntity light,45,0,0

; Load level
Global level=LoadMesh("interior.x",all)	
ScaleEntity level,100,100,100
EntityType level,type_scenery
EntityPickMode level,2
UpdateNormals level;update the normals of mesh

; Load ladders collision mesh
Global ladders=LoadMesh("ladders.x",all)
ScaleEntity ladders,100,100,100
EntityType ladders,type_ladders
EntityAlpha ladders,0

; Initialise collisions
Collisions type_camera,type_scenery,2,3
Collisions type_camera,type_ladders,2,2


; Main loop
; ---------

Global old_time=MilliSecs()
While Not KeyHit(1)

	UpdateGame()
	UpdateWorld
	RenderWorld
	
	; FPS
	frames=frames+1
	If MilliSecs()-render_time=>1000 Then fps=frames : frames=0 : render_time=MilliSecs()	
	Text 0,0,fps
	
	Flip
	
Wend
End


; --------------------
; Update game function
; --------------------

Function UpdateGame()

	GameInput()
	
End Function


; -------------------
; Game input function
; -------------------

Function GameInput()


	; Mouse look
	; ----------

	; Mouse x and y speed
	mxs=MouseXSpeed()
	mys=MouseYSpeed()
	
	; Mouse shake (total mouse movement)
	mouse_shake=Abs(((mxs+mys)/2)/1000.0)

	; Destination camera angle x and y values
	dest_cam_yaw#=dest_cam_yaw#-mxs
	dest_cam_pitch#=dest_cam_pitch#+mys

	; Current camera angle x and y values
	cam_yaw=cam_yaw+((dest_cam_yaw-cam_yaw)/5)
	cam_pitch=cam_pitch+((dest_cam_pitch-cam_pitch)/5)
	
;	RotateEntity camera,cam_pitch#,cam_yaw#,0
	RotateEntity collision_sphere,cam_pitch#,cam_yaw#,0

	
	; Rest mouse position to centre of screen
	MoveMouse width/2,height/2
	

	; Camera move
	; -----------
	
	; Forward/backwards - destination camera move z values
	If KeyDown(200)=True Or MouseDown(2)=True Then dest_cam_z=1
	If KeyDown(208)=True Then dest_cam_z#=-1

	; Strafe - destination camera move x values
	If KeyDown(205)=True Then dest_cam_x=1
	If KeyDown(203)=True Then dest_cam_x=-1
	
	; Current camera move x and z values
	cam_z=cam_z+((dest_cam_z-cam_z)/5)
	cam_x=cam_x+((dest_cam_x-cam_x)/5)

	; Move camera
	MoveEntity collision_sphere,cam_x,0,cam_z
	dest_cam_x=0 : dest_cam_z=0
	
	; Climb ladders
	If EntityCollided(collision_sphere,type_ladders)<>0 Then TranslateEntity collision_sphere,0,1,0

	; Gravity
	TranslateEntity collision_sphere,0,-1,0,True

	; If A key pressed, raise ALL
	If KeyDown(30)=True
		TranslateEntity all, 0, 0.1, 0
	EndIf

	; If Z key pressed, lower ALL
	If KeyDown(44)=True
		TranslateEntity all, 0, -0.1, 0
	EndIf


End Function



Ross C(Posted 2003) [#6]
Hey, there is no need to create a sphere to represent the camera's collision.

The reason it is not working as far as i can see, is the camera has no collisions assigned to it. You are parenting the camera to a sphere that has collisions on it, apart from collisions with the camera_sphere. Setting the camera_sphere to collide with the camera isn't going to work for two reasons.

1. The camera is inside the camera sphere and collisions cannot occur when this happens.

2. The camera is parented to the camera_sphere, so they will never actually collide.

So what you really need to do is get rid of the collision_sphere and all colisions between it. Now set up collisions between the actual camera and the level.

EntityRadius camera,2


Set the camera collision radius to 2 units. This will create an invisible sphere around the camera which is used for collisions.

EntityType camera,type_camera


Give the camera the collisiontype you assigned at the top of the program

Collisions type_camera,type_scenery,2,3


Set up your collisions. I see you've already done that now. Well, try that out anyway. You don't have any need for the whole collision shpere thing. :) Hope this helps!


Mac M(Posted 2003) [#7]
The problem is that I want to conserve the collision sphere to make it work as the player feet and put the camera entity a few units higher (as the player eyes). I do this because I want to set the level in a ship, and the player needs to move in very close places, and if I set the camera with a high radius, it doesn't fit, and with less radius, it's very close to floor. The movement of the ship is what I want to achieve by moving the ALL pivot.

However, I have the same problem with the collision sphere thing and without it.


Ross C(Posted 2003) [#8]
Well, give the player a head collision as well, and don't give the camera a collision type. You definetly don't need to set up collisions between the camera and the feet sphere. I'll try this out when i get home, cause it's hard to visualize right now. I'm in college :) be home in 2 hours.


Ross C(Posted 2003) [#9]
Ok, think i've got it. It all boils down to the way the collisions work. Blitz cannot do collisions were the moving scenary is colliding against the collisions sphere.

collisions type_camera,type_scenery

the first item mentioned in the collisions command, is the only entity that can move when checking collisions. The next item, type_scenery, must be stationary, or else they will just go thru each other. So it's got to be moving >>> non-moving collisions.

I don't inderstand why you would want the whole level to move up and down anyways. Best just moving the player. It's faster too :)


Mac M(Posted 2003) [#10]
Ok, thanks Ross. I have read several posts with the same problem (how to make a moving floor with collisions) and as you say, Blitz doesn't handle 2 moving entities with collision. Hope Mark will feature this in a future.

I want to move the entire level because in my project the level is a ship (a german u-boat), and of course in open sea she moves and rotates. This way:


Since now I was simulating this movement by moving the entire world except the own ship, and it works in matter of player collisions with the ship, but makes it very abstract to move the rest of the world instead of the ship :P.

Then I though that if I parent the camera to the collision map, in theory the collision data shouldn't be lost, because the camera don't moves in relation to the level, but it seems that depends on other things too...

I will investigate it more.

Thanks.


Ross C(Posted 2003) [#11]
Try looking at the LinePick command. It basically sends a line out in a user specified direction and returns collision value. Like pickedx, pickedy and pickedz. You could use line pick straightdown from your boat then position the boat at the pickedY() co-ords. That should solve your problem. :)


Mac M(Posted 2003) [#12]
The problem is not the position of the boat. I can rotate and position it at sea without any problem. The headache comes when I try to move the camera with it (the collision sphere is child of the boat). It is clear that Blitz cannot handle this at the moment.

I tried with linepick, but there is the same problem: it seems that Blitz doesn't handle very well linepick in the destination entity when moving it.


Ross C(Posted 2003) [#13]
do your linepick command, then updateworld, get your info, then move all your entities, then updateworld as normal. So basically use updateworld twice. I'm goin for kip, but i'll tryin help in the morning. There IS a way to do it ;) Always is.


MSW(Posted 2003) [#14]
Actually looking at the code...Um..you create a pivit named ALL...load a mesh for the level (makeing it a child of ALL)...create a sphere (another child of ALL)...create a light (child of ALL) ... and a camera (child of the collision sphere (which is a child of ALL))

then you are translateing and rotateing the entity ALL...which in turn should translate and rotate the children (and children's children) of ALL...meaning nothing should appear to happen...

However you are also moveing the camera (a child of the sphere..which is a child of the pivot ALL)...instead of actually moveing/rotateing the camera, move/rotate the sphere instead (apply gravity to the sphere the camera is a child of)