You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

339 lines
8.6 KiB
C#

/******************************************************************************/
/*
Project - MudBun
Publisher - Long Bunny Labs
http://LongBunnyLabs.com
Author - Ming-Lun "Allen" Chou
http://AllenChou.net
*/
/******************************************************************************/
using System.Runtime.InteropServices;
using UnityEngine;
namespace MudBun
{
public class Codec
{
// Vector2 between 0.0 and 1.0
// https://stackoverflow.com/questions/17638800/storing-two-float-values-in-a-single-float-variable
//-----------------------------------------------------------------------------
public static float PackSaturated(float a, float b)
{
const int precision = 4096;
a = Mathf.Floor(a * (precision - 1));
b = Mathf.Floor(b * (precision - 1));
return a * precision + b;
}
public static float PackSaturated(Vector2 v)
{
return PackSaturated(v.x, v.y);
}
public static Vector2 UnpackSaturated(float f)
{
const int precision = 4096;
return new Vector2(Mathf.Floor(f / precision), Mathf.Repeat(f, precision)) / (precision - 1);
}
//-----------------------------------------------------------------------------
// end: Vector2 between 0.0 and 1.0
// normals
// https://knarkowicz.wordpress.com/2014/04/16/octahedron-normal-vector-encoding/
//-----------------------------------------------------------------------------
public static Vector2 OctWrap(Vector2 v)
{
return
(Vector2.one - new Vector2(Mathf.Abs(v.y), Mathf.Abs(v.x)))
* new Vector2(Mathf.Sign(v.x), Mathf.Sign(v.y));
}
public static float PackNormal(Vector3 n)
{
n /= (Mathf.Abs(n.x) + Mathf.Abs(n.y) + Mathf.Abs(n.z));
Vector2 n2 = n.z >= 0.0f ? new Vector2(n.x, n.y) : OctWrap(new Vector2(n.x, n.y));
n2 = n2 * 0.5f + 0.5f * Vector2.one;
return PackSaturated(n2);
}
public static Vector3 UnpackNormal(float f)
{
Vector2 v = UnpackSaturated(f);
v = v * 2.0f - Vector2.one;
Vector3 n = new Vector3(v.x, v.y, 1.0f - Mathf.Abs(v.x) - Mathf.Abs(v.y));
float t = Mathf.Clamp01(-n.z);
n.x += n.x >= 0.0f ? -t : t;
n.y += n.y >= 0.0f ? -t : t;
return n.normalized;
}
//-----------------------------------------------------------------------------
// end: normals
// colors
//-----------------------------------------------------------------------------
public static uint PackRgb(Color color)
{
return
(((uint) (color.b * 255)) << 16)
| (((uint) (color.g * 255)) << 8)
| (((uint) (color.r * 255)) << 0);
}
public static Color UnpackRgb(uint i)
{
return
new Color
(
((i & 0x000000FF) >> 0) / 255.0f,
((i & 0x0000FF00) >> 8) / 255.0f,
((i & 0x00FF0000) >> 16) / 255.0f
);
}
public static uint PackRgba(Color color)
{
return
(((uint) (color.a * 255)) << 24)
| (((uint) (color.b * 255)) << 16)
| (((uint) (color.g * 255)) << 8)
| (((uint) (color.r * 255)) << 0);
}
public static Color UnpackRgba(uint i)
{
return
new Color
(
((i & 0x000000FF) >> 0) / 255.0f,
((i & 0x0000FF00) >> 8) / 255.0f,
((i & 0x00FF0000) >> 16) / 255.0f,
((i & 0xFF000000) >> 24) / 255.0f
);
}
//-----------------------------------------------------------------------------
// end: colors
// bits
//-----------------------------------------------------------------------------
public static uint Pack8888(uint x, uint y, uint z, uint w)
{
return
((x & 0xFF) << 24)
| ((y & 0xFF) << 16)
| ((z & 0xFF) << 8)
| ((w & 0xFF) << 0);
}
public static void Unpack8888(uint i, out uint x, out uint y, out uint z, out uint w)
{
x = (i >> 24) & 0xFF;
y = (i >> 16) & 0xFF;
z = (i >> 8) & 0xFF;
w = (i >> 0) & 0xFF;
}
//-----------------------------------------------------------------------------
// end: bits
// hash
//-----------------------------------------------------------------------------
public static readonly int FnvDefaultBasis = unchecked((int) 2166136261);
public static readonly int FnvPrime = 16777619;
[StructLayout(LayoutKind.Explicit)]
private struct IntFloat
{
[FieldOffset(0)]
public int IntValue;
[FieldOffset(0)]
public float FloatValue;
}
private static int IntReinterpret(float f)
{
return (new IntFloat { FloatValue = f }).IntValue;
}
public static int HashConcat(int hash, int i)
{
return (hash ^ i) * FnvPrime;
}
public static int HashConcat(int hash, long i)
{
hash = HashConcat(hash, (int) (i & 0xFFFFFFFF));
hash = HashConcat(hash, (int) (i >> 32));
return hash;
}
public static int HashConcat(int hash, float f)
{
return HashConcat(hash, IntReinterpret(f));
}
public static int HashConcat(int hash, bool b)
{
return HashConcat(hash, b ? 1 : 0);
}
public static int HashConcat(int hash, params int [] ints)
{
foreach (int i in ints)
hash = HashConcat(hash, i);
return hash;
}
public static int HashConcat(int hash, params float [] floats)
{
foreach (float f in floats)
hash = HashConcat(hash, f);
return hash;
}
public static int HashConcat(int hash, Vector2 v)
{
return HashConcat(hash, v.x, v.y);
}
public static int HashConcat(int hash, Vector3 v)
{
return HashConcat(hash, v.x, v.y, v.z);
}
public static int HashConcat(int hash, Vector4 v)
{
return HashConcat(hash, v.x, v.y, v.z, v.w);
}
public static int HashConcat(int hash, Quaternion q)
{
return HashConcat(hash, q.x, q.y, q.z, q.w);
}
public static int HashConcat(int hash, Color c)
{
return HashConcat(hash, c.r, c.g, c.b, c.a);
}
public static int HashConcat(int hash, in MudMaterialBase m)
{
hash = HashConcat(hash, m.Color);
hash = HashConcat(hash, m.Emission);
hash = HashConcat(hash, m.Metallic);
hash = HashConcat(hash, m.Smoothness);
hash = HashConcat(hash, m.TextureIndex);
hash = HashConcat(hash, m.SplatSize);
hash = HashConcat(hash, m.BlendTightness);
return hash;
}
public static int HashConcat(int hash, in MudSharedMaterialBase m)
{
hash = HashConcat(hash, m.Color);
hash = HashConcat(hash, m.Emission);
hash = HashConcat(hash, m.Metallic);
hash = HashConcat(hash, m.Smoothness);
hash = HashConcat(hash, m.TextureIndex);
hash = HashConcat(hash, m.SplatSize);
hash = HashConcat(hash, m.BlendTightness);
return hash;
}
public static int HashConcat(int hash, in SdfBrushMaterial m)
{
hash = HashConcat(hash, m.Color);
hash = HashConcat(hash, m.EmissionHash);
hash = HashConcat(hash, m.MetallicSmoothnessSizeTightness);
hash = HashConcat(hash, m.TextureWeight);
return hash;
}
public static int Hash(int i)
{
return HashConcat(FnvDefaultBasis, i);
}
public static int Hash(long i)
{
return HashConcat(FnvDefaultBasis, i);
}
public static int Hash(float f)
{
return HashConcat(FnvDefaultBasis, f);
}
public static int Hash(bool b)
{
return HashConcat(FnvDefaultBasis, b);
}
public static int Hash(params int[] ints)
{
return HashConcat(FnvDefaultBasis, ints);
}
public static int Hash(params float[] floats)
{
return HashConcat(FnvDefaultBasis, floats);
}
public static int Hash(Vector2 v)
{
return HashConcat(FnvDefaultBasis, v);
}
public static int Hash(Vector3 v)
{
return HashConcat(FnvDefaultBasis, v);
}
public static int Hash(Vector4 v)
{
return HashConcat(FnvDefaultBasis, v);
}
public static int Hash(Quaternion q)
{
return HashConcat(FnvDefaultBasis, q);
}
public static int Hash(Color c)
{
return HashConcat(FnvDefaultBasis, c);
}
public static int Hash(in MudMaterialBase m)
{
return HashConcat(FnvDefaultBasis, m);
}
public static int Hash(in MudSharedMaterialBase m)
{
return HashConcat(FnvDefaultBasis, m);
}
public static int HashConcat(in SdfBrushMaterial m)
{
return HashConcat(FnvDefaultBasis, m);
}
//-----------------------------------------------------------------------------
// end: hash
}
}