Example #1
0
func tween(a, b mgl32.Vec2) (x, y float32) {
	v := b.Sub(a)
	v = v.Mul(0.5)
	v = a.Add(v)

	return v.Elem()
}
Example #2
0
func (c *Container) mouseClick(button int, release bool, position mgl32.Vec2) {
	offsetPos := position.Sub(c.offset)
	c.Hitbox.MouseClick(button, release, offsetPos.Sub(c.backgroundOffset))
	for _, child := range c.children {
		child.mouseClick(button, release, offsetPos.Sub(c.elementsOffset))
	}
}
Example #3
0
func makeDot(v mgl32.Vec2, a float32, i int, clr mgl32.Vec4) mesh.Mesh {
	m := mesh.Mesh{
		Nmbr: mesh.Number(i),
		Dpth: 0.5,
		Vrts: []mgl32.Vec2{
			{-dotx, 0}, // 0
			{0, -doty}, // 1
			{dotx, 0},  // 2
			{0, doty},  // 3
		},
		Clrs: []mgl32.Vec4{
			clr,
		},
		Trngls: []mesh.Triangle{
			{
				Vnd:  mesh.Nd{0, 1, 2},
				Flvr: mesh.CONVEX,
			},
			{
				Vnd:  mesh.Nd{2, 3, 0},
				Flvr: mesh.CONVEX,
			},
		},
	}
	m.Transform(mgl32.HomogRotate2D(a))      // rotate by a
	m.Transform(mgl32.Translate2D(v.Elem())) // translate by v
	return m
}
Example #4
0
/** Calculate line boundary points.
 *
 * Sketch:
 *
 *     uh1___uh2
 *      .'   '.
 *    .'   q   '.
 *  .'   '   '   '.
 *.'   '  .'.  '   '.
 *   '  .' ul'.  '
 * p  .'       '.  r
 *
 *
 * ul can be found as above, uh1 and uh2 are much simpler:
 *
 * uh1 = q + ns * w/2, uh2 = q + nt * w/2
 */
