{"action":"created","issue":{"url":"https://api.github.com/repos/ethz-asl/kindr/issues/59","labels_url":"https://api.github.com/repos/ethz-asl/kindr/issues/59/labels{/name}","comments_url":"https://api.github.com/repos/ethz-asl/kindr/issues/59/comments","events_url":"https://api.github.com/repos/ethz-asl/kindr/issues/59/events","html_url":"https://github.com/ethz-asl/kindr/issues/59","id":58105683,"number":59,"title":"uint8 quaternion implementation","user":{"login":"simonlynen","id":966785,"avatar_url":"https://avatars.githubusercontent.com/u/966785?v=3","gravatar_id":"","url":"https://api.github.com/users/simonlynen","html_url":"https://github.com/simonlynen","followers_url":"https://api.github.com/users/simonlynen/followers","following_url":"https://api.github.com/users/simonlynen/following{/other_user}","gists_url":"https://api.github.com/users/simonlynen/gists{/gist_id}","starred_url":"https://api.github.com/users/simonlynen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/simonlynen/subscriptions","organizations_url":"https://api.github.com/users/simonlynen/orgs","repos_url":"https://api.github.com/users/simonlynen/repos","events_url":"https://api.github.com/users/simonlynen/events{/privacy}","received_events_url":"https://api.github.com/users/simonlynen/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2015-02-18T18:14:44Z","updated_at":"2015-02-25T22:33:34Z","closed_at":null,"body":"We would like to store data more compact and thus are interested in an quaternion with 4 bytes only."},"comment":{"url":"https://api.github.com/repos/ethz-asl/kindr/issues/comments/76075768","html_url":"https://github.com/ethz-asl/kindr/issues/59#issuecomment-76075768","issue_url":"https://api.github.com/repos/ethz-asl/kindr/issues/59","id":76075768,"user":{"login":"mikebosse","id":6094200,"avatar_url":"https://avatars.githubusercontent.com/u/6094200?v=3","gravatar_id":"","url":"https://api.github.com/users/mikebosse","html_url":"https://github.com/mikebosse","followers_url":"https://api.github.com/users/mikebosse/followers","following_url":"https://api.github.com/users/mikebosse/following{/other_user}","gists_url":"https://api.github.com/users/mikebosse/gists{/gist_id}","starred_url":"https://api.github.com/users/mikebosse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mikebosse/subscriptions","organizations_url":"https://api.github.com/users/mikebosse/orgs","repos_url":"https://api.github.com/users/mikebosse/repos","events_url":"https://api.github.com/users/mikebosse/events{/privacy}","received_events_url":"https://api.github.com/users/mikebosse/received_events","type":"User","site_admin":false},"created_at":"2015-02-25T22:33:34Z","updated_at":"2015-02-25T22:33:34Z","body":"Here is some quick code that I just wrote (completely untested of course)\r\n\r\nSo it will need verification that I packed and unpacked the bits correctly with their sign bits.\r\n\r\n```\r\nuint32 compressQuat(double w, double x, double y, double z)\r\n{\r\n  int max_index = 0;\r\n  double max_val = fabs(w);\r\n  if (fabs(x) > max_val) { max_val = fabs(x); max_index = 1;}\r\n  if (fabs(y) > max_val) { max_val = fabs(y); max_index = 2;}\r\n  if (fabs(z) > max_val) { max_val = fabs(z); max_index = 3;}\r\n\r\n  int sign_max; \r\n  int a,b,c;\r\n  const int kSF = 722; // floor(sqrt(2)*511), the largest scale factor such that 2nd largest component fits in 9 bits\r\n\r\n  switch(max_index) {\r\n   case 0:\r\n    sign_max = w > 0 ? kSF : -kSF;\r\n    a = sign_max * x; b = sign_max * y; c = sign_max * z;\r\n    break;\r\n   case 1:\r\n    sign_max = x > 0 ? kSF : -kSF;\r\n    a = sign_max * w; b = sign_max * y; c = sign_max * z;\r\n    break;\r\n   case 2:\r\n    sign_max = y > 0 ? kSF : -kSF;\r\n    a = sign_max * x; b = sign_max * w; c = sign_max * z;\r\n    break;\r\n   case 3:\r\n    sign_max = z > 0 ? kSF : -kSF;\r\n    a = sign_max * x; b = sign_max * y; c = sign_max * w;\r\n    break;\r\n  }\r\n\r\n  const int k10bitmask = 0x3FF;\r\n\r\n  uint32 compressed_quat = (max_index << 30) | ((a & k10bitmask) << 20) | ((b & k10bitmask) << 10) | (c & k10bitmask);\r\n  return compressed_quat;\r\n}\r\n\r\nuncompressQuaterion(uint32 cq, double *wOut, double *xOut, double *yOut, double *zOut)\r\n{\r\n  const int k10bitmask = 0x3FF;\r\n  const double kSF = 1.0/722;\r\n  int max_ind = cq >> 30;\r\n  int a = (cq >> 20) & k10bitmask;\r\n  int b = (cq >> 10) & k10bitmask;\r\n  int c = cq & k10bitmask;\r\n \r\n  // turn back into a 10bit signed value\r\n  if (a >= 512) { a -= 1024; }\r\n  if (b >= 512) { b -= 1024; }\r\n  if (c >= 512) { c -= 1024; }\r\n\r\n  double w,x,y,z;\r\n  switch (max_ind) {\r\n   case 0:\r\n    x = a*kSF; y = b*kSF; z = c*kSF;\r\n    w = sqrt(1.0 - x * x - y * y - z * z);\r\n    break;\r\n   case 1:\r\n    w = a*kSF; y = b*kSF; z = c*kSF;\r\n    x = sqrt(1.0 - w * w - y * y - z * z);\r\n    break;\r\n   case 2:\r\n    x = a*kSF; w = b*kSF; z = c*kSF;\r\n    y = sqrt(1.0 - x * x - w * w - z * z);\r\n    break;\r\n   case 3:\r\n    x = a*kSF; y = b*kSF; w = c*kSF;\r\n    z = sqrt(1.0 - x * x - y * y - w * w);\r\n    break;\r\n  }\r\n\r\n  *wOut = w;\r\n  *xOut = x;\r\n  *yOut = y;\r\n  *zOut = z;\r\n}\r\n\r\n```"}}