func EulerZXY(angleX, angleY, angleZ float32) Matrix {
	c1 := math32.Cos(angleZ)
	s1 := math32.Sin(angleZ)
	c2 := math32.Cos(angleX)
	s2 := math32.Sin(angleX)
	c3 := math32.Cos(angleY)
	s3 := math32.Sin(angleY)
	return Matrix{
		{c1*c3 - s1*s2*s3, c3*s1 + c1*s2*s3, -c2 * s3},
		{-c2 * s1, c1 * c2, s2},
		{c1*s3 + c3*s1*s2, s1*s3 - c1*c3*s2, c2 * c3},
		{0, 0, 0, 1},
	}
}
EulerZXY returns a transformation matrix corresponding to a sequence of three
intrinsic rotations around the (local) axis Z, X, Y, in that order.
package space
import (
	"github.com/cozely/cozely/coord"
	"github.com/cozely/cozely/x/math32"
)
func Identity() Matrix {
	return Matrix{
		{1, 0, 0, 0},
		{0, 1, 0, 0},
		{0, 0, 1, 0},
		{0, 0, 0, 1},
	}
}
func Apply(m Matrix, v coord.XYZW) coord.XYZW {
	return coord.XYZW{
		X: m[0][0]*v.X + m[1][0]*v.Y + m[2][0]*v.Z + m[3][0]*v.W,
		Y: m[0][1]*v.X + m[1][1]*v.Y + m[2][1]*v.Z + m[3][1]*v.W,
		Z: m[0][2]*v.X + m[1][2]*v.Y + m[2][2]*v.Z + m[3][2]*v.W,
		W: m[0][3]*v.X + m[1][3]*v.Y + m[2][3]*v.Z + m[3][3]*v.W,
	}
}
func Translation(t coord.XYZ) Matrix {
	return Matrix{
		{1, 0, 0, 0},
		{0, 1, 0, 0},
		{0, 0, 1, 0},
		{t.X, t.Y, t.Z, 1},
	}
}
func Rotation(angle float32, axis coord.XYZ) Matrix {
	c := math32.Cos(angle)
	s := math32.Sin(angle)
	x, y, z := axis.X, axis.Y, axis.Z
	return Matrix{
		{c + x*x*(1-c), -z*s + x*y*(1-c), y*s + x*z*(1-c), 0},
		{z*s + y*x*(1-c), c + y*y*(1-c), -x*s + y*z*(1-c), 0},
		{-y*s + z*x*(1-c), x*s + z*y*(1-c), c + z*z*(1-c), 0},
		{0, 0, 0, 1},
	}
}
func EulerYXZ(angleX, angleY, angleZ float32) Matrix {
	c1 := math32.Cos(angleY)
	s1 := math32.Sin(angleY)
	c2 := math32.Cos(angleX)
	s2 := math32.Sin(angleX)
	c3 := math32.Cos(angleZ)
	s3 := math32.Sin(angleZ)
	return Matrix{
		{c1*c3 + s1*s2*s3, c2 * s3, c1*s2*s3 - c3*s1},
		{c3*s1*s2 - c1*s3, c2 * c3, c1*c3*s2 + s1*s3},
		{c2 * s1, -s2, c1 * c2},
		{0, 0, 0, 1},
	}
}
func EulerXYZ(angleX, angleY, angleZ float32) Matrix {
	c1 := math32.Cos(angleX)
	s1 := math32.Sin(angleX)
	c2 := math32.Cos(angleY)
	s2 := math32.Sin(angleY)
	c3 := math32.Cos(angleZ)
	s3 := math32.Sin(angleZ)
	return Matrix{
		{c2 * c3, c1*s3 + c3*s1*s2, s1*s3 - c1*c3*s2},
		{-c2 * s3, c1*c3 - s1*s2*s3, c3*s1 + c1*s2*s3},
		{s2, -c2 * s1, c1 * c2},
		{0, 0, 0, 1},
	}
}
func EulerZYX(angleX, angleY, angleZ float32) Matrix {
	c1 := math32.Cos(angleZ)
	s1 := math32.Sin(angleZ)
	c2 := math32.Cos(angleY)
	s2 := math32.Sin(angleY)
	c3 := math32.Cos(angleX)
	s3 := math32.Sin(angleX)
	return Matrix{
		{c1 * c2, c2 * s1, -s2},
		{c1*s2*s3 - c3*s1, c1*c3 + s1*s2*s3, c2 * s3},
		{s1*s3 + c1*c3*s2, c3*s1*s2 - c1*s3, c2 * c3},
		{0, 0, 0, 1},
	}
}
func EulerXZY(angleX, angleY, angleZ float32) Matrix {
	c1 := math32.Cos(angleX)
	s1 := math32.Sin(angleX)
	c2 := math32.Cos(angleZ)
	s2 := math32.Sin(angleZ)
	c3 := math32.Cos(angleY)
	s3 := math32.Sin(angleY)
	return Matrix{
		{c2 * c3, s1*s3 + c1*c3*s2, c3*s1*s2 - c1*s3},
		{-s2, c1 * c2, c2 * s1},
		{c2 * s3, c1*s2*s3 - c3*s1, c1*c3 + s1*s2*s3},
		{0, 0, 0, 1},
	}
}
func EulerYZX(angleX, angleY, angleZ float32) Matrix {
	c1 := math32.Cos(angleY)
	s1 := math32.Sin(angleY)
	c2 := math32.Cos(angleZ)
	s2 := math32.Sin(angleZ)
	c3 := math32.Cos(angleX)
	s3 := math32.Sin(angleX)
	return Matrix{
		{c1 * c2, s2, -c2 * s1},
		{s1*s3 - c1*c3*s2, c2 * c3, c1*s3 + c3*s1*s2},
		{c3*s1 + c1*s2*s3, -c2 * s3, c1*c3 - s1*s2*s3},
		{0, 0, 0, 1},
	}
}