<?xml version="1.0" encoding="UTF-8" standalone="yes"?><oembed><version><![CDATA[1.0]]></version><provider_name><![CDATA[The ryg blog]]></provider_name><provider_url><![CDATA[https://fgiesen.wordpress.com]]></provider_url><author_name><![CDATA[fgiesen]]></author_name><author_url><![CDATA[https://fgiesen.wordpress.com/author/fgiesen/]]></author_url><title><![CDATA[Decoding Morton Codes]]></title><type><![CDATA[link]]></type><html><![CDATA[<p>There&#8217;s lots of material on the web about computing Morton codes (also called Morton keys or Morton numbers) efficiently &#8211; bitwise interleaving of two or more numbers. This may sound esoteric, but it&#8217;s surprisingly useful in some applications. If you haven&#8217;t heard of Morton codes yet, step by <a href="http://en.wikipedia.org/wiki/Z-order_%28curve%29">Wikipedia</a> or look into a book like <a href="http://realtimecollisiondetection.net/books/rtcd/">Real-Time Collision Detection</a> to learn more about them. Anyway, the subject of this post is not to introduce you to Morton codes, but rather to fill a rather curious gap: As I discovered a few months ago, there&#8217;s lots of material on the web and in books about how to generate morton codes from 2 or 3 numbers, but I didn&#8217;t find a single site explaining how to de-interleave the bits again to get the original numbers back from a morton code! I figured it&#8217;s time to change that.<br />
<!--more--></p>
<p>The &#8220;classic&#8221; algorithms to generate Morton codes look like this:</p>
<pre>
uint32 EncodeMorton2(uint32 x, uint32 y)
{
  return (Part1By1(y) &lt;&lt; 1) + Part1By1(x);
}

uint32 EncodeMorton3(uint32 x, uint32 y, uint32 z)
{
  return (Part1By2(z) &lt;&lt; 2) + (Part1By2(y) &lt;&lt; 1) + Part1By2(x);
}

// "Insert" a 0 bit after each of the 16 low bits of x
uint32 Part1By1(uint32 x)
{
  x &amp;= 0x0000ffff;                  // x = ---- ---- ---- ---- fedc ba98 7654 3210
  x = (x ^ (x &lt;&lt;  8)) &amp; 0x00ff00ff; // x = ---- ---- fedc ba98 ---- ---- 7654 3210
  x = (x ^ (x &lt;&lt;  4)) &amp; 0x0f0f0f0f; // x = ---- fedc ---- ba98 ---- 7654 ---- 3210
  x = (x ^ (x &lt;&lt;  2)) &amp; 0x33333333; // x = --fe --dc --ba --98 --76 --54 --32 --10
  x = (x ^ (x &lt;&lt;  1)) &amp; 0x55555555; // x = -f-e -d-c -b-a -9-8 -7-6 -5-4 -3-2 -1-0
  return x;
}

// "Insert" two 0 bits after each of the 10 low bits of x
uint32 Part1By2(uint32 x)
{
  x &amp;= 0x000003ff;                  // x = ---- ---- ---- ---- ---- --98 7654 3210
  x = (x ^ (x &lt;&lt; 16)) &amp; 0xff0000ff; // x = ---- --98 ---- ---- ---- ---- 7654 3210
  x = (x ^ (x &lt;&lt;  8)) &amp; 0x0300f00f; // x = ---- --98 ---- ---- 7654 ---- ---- 3210
  x = (x ^ (x &lt;&lt;  4)) &amp; 0x030c30c3; // x = ---- --98 ---- 76-- --54 ---- 32-- --10
  x = (x ^ (x &lt;&lt;  2)) &amp; 0x09249249; // x = ---- 9--8 --7- -6-- 5--4 --3- -2-- 1--0
  return x;
}
</pre>
<p>The meat is in the Part1By1 and Part1By2 functions, which separate the bits from each other. Reversing this function is actually very easy &#8211; it mainly boils down to executing the function in reverse, turning left shifts into right shifts and moving the masks aroundd a bit. All of this is pretty easy to work out by taking one single step and figuring out how to reverse it. So, without further ado, here&#8217;s the inverses of Part1By1 and Part1By2:</p>
<pre>
// Inverse of Part1By1 - "delete" all odd-indexed bits
uint32 Compact1By1(uint32 x)
{
  x &amp;= 0x55555555;                  // x = -f-e -d-c -b-a -9-8 -7-6 -5-4 -3-2 -1-0
  x = (x ^ (x &gt;&gt;  1)) &amp; 0x33333333; // x = --fe --dc --ba --98 --76 --54 --32 --10
  x = (x ^ (x &gt;&gt;  2)) &amp; 0x0f0f0f0f; // x = ---- fedc ---- ba98 ---- 7654 ---- 3210
  x = (x ^ (x &gt;&gt;  4)) &amp; 0x00ff00ff; // x = ---- ---- fedc ba98 ---- ---- 7654 3210
  x = (x ^ (x &gt;&gt;  8)) &amp; 0x0000ffff; // x = ---- ---- ---- ---- fedc ba98 7654 3210
  return x;
}

// Inverse of Part1By2 - "delete" all bits not at positions divisible by 3
uint32 Compact1By2(uint32 x)
{
  x &amp;= 0x09249249;                  // x = ---- 9--8 --7- -6-- 5--4 --3- -2-- 1--0
  x = (x ^ (x &gt;&gt;  2)) &amp; 0x030c30c3; // x = ---- --98 ---- 76-- --54 ---- 32-- --10
  x = (x ^ (x &gt;&gt;  4)) &amp; 0x0300f00f; // x = ---- --98 ---- ---- 7654 ---- ---- 3210
  x = (x ^ (x &gt;&gt;  8)) &amp; 0xff0000ff; // x = ---- --98 ---- ---- ---- ---- 7654 3210
  x = (x ^ (x &gt;&gt; 16)) &amp; 0x000003ff; // x = ---- ---- ---- ---- ---- --98 7654 3210
  return x;
}
</pre>
<p>Using these, getting the original x, y and z coordinates from Morton codes is then trivial:</p>
<pre>
uint32 DecodeMorton2X(uint32 code)
{
  return Compact1By1(code &gt;&gt; 0);
}

uint32 DecodeMorton2Y(uint32 code)
{
  return Compact1By1(code &gt;&gt; 1);
}

uint32 DecodeMorton3X(uint32 code)
{
  return Compact1By2(code &gt;&gt; 0);
}

uint32 DecodeMorton3Y(uint32 code)
{
  return Compact1By2(code &gt;&gt; 1);
}

uint32 DecodeMorton3Z(uint32 code)
{
  return Compact1By2(code &gt;&gt; 2);
}
</pre>
<p>There you go, hope it comes in handy.</p>
]]></html></oembed>