func (polyline *polyLine) renderBevelEdge(sleeve, current, next mgl32.Vec2) {
	t := next.Sub(current)
	len_t := t.Len()

	det := determinant(sleeve, t)
	if mgl32.Abs(det)/(sleeve.Len()*len_t) < LINES_PARALLEL_EPS && sleeve.Dot(t) > 0 {
		// lines parallel, compute as u1 = q + ns * w/2, u2 = q - ns * w/2
		n := getNormal(t, polyline.halfwidth/len_t)
		polyline.normals = append(polyline.normals, n)
		polyline.normals = append(polyline.normals, n.Mul(-1))
		polyline.generateEdges(current, 2)
		return // early out
	}

	// cramers rule
	sleeve_normal := getNormal(sleeve, polyline.halfwidth/sleeve.Len())
	nt := getNormal(t, polyline.halfwidth/len_t)
	lambda := determinant(nt.Sub(sleeve_normal), t) / det
	d := sleeve_normal.Add(sleeve.Mul(lambda))

	if det > 0 { // 'left' turn -> intersection on the top
		polyline.normals = append(polyline.normals, d)
		polyline.normals = append(polyline.normals, sleeve_normal.Mul(-1))
		polyline.normals = append(polyline.normals, d)
		polyline.normals = append(polyline.normals, nt.Mul(-1))
	} else {
		polyline.normals = append(polyline.normals, sleeve_normal)
		polyline.normals = append(polyline.normals, d.Mul(-1))
		polyline.normals = append(polyline.normals, nt)
		polyline.normals = append(polyline.normals, d.Mul(-1))
	}
	polyline.generateEdges(current, 4)
}
Example #5
0
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))
}
Example #6
0
func (c *Container) mouseMove(position mgl32.Vec2) {
	offsetPos := position.Sub(c.offset)
	c.Hitbox.MouseMove(offsetPos.Sub(c.backgroundOffset))
	for _, child := range c.children {
		child.mouseMove(offsetPos.Sub(c.elementsOffset))
	}
}
Example #7
0
func (polyline *polyLine) render(coords []float32) {
	var sleeve, current, next mgl32.Vec2
	polyline.vertices = []mgl32.Vec2{}
	polyline.normals = []mgl32.Vec2{}

	coords_count := len(coords)
	is_looping := (coords[0] == coords[coords_count-2]) && (coords[1] == coords[coords_count-1])
	if !is_looping { // virtual starting point at second point mirrored on first point
		sleeve = mgl32.Vec2{coords[2] - coords[0], coords[3] - coords[1]}
	} else { // virtual starting point at last vertex
		sleeve = mgl32.Vec2{coords[0] - coords[coords_count-4], coords[1] - coords[coords_count-3]}
	}

	for i := 0; i+3 < coords_count; i += 2 {
		current = mgl32.Vec2{coords[i], coords[i+1]}
		next = mgl32.Vec2{coords[i+2], coords[i+3]}
		polyline.renderEdge(sleeve, current, next)
		sleeve = next.Sub(current)
	}

	if is_looping {
		polyline.renderEdge(sleeve, next, mgl32.Vec2{coords[2], coords[3]})
	} else {
		polyline.renderEdge(sleeve, next, next.Add(sleeve))
	}

	if polyline.join == LINE_JOIN_NONE {
		polyline.vertices = polyline.vertices[2 : len(polyline.vertices)-2]
	}

	polyline.draw(is_looping)
}
Example #8
0
func (c *Camera) project(pt mgl32.Vec2) mgl32.Vec2 {
	var (
		screen = pt.Vec4(1, 1)
		out    mgl32.Vec4
	)
	out = c.Projection.Mul4x1(screen)
	return out.Vec2()
}
Example #9
0
func (c *Camera) unproject(pt mgl32.Vec2) mgl32.Vec2 {
	var (
		screen = pt.Vec4(1, 1)
		out    mgl32.Vec4
	)
	out = c.Inverse.Mul4x1(screen)
	out = out.Mul(1.0 / out[3])
	return out.Vec2()
}
Example #10
0
func normalize(v1 mgl32.Vec2, length float32) mgl32.Vec2 {
	length_current := v1.Len()

	if length_current > 0 {
		v1 = v1.Mul(length / length_current)
	}

	return v1
}
Example #11
0
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))
}
Example #12
0
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)
}
Example #13
0
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,
	}
}
Example #14
0
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,
	}
}
Example #15
0
func computeMiter(lineA, lineB mgl32.Vec2, halfThick float32) (miter mgl32.Vec2, length float32) {
	var (
		tangent mgl32.Vec2
		tmp     mgl32.Vec2
	)
	tangent = lineA.Add(lineB).Normalize()
	miter = mgl32.Vec2{-tangent[1], tangent[0]}
	tmp = mgl32.Vec2{-lineA[1], lineA[0]}
	length = halfThick / miter.Dot(tmp)
	return
}
Example #16
0
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,
	}
}
Example #17
0
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(),
	)
}
Example #18
0
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)
}
Example #19
0
// TwoSegmentIntersect - find the intersection point of two line segments <p11-p12> and <p21-p22>
func TwoSegmentIntersect(p11, p12, p21, p22 mgl32.Vec2) (mgl32.Vec2, error) {
	p := p11
	q := p21
	r := p12.Sub(p11)
	s := p22.Sub(p21)
	if math.Abs(float64(Vec2Cross(r, s))) < 0.0000001 {
		return mgl32.Vec2{}, fmt.Errorf("No intersections: lines parallel")
	}
	t := Vec2Cross(q.Sub(p), s) / Vec2Cross(r, s)
	u := Vec2Cross(p.Sub(q), r) / Vec2Cross(s, r)
	if t >= 0 && t <= 1 && u >= 0 && u <= 1 {
		return p.Add(r.Mul(t)), nil
	}
	return mgl32.Vec2{}, fmt.Errorf("No intersections")
}
Example #20
0
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
}
Example #21
0
func ClickAndDragWindow(window *Window, hitbox Hitbox, c controller.Controller) {
	grabbed := false
	grabOffset := mgl32.Vec2{}
	hitbox.AddOnClick(func(button int, release bool, position mgl32.Vec2) {
		grabOffset = position
		grabbed = !release
	})
	c.BindMouseAction(func() {
		grabbed = false
	}, controller.MouseButton1, controller.Release)
	c.BindAxisAction(func(xpos, ypos float32) {
		if grabbed {
			position := mgl32.Vec2{xpos, ypos}
			window.SetTranslation(position.Sub(grabOffset).Vec3(0))
		}
	})
}
Example #22
0
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
}
Example #23
0
/** Calculate line boundary points.
 *
 * Sketch:
 *
 *              u1
 * -------------+---...___
 *              |         ```'''--  ---
 * p- - - - - - q- - . _ _           | w/2
 *              |          ` ' ' r   +
 * -------------+---...___           | w/2
 *              u2         ```'''-- ---
 *
 * u1 and u2 depend on four things:
 *   - the half line width w/2
 *   - the previous line vertex p
 *   - the current line vertex q
 *   - the next line vertex r
 *
 * u1/u2 are the intersection points of the parallel lines to p-q and q-r,
 * i.e. the point where
 *
 *    (q + w/2 * ns) + lambda * (q - p) = (q + w/2 * nt) + mu * (r - q)   (u1)
 *    (q - w/2 * ns) + lambda * (q - p) = (q - w/2 * nt) + mu * (r - q)   (u2)
 *
 * with nt,nt being the normals on the segments s = p-q and t = q-r,
 *
 *    ns = perp(s) / |s|
 *    nt = perp(t) / |t|.
 *
 * Using the linear equation system (similar for u2)
 *
 *         q + w/2 * ns + lambda * s - (q + w/2 * nt + mu * t) = 0                 (u1)
 *    <=>  q-q + lambda * s - mu * t                          = (nt - ns) * w/2
 *    <=>  lambda * s   - mu * t                              = (nt - ns) * w/2
 *
 * the intersection points can be efficiently calculated using Cramer's rule.
 */
