'Drag' Scrolling in 3D

Blitz3D Forums/Blitz3D Programming/'Drag' Scrolling in 3D

John Pickford(Posted 2005) [#1]
I'm thinking of implementing a Black & White style drag scroll in my game. The problem is I have no idea where to start.

How do I translate a 2D vector (from the mouse) to a 3D movement in my game world?

Any pointers?


Simian(Posted 2005) [#2]
I'm doing something similar in my current project. All I do is use MouseXSpeed() and MouseYSpeed() values to move the camera in the X and Z axes when the right mouse button is pressed. Seems to do the trick.


John Pickford(Posted 2005) [#3]
I need it to work whatever the orientation of the camera and at the right speed for the distance of the bit of the landscape I'm grabbing.

The maths is a bit beyond me.


Tom(Posted 2005) [#4]
Hi,

I never played B&W so I'm not sure if you mean entity or camera movement, here's a camera method, is this right?

Use LMB to drag, and cursors left/right to rotate

Graphics3D 800,600,32,2


piv=CreatePivot()
cam=CreateCamera(piv)

PositionEntity piv,0,8,0
RotateEntity cam,30,0,0

light=CreateLight()
RotateEntity light,30,30,0

plane=CreatePlane()
EntityColor plane,100,200,200

Dim box(200)

box(1)=CreateCube()
ScaleEntity box(1),Rnd(.2,.4),Rnd(1,1.5),Rnd(.2,.4)
EntityColor box(1),Rand(100,255),Rand(100,255),Rand(100,255)

For i=2 To 200
	box(i)=CopyEntity(box(1))
	ScaleEntity box(i),Rnd(.2,.4),Rnd(1,1.5),Rnd(.2,.4)
	EntityColor box(i),Rand(100,255),Rand(100,255),Rand(100,255)
	PositionEntity box(i),Rnd(-50,50),.5,Rnd(-50,50)
Next


While Not KeyDown(1)

	If MouseHit(1) Gosub moveLoop

	If KeyDown(203) TurnEntity piv,0,1,0
	If KeyDown(205) TurnEntity piv,0,-1,0
	
	UpdateWorld
	RenderWorld
	Flip
Wend
End

.moveLoop
	;Clicked X,Y
	cx#=MouseX()
	cy#=MouseY()

	ex#=EntityX#(piv,1)
	ez#=EntityZ#(piv,1)

	sens#=.025
	
	While MouseDown(1)
		mx#=MouseX()-cx
		mz#=MouseY()-cy

		mx=-mx*sens
		mz=mz*sens

		If KeyDown(203) TurnEntity piv,0,1,0
		If KeyDown(205) TurnEntity piv,0,-1,0

		TFormVector mx,0,mz,piv,0

		PositionEntity piv,ex#+TFormedX#(),8,ez#+TFormedZ#()
		UpdateWorld
		RenderWorld
		Flip
	Wend
Return


Tom


RiverRatt(Posted 2005) [#5]
If I understand what you want, you could use camerapick on the terrain or on an invisible plane, and do something like this...
;keep track of mouse position relative to visable grid function
Function track_mouse(marker,camera)
marker_X#=Int(PickedX#())+.5
marker_Z#=Int(PickedZ#())+.5
marker_Y#=Int(PickedY#())+.5
CameraPick(camera,MouseX(),MouseY())
End Function
parent and point the camera at a point that follows a marker position found with this function.


_Skully(Posted 2005) [#6]
Its possible to map 3D X and Y positions to the 2D mouse X and Y positions.

I did this ages ago. If I recall, what I did was set my camera position and then Projected the 3d point to the 2d screen, then projected a second point +1x, +1y to get a ratio between the 3d single point movement and the 2d movement. Then you just need to flip it 1.0/DeltaX# 1.0/deltaY# to get your ratio from 2D to 3D. This has limited use though because if you move the camera you have to re-project it but if thats what you need its possible.

If your just wanting the camera to move with the mouse in the 3d world which is the recommended way of doing it then just use the MouseXspeed(), MouseYSpeed() on the camera movement commands.


John Pickford(Posted 2005) [#7]
Toms example is close to what I want (cheers for that Tom).

I'll have tinker with it tomorrow and see if I can make it work the way I want. Ideally I want it to feel like you have actually grabbed hold of an object/part of the landscape. So if I grab a tower then then I can drag it around the screen with the tower staying with the mouse pointer. Grabbing somewhere further in the distance will result in a different speed/scale of movement than grabbing something closer.


Rob Farley(Posted 2005) [#8]
My not just camera pick the mouse position on the terrain?


John Pickford(Posted 2005) [#9]
And then what?


Rob Farley(Posted 2005) [#10]
Then you know the XYZ of the where the mouse is using pickedx pickedy and pickedz

Then if you take the current xyz of the mouse and take it away from the last XYZ of the mouse you will know the xyz mouse speed.


John Pickford(Posted 2005) [#11]
I can't see that working. If I 'grabbed' the top of a tower then moved the mouse to the side then the mouse mighty be over something miles away in the distance. So it would register a massive movement. What I want is the camera to move in such a way that the tower stays under the mouse cursor.

I'm thinking of getting the x,y,z location the way you say and then finding where on screen x+1,y,z is and where x,y,z+1 is. Then I would have some kind of scale for the dragging. Something close to the camera would need smaller movement (in world coords) than something far away in order to keep up with the mouse.


Rob Farley(Posted 2005) [#12]
I knew I'd seen something like this before...

This might help.

http://www.blitzbasic.com/codearcs/codearcs.php?code=379


John Pickford(Posted 2005) [#13]
That seems to be on the right track but it locks the objects Z position. I need it to lock in the y.


Damien Sturdy(Posted 2005) [#14]
How about the mouse routine as before (using mousespeed and linepick)
but
Position a pivot at the picked co-ordinates.
move the object by mousespeed multiplied by the distance of the camera to the pivot?


This is only theory but it should work. Let me know :)

If it fails, Kick me :P


John Pickford(Posted 2005) [#15]
That's pretty similar current solution (written this morning) and it works pretty well. But it's not perfect, I'd really like the target object to stay exactly under the mouse cursor.


Damien Sturdy(Posted 2005) [#16]
lower the radius of the linepick? :/