func SegmentCircleIntersect(radius float32, center, start, finish mgl32.Vec2) (mgl32.Vec2, error) { d := finish.Sub(start) f := start.Sub(center) a := d.Dot(d) b := f.Mul(2).Dot(d) c := f.Dot(f) - radius*radius discriminant := b*b - 4*a*c if discriminant < 0 { return mgl32.Vec2{}, fmt.Errorf("No intersection") } else { discriminant = float32(math.Sqrt(float64(discriminant))) t1 := (-b - discriminant) / (2 * a) t2 := (-b + discriminant) / (2 * a) if t1 >= 0 && t1 <= 1 { return mgl32.Vec2{start.X() + t1*d.X(), start.Y() + t1*d.Y()}, nil } if t2 >= 0 && t2 <= 1 { return mgl32.Vec2{start.X() + t2*d.X(), start.Y() + t2*d.Y()}, nil } } return mgl32.Vec2{}, fmt.Errorf("No intersections") }
func (ai *AI) moveAlongPath(targetPosition mgl32.Vec2, path []graph.Node) { minDistance2 := square(float32(ai.Me.Size) + costMapReduction*1.3) var pathNode *mapNode var pathVecs []mgl32.Vec2 for _, rawNode := range path { node := rawNode.(*mapNode) pos := mgl32.Vec2{float32(node.X) * costMapReduction, float32(node.Y) * costMapReduction} if pathNode == nil && dist2(ai.Me.Position, pos) >= minDistance2 { pathNode = node } pathVecs = append(pathVecs, pos) } if pathNode == nil { ai.addStatusMessage("Failed to find path node that was far enough away. Moving directly to objective.") ai.Path = []mgl32.Vec2{ai.Me.Position, targetPosition} ai.g.SetTargetPos(targetPosition.X(), targetPosition.Y()) return } ai.Path = pathVecs ai.g.SetTargetPos(float32(pathNode.X*costMapReduction), float32(pathNode.Y*costMapReduction)) }
func (ai *AI) getPseudoMe() *agario.Cell { firstCell := ai.OwnCells[0] me := &agario.Cell{ ID: firstCell.ID, Name: firstCell.Name, Heading: firstCell.Heading, Color: firstCell.Color, IsVirus: firstCell.IsVirus, } var avgPosition mgl32.Vec2 for _, cell := range ai.OwnCells { me.Size += cell.Size if avgPosition.X() == 0 && avgPosition.Y() == 0 { avgPosition = cell.Position continue } avgPosition = avgPosition.Add(cell.Position) } n := float32(len(ai.OwnCells)) avgPosition[0] = avgPosition[0] / n avgPosition[1] = avgPosition[1] / n me.Position = avgPosition return me }
func (s *Sprite) textureBounds(textureBounds mgl32.Vec2) render.UniformSprite { return render.NewUniformSprite( s.bounds.X()/textureBounds.X(), s.bounds.Y()/textureBounds.Y(), s.offset.X()/textureBounds.X(), 1.0-(s.offset.Y()+s.bounds.Y()-1.0)/textureBounds.Y(), ) }
func (te *TextElement) updateImage(size mgl32.Vec2) { // Initialize the context. bg := image.Transparent c := te.getContext() text := te.GetHiddenText() if len(text) == 0 { text = te.props.placeholder r, g, b, _ := te.props.textColor.RGBA() placeholderColor := color.RGBA{uint8(r), uint8(g), uint8(b), 80} c.SetSrc(image.NewUniform(placeholderColor)) } // Establish image dimensions and do word wrap textHeight := c.PointToFixed(float64(te.props.textSize)) var width int var height int = int(textHeight >> 6) words := strings.Split(text, " ") lines := []string{""} lineNb := 0 for _, word := range words { wordWithSpace := fmt.Sprintf("%v ", word) dimensions, _ := c.StringDimensions(wordWithSpace) width += int(dimensions.X >> 6) if width > int(size.X()) { width = int(dimensions.X >> 6) height += int(dimensions.Y>>6) + 1 lines = append(lines, "") lineNb += 1 } lines[lineNb] = fmt.Sprintf("%v%v", lines[lineNb], wordWithSpace) } if te.props.height > 0 { height = int(te.props.height) } rgba := image.NewRGBA(image.Rect(0, 0, int(size.X()), height+int(textHeight>>6)/3)) draw.Draw(rgba, rgba.Bounds(), bg, image.ZP, draw.Src) c.SetClip(rgba.Bounds()) c.SetDst(rgba) // Draw the text. pt := freetype.Pt(0, int(textHeight>>6)) for _, line := range lines { _, err := c.DrawString(line, pt) if err != nil { log.Printf("Error drawing string: %v\n", err) return } pt.Y += textHeight } te.img.SetImage(imaging.FlipV(rgba)) te.img.SetWidth(float32(rgba.Bounds().Size().X)) te.img.SetHeight(float32(rgba.Bounds().Size().Y)) }
func (r *SplashRenderer) splashConfig(sheet *twodee.Spritesheet, pt mgl32.Vec2, name string) twodee.SpriteConfig { frame := sheet.GetFrame(name) return twodee.SpriteConfig{ View: twodee.ModelViewConfig{ pt.X() + frame.Width/2.0, pt.Y() + frame.Height/2.0, 0.0, // Center 0, 0, 0, 1.0, 1.0, 1.0, }, Frame: frame.Frame, } }
func (h *HudLayer) cursorSpriteConfig(sheet *twodee.Spritesheet, pt mgl32.Vec2, cursor string) twodee.SpriteConfig { frame := sheet.GetFrame(cursor) return twodee.SpriteConfig{ View: twodee.ModelViewConfig{ pt.X(), pt.Y(), 0.0, 0, 0, 0, 1.0, 1.0, 1.0, }, Frame: frame.Frame, } }
func (h *HudLayer) highlightSpriteConfig(sheet *twodee.Spritesheet, pt mgl32.Vec2, name string) twodee.SpriteConfig { frame := sheet.GetFrame(name) return twodee.SpriteConfig{ View: twodee.ModelViewConfig{ pt.X() + frame.Width/2.0, pt.Y() + frame.Height/6.0, 0.0, // Left aligned 0, 0, 0, 1.0, 1.0, 1.0, }, Frame: frame.Frame, } }
func (c *Camera) ScreenToWorldCoords(screenCoords mgl32.Vec2) mgl32.Vec2 { // http://stackoverflow.com/questions/7692988/ var ( half = c.ScreenSize.Mul(0.5) pt = mgl32.Vec2{ (screenCoords.X() - half.X()) / half.X(), (half.Y() - screenCoords.Y()) / half.Y(), } ) return c.unproject(pt) }
func (te *TextElement) Render(size, offset mgl32.Vec2) mgl32.Vec2 { te.props.size, te.props.offset = size, offset textWidth, textHeight := size.X(), size.Y() if te.props.width > 0 { textWidth = te.props.width } if te.props.height > 0 { textHeight = te.props.height } if te.previousProps != te.props { te.updateImage(mgl32.Vec2{textWidth, textHeight}) te.previousProps = te.props } return te.img.Render(size, offset) }
func (ie *ImageElement) Render(size, offset mgl32.Vec2) mgl32.Vec2 { ie.size, ie.offset = size, offset width, height := ie.getWidth(size.X()), ie.getHeight(size.X()) if ie.img != nil { if width <= 0 && height <= 0 { width = float32(ie.img.Bounds().Size().X) height = float32(ie.img.Bounds().Size().Y) } else if width <= 0 { width = height * float32(ie.img.Bounds().Size().X) / float32(ie.img.Bounds().Size().Y) } else if height <= 0 { height = width * float32(ie.img.Bounds().Size().Y) / float32(ie.img.Bounds().Size().X) } } imgSize := mgl32.Vec2{width, height} ie.node.SetScale(imgSize.Vec3(0)) ie.node.SetTranslation(offset.Vec3(0)) ie.offset = offset ie.Hitbox.SetSize(imgSize) return imgSize }
func createTextVertices(text string, position mgl32.Vec2, size float32, font *Font) (vertices []mgl32.Vec2, uvs []mgl32.Vec2) { x := position.X() y := float32(currentWindow.Height()) - position.Y() for c, char := range text { i := float32(c) upLeft := mgl32.Vec2{x + i*size, y + size} upRight := mgl32.Vec2{x + i*size + size, y + size} downRight := mgl32.Vec2{x + i*size + size, y} downLeft := mgl32.Vec2{x + i*size, y} vertices = append(vertices, upLeft, downLeft, upRight) vertices = append(vertices, downRight, upRight, downLeft) glyph := font.font.Glyphs().Find(string(char)) fullWidth := float32(font.font.Width) fullHeight := float32(font.font.Height) width := float32(glyph.Width) height := float32(glyph.Height) x := float32(glyph.X) y := float32(glyph.Y) uvX := x / fullWidth uvY := (fullHeight - y) / fullHeight uvWidth := width / fullWidth uvHeight := height / fullHeight uvUpLeft := mgl32.Vec2{uvX, uvY} uvUpRight := mgl32.Vec2{uvX + uvWidth, uvY} uvDownRight := mgl32.Vec2{uvX + uvWidth, uvY - uvHeight} uvDownLeft := mgl32.Vec2{uvX, uvY - uvHeight} uvs = append(uvs, uvUpLeft, uvDownLeft, uvUpRight) uvs = append(uvs, uvDownRight, uvUpRight, uvDownLeft) } return }
func (m *Mob) moveTowardExit(elapsed time.Duration, level *Level) { var ( dest mgl32.Vec2 ok bool pct = float32(elapsed) / float32(time.Second) gridDist mgl32.Vec2 goalDist int32 stepDist = pct * m.Speed ) if dest, goalDist, ok = level.Grid.GetNextStepToSink(m.Pos); !ok { return } gridDist = dest.Sub(m.Pos) if goalDist == 1 && gridDist.Len() < stepDist+0.5 { m.PendingDisable = true } if gridDist.X() > 0 { m.swapState(Left, Right) } else { m.swapState(Right, Left) } m.Pos = m.Pos.Add(gridDist.Normalize().Mul(stepDist)) }
func (ai *AI) movePathed(position mgl32.Vec2) { minDistance2 := square(float32(ai.Me.Size) + costMapReduction*1.3) if dist2(ai.Me.Position, position) < minDistance2 { ai.addStatusMessage("Objective is within minimum distance. Moving directly to objective.") ai.Path = []mgl32.Vec2{ai.Me.Position, position} ai.g.SetTargetPos(position.X(), position.Y()) return } // meNode := ai.Map.GetNode(gameToCostMap(ai.Me.Position.Elem())) // positionNode := ai.Map.GetNode(gameToCostMap(position.Elem())) // path, cost, nodes := search.AStar(meNode, positionNode, ai.Map, nil, nil) // if path == nil { // ai.addStatusMessage("Failed to find path. Trying undirected.") // ai.movePathedUndirected(position) // return // } // ai.addStatusMessage(fmt.Sprintf("A*: path cost: %.2f / nodes expanded: %d", cost, nodes)) positionNode := ai.Map.GetNode(gameToCostMap(position.Elem())) path, cost := ai.DijkstraMap.To(positionNode) if path == nil { ai.addStatusMessage("movePathed: Failed to find path. Moving directly to objective.") ai.Path = []mgl32.Vec2{ai.Me.Position, position} ai.g.SetTargetPos(position.X(), position.Y()) return } ai.addStatusMessage(fmt.Sprintf("movePathed: path cost: %.2f", cost)) ai.moveAlongPath(position, path) }
func (c *Container) Render(size, offset mgl32.Vec2) mgl32.Vec2 { c.size, c.offset = size, offset padding := convertMargin(c.padding, c.paddingPercent, size.X()) margin := convertMargin(c.margin, c.marginPercent, size.X()) sizeMinusMargins := size.Sub(mgl32.Vec2{ margin.Left + margin.Right + padding.Left + padding.Right, margin.Top + margin.Bottom + padding.Top + padding.Bottom, }) containerSize := sizeMinusMargins if c.width > 0 { containerSize[0] = c.getWidth(size.X()) - padding.Left - padding.Right } if c.height > 0 { containerSize[1] = c.getHeight(size.X()) - padding.Top - padding.Bottom } var width, height, highest float32 = 0, 0, 0 for _, child := range c.children { childSize := child.Render(containerSize, mgl32.Vec2{width, height}) width += childSize.X() if width > containerSize.X() { height += highest highest = 0 childSize = child.Render(containerSize, mgl32.Vec2{0, height}) width = childSize.X() } if childSize.Y() > highest { highest = childSize.Y() } } height += highest if mgl32.FloatEqual(c.height, 0) { containerSize[1] = height } //offsets and sizes c.backgroundOffset = mgl32.Vec2{margin.Left, margin.Top} c.elementsOffset = mgl32.Vec2{margin.Left + padding.Left, margin.Top + padding.Top} backgroundSize := containerSize.Add(mgl32.Vec2{padding.Left + padding.Right, padding.Top + padding.Bottom}) totalSize := backgroundSize.Add(mgl32.Vec2{margin.Left + margin.Right, margin.Top + margin.Bottom}) c.background.SetScale(backgroundSize.Vec3(0)) c.background.SetTranslation(c.backgroundOffset.Vec3(0)) c.elementsNode.SetTranslation(c.elementsOffset.Vec3(0)) c.node.SetTranslation(c.offset.Vec3(0)) c.Hitbox.SetSize(backgroundSize) return totalSize }
func (c *Camera) GetMouseVector(windowSize mgl32.Vec2, mouse mgl32.Vec2) mgl32.Vec3 { v, err := mgl32.UnProject( mgl32.Vec3{mouse.X(), windowSize.Y() - mouse.Y(), 0.5}, mgl32.LookAtV(c.Translation, c.Lookat, c.Up), mgl32.Perspective(mgl32.DegToRad(c.Angle), windowSize.X()/windowSize.Y(), c.Near, c.Far), 0, 0, int(windowSize.X()), int(windowSize.Y()), ) if err == nil { return v.Sub(c.Translation).Normalize() } else { log.Println("Error converting camera vector: ", err) } return c.Lookat }
/* ***************** MAIN FUNCTION ************************ */ func main() { /* **************** OVR INIT CODE ***************** */ if err := glfw.Init(); err != nil { log.Fatalln("failed to initialize glfw") } defer glfw.Terminate() C.ovr_Initialize(nil) //create an HMD for reference. var hmd C.ovrHmd = nil // find number of headsets hmdCount := (int)(C.ovrHmd_Detect()) // print headset count fmt.Println(hmdCount) fmt.Printf("Found %d connected Rift device(s)\n\n", hmdCount) // grab the first headset if hmdCount > 0 { for i := 0; i < 1; i++ { hmd = C.ovrHmd_Create((C.int)(i)) //Print headset name fmt.Println(C.GoString(hmd.ProductName)) } } //if there is no headset connected, create a new debug. if hmd == nil { fmt.Println("Unable to open rift device\n Creating debug device.\n") hmd = C.ovrHmd_CreateDebug(C.ovrHmd_DK2) } //Starts the sensor device if C.ovrHmd_ConfigureTracking(hmd, C.ovrTrackingCap_Orientation|C.ovrTrackingCap_Position, 0) == 0 { fmt.Println("Unable to start Rift head tracker\n") } //extendedMode := C.ovrHmdCap_ExtendDesktop & hmd.HmdCaps //positioning of window and size of window var outposition mgl32.Vec2 outposition[0] = (float32)(hmd.WindowsPos.x) outposition[1] = (float32)(hmd.WindowsPos.y) //TODO: Change this to output at chosen resolution, not necessarily native pg. 76 Oculus Rift in action var outsize mgl32.Vec2 outsize[0] = (float32)(hmd.Resolution.w) outsize[1] = (float32)(hmd.Resolution.h) //print position and sizes to console fmt.Printf("Rift position:\t\t %f \t %f \nRift Size:\t\t %f \t %f \n\n", outposition.X(), outposition.Y(), outsize.X(), outsize.Y()) monitors := glfw.GetMonitors() var riftIndex int //loop over the monitors for index, element := range monitors { //print the monitor positions posX, posY := element.GetPos() fmt.Printf("Monitor Position:\t\t %d \t %d\n", posX, posY) if float32(posX) == outposition.X() && float32(posY) == outposition.Y() { riftIndex = index } } //Get video mode of monitor mode := monitors[riftIndex].GetVideoMode() outsize[0] = float32(mode.Width) outsize[1] = float32(mode.Height) /* ***************************************************** */ // ************* OPENGL / GLFW INIT CODE ************** */ glfw.WindowHint(glfw.Decorated, 0) glfw.WindowHint(glfw.Resizable, glfw.False) glfw.WindowHint(glfw.ContextVersionMajor, 4) glfw.WindowHint(glfw.ContextVersionMinor, 1) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) window, err := glfw.CreateWindow(int(outsize.X()), int(outsize.Y()), "LinuxVR", nil, nil) window.SetPos(int(outposition.X()), int(outposition.Y())) if gl.Init(); err != nil { panic(err) } window.MakeContextCurrent() //Print OpenGL Version to console version := gl.GoStr(gl.GetString(gl.VERSION)) fmt.Println("OpenGL Version", version, "\n\n") //keyboard input callback window.SetKeyCallback(onKey) /* **************************************************** */ previousTime := glfw.GetTime() totalTime := 0.0000 /* ******************* MAIN LOOP ******************** */ for !window.ShouldClose() { glfw.PollEvents() //Update time := glfw.GetTime() elapsed := time - previousTime previousTime = time totalTime = totalTime + elapsed //get current head state state := C.ovrHmd_GetTrackingState(hmd, 0) orientation := state.HeadPose.ThePose.Orientation //convert to go type float32 var q mgl32.Quat q.W = (float32)(orientation.w) q.V[0] = (float32)(orientation.x) q.V[1] = (float32)(orientation.y) q.V[2] = (float32)(orientation.z) //publish tracking information once a second if totalTime >= 1 { fmt.Printf("w: %f X: %f Y: %f Z: %f\n", q.W, q.X(), q.Y(), q.Z()) totalTime = 0 } //basic opengl things draw(window) //Swap buffers window.SwapBuffers() //Poll for events (keyboard, resize, etc) } /* ***************** OVR SHUTDOWN ******************** */ C.ovrHmd_Destroy(hmd) C.ovr_Shutdown() }
func Vector2bytes(w io.Writer, vector mgl32.Vec2) { Float32bytes(w, vector.X()) Float32bytes(w, vector.Y()) }
//PointLiesInsideAABB - return true if the point lies within the rectan formed by points a and b func PointLiesInsideAABB(a, b, point mgl32.Vec2) bool { if (point.X() > a.X() && point.X() > b.X()) || (point.X() < a.X() && point.X() < b.X()) { return false } if (point.Y() > a.Y() && point.Y() > b.Y()) || (point.Y() < a.Y() && point.Y() < b.Y()) { return false } return true }
func (cBody *ChipmunkBody) SetForce(force mgl32.Vec2) { cBody.Body.SetForce(force.X(), force.Y()) }
func (cBody *ChipmunkBody) SetVelocity(velocity mgl32.Vec2) { cBody.Body.SetVelocity(velocity.X(), velocity.Y()) }
func convertToVect(v mgl32.Vec2) vect.Vect { return vect.Vect{X: vect.Float(v.X()), Y: vect.Float(v.Y())} }