3d Mouse Control

Blitz3D Forums/Blitz3D Beginners Area/3d Mouse Control

Gauge(Posted 2004) [#1]
How can you move a cube around a 3d world by using the mouse? Anyone possibly have any code?


RiverRatt(Posted 2004) [#2]
Look at code in the games section that came with blitz.
The tunnel run game uses mouse control.
Unless your talking about Diablo stile where you click on a point and the caracter moves to that point. I think you would use Camerapick() and picked x,y,z to give the object a destination turn the object to face the picked coordinates and moveentity 0,0,1.
I'm sure there are lots of other ways to do these.


jfk EO-11110(Posted 2004) [#3]
You could use a Grid made of a Plane that you can move up and down with the mouse when you press eg. the shift key. Then, without pressing the shift key, you would use CameraPick to determine the 3D Position of the mousepointer on the grid plane. Of course the plane needs to be pickable.
(Kind of like in Maplet)


bradford6(Posted 2004) [#4]
best way in my opinion is to create a manipulator object with arrows pointing in the X,Y and Z directions, if you click and hold the directional arrow, track mousemove to move the cube


bradford6(Posted 2004) [#5]
try this- very rough but explains my idea

click and hold the color manipulator to move the cube

Graphics3D 640,480
	Global	midw = GraphicsWidth()/2
	Global  midh =GraphicsHeight()/2

Global cam = CreateCamera() : MoveEntity cam,0,5,-15
light = CreateLight()
Global plane = CreateCube() : ScaleEntity plane,64,.25,64 : EntityAlpha plane,.5
planetex = CreateTexture(256,256) : ScaleTexture planetex,.025,.025 : SetBuffer TextureBuffer(planetex)
	Color 255,255,0 : Rect 0,0,255,255,0
EntityTexture plane,planetex 

Global cube = CreateCube() : EntityColor cube,255,0,0
Global MX#
Global MY#
; manipulator

m = CreatePivot()
Global Xdir = CreateCone(5,1,m) : EntityColor xdir,255,0,0 : ScaleEntity Xdir,.25,1,.25
	RotateEntity xdir,0,0,90 : TranslateEntity xdir,-1.25,0,0
Global Ydir = CreateCone(5,1,m) : EntityColor ydir,0,255,0 : ScaleEntity ydir,.25,1,.25
	RotateEntity ydir,0,0,0 : TranslateEntity ydir,0,1.25,0
Global zdir = CreateCone(5,1,m) : EntityColor zdir,0,0,255 : ScaleEntity zdir,.25,1,.25
	RotateEntity zdir,90,0,0 : TranslateEntity zdir,0,0,1.25


EntityPickMode xdir,2 : EntityPickMode ydir,2 : EntityPickMode zdir,2

MoveEntity m,-2,5,-12




SetBuffer BackBuffer()

Repeat

If MouseDown(1) = 1 Then campick()

	RenderWorld 
		debug() 
	Flip
Until KeyHit(1) = 1
End

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


Function campick()
	pictentity = 0
	mox = MouseX()
	moy = MouseY()
	foo = MouseYSpeed() : foo = MouseXSpeed() ; flush 
	CameraPick(cam,MouseX(),MouseY())
	pictentity = PickedEntity() 
	If Pictentity<>0
		;MY# = MouseYSpeed()/64
		;MY#=curvevalue#(MouseYSpeed(),MY#,128 )
		;MX#=curvevalue#(MouseXSpeed(),MX#,128 )
	
		pcx# = PickedX#()
		pcy# = PickedY#()
		pcz# = PickedZ#()
		If pictentity = xdir
			Repeat
				
				MY#=curvevalue#(MouseYSpeed(),MY#,3 )/16
				MX#=curvevalue#(MouseXSpeed(),MX#,3 )/16

				MoveEntity cube,mx#,0,0
				MoveMouse mox,moy
				RenderWorld : debug() : Flip
			Until MouseDown(1) = 0
		EndIf

		If pictentity = ydir
			Repeat
				
				MY#=curvevalue#(MouseYSpeed(),MY#,3 )/16
				MX#=curvevalue#(MouseXSpeed(),MX#,3 )/16

				MoveEntity cube,0,-MY#,0
				MoveMouse mox,moy
				RenderWorld : debug() : Flip

			Until MouseDown(1) = 0
		EndIf

		If pictentity = zdir
			Repeat
				
				MY#=curvevalue#(MouseYSpeed(),MY#,3 )/16
				MX#=curvevalue#(MouseXSpeed(),MX#,3 )/16

				MoveEntity cube,0,0,MY#
				MoveMouse mox,moy
				RenderWorld : debug() : Flip

			Until MouseDown(1) = 0
		EndIf
	
	EndIf
	

End Function

Function debug()
	cx# = EntityX(cube)
	cy# = EntityY(cube)
	cz# = EntityZ(cube)
	CameraProject(cam,cx#,cy#,cz#)
	dstring$ = "X: "+cx#+" Y: "+cy#+" Z: "+cz#
	p# = (Len(dstring$)*FontWidth())/2
	Text ProjectedX#()-p#,ProjectedY#(),dstring$
	

End Function





RiverRatt(Posted 2004) [#6]
Here is a idea I have bin thinking of for a while.



bradford6(Posted 2004) [#7]
very cool RiverRatt.


BlackJumper(Posted 2004) [#8]
Very efficient control system RiverRatt. Very nice.


RiverRatt(Posted 2004) [#9]
Thank you. Glad you like it. I plan on doing more with it.
The end goal is to get it to control like a stearing wheel.
But it has other possible uses. For instance try comenting out the "If ImagesOverlap(mousepoint,MouseX(),MouseY(),rotate\image,rotate\x,rotate\y) Then" statement and move the rotation graph to the center of the screen. If the camera was set at an orthographic position you have diablo style control. Also the graph does not even have to be drawn for it to work.


Gauge(Posted 2004) [#10]
I figured it out, though with picking the plane i have to subtract/add the picked x/y positiong to put an entity at that location. However heres my code. This places a cone, sphere or cube on a 3d grid, mouse to wander, hit the up/down arrow keys to move to a diff level, and left clicking the mouse drops the object. I was kind of thinking of a making a "super maplet" level editor thingy, shrug if I will.


RiverRatt(Posted 2004) [#11]
Hey quit holding out. Lets see it.


RiverRatt(Posted 2004) [#12]
I don't know about a "super maplet" but I have bin thinking of making a Maplet clone for a few months now. I need to study up on how to make custom meshes. I have figured out how to directly move an object on a 3d grid. Next step I think is to make a square surface by storing the marker position when the mouse is hit and scale the surface to where the mouse is released. Anyone want to help? This could be a cool comunity project and we might end up with a great tool, like Maplet but improved texture, movement and more when we get that much done.




Gauge(Posted 2004) [#13]
This is how I started, this is really really ugly and simple, and just places a few things. Can I readjust the x/y/z picks any better?

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

ClsColor 0,0,255
camera=CreateCamera()
PositionEntity camera,0,5,-1
RotateEntity camera,45,0,0
CameraClsColor camera,0,0,128
light=CreateLight()
RotateEntity light,90,0,0
PositionEntity light, 0,0,0
light2=CreateLight()
PositionEntity light,0,50,0
plane=CreateTerrain(128)
PositionEntity plane,-64,0,0
EntityPickMode plane,2 
ground_tex=LoadTexture("c:\gridtex2.bmp")
EntityTexture plane,ground_tex
cube=CreateCube()
cube_tex=LoadTexture("c:\gridtex.bmp")
FitMesh cube,1,0,1,1,.1,1
EntityTexture cube,cube_tex 
PositionEntity cube,0,.1,0
EntityAlpha plane,.1
EntityParent light,cube 
LightMesh CUBE,255,0,0
Const game=1
Const menu=2
image=LoadImage("c:\menua.bmp")
image2=LoadImage("c:\fileimage.bmp")

Dim mObject(3)
mObject(1)=CreateCube()
mObject(2)=CreateSphere()
mObject(3)=CreateCone()
For x=1 To 3 Step 1
FitMesh mobject(x),1,1,1,1,1,1
Next

HideEntity mObject(1)
HideEntity mObject(2)
HideEntity mObject(3)
mtype=1
obj$="cube"
curr_level=-1
EntityParent camera,plane
While Not KeyDown( 1 )
If KeyHit(208)=True Then
MoveEntity plane,0,-1,0
MoveEntity cube,0,-1,0
curr_level=curr_level-1
EndIf
If KeyHit(200)=True Then
MoveEntity plane,0,1,0
MoveEntity cube,0,1,0
curr_level=curr_level+1
EndIf

status=game
If KeyDown( 205 )=True Then TurnEntity camera,0,-1,0
If KeyDown( 203 )=True Then TurnEntity camera,0,1,0
If KeyDown( 208 )=True Then MoveEntity camera,0,0,-0.05
If KeyDown( 200 )=True Then MoveEntity camera,0,0,0.05
newx=MouseX()
newy=MouseY()
If newy<100  status=menu
;a=0
;If newx>oldx+5 Then a=1
;If newx<oldx-5 Then a=1
;If newy<oldy-5 Then a=1
;If newy>oldy+5 Then a=1
;oldx=newx
;oldy=newy
;If a=1
;If MouseHit(1) Then
If status=menu Then
If MouseHit(1) Then
Select True
Case newx<100
	mtype=1
	obj$="cube"
Case newx>100 And newx<320
	mtype=2
	obj$="sphere"
Case newx>320
	mtype=3
	obj$="cone"
End Select
EndIf
EndIf

If status=game Then
CameraPick(camera,MouseX(),MouseY())
x1=Int(PickedX#()-1.25)
y1=Int(PickedY#())
z1=Int(PickedZ#()-1.5)
PositionEntity cube,x1,y1,z1
If MouseHit(1) Then
entity=CopyEntity(mObject(mtype))
UpdateNormals entity
PositionEntity entity,x1,curr_level,z1
EndIf
EndIf
Cls
UpdateNormals cube
RenderWorld
DrawImage image,0,0
DrawImage image2,0,0
Text 10,50,"Current object: "+obj$
Flip
Delay 100
Wend
 
ClearWorld()
End



RiverRatt(Posted 2004) [#14]
It would help if you use blitz primatives and a generated grid texture rather than loading media. I can't run it to see what your talking about. Also please describe the problem better.
And the awnser is yes... There is always a better way.


Gauge(Posted 2004) [#15]
I figured out why i had to readjust the pick coordinates, fitmesh cube,1,1,1,1,1,1 doesn't exactly work right, sorry about the need for the media. Here try this.

Right Click places a 1x1x1 floor tile, right clicking lets you select how big it is.(doesn't work right if you go down/left though). I only made 1 1 color brush *sniff*.
Graphics3D 800,600,0,1
SetBuffer BackBuffer()
ClsColor 255,0,0
Cls

;brush1=CreateBrush(255,0,0)
brush2=CreateBrush(255,0,0)

camera=CreateCamera()
PositionEntity camera,0,5,-1
RotateEntity camera,45,0,0
CameraClsColor camera,0,0,128

light=CreateLight()
RotateEntity light,90,0,0
PositionEntity light, 0,0,0

plane=CreateTerrain(128)
PositionEntity plane,-64,0,0
EntityPickMode plane,2
;PaintEntity plane,brush1

cube=CreateMesh()
surf=CreateSurface(cube)
v1=AddVertex(surf,0,0,0,0,0)
v2=AddVertex(surf,1,0,0,1,0)
v3=AddVertex(surf,1,0,1,1,1)
v4=AddVertex(surf,0,0,1,0,1)
tri=AddTriangle(surf,v4,v3,v1)
tri2=AddTriangle(surf,v3,v2,v1)

PaintEntity cube,brush2
PositionEntity cube,0,.1,0
EntityAlpha plane,.1
EntityParent light,cube 
LightMesh CUBE,255,0,0
obj$="floor"
status=game

sel=0

While Not KeyDown( 1 )
If KeyDown( 205 )=True Then TurnEntity camera,0,-1,0
If KeyDown( 203 )=True Then TurnEntity camera,0,1,0
If KeyDown( 208 )=True Then MoveEntity camera,0,0,-0.05
If KeyDown( 200 )=True Then MoveEntity camera,0,0,0.0

CameraPick(camera,MouseX(),MouseY())
x1=Int(PickedX#())
y1=Int(PickedY#())
z1=Int(PickedZ#())
PositionEntity cube,x1,curr_level,z1

If sel=1 Then
If x1>oldx xd=oldx-x1
If z1>oldz zd=oldz-z1
ScaleEntity ex,xd,1,zd
PositionEntity ex,x1,curr_level,z1
UpdateNormals(ex)
obj$=oldx+","+oldz+","+newx+","+newz
EndIf

If MouseHit(1) Then
entity=CopyEntity(cube)
PositionEntity entity,x1,curr_level,z1
EndIf

If MouseHit(2) Then
Select True
Case sel=0
	oldx=x1
	oldy=y1
	oldz=z1
	sel=1
	sy=1
	sz=1
	sx=1
	ex=CopyEntity(cube)
	UpdateNormals(ex)
	PositionEntity ex,oldx,curr_level,oldz
	HideEntity cube
	LightMesh ex,255,0,0
Case sel=1
	newx=x1
	newy=y1
	newz=z1
	If newx>oldx xd=newx-oldx
	If newz>oldz zd=newz-oldz
	If newx<1 newx=1
	If newz<1 newz=1
	;entity=CopyEntity(cube)
	;ScaleEntity entity,sx,1,sz
	;PositionEntity entity,oldx,curr_level,oldz
	sel=0
	ShowEntity cube
	End Select
EndIf

Cls
FlushMouse

UpdateNormals cube
RenderWorld
Text 10,50,"Current object: "+obj$
Flip
Delay 100
Wend
 
ClearWorld()
End