func (v Vec4) Z() float64 {
	return v[2]
}
Z is an element access func, it is equivalent to v[n] where
n is some valid index. The mappings are XYZW (X=0, Y=1 etc). Benchmarks
show that this is more or less as fast as direct acces, probably due to
inlining, so use v[0] or v.X() depending on personal preference.
package mgl64
import (
	"math"
	"golang.org/x/image/math/f64"
)
type Vec2 f64.Vec2
type Vec3 f64.Vec3
type Vec4 f64.Vec4
func (v Vec2) Vec3(z float64) Vec3 {
	return Vec3{v[0], v[1], z}
}
func (v Vec2) Vec4(z, w float64) Vec4 {
	return Vec4{v[0], v[1], z, w}
}
func (v Vec3) Vec4(w float64) Vec4 {
	return Vec4{v[0], v[1], v[2], w}
}
func (v Vec3) Vec2() Vec2 {
	return Vec2{v[0], v[1]}
}
func (v Vec4) Vec2() Vec2 {
	return Vec2{v[0], v[1]}
}
func (v Vec4) Vec3() Vec3 {
	return Vec3{v[0], v[1], v[2]}
}
func (v Vec2) Elem() (x, y float64) {
	return v[0], v[1]
}
func (v Vec3) Elem() (x, y, z float64) {
	return v[0], v[1], v[2]
}
func (v Vec4) Elem() (x, y, z, w float64) {
	return v[0], v[1], v[2], v[3]
}
func (v1 Vec3) Cross(v2 Vec3) Vec3 {
	return Vec3{v1[1]*v2[2] - v1[2]*v2[1], v1[2]*v2[0] - v1[0]*v2[2], v1[0]*v2[1] - v1[1]*v2[0]}
}
func (v Vec4) Quat() Quat {
	return Quat{v[3], Vec3{v[0], v[1], v[2]}}
}
func (v1 Vec2) Add(v2 Vec2) Vec2 {
	return Vec2{v1[0] + v2[0], v1[1] + v2[1]}
}
func (v1 Vec2) Sub(v2 Vec2) Vec2 {
	return Vec2{v1[0] - v2[0], v1[1] - v2[1]}
}
func (v1 Vec2) Mul(c float64) Vec2 {
	return Vec2{v1[0] * c, v1[1] * c}
}
func (v1 Vec2) Dot(v2 Vec2) float64 {
	return v1[0]*v2[0] + v1[1]*v2[1]
}
func (v1 Vec2) Len() float64 {
	return float64(math.Hypot(float64(v1[0]), float64(v1[1])))
}
func (v1 Vec2) LenSqr() float64 {
	return v1[0]*v1[0] + v1[1]*v1[1]
}
func (v1 Vec2) Normalize() Vec2 {
	l := 1.0 / v1.Len()
	return Vec2{v1[0] * l, v1[1] * l}
}
func (v1 Vec2) ApproxEqual(v2 Vec2) bool {
	for i := range v1 {
		if !FloatEqual(v1[i], v2[i]) {
			return false
		}
	}
	return true
}
func (v1 Vec2) ApproxEqualThreshold(v2 Vec2, threshold float64) bool {
	for i := range v1 {
		if !FloatEqualThreshold(v1[i], v2[i], threshold) {
			return false
		}
	}
	return true
}
func (v1 Vec2) ApproxFuncEqual(v2 Vec2, eq func(float64, float64) bool) bool {
	for i := range v1 {
		if !eq(v1[i], v2[i]) {
			return false
		}
	}
	return true
}
func (v Vec2) X() float64 {
	return v[0]
}
func (v Vec2) Y() float64 {
	return v[1]
}
func (v1 Vec2) OuterProd2(v2 Vec2) Mat2 {
	return Mat2{v1[0] * v2[0], v1[1] * v2[0], v1[0] * v2[1], v1[1] * v2[1]}
}
func (v1 Vec2) OuterProd3(v2 Vec3) Mat2x3 {
	return Mat2x3{v1[0] * v2[0], v1[1] * v2[0], v1[0] * v2[1], v1[1] * v2[1], v1[0] * v2[2], v1[1] * v2[2]}
}
func (v1 Vec2) OuterProd4(v2 Vec4) Mat2x4 {
	return Mat2x4{v1[0] * v2[0], v1[1] * v2[0], v1[0] * v2[1], v1[1] * v2[1], v1[0] * v2[2], v1[1] * v2[2], v1[0] * v2[3], v1[1] * v2[3]}
}
func (v1 Vec3) Add(v2 Vec3) Vec3 {
	return Vec3{v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]}
}
func (v1 Vec3) Sub(v2 Vec3) Vec3 {
	return Vec3{v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]}
}
func (v1 Vec3) Mul(c float64) Vec3 {
	return Vec3{v1[0] * c, v1[1] * c, v1[2] * c}
}
func (v1 Vec3) Dot(v2 Vec3) float64 {
	return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]
}
func (v1 Vec3) Len() float64 {
	return float64(math.Sqrt(float64(v1[0]*v1[0] + v1[1]*v1[1] + v1[2]*v1[2])))
}
func (v1 Vec3) LenSqr() float64 {
	return v1[0]*v1[0] + v1[1]*v1[1] + v1[2]*v1[2]
}
func (v1 Vec3) Normalize() Vec3 {
	l := 1.0 / v1.Len()
	return Vec3{v1[0] * l, v1[1] * l, v1[2] * l}
}
func (v1 Vec3) ApproxEqual(v2 Vec3) bool {
	for i := range v1 {
		if !FloatEqual(v1[i], v2[i]) {
			return false
		}
	}
	return true
}
func (v1 Vec3) ApproxEqualThreshold(v2 Vec3, threshold float64) bool {
	for i := range v1 {
		if !FloatEqualThreshold(v1[i], v2[i], threshold) {
			return false
		}
	}
	return true
}
func (v1 Vec3) ApproxFuncEqual(v2 Vec3, eq func(float64, float64) bool) bool {
	for i := range v1 {
		if !eq(v1[i], v2[i]) {
			return false
		}
	}
	return true
}
func (v Vec3) X() float64 {
	return v[0]
}
func (v Vec3) Y() float64 {
	return v[1]
}
func (v Vec3) Z() float64 {
	return v[2]
}
func (v1 Vec3) OuterProd2(v2 Vec2) Mat3x2 {
	return Mat3x2{v1[0] * v2[0], v1[1] * v2[0], v1[2] * v2[0], v1[0] * v2[1], v1[1] * v2[1], v1[2] * v2[1]}
}
func (v1 Vec3) OuterProd3(v2 Vec3) Mat3 {
	return Mat3{v1[0] * v2[0], v1[1] * v2[0], v1[2] * v2[0], v1[0] * v2[1], v1[1] * v2[1], v1[2] * v2[1], v1[0] * v2[2], v1[1] * v2[2], v1[2] * v2[2]}
}
func (v1 Vec3) OuterProd4(v2 Vec4) Mat3x4 {
	return Mat3x4{v1[0] * v2[0], v1[1] * v2[0], v1[2] * v2[0], v1[0] * v2[1], v1[1] * v2[1], v1[2] * v2[1], v1[0] * v2[2], v1[1] * v2[2], v1[2] * v2[2], v1[0] * v2[3], v1[1] * v2[3], v1[2] * v2[3]}
}
func (v1 Vec4) Add(v2 Vec4) Vec4 {
	return Vec4{v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2], v1[3] + v2[3]}
}
func (v1 Vec4) Sub(v2 Vec4) Vec4 {
	return Vec4{v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2], v1[3] - v2[3]}
}
func (v1 Vec4) Mul(c float64) Vec4 {
	return Vec4{v1[0] * c, v1[1] * c, v1[2] * c, v1[3] * c}
}
func (v1 Vec4) Dot(v2 Vec4) float64 {
	return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2] + v1[3]*v2[3]
}
func (v1 Vec4) Len() float64 {
	return float64(math.Sqrt(float64(v1[0]*v1[0] + v1[1]*v1[1] + v1[2]*v1[2] + v1[3]*v1[3])))
}
func (v1 Vec4) LenSqr() float64 {
	return v1[0]*v1[0] + v1[1]*v1[1] + v1[2]*v1[2] + v1[3]*v1[3]
}
func (v1 Vec4) Normalize() Vec4 {
	l := 1.0 / v1.Len()
	return Vec4{v1[0] * l, v1[1] * l, v1[2] * l, v1[3] * l}
}
func (v1 Vec4) ApproxEqual(v2 Vec4) bool {
	for i := range v1 {
		if !FloatEqual(v1[i], v2[i]) {
			return false
		}
	}
	return true
}
func (v1 Vec4) ApproxEqualThreshold(v2 Vec4, threshold float64) bool {
	for i := range v1 {
		if !FloatEqualThreshold(v1[i], v2[i], threshold) {
			return false
		}
	}
	return true
}
func (v1 Vec4) ApproxFuncEqual(v2 Vec4, eq func(float64, float64) bool) bool {
	for i := range v1 {
		if !eq(v1[i], v2[i]) {
			return false
		}
	}
	return true
}
func (v Vec4) X() float64 {
	return v[0]
}
func (v Vec4) Y() float64 {
	return v[1]
}