import math import struct MAX_5_BYTE_QUATERNION = 1 / (2 ** 0.5) SCALE_8_BYTE_QUATERNION_COMPRESS = 10000 SCALE_8_BYTE_QUATERNION_DECOMPRESS = 1.0 / SCALE_8_BYTE_QUATERNION_COMPRESS SCALE_6_BYTE_VECTOR3_COMPRESS = 32000 SCALE_6_BYTE_VECTOR3_DECOMPRESS = 1.0 / SCALE_6_BYTE_VECTOR3_COMPRESS def findBiggest(quat): biggest_i = -1 biggest_v = 0 for i, v in enumerate(quat): if abs(v) > biggest_v: biggest_v = abs(v) biggest_i = i if quat[biggest_i] < 0: return (biggest_i, (-quat[0], -quat[1], -quat[2], -quat[3])) else: return (biggest_i, ( quat[0], quat[1], quat[2], quat[3])) def compressQuaternion_5Byte(quat): #Find biggset value and negate the quaternion to make it positive. missing, q = findBiggest(quat) d = [] for i in range(4): if i == missing: continue v = int(math.floor(0.5 + q[i] / MAX_5_BYTE_QUATERNION * 2048)) if v < -2048: v = -2048 elif v > 2047: v = 2047 d.append(v + 2048) v = ( (missing << 36) | (d[0] << 24) | (d[1] << 12) | d[2] ) s = struct.pack("> 36) & 0x3 d = [ (v >> 24) & 0xfff, (v >> 12) & 0xfff, v & 0xfff, ] #Rescale values and summing the squares into x. x = 0 #print("%s" % (d, )) for i in range(3): d[i] = (d[i] - 2048) * MAX_5_BYTE_QUATERNION / 2048.0 x += d[i] ** 2.0 #print("%s -> %s" % (d, x)) #Use pythagoras to compute the missing field into x. x = (1 - x) ** 0.5 #Rebuild the quaternion. d_i = 0; q = [] for i in range(4): if i == missing: q.append(x) else: q.append(d[d_i]) d_i += 1 return q def compressQuaternion_8Byte(quat): return struct.pack("