Compressing Quaternions

Godot Version

4.3.1

Question

Hi everyone,

I have some code I’m using to compress some quaternions and send them over the network in packets. My issue is that when I uncompress them, I don’t get the correct value for W.

Here is my code:

func compress_quaternion(quat : Quaternion):
	quat = quat.normalized()
	var x : int = int(round((quat.x * 100)))
	var y : int = int(round((quat.y * 100)))
	var z : int = int(round((quat.z * 100)))
	return Vector3i(x, y, z)

func uncompress_quaternion(x_enc, y_enc, z_enc):
	var x : float = x_enc / 100.0
	var y : float = y_enc / 100.0
	var z : float = z_enc / 100.0
	var w : float = sqrt(1.0 - (x * x + y * y + z * z))
	return Quaternion(x,y,z,w)

For instance, when I have the quaternion (W = 0.738, x = 0.334, y = 0.334, z = -0.482), and I use uncompress_quaternion to get W back after compressing it, I get 1.00628 instead if 0.738.

Does anyone have any advice on why this won’t work correctly?

Thanks

Turns out I had the wrong equation, instead of adding you need to subtract the components in the square root. You also gotta inverse the whole quaternion if w is negative or else you’ll get weird snapping if you want to interpolate the quaternion from another.

Here’s the fixed functions:

func compress_quaternion(quat : Quaternion):
	quat = quat.normalized()
	var x : int = int(round((quat.x * 100)))
	var y : int = int(round((quat.y * 100)))
	var z : int = int(round((quat.z * 100)))
	if quat.w < 0:
		x = x * -1
		y = y * -1
		z = z * -1
	return Vector3i(x, y, z)

func uncompress_quaternion(x_enc, y_enc, z_enc)
	var x : float = x_enc / 100.0
	var y : float = y_enc / 100.0
	var z : float = z_enc / 100.0
	var w : float = sqrt(1.0 - (x * x) - (y * y) - (z * z))
	return Quaternion(x,y,z,w).normalized()

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.