Movement Arrows/Pegs/Things

Blitz3D Forums/Blitz3D Programming/Movement Arrows/Pegs/Things

I did it :)
Basically, it uses arrows drawn in 2d to drag 3d objects about (handy for 3d editors of all sorts). I still have to implement rotation, but here it is so far. It also has a rectangle over line function in case you don't have one already, (and some exerts from the "Picklesworth Stupid 1 Line Functions" collection).

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

Type MovePegs
	Field BaseX,BaseY	
	Field BaseDrag
	Field PegXDrag,PegYDrag,PegZDrag
	Field LastX#,LastY#	
	Field XSpeed#,YSpeed#,ZSpeed#
	Field MoveScale
	Field Size#
End Type

AmbientLight 255,255,255

cam = CreateCamera()
PositionEntity cam,0,0,-10

cube = CreateCube()

;movement pegs
;Base = CreatePivot()
;X = CreatePivot(Base)
;PositionEntity X,2,0,0
;Y = CreatePivot(Base)
;PositionEntity Y,0,2,0
;Z = CreatePivot(Base)
;PositionEntity Z,1.5,1.5,2

MovePegs=MovePegs_Create(700,500,5)

While Not KeyDown(1)		
	MoveEntity cube,GetPegOutputX(MovePegs),GetPegOutputY(MovePegs),GetPegOutputZ(MovePegs)	
	RenderWorld
	updateMovePegs()
	Flip
	Cls
Wend
End

Function RectOverLine(x1#,y1#,x2#,y2#,rx#,ry#,rw#,rh#)
	For h = -rh/2 To rh
	For w = -rw/2 To rw
		If PointOverLine(x1#,y1#,x2#,y2#,rx#+w,ry#+h) = True Then Return True
	Next
	Next
End Function

Function PointOverLine(x1#,y1#,x2#,y2#,px#,py#)
	m1# = (y2-y1)/(x2-x1)
	m2# = (py-y1)/(px-x1)
	If m1=m2 And Distance(x1,y1,px,py) <= Distance(x1,y1,x2,y2) Then Return True Else Return False
End Function

Function MovePegs_Create(x,y,moveScale=1,size#=80)
	m.movepegs = New movepegs
	m\MoveScale = moveScale
	m\baseX = x
	m\baseY = y
	m\size=size
	Return Handle(m)
End Function

Function MovePegs_Position(entity,x,y,Glob=True)
	m.movepegs=Object.movepegs(entity)
	If Glob
		m\baseX = x
		m\baseY = y		 
	Else 
		m\baseX = m\baseX + x
		m\baseY = m\baseY + y
	EndIf
End Function

Function MovePegs_SetSize(entity,size#)
	m.movepegs=Object.movepegs(entity)
	m\size# = size
End Function

Function MovePegs_SetMoveScale(entity,scale#)
	m.movepegs=Object.movepegs(entity)
	m\MoveScale# = scale
End Function

Function UpdateMovePegs()
	For m.movepegs = Each movepegs
		
		If m\pegXdrag Then Color 255,255,0 Else Color 255,0,0 ;X line
		Line m\BaseX,m\BaseY,m\BaseX+m\size,m\BaseY
		If m\pegYdrag Then Color 255,255,0 Else Color 0,255,0 ;Y line
		Line m\BaseX,m\BaseY,m\BaseX,m\BaseY-m\size
		If m\pegZdrag Then Color 255,255,0 Else Color 0,0,255 ;Z line
		Line m\BaseX,m\BaseY,m\BaseX+(m\size/1.6),m\BaseY-(m\size/1.6)
		
		Color 100,100,100
		Rect m\BaseX-3,m\BaseY-3,6,6
		
		;Color 255,255,255		
		;Line m\baseX+4,m\baseY-4,m\BaseX+50,m\BaseY-50
		
		;m\pegXdrag=0 And m\pegYdrag=0 And m\pegZdrag=0
				
		If MouseHit(1)
			If RectsOverlap(MouseX(),MouseY(),1,1,m\BaseX-4,m\BaseY-4,8,8) Then m\BaseDrag = True : Goto skipclick
			
			If RectOverLine(m\baseX,m\baseY,m\BaseX+(m\size/1.6),m\BaseY-(m\size/1.6),MouseX(),MouseY(),8,8) Then m\PegZDrag = True : m\Lastx=MouseX() : m\LastY=MouseY() : Goto skipclick ;Z Axis
			If RectOverLine(m\BaseX,m\BaseY,m\BaseX+m\size,m\BaseY,MouseX(),MouseY(),8,8) Then m\PegXDrag = True : m\Lastx=MouseX() : m\LastY=MouseY() : Goto skipclick ;X Axis
			If RectOverLine(m\BaseX,m\BaseY,m\BaseX,m\BaseY-m\size,MouseX(),MouseY(),8,8) Then m\PegYDrag = True : m\Lastx=MouseX() : m\LastY=MouseY() : Goto skipclick ;Y Axis

			ElseIf Not MouseDown(1)
				m\BaseDrag = False : m\PegXDrag = False : m\PegYDrag = False : m\PegZDrag = False
				m\XSpeed# = 0 : m\YSpeed# = 0 : m\ZSpeed# = 0
		EndIf
		.skipclick
		If m\BaseDrag
			m\baseX = MouseX()
			m\baseY = MouseY()			
		EndIf
		
		If m\pegXDrag
			;m\XSpeed# = GetGreatest(MouseXSpeed() ,MouseYSpeed())
			m\XSpeed# = (MouseX() - m\LastX#) / m\MoveScale
			m\LastX# = MouseX()
			m\LastY# = MouseY()
			DebugLog "Dragging X " + m\XSpeed#					
		EndIf
		If m\pegYDrag
			;m\YSpeed# = GetGreatest(MouseXSpeed(),MouseYSpeed())
			m\YSpeed# = (m\LastY# - MouseY()) / m\MoveScale
			m\LastX# = MouseX()
			m\LastY# = MouseY()
			DebugLog "Dragging Y " + m\YSpeed#				
		EndIf
		If m\pegZDrag
			;m\ZSpeed# = GetGreatest(MouseXSpeed(),MouseYSpeed())
			m\ZSpeed# = (m\LastY# - MouseY()) / m\MoveScale
			m\LastX# = MouseX()
			m\LastY# = MouseY()
			DebugLog "Dragging Z " + m\ZSpeed#				
		EndIf
	Next
End Function

Function GetPegOutputX#(entity)
	m.movepegs = Object.movepegs(entity)
	Return m\XSpeed#
End Function
Function GetPegOutputY#(entity)
	m.movepegs = Object.movepegs(entity)
	Return m\YSpeed#
End Function
Function GetPegOutputZ#(entity)
	m.movepegs = Object.movepegs(entity)
	Return m\ZSpeed#
End Function

Function EntityProject(camera,entity)
	CameraProject camera,EntityX(entity,1),EntityY(entity,1),EntityZ(entity,1)
End Function

Function GetGreatest(a#,b#)
        ;An advanced sorting algorithm to grab the highest number of two possibilities.
	If a#>b# Then Return a# Else Return b#
End Function

It's all quite simple, but nothing like this has had its source code posted yet so I may as well save someone a bit of time.
Is there anything I'm missing here that I should add? I plan to put this in the code archives for fun, but may as well have everything I need first time round, and may as well be forced to add it before I tell myself I'm done (it works better that way, regardless of how small the project is).