func (polyline *polyLine) renderMiterEdge(sleeve, current, next mgl32.Vec2) {
	sleeve_normal := getNormal(sleeve, polyline.halfwidth/sleeve.Len())
	t := next.Sub(current)
	len_t := t.Len()

	det := determinant(sleeve, t)
	// lines parallel, compute as u1 = q + ns * w/2, u2 = q - ns * w/2
	if mgl32.Abs(det)/(sleeve.Len()*len_t) < LINES_PARALLEL_EPS && sleeve.Dot(t) > 0 {
		polyline.normals = append(polyline.normals, sleeve_normal)
		polyline.normals = append(polyline.normals, sleeve_normal.Mul(-1))
	} else {
		// cramers rule
		nt := getNormal(t, polyline.halfwidth/len_t)
		lambda := determinant(nt.Sub(sleeve_normal), t) / det
		d := sleeve_normal.Add(sleeve.Mul(lambda))

		polyline.normals = append(polyline.normals, d)
		polyline.normals = append(polyline.normals, d.Mul(-1))
	}
	polyline.generateEdges(current, 2)
}
Example #24
0
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
}
Example #25
0
func moveC(v mgl32.Vec2) {
	d := v.Sub(lstPnt) // calculate delta vec
	lstPnt = v

	switch slctdC {

	case 0:
		c0dy += d[1]

	case 1:
		c1dy += d[1]

	case 2:
		c2dy += d[1]

	case 4:
		c4dx += d[0]

	case 5:
		c5dx += d[0]
		c5dy += d[1]
	}
}
Example #26
0
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))
}
Example #27
0
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)
}
Example #28
0
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
}
Example #29
0
func (polyline *polyLine) renderNoEdge(sleeve, current, next mgl32.Vec2) {
	sleeve_normal := getNormal(sleeve, polyline.halfwidth/sleeve.Len())

	polyline.normals = append(polyline.normals, sleeve_normal)
	polyline.normals = append(polyline.normals, sleeve_normal.Mul(-1))

	sleeve = next.Sub(current)
	sleeve_normal = getNormal(sleeve, polyline.halfwidth/sleeve.Len())

	polyline.normals = append(polyline.normals, sleeve_normal.Mul(-1))
	polyline.normals = append(polyline.normals, sleeve_normal)

	polyline.generateEdges(current, 4)
}
Example #30
0
func makeTriangle(n mesh.Number, d float32, o mgl32.Vec2) mesh.Mesh {
	return mesh.Mesh{
		Nmbr: n,
		Dpth: d,
		Vrts: []mgl32.Vec2{
			o.Add(mgl32.Vec2{0, 0}),
			o.Add(mgl32.Vec2{0, 100}),
			o.Add(mgl32.Vec2{100, 100}),
		},
		Clrs: []mgl32.Vec4{
			{0.7, 1.0, 0.0, 0.7},
		},
		Trngls: []mesh.Triangle{
			{Vnd: mesh.Nd{0, 1, 2}},
		},
	}
}