Camera Problems...

Blitz3D Forums/Blitz3D Programming/Camera Problems...

I have two issues with the camera system in my game...minor but very annoying.

First: Collision
Every time I update the camera, I position a pivot (CamPoint) at the location of the player, after turning off it's collision state. Then I re-enable collision for it (it has it's own type that only collides with the world), and move it up and behind the player. Then I position the camera at it's location.

The problem is, the collision never works. I thought it might be related to enabling/disabling the collision detection, but leaving it on all the time doesn't solve the problem. This is the only time I've ever had a problem with Blitz collisions failing to work at all. Anyone have an idea why?

Second: Rotation
To orient the camera smoothly, I use this method:
If EntityYaw(Player) > EntityYaw(CamPoint) + 1 Then
TurnEntity(CamPoint,0,1,0)
ElseIf EntityYaw(Player) < EntityYaw(CamPoint) -1 Then
TurnEntity(CamPoint,0,-1,0)
End If

The + 1 and - 1 are to keep the camera from getting "stuck" between two values, which results in seriously blurred scenes. My only problem is, sometimes the camera "flips" direction and takes the long way around, if the player turns really far before the camera catches up. Anyone know how I could fix this?

Could you post the code for the bit where you enable, disable collisions for the camera?

Actually the collision is with the CamPoint pivot:

EntityType(CamPoint,0)
PositionEntity(CamPoint,EntityX(Player),EntityY(Player),EntityZ(Player))
EntityType(Cam,CT_Cam)
MoveEntity(CamPoint,0,5,-10)

And then I place the Cam at the position of CamPoint.

Does the camera have a collision type assigned to it?

In that code, you're not turning the CamPoint collision back on. Presumably you are doing this somewhere in your code?

Yeah, good point... hehehe

Erm, that was a typo. It's turns collision back on for campoint, not cam.

Thought it may have been a typo, but wasn't sure.

- Are you sure you've set up the collision for CamPoint-to-world correctly?
- What value does the CT_Cam constant have? Not zero, I hope.
- Are you sure you've actually defined the CT_Cam constant in your code? If not, it'll default to zero. It'll also default to zero if you've mis-spelled the constant name in the 'EntityType(CamPoint,CT_Cam)' line. Worth double-checking.

Just some thoughts. We really need to see the code to help any more.

Does the camera have a collision type assigned to it? If it doesn't your camera isn't really going to collided with anything.

Ross, I think he just wants to check for collisions on the CamPoint (pivot), not the camera itself. Why he's even using a pivot and not just the camera itself, I don't know. It seems to be redundant, as I understand things.

For the rotation thing: instead of adding and subtracting 1 you should try to smooth out the rotation by using the diffrence divided by the amount of step used by the smoothing,eg:

a1#=a1#+ mouseXspeed()

a2#=a2#+((a1#-a2#)/4.0)

if a1# <0 then 
 a1#=a1# + 360
 a2#=a2# + 360
endif

if a1# >360 then 
 a1#=a1# - 360
 a2#=a2# - 360
endif

rotateentity whatever,0,a2,0

Not sure if you should swap a1 and a2 on this line:
a2#=a2#+((a1#-a2#)/4.0)

(Also: MouseXspeed must be at the right position relative to the vsync and the last MoveMouse.)

I'll make up a simple code only demo to show you guys the problem later...yes CT_Cam is set up exactly the same as my other collision types, with a different number of course. I've used the same method to collide particles, characters, projectiles, pretty much anything.

big10p: I actully used the campoint because I thought the collision problem was related to the camera, so I wanted to use something I know works (pivot). I'll be removing it eventually.

jfk: Will try that out as soon as I get a chance.

Ok, this should demonstrate the problems fully, though it looks like crap and hurts the eyes. Anyway, the cam shouldn't go through walls...in theory, but it does.

Global gameFPS = 60

Graphics3D(800,600,32,2)
Dither(False)
HidePointer()

Global Cam = CreateCamera()

Const CT_None = 0
Const CT_Player  = 1
Const CT_Map = 2
Const CT_Cam = 3

Collisions CT_Player,CT_Map,2,2
Collisions CT_Cam,CT_Map,2,1

Map = CreateCube()
ScaleEntity(Map,50,20,50)
FlipMesh(Map)
EntityType(Map,CT_Map)

Global Player = CreateSphere(8)
ScaleEntity(Player,1,2.5,1)
EntityType(Player,CT_Player)
EntityRadius(Player,1,2.5)
PositionEntity(Player,0,2.5,0)
EntityColor(Player,255,0,0)

Light = CreateLight(2)
PositionEntity(Light,50,50,50)

framePeriod = 1000 / gameFPS
frameTime = MilliSecs () - framePeriod

Repeat

	Repeat
		frameElapsed = MilliSecs () - frameTime
	Until frameElapsed

	frameTicks = frameElapsed / framePeriod
	
	frameTween# = Float(frameElapsed Mod framePeriod) / Float(framePeriod)
	
	For frameLimit = 1 To frameTicks
		If frameLimit = frameTicks Then CaptureWorld
		frameTime = frameTime + framePeriod
		
		UpdateGame()
		UpdateWorld()
		UpdateCam()
	Next
	
	RenderWorld frameTween
	
	Flip

Until KeyHit (1)

End

; ------------------------------------------------------------------
; Game update routine, called from frame limiting code
; ------------------------------------------------------------------

Function UpdateGame()

If KeyDown(17)
	If KeyDown(42)
		MoveEntity(Player,0,0,0.5)
	Else
		MoveEntity(Player,0,0,0.2)
	EndIf
ElseIf KeyDown(31)
	MoveEntity(Player,0,0,-0.1)
EndIf
If KeyDown(32)
	TurnEntity(Player,0,1,0)
ElseIf KeyDown(30)
	TurnEntity(Player,0,-1,0)
EndIf

End Function

Function UpdateCam()
	EntityType(Cam,0)
	PositionEntity(Cam,EntityX(Player),EntityY(Player),EntityZ(Player))
	If EntityYaw(Player) > EntityYaw(Cam) + 1 Then
		TurnEntity(Cam,EntityPitch(Cam),1,EntityRoll(Cam))
	ElseIf EntityYaw(Player) < EntityYaw(Cam) - 1 Then
		TurnEntity(Cam,EntityPitch(Cam),-1,EntityRoll(Cam))
	End If
	EntityType(Cam,CT_Cam)
	MoveEntity(Cam,0,5,-10)
End Function


Move the updatecam() function to before updateworld - which makes sense given that updateworld updates collisions, before rendering.

I'm not sure why I put it after updateworld...but that fixed it here. It didn't fix it in my main code, so I must be missing something there, at least now I know what to look for. Shouldn't be too hard to fix it...

Thanks for pointing that out.