module Rattletrap.Primitive.Vector where import Rattletrap.Primitive.CompressedWord import qualified Data.Binary.Bits.Get as BinaryBit import qualified Data.Binary.Bits.Put as BinaryBit data Vector = Vector { vectorBias :: Word , vectorX :: Int , vectorY :: Int , vectorZ :: Int } deriving (Eq, Ord, Show) getVector :: BinaryBit.BitGet Vector getVector = do bitSize <- getCompressedWord 19 let limit = 2 ^ (compressedWordValue bitSize + 2) dx <- getCompressedWord limit dy <- getCompressedWord limit dz <- getCompressedWord limit let fromCompressedWord x = fromIntegral (compressedWordValue x) let bias = 2 ^ (fromCompressedWord bitSize + 1 :: Word) let x = fromCompressedWord dx - fromIntegral bias let y = fromCompressedWord dy - fromIntegral bias let z = fromCompressedWord dz - fromIntegral bias pure (Vector bias x y z) putVector :: Vector -> BinaryBit.BitPut () putVector vector = do let bitSize = round (logBase (2 :: Float) (fromIntegral (vectorBias vector))) - 1 putCompressedWord (CompressedWord 19 bitSize) let dx = fromIntegral (vectorX vector + fromIntegral (vectorBias vector)) let dy = fromIntegral (vectorY vector + fromIntegral (vectorBias vector)) let dz = fromIntegral (vectorZ vector + fromIntegral (vectorBias vector)) let limit = 2 ^ (bitSize + 2) putCompressedWord (CompressedWord limit dx) putCompressedWord (CompressedWord limit dy) putCompressedWord (CompressedWord limit dz)