83 lines
40 KiB
C#
83 lines
40 KiB
C#
![]() |
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.IO;
namespace Obi
{
public static class Constants
{
public const int maxVertsPerMesh = 65000;
public const int maxInstancesPerBatch = 1023;
}
public static class ObiUtils
{
public const float epsilon = 0.0000001f;
public const float sqrt3 = 1.73205080f;
public const float sqrt2 = 1.41421356f;
public const int FilterMaskBitmask = unchecked((int)0xffff0000);
public const int FilterCategoryBitmask = 0x0000ffff;
public const int ParticleGroupBitmask = 0x00ffffff;
public const int CollideWithEverything = 0x0000ffff;
public const int CollideWithNothing= 0x0;
public const int MaxCategory = 15;
public const int MinCategory = 0;
[Flags]
public enum ParticleFlags
{
SelfCollide = 1 << 24,
Fluid = 1 << 25,
OneSided = 1 << 26
}
// Colour alphabet from https://www.aic-color.org/resources/Documents/jaic_v5_06.pdf
public static readonly Color32[] colorAlphabet =
{
new Color32(240,163,255,255),
new Color32(0,117,220,255),
new Color32(153,63,0,255),
new Color32(76,0,92,255),
new Color32(25,25,25,255),
new Color32(0,92,49,255),
new Color32(43,206,72,255),
new Color32(255,204,153,255),
new Color32(128,128,128,255),
new Color32(148,255,181,255),
new Color32(143,124,0,255),
new Color32(157,204,0,255),
new Color32(194,0,136,255),
new Color32(0,51,128,255),
new Color32(255,164,5,255),
new Color32(255,168,187,255),
new Color32(66,102,0,255),
new Color32(255,0,16,255),
new Color32(94,241,242,255),
new Color32(0,153,143,255),
new Color32(224,255,102,255),
new Color32(116,10,255,255),
new Color32(153,0,0,255),
new Color32(255,255,128,255),
new Color32(255,255,0,255),
new Color32(255,80,5,255)
};
public static readonly string[] categoryNames =
{
"0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"
};
public static void DrawArrowGizmo(float bodyLenght, float bodyWidth, float headLenght, float headWidth)
{
float halfBodyLenght = bodyLenght * 0.5f;
float halfBodyWidth = bodyWidth * 0.5f;
// arrow body:
Gizmos.DrawLine(new Vector3(halfBodyWidth, 0, -halfBodyLenght), new Vector3(halfBodyWidth, 0, halfBodyLenght));
Gizmos.DrawLine(new Vector3(-halfBodyWidth, 0, -halfBodyLenght), new Vector3(-halfBodyWidth, 0, halfBodyLenght));
Gizmos.DrawLine(new Vector3(-halfBodyWidth, 0, -halfBodyLenght), new Vector3(halfBodyWidth, 0, -halfBodyLenght));
// arrow head:
Gizmos.DrawLine(new Vector3(halfBodyWidth, 0, halfBodyLenght), new Vector3(headWidth, 0, halfBodyLenght));
Gizmos.DrawLine(new Vector3(-halfBodyWidth, 0, halfBodyLenght), new Vector3(-headWidth, 0, halfBodyLenght));
Gizmos.DrawLine(new Vector3(0, 0, halfBodyLenght + headLenght), new Vector3(headWidth, 0, halfBodyLenght));
Gizmos.DrawLine(new Vector3(0, 0, halfBodyLenght + headLenght), new Vector3(-headWidth, 0, halfBodyLenght));
}
|
||
|
|
||
|
public static void DebugDrawBox(Vector3 pos, Quaternion rot, Vector3 scale, Color c)
|
||
|
{
|
||
|
// create matrix
|
||
|
Matrix4x4 m = new Matrix4x4();
|
||
|
m.SetTRS(pos, rot, scale);
|
||
|
|
||
|
var point1 = m.MultiplyPoint(new Vector3(-0.5f, -0.5f, 0.5f));
|
||
|
var point2 = m.MultiplyPoint(new Vector3(0.5f, -0.5f, 0.5f));
|
||
|
var point3 = m.MultiplyPoint(new Vector3(0.5f, -0.5f, -0.5f));
|
||
|
var point4 = m.MultiplyPoint(new Vector3(-0.5f, -0.5f, -0.5f));
|
||
|
|
||
|
var point5 = m.MultiplyPoint(new Vector3(-0.5f, 0.5f, 0.5f));
|
||
|
var point6 = m.MultiplyPoint(new Vector3(0.5f, 0.5f, 0.5f));
|
||
|
var point7 = m.MultiplyPoint(new Vector3(0.5f, 0.5f, -0.5f));
|
||
|
var point8 = m.MultiplyPoint(new Vector3(-0.5f, 0.5f, -0.5f));
|
||
|
|
||
|
Debug.DrawLine(point1, point2, c);
|
||
|
Debug.DrawLine(point2, point3, c);
|
||
|
Debug.DrawLine(point3, point4, c);
|
||
|
Debug.DrawLine(point4, point1, c);
|
||
|
|
||
|
Debug.DrawLine(point5, point6, c);
|
||
|
Debug.DrawLine(point6, point7, c);
|
||
|
Debug.DrawLine(point7, point8, c);
|
||
|
Debug.DrawLine(point8, point5, c);
|
||
|
|
||
|
Debug.DrawLine(point1, point5, c);
|
||
|
Debug.DrawLine(point2, point6, c);
|
||
|
Debug.DrawLine(point3, point7, c);
|
||
|
Debug.DrawLine(point4, point8, c);
|
||
|
}
|
||
|
public static void DebugDrawCross(Vector3 pos, float size, Color color)
{
Debug.DrawLine(pos - Vector3.right * size, pos + Vector3.right * size, color);
Debug.DrawLine(pos - Vector3.up * size, pos + Vector3.up * size, color);
Debug.DrawLine(pos - Vector3.forward * size, pos + Vector3.forward * size, color);
}
public static int CeilToPowerOfTwo(this int count)
{
int powerOfTwo = 1;
while (powerOfTwo < count)
powerOfTwo <<= 1;
return powerOfTwo;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Swap<T>(ref T lhs, ref T rhs)
{
T temp = lhs;
lhs = rhs;
rhs = temp;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Swap<T>(this T[] source, int index1, int index2)
{
if (source != null && index1 >= 0 && index2 >= 0 && index1 < source.Length && index2 < source.Length)
{
T temp = source[index1];
source[index1] = source[index2];
source[index2] = temp;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Swap<T>(this IList<T> list, int index1, int index2)
{
if (list != null && index1 >= 0 && index2 >= 0 && index1 < list.Count && index2 < list.Count)
{
T temp = list[index1];
list[index1] = list[index2];
list[index2] = temp;
}
}
public static void ShiftLeft<T>(this T[] source, int index, int count, int positions)
{
for (int j = 0; j < positions; ++j)
{
for (int i = index; i < index + count; ++i)
source.Swap(i, i - 1);
index--;
}
}
public static void ShiftRight<T>(this T[] source, int index, int count, int positions)
{
for (int j = 0; j < positions; ++j)
{
for (int i = index + count - 1; i >= index; --i)
source.Swap(i, i + 1);
index++;
}
}
public static int Unique<T>(this IList<T> list, Func<T,T,bool> equals)
{
int result = 0;
for (int i = 0; i < list.Count; ++i)
{
if (!equals(list[result],list[i]) && ++result != i)
list[result] = list[i];
}
result++;
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool AreValid(this Bounds bounds)
{
return !(float.IsNaN(bounds.max.x) || float.IsInfinity(bounds.max.x) ||
float.IsNaN(bounds.max.y) || float.IsInfinity(bounds.max.y) ||
float.IsNaN(bounds.max.z) || float.IsInfinity(bounds.max.z) ||
float.IsNaN(bounds.min.x) || float.IsInfinity(bounds.min.x) ||
float.IsNaN(bounds.min.y) || float.IsInfinity(bounds.min.y) ||
float.IsNaN(bounds.min.z) || float.IsInfinity(bounds.min.z));
}
public static Bounds Transform(this Bounds b, Matrix4x4 m)
{
var xa = m.GetColumn(0) * b.min.x;
var xb = m.GetColumn(0) * b.max.x;
var ya = m.GetColumn(1) * b.min.y;
var yb = m.GetColumn(1) * b.max.y;
var za = m.GetColumn(2) * b.min.z;
var zb = m.GetColumn(2) * b.max.z;
Bounds result = new Bounds();
Vector3 pos = m.GetColumn(3);
result.SetMinMax(Vector3.Min(xa, xb) + Vector3.Min(ya, yb) + Vector3.Min(za, zb) + pos,
Vector3.Max(xa, xb) + Vector3.Max(ya, yb) + Vector3.Max(za, zb) + pos);
return result;
}
public static int CountTrailingZeroes(int x)
{
int mask = 1;
for (int i = 0; i
|
||
|
return MergeBatches(batches, batches.Count, true);
}
public static void Concatenate(this MemoryStream ms, Vector3 v)
{
for (int i = 0; i < 3; ++i)
{
var b = BitConverter.GetBytes(v[i]);
ms.Write(b, 0, b.Length);
}
}
public static void Concatenate(this MemoryStream ms, Quaternion q)
{
for (int i = 0; i < 4; ++i)
{
var b = BitConverter.GetBytes(q[i]);
ms.Write(b, 0, b.Length);
}
}
public static void Concatenate(this MemoryStream ms, float f)
{
var b = BitConverter.GetBytes(f);
ms.Write(b, 0, b.Length);
}
public static void Concatenate(this MemoryStream ms, int f)
{
var b = BitConverter.GetBytes(f);
ms.Write(b, 0, b.Length);
}
public static uint Adler32(byte[] bytes)
{
const int mod = 65521;
uint a = 1, b = 0;
foreach (byte c in bytes)
{
a = (a + c) % mod;
b = (b + a) % mod;
}
return (b << 16) | a;
}
|
||
|
|
||
|
public unsafe static Vector3 OctDecode(float k)
|
||
|
{
|
||
|
uint d = *(uint*)&k;
|
||
|
Vector2 f = new Vector2((d >> 16) / 65535f, (d & 0xffff) / 65535f);
|
||
|
f.x = f.x * 2 - 1;
|
||
|
f.y = f.y * 2 - 1;
|
||
|
|
||
|
Vector3 n = new Vector3(f.x, f.y, 1.0f - Mathf.Abs(f.x) - Mathf.Abs(f.y));
|
||
|
float t = Mathf.Max(-n.z, 0);
|
||
|
n.x += n.x >= 0.0f ? -t : t;
|
||
|
n.y += n.y >= 0.0f ? -t : t;
|
||
|
return Vector3.Normalize(n);
|
||
|
}
|
||
|
|
||
|
public unsafe static Vector4 UnpackFloatRGBA(float v)
|
||
|
{
|
||
|
uint rgba = *(uint*)&v;
|
||
|
float r = ((rgba & 0xff000000) >> 24) / 255f;
|
||
|
float g = ((rgba & 0x00ff0000) >> 16) / 255f;
|
||
|
float b = ((rgba & 0x0000ff00) >> 8) / 255f;
|
||
|
float a = (rgba & 0x000000ff) / 255f;
|
||
|
return new Vector4(r, g, b, a);
|
||
|
}
|
||
|
|
||
|
public unsafe static float PackFloatRGBA(Vector4 enc)
|
||
|
{
|
||
|
uint rgba = ((uint)(enc.x * 255f) << 24) +
|
||
|
((uint)(enc.y * 255f) << 16) +
|
||
|
((uint)(enc.z * 255f) << 8) +
|
||
|
(uint)(enc.w * 255f);
|
||
|
return *(float*)&rgba;
|
||
|
}
|
||
|
|
||
|
public unsafe static Vector2 UnpackFloatRG(float v)
|
||
|
{
|
||
|
uint rgba = *(uint*)&v;
|
||
|
float r = ((rgba & 0xffff0000) >> 16) / 65535f;
|
||
|
float g = (rgba & 0x0000ffff) / 65535f;
|
||
|
return new Vector2(r, g);
|
||
|
}
|
||
|
|
||
|
public unsafe static float PackFloatRG(Vector2 enc)
|
||
|
{
|
||
|
uint rgba = ((uint)(enc.x * 65535f) << 16) +
|
||
|
(uint)(enc.y * 65535f);
|
||
|
return *(float*)&rgba;
|
||
|
}
}
}
|