Cameras & Movement

Blitz3D Forums/Blitz3D Programming/Cameras & Movement

3DMan(Posted 2007) [#1]
Greetings,

I have set up several static cameras around a level, now I would like to control the player character movement by using WSAD keys.

When S would be pressed the character would run towards the camera, on W key press he would run away from the camera and with A & D he would move sideways.

The character model would also need to turn(rotate) away from the camera on S, and face it on W.

How could this be done?
Thank you very much


Matty(Posted 2007) [#2]
Use the TFormNormal/TFormVector commands to calculate the appropriate vector for movement relative to the specific camera viewed from.

IE

if 'Camera1' is active and is observing the scene and the player presses 'A' to go left relative to that camera view it would be done something like this:

TFormNormal -1,0,0,Camera1,0


The above line would transform the 'left direction' in Camera1's space to the corresponding vector relative to 'world space'. I Use TFormNormal as that uses 'unit vectors' as we only need to know the direction not the magnitude of the vector.

Then you would do something like this
TranslateEntity CharacterEntity,TFormedX()*CharacterSpeed,TFormedY()*CharacterSpeed,TFormedZ()*CharacterSpeed


that line would then move the characterentity in the appropriate world space direction a distance equal to the character's speed.

Hope that is of some help.


3DMan(Posted 2007) [#3]
Thank you very much Matty!

By the way, is there any special way of turning the player relative to the camera view or no?


Stevie G(Posted 2007) [#4]
Here's an example I posted a few years back ..

Graphics3D 640,480,16,1

Global LIGHT = CreateLight()
Global PLANE = CreatePlane() 
EntityColor PLANE, 200,100,100
texture = CreateTexture( 32, 32 )
SetBuffer TextureBuffer( texture )
For y = 0 To 1
	For x = 0 To 1
		Color 100, 150+25*( ( x+y) Mod 2 ) , 100
		Rect x*16,y*16,16,16,1
	Next
Next
SetBuffer BackBuffer()
ScaleTexture texture, 50,50
EntityTexture PLANE, texture
FreeTexture texture

Global CUBE = CreateCube() : FitMesh CUBE, -2,0,-2,4,10,4 
Tmp = CreateCube() : FitMesh Tmp, -1,7,2,2,2,2 : AddMesh Tmp, CUBE : FreeEntity Tmp
Global TARGET = CreatePivot()

Global CAMERApivot = CreatePivot()
Global CAMERA = CreateCamera( CAMERApivot )
PositionEntity CAMERA, 0,50,-50
PointEntity CAMERA , CAMERApivot

While Not KeyDown(1)

	PositionEntity CAMERApivot , EntityX( CUBE ) , 0, EntityZ( CUBE )
	TurnEntity CAMERApivot, 0 , KeyDown(31) - KeyDown(30) , 0
	
	;move relative to camera
	Mx# = KeyDown(205) - KeyDown(203)
	Mz# = KeyDown(200) - KeyDown(208 )

	If Mx <> 0 Or Mz <> 0
		;move relative to camera
		TFormVector Mx, 0, Mz , CAMERApivot , 0
		TranslateEntity CUBE, TFormedX(), 0, TFormedZ()
		;turn relative to movement
		PositionEntity TARGET, EntityX( CUBE ) + TFormedX() , 0, EntityZ( CUBE ) + TFormedZ()
		TurnEntity CUBE, 0 , DeltaYaw( CUBE, TARGET ) * .25, 0
	EndIf
	
	RenderWorld()
	Flip

Wend




3DMan(Posted 2007) [#5]
Thank you very much Stevie!

One more Q - right now if both A & W, W & D, A & S or S & D keys are pressed the character moves under 45 degrees angle ( as it should ), but it moves twice as fast. How could that be fixed?

Also I'm curious - is this the only way of doing the camera relative turning (with creating the target pivot) or are there any other ways?


DJWoodgate(Posted 2007) [#6]
Normalise the movement vector given by the keydowns?
	ML# = Sqr(MX*MX+MZ*MZ)
	If ML<>0 Then 
		MX# = MX/ML
		MZ# = MZ/ML
	EndIf


or use TformNormal instead of TformVector which does something similar.


Stevie G(Posted 2007) [#7]
As DJWoodgate says, use Tformnormal ...

Speed# = .5

	If Mx <> 0 Or Mz <> 0
		;move relative to camera
		TFormNormal Mx, 0, Mz , CAMERApivot , 0
		TranslateEntity CUBE, TFormedX() * Speed , 0, TFormedZ() * Speed
		;turn relative to movement
		PositionEntity TARGET, EntityX( CUBE ) + TFormedX() , 0, EntityZ( CUBE ) + TFormedZ()
		TurnEntity CUBE, 0 , DeltaYaw( CUBE, TARGET ) * .25, 0
	EndIf


I doubt that there is another more efficient way. The target pivot is required to obtain orientation relative to the camera - which your always going to need.

Stevie


3DMan(Posted 2007) [#8]
Thank you guys!

Two more Q's if you don't mind:

How about if i only wanted to turn the character relative to camera, without moving it ( right now turning is relative to movement ), how could that be done?

And, is there any way, instead of moving the character relative to camera, to move the character according to room orientation? right now if you put 0 instead of CameraPivot it will move the character according to world coords. I want to move the character according to room's local coords, so even if the room is rotated the character will move accordingly.

Much appreciated.


3DMan(Posted 2007) [#9]
Anyone?


Stevie G(Posted 2007) [#10]
You want to turn the character relative to a static camera but move relative to a room orientation? Like this .... ( use A & D to rotate the room)




Otherwise you'll need to explain yourself a bit better as that doesn't make much sense? What exactly are you trying to achieve - resident evil style movement?


3DMan(Posted 2007) [#11]
Thank you Stevie;

Yeah, that's exactly what I'm trying to achieve - resident evil style movement.
After comparing movement relative to camera and movement relative to level (if CAMERApointer is zero), it turns out that movement relative to level makes more sense when STATIC camera isn't facing the room at the right angles. It simply works better for my taste, so I decided to go with that.
I've sent you my sandbox level to your email, so you can get the exact idea.
The problem with this code though is that when the room is rotated in world space, the key setup doesnt match the exact same room coordinates movement, of course, since it moves the character by 1 or -1 relative to world coords.
I'm trying to have the same key configuration for all the rooms in the level no matter at what angles they're rotated under the world coords, or where the camera is placed - which is, W moves the character deeper into the "monitor", S moves him towards you, and A and D move him left or right on the monitor ( no matter where the camera is placed, or how the room is rotated ), but relative to room's coords, not cameras.

Btw, press the right mouse button to go into "aim mode" and that's where i want the character to use the same key config relative to room's coords as well ( the only difference being it doesn't move, only turn.

I hope with this explanation and the sandbox i sent you get a clear picture. But your resident evil style movement explains alot too. :]

Thank you for helping!