Mouselook makes camera constantly slide...?

Blitz3D Forums/Blitz3D Programming/Mouselook makes camera constantly slide...?

.rIKmAN.(Posted 2012) [#1]
Hey guys,

Not used B3D (or the forums) in a while, and have just been trying to knock up a quick idea but have hit a problem and have spent more time searching the forums for an answer than I have coding.

I have merged bits of code from various posts on here and am almost there, I'm hoping the brains on here can point me in the right direction - I'm sure it's something simple.

Basically I have a plane (have tried a terrain too), and a camera that is controlled with "mouselook" controls and WSAD movement.

You can select a grid space on the plane and click the LMB to place a cube, and click an existing cube with the RMB to make it transparent.

Everything is fine so far when I don't apply a gravity effect to keep the player on the ground, but this means he can fly around like a freelook mode.

If I try to add gravity on the y-axis then the pitch of the camera (looking up/down) make the player move forward/backwards which then makes it impossible to do much at all apart from stare straight forward.

As I said the code is cannibalised from various snippets on here so there is probably something stupid I am missing/not following.

Hope someone can help, here is the code, no media required.

The lines that show my explanations are commented with ###, just switch them round and you will see what I mean.

Thanks in advance.


Graphics3D 800,600,0,2
SetBuffer BackBuffer()

Global cx#,cz#,mousespeed#,camerasmoothness#,pitch#,yaw#,my#,mx#

; Collision type values
Const COL_GROUND=1
Const COL_PLAYER=2

; Set camera
camera=CreateCamera()
CameraClsColor camera,0,0,128
PositionEntity camera,10,20,15

EntityType camera,COL_PLAYER
EntityRadius camera,1.4

; Set Lights
light=CreateLight()
RotateEntity light,45,0,0

; Set Plane
ground = CreatePlane()
PositionEntity ground,-64,0,0
EntityPickMode ground,2 
EntityType ground,COL_GROUND

; Set Player
player=CreateSphere()
EntityColor player,200,0,0
EntityRadius player,1
PositionEntity player,0,10,15
EntityType player,COL_PLAYER

; Set Mouse Cursor Cube
cube = CreateCube()
FitMesh cube,1,0,1,1,.1,1
PositionEntity cube,0,.1,0
EntityPickMode(cube,2)

; Master Cube
Dim mCube(1)

mCube(1)=CreateCube()
FitMesh mCube(1),1,1,1,1,1,1
HideEntity mCube(1)

; Set Collisions
Collisions COL_PLAYER,COL_GROUND,2,3

; Set Mouse Values
mousespeed#=0.2
cameraspeed#=.1
camerasmoothness#=3

; Face Sphere (for visual reference)
PointEntity camera,player

While Not KeyDown(1)

	Cls

	; Get mouse position
	CameraPick(camera,MouseX(),MouseY())
	x1#=Int(PickedX#()-1.25);-1.25
	y1#=Int(PickedY#());''
	z1#=Int(PickedZ#()-1.25);''

	PositionEntity cube,x1,y1,z1
	
	; LMB Clicked
	If MouseHit(1)
		entity=CopyEntity(mCube(1))
		EntityPickMode(entity,2)
		EntityColor entity,Rnd(0,255),Rnd(0,255),Rnd(0,255)
		UpdateNormals entity
		PositionEntity entity,x1,y1-1,z1
	EndIf

	; RMB Clicked
	If MouseHit(2)
		DebugLog CameraPick(camera,MouseX(),MouseY())
		obj=CameraPick(camera,MouseX(),MouseY())
		EntityAlpha obj,0.2
	EndIf

	; Camera Controls
	mx=CurveValue(MouseXSpeed()*mousespeed,mx,camerasmoothness)
	my=CurveValue(MouseYSpeed()*mousespeed,my,camerasmoothness)
	MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
	pitch=EntityPitch(camera)
	yaw=EntityYaw(camera)
	pitch=pitch+my
	yaw=yaw-mx
	If pitch>89 pitch=89
	If pitch<-89 pitch=-89
	RotateEntity camera,0,yaw,0
	TurnEntity camera,pitch,0,0
	
	cx=(KeyDown(32)-KeyDown(30))*cameraspeed
	cz=(KeyDown(17)-KeyDown(31))*cameraspeed

	; ### WORKS BUT CAN FLY UP/DOWN ###
	MoveEntity camera,cx,0,cz

	; ### CANNOT FLY BUT CONSTANT SLIDING FROM MOUSELOOK UP/DOWN###
	;MoveEntity camera,cx,-0.5,cz
		
	MoveEntity player,0,-.5,0
	UpdateNormals cube

	UpdateWorld 
	RenderWorld
	
	Flip

Wend

ClearWorld()
End

Function CurveValue#(newvalue#,oldvalue#,increments )
	If increments>1 oldvalue#=oldvalue#-(oldvalue#-newvalue#)/increments
	If increments<=1 oldvalue=newvalue
	Return oldvalue#
End Function


Last edited 2012


Rob the Great(Posted 2012) [#2]
Gravity always deals with a Global direction of movement. In other words, it doesn't matter if something is turned sideways, upside down, or facing normal, it's always going to be pulled downwards according to the world's orientation.

MoveEntity always moves an entity according to its local orientation. Your bellybutton will always be lower than your head from your perspective, even if you are turned upside or sideways. This means that calling MoveEntity x,-0.5,z will move the entity downward from the entity's perspective, which is fine as long as your object's pitch is lined up with the world's pitch. But, as soon as you change the pitch, the direction of "downward" movement changes with it.

To fix this, always use globally oriented commands such as TranslateEntity when using gravity, rather than locally oriented commands such as MoveEntity.

; ### WORKS BUT CAN FLY UP/DOWN ###
	MoveEntity camera,cx,0,cz
;ADD THIS LINE HERE AND REMOVE THE OTHER CAMERA MOVEMENT LINE
        TranslateEntity camera,0,-0.5,0


P.S., I'm not sure if cannibalized was the right word you were looking when talking about piecing code together. It sounds kind of...morbid. lol.

Last edited 2012


.rIKmAN.(Posted 2012) [#3]
I knew it would be something stupidly simple - thanks for the help!

The morbid thing, well even using using the word "hacked" after I have mentioned cannibalism doesn't have quite the same meaning.. :)

Thanks again.