using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace UltraTerrain.Common.Morton
{
public static class MortonHelper
{
public static uint GetLeftMostBit(uint value)
{
uint pos = 0;
while (value > 0)
{
value >>= 1;
pos++;
}
return pos;
}
public static uint Part1By2(uint n)
{
n &= 0x000003ff;
n = (n ^ (n << 16)) & 0xff0000ff;
n = (n ^ (n << 8)) & 0x0300f00f;
n = (n ^ (n << 4)) & 0x030c30c3;
n = (n ^ (n << 2)) & 0x09249249;
return n;
}
public static uint Unpart1By2(uint n)
{
n &= 0x09249249;
n = (n ^ (n >> 2)) & 0x030c30c3;
n = (n ^ (n >> 4)) & 0x0300f00f;
n = (n ^ (n >> 8)) & 0xff0000ff;
n = (n ^ (n >> 16)) & 0x000003ff;
return n;
}
public static uint ToMorton(uint x, uint y, uint z)
{
return MortonHelper.Part1By2(x) | (MortonHelper.Part1By2(y) << 1) | (MortonHelper.Part1By2(z) << 2);
}
public static uint FromBinary(this string binary)
{
binary = binary.Replace(".", "").PadLeft(32, '0');
uint value = 0;
for (int i = 31; i >= 0; --i)
{
if (binary[i] == '1')
{
value |= 1u << (31 - i);
}
}
return value;
}
public static uint ToMorton(this Integer3 that)
{
return MortonHelper.Part1By2((uint)that.X) | (MortonHelper.Part1By2((uint)that.Y) << 1) | (MortonHelper.Part1By2((uint)that.Z) << 2);
}
public static Integer3 ToInteger3(this uint morton)
{
return new Integer3((int)MortonHelper.Unpart1By2(morton), (int)MortonHelper.Unpart1By2(morton >> 1), (int)MortonHelper.Unpart1By2(morton >> 2));
}
public static Vector3 ToVector3(this uint morton)
{
return new Vector3((float)MortonHelper.Unpart1By2(morton), (float)MortonHelper.Unpart1By2(morton >> 1), (float)MortonHelper.Unpart1By2(morton >> 2));
}
}
}