Skip to content

Instantly share code, notes, and snippets.

@Kas-tle
Last active February 13, 2022 07:39
Show Gist options
  • Save Kas-tle/8c77a154c4ab92e1746a30a02498227b to your computer and use it in GitHub Desktop.
Save Kas-tle/8c77a154c4ab92e1746a30a02498227b to your computer and use it in GitHub Desktop.
#XYZ -> ZYX
# Make pi available as constant
def pi: 1 | atan *4;
# Convert degrees to radians
def deg2rad($deg): $deg*(pi/180);
# Convert radians to degrees
def rad2deg($rad): $rad*(180/pi);
# Implement clamp via min since JQ lacks it
def clamp($inp; $min; $max): fmin(fmax($inp; $min); $max);
# Convert XYZ parented Euler angles to quaternions
# Adapted from https://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/steps/index.htm
def XYZeuler2quaternion($rot):
((deg2rad($rot[0])/2) | cos) as $c1
| ((deg2rad($rot[1])/2) | cos) as $c2
| ((deg2rad($rot[2])/2) | cos) as $c3
| ((deg2rad($rot[0])/2) | sin) as $s1
| ((deg2rad($rot[1])/2) | sin) as $s2
| ((deg2rad($rot[2])/2) | sin) as $s3
| ($s1 * $c2 * $c3 + $c1 * $s2 * $s3) as $qx
| ($c1 * $s2 * $c3 - $s1 * $c2 * $s3) as $qy
| ($c1 * $c2 * $s3 + $s1 * $s2 * $c3) as $qz
| ($c1 * $c2 * $c3 - $s1 * $s2 * $s3) as $qw
| [$qx, $qy, $qz, $qw]
;
# Define an XYZ rotation matrix
# Adapted from http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.htm
def rotationMatrix($q):
$q[0] as $qx
| $q[1] as $qy
| $q[2] as $qz
| $q[3] as $qw
| [
[(1 - 2 * ($qy * $qy + $qz * $qz)), (2 * ( $qx * $qy - $qz * $qw)), (2 * ($qx * $qz + $qy * $qw)) ],
[(2 * ($qx * $qy + $qz * $qw)), (1 - 2 * ($qx * $qx + $qz * $qz)), (2* ($qy * $qz - $qx * $qw)) ],
[(2 * ( $qx * $qz - $qy * $qw)), (2 * ($qy * $qz + $qx * $qw)), (1 - 2 * ($qx * $qx + $qy * $qy))]
]
;
# Convert quaternions to ZYX parented Euler angles
# Adapted from https://github.com/mrdoob/three.js/blob/8ff5d832eedfd7bc698301febb60920173770899/src/math/Euler.js#L169
def quaternion2ZYXeuler($q):
(rotationMatrix($q) | .[2][0]) as $r20
| (rotationMatrix($q) | .[2][1]) as $r21
| (rotationMatrix($q) | .[2][2]) as $r22
| (rotationMatrix($q) | .[0][0]) as $r00
| (rotationMatrix($q) | .[1][0]) as $r10
| (rotationMatrix($q) | .[0][1]) as $r01
| (rotationMatrix($q) | .[1][1]) as $r11
| (-1 * clamp($r20; -1; 1) | asin) as $y
| (if ($r20 | fabs) < 0.9999999 then atan2($r21; $r22) else 0 end) as $x
| (if ($r20 | fabs) < 0.9999999 then atan2($r10; $r00) else atan2(-1 * $r01; $r11) end) as $z
| [rad2deg($x), rad2deg($y), rad2deg($z)]
;
def eulerXYZ2ZYX($rot): quaternion2ZYXeuler(XYZeuler2quaternion($rot));
# Find required offset to move our pivot from [8, 8, 8] to [16, 16, 8]
# Adapted from https://www.euclideanspace.com/maths/geometry/affine/conversions/eulerToMatrix/index.htm
def linearTranslation($q):
$q[0] as $qx
| $q[1] as $qy
| $q[2] as $qz
| $q[3] as $qw
| ($qx * $qx) as $sqx
| ($qy * $qy) as $sqy
| ($qz * $qz) as $sqz
| ($qw * $qw) as $sqw
| ($qx * $qy) as $tmp1
| ($qz * $qw) as $tmp2
| ($qx * $qz) as $tmp3
| ($qy * $qw) as $tmp4
| ($qy * $qz) as $tmp5
| ($qx * $qw) as $tmp6
| ($sqx - $sqy - $sqz + $sqw) as $m00
| (- $sqx + $sqy - $sqz + $sqw) as $m11
| (- $sqx - $sqy + $sqz + $sqw) as $m22
| (2 * ($tmp1 + $tmp2)) as $m01
| (2 * ($tmp1 - $tmp2)) as $m10
| (2 * ($tmp3 - $tmp4)) as $m02
| (2 * ($tmp3 + $tmp4)) as $m20
| (2 * ($tmp5 + $tmp6)) as $m12
| (2 * ($tmp5 - $tmp6)) as $m21
| 8 as $tx
| 8 as $ty
| 0 as $tz
| ($tx - $tx * $m00 - $ty * $m01 - $tz * $m02) as $x
| ($ty - $tx * $m10 - $ty * $m11 - $tz * $m12) as $y
| ($tz - $tx * $m20 - $ty * $m21 - $tz * $m22) as $z
| [$x, $y, $z]
;
# Test functions
{
"XYZ_angle": .euler,
"quaternions": XYZeuler2quaternion(.euler),
"ZYX_angle": eulerXYZ2ZYX(.euler),
"rotation_matrix": rotationMatrix(XYZeuler2quaternion(.euler)),
"linear_translation": linearTranslation(XYZeuler2quaternion(.euler))
}
# The next required task is to find the proper render offsets to produce an equivalent to the appearance non-scaled, non-rotated, non-translated display set item
# These will be the hard-coded values
# From there, we will swap rotation orders from java to bedrock, apply the pivot change, then apply the hardcodes we previously found
# We must also see if position is scaled with image size (Preliminarily, I think not)
# Input (Add me!)
# {"euler": [45, 45, 45]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment