# G3N mouse picking and gui (further 3d adventures with golang)

When I started coding for this blog post, I had in mind a GUI example, but thought I may as well throw in mouse picking in a 3D scene.  Still having my OpenGL head on my initial thought was to grab the view matrix from the camera, unproject the mouse coordinates…. and do almost everything myself… then thankfully I had second thoughts and had a proper look at the G3N camera, guess what most of the work is there and already done for you…!

```func (a *myApp) onMouseDown(evname string, ev interface{}) {

me := ev.(*window.MouseEvent)
w,h := a.Window().Size()

r := core.NewRaycaster(&math32.Vector3{}, &math32.Vector3{})
a.CameraPersp().SetRaycaster(r, (-.5 + me.Xpos/float32(w)) *2.0 , (.5 - me.Ypos/float32(h)) *2.0)
i := r.IntersectObject(a.Scene(), true)

var object *core.Node

if len(i)!=0 {
object = i[0].Object.GetNode()
....
}

....
}```

A simple mouse click callback is no mystery, however there are some things that we need to look at in closer detail, for a start we can’t simply give the raycaster raw mouse positions.  The near view plane is described by 2d coordinates ranging from -1 to +1 regardless of the screens aspect ratio, this is why for example the X coordinate is divided by the screen width, biased by 0.5 and finally multiplied by 2.

When you use IntersectObject you can do so recursively which is handy as you can just throw the root of the scene at it, what you get back is an array or slice of nodes that are intersected by the ray, crucially this array is sorted in depth order of distance from the camera – meaning that the first item (index 0) is always nearest to the camera.

There is really not too much complication with the GUI widgets, the Application structure handles the root GUI node and automagically resizes it for us when needed.  All we have to do is add widgets in a hierarchy to build an interface, there are a number layouts that can be used together to make really complex interfaces that could be made to resize depending on the current screen window (You’d maybe have to manually resize GUI windows when there’s a resize event).  Encouragingly for the future there is a way to load GUI’s from YAML files, while hand creating a YAML file (and getting it correct) might cause some challenges compared with just coding the GUI in GO, it does hold out the hope that someone might contribute a GUI editor that saves out nice YAML files…

```    g.window = gui.NewWindow(140,130)
g.window.SetTitle("Properties")
g.window.SetPosition(16, 16)

g.panel = gui.NewPanel(124,100)
g.panel.SetBorders(8, 8, 8, 8)
g.panel.SetColor(math32.NewColor("blue"))
g.panel.SetBordersColor(math32.NewColor("blue"))

g.panel.SetLayoutParams(&gui.VBoxLayoutParams{Expand: 8, AlignH: gui.AlignCenter})
layout := gui.NewVBoxLayout()
layout.SetSpacing(8)
g.panel.SetLayout(layout)