red-sim-light-volumesudon/VRCLightVolumes/LVUtils.cs
2025-09-17 01:38:27 +01:00

251 lines
No EOL
8.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEngine.Rendering;
namespace VRCLightVolumes
{
public class LVUtils
{
public LVUtils()
{
}
public static bool Apply3DTextureData(Texture3D texture, Color[] colors)
{
bool flag;
try
{
texture.SetPixels(colors);
texture.Apply(false);
flag = true;
}
catch (UnityException unityException)
{
Debug.LogError(String.Concat("[LightVolumeUtils] Failed to SetPixels in the Texture3D. Error: ", unityException.Message));
flag = false;
}
return flag;
}
public static Vector3[] BilateralDenoise3D(Vector3[] input, int w, int h, int d, float sigmaSpatial = 1f, float sigmaRange = 0.1f)
{
Vector3[] vector3Array = new Vector3[(int)input.Length];
int num = Mathf.CeilToInt(2f * sigmaSpatial);
for (int i = 0; i < d; i++)
{
for (int j = 0; j < h; j++)
{
for (int k = 0; k < w; k++)
{
int num1 = k + j * w + i * w * h;
Vector3 vector3 = input[num1];
Vector3 _zero = Vector3.get_zero();
float single = 0f;
for (int l = -num; l <= num; l++)
{
for (int m = -num; m <= num; m++)
{
for (int n = -num; n <= num; n++)
{
int num2 = k + n;
int num3 = j + m;
int num4 = i + l;
if ((num2 < 0 || num3 < 0 || num4 < 0 || num2 >= w || num3 >= h ? false : num4 < d))
{
int num5 = num2 + num3 * w + num4 * w * h;
Vector3 vector31 = input[num5];
float single1 = (float)(n * n + m * m + l * l);
float _sqrMagnitude = (vector31 - vector3).get_sqrMagnitude();
float single2 = Mathf.Exp(-single1 / (2f * sigmaSpatial * sigmaSpatial));
float single3 = Mathf.Exp(-_sqrMagnitude / (2f * sigmaRange * sigmaRange));
float single4 = single2 * single3;
_zero = _zero + (vector31 * single4);
single += single4;
}
}
}
}
vector3Array[num1] = (single > 0f ? _zero / single : vector3);
}
}
}
return vector3Array;
}
public static Bounds BoundsFromTRS(Matrix4x4 trs)
{
Vector3 column = trs.GetColumn(3);
Vector3 vector3 = trs.GetColumn(0) * 0.5f;
Vector3 column1 = trs.GetColumn(1) * 0.5f;
Vector3 vector31 = trs.GetColumn(2) * 0.5f;
Vector3 vector32 = new Vector3(Mathf.Abs(vector3.x) + Mathf.Abs(column1.x) + Mathf.Abs(vector31.x), Mathf.Abs(vector3.y) + Mathf.Abs(column1.y) + Mathf.Abs(vector31.y), Mathf.Abs(vector3.z) + Mathf.Abs(column1.z) + Mathf.Abs(vector31.z));
return new Bounds(column, vector32 * 2f);
}
public static bool CheckSHL2(SphericalHarmonicsL2 sh)
{
bool flag;
int num = 0;
while (true)
{
if (num < 3)
{
int num1 = 4;
while (num1 < 9)
{
if (sh.get_Item(num, num1) == 0f)
{
num1++;
}
else
{
flag = true;
return flag;
}
}
num++;
}
else
{
flag = false;
break;
}
}
return flag;
}
public static SphericalHarmonicsL2 DeringSH(SphericalHarmonicsL2 sh)
{
Vector3 vector3 = new Vector3(sh.get_Item(0, 0), sh.get_Item(1, 0), sh.get_Item(2, 0));
Vector3 vector31 = new Vector3(sh.get_Item(0, 3), sh.get_Item(0, 1), sh.get_Item(0, 2));
Vector3 vector32 = new Vector3(sh.get_Item(1, 3), sh.get_Item(1, 1), sh.get_Item(1, 2));
Vector3 vector33 = new Vector3(sh.get_Item(2, 3), sh.get_Item(2, 1), sh.get_Item(2, 2));
vector31 = LVUtils.DeringSingleSH(vector3.x, vector31);
vector32 = LVUtils.DeringSingleSH(vector3.y, vector32);
vector33 = LVUtils.DeringSingleSH(vector3.z, vector33);
sh.set_Item(0, 3, vector31.x);
sh.set_Item(0, 1, vector31.y);
sh.set_Item(0, 2, vector31.z);
sh.set_Item(1, 3, vector32.x);
sh.set_Item(1, 1, vector32.y);
sh.set_Item(1, 2, vector32.z);
sh.set_Item(2, 3, vector33.x);
sh.set_Item(2, 1, vector33.y);
sh.set_Item(2, 2, vector33.z);
return sh;
}
public static Vector3 DeringSingleSH(float L0, Vector3 L1)
{
L1 *= 0.5f;
float _magnitude = L1.get_magnitude();
if (((double)_magnitude <= 0 ? false : (double)L0 > 0))
{
L1 *= Mathf.Min(L0 / _magnitude, 1.13f);
}
return L1;
}
public static Mesh GenerateIcoSphere(float radius = 0.5f, int subdivisions = 2)
{
LVUtils.u003cu003ec__DisplayClass12_0 vector3s = new LVUtils.u003cu003ec__DisplayClass12_0();
Vector3[] vector3 = new Vector3[] { new Vector3(-0.5257311f, 0.8506508f, 0f), new Vector3(0.5257311f, 0.8506508f, 0f), new Vector3(-0.5257311f, -0.8506508f, 0f), new Vector3(0.5257311f, -0.8506508f, 0f), new Vector3(0f, -0.5257311f, 0.8506508f), new Vector3(0f, 0.5257311f, 0.8506508f), new Vector3(0f, -0.5257311f, -0.8506508f), new Vector3(0f, 0.5257311f, -0.8506508f), new Vector3(0.8506508f, 0f, -0.5257311f), new Vector3(0.8506508f, 0f, 0.5257311f), new Vector3(-0.8506508f, 0f, -0.5257311f), new Vector3(-0.8506508f, 0f, 0.5257311f) };
int[] numArray = new Int32[] { 0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8, 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1 };
vector3s.verts = new List<Vector3>(vector3);
List<int> nums = new List<int>(numArray);
vector3s.cache = new Dictionary<long, int>();
subdivisions = Mathf.Clamp(subdivisions, 0, 8);
for (int i = 0; i < subdivisions; i++)
{
vector3s.cache.Clear();
List<int> nums1 = new List<int>(nums.Count * 4);
for (int j = 0; j < nums.Count; j += 3)
{
int item = nums[j];
int num = nums[j + 1];
int item1 = nums[j + 2];
int num1 = LVUtils.u003cGenerateIcoSphereu003eg__Midpointu007c12_0(item, num, ref vector3s);
int num2 = LVUtils.u003cGenerateIcoSphereu003eg__Midpointu007c12_0(num, item1, ref vector3s);
int num3 = LVUtils.u003cGenerateIcoSphereu003eg__Midpointu007c12_0(item1, item, ref vector3s);
nums1.AddRange((IEnumerable<!0>)(new Int32[] { item, num1, num3, num, num2, num1, item1, num3, num2, num1, num2, num3 }));
}
nums = nums1;
}
for (int k = 0; k < vector3s.verts.Count; k++)
{
List<Vector3> vector3s1 = vector3s.verts;
Vector3 vector31 = vector3s.verts[k];
vector3s1[k] = vector31.get_normalized() * radius;
}
Mesh mesh = new Mesh();
mesh.set_name(String.Format("IcoSphere_{0}", subdivisions));
Mesh mesh1 = mesh;
mesh1.SetVertices(vector3s.verts);
mesh1.SetTriangles(nums, 0);
mesh1.RecalculateNormals();
mesh1.RecalculateBounds();
return mesh1;
}
public static Vector3[] GetPlaneVertices(Vector3 center, Quaternion rotation, float size)
{
Vector3 vector3 = (rotation * Vector3.get_right()) * size;
Vector3 vector31 = (rotation * Vector3.get_up()) * size;
return new Vector3[] { (center - vector3) - vector31, (center - vector3) + vector31, (center + vector3) + vector31, (center + vector3) - vector31 };
}
public static bool IsInPrefabAsset(object obj)
{
return false;
}
public static void MarkDirty(object obj)
{
}
public static float Remap(float value, float MinOld, float MaxOld, float MinNew, float MaxNew)
{
float minNew = MinNew + (value - MinOld) * (MaxNew - MinNew) / (MaxOld - MinOld);
return minNew;
}
public static float RemapTo01(float value, float MinOld, float MaxOld)
{
return (value - MinOld) / (MaxOld - MinOld);
}
public static void SaveAsAsset(object asset, string assetPath)
{
Debug.LogError("[LightVolumeUtils] You can only save asset in editor!");
}
public static void SaveAsAssetDelayed(object asset, string assetPath, Action<bool> callback = null)
{
Debug.LogError("[LightVolumeUtils] You can only save asset in editor!");
}
public static void SetLossyScale(Transform transform, Vector3 targetLossyScale, int maxIterations = 20)
{
Vector3 _localScale = transform.get_localScale();
for (int i = 0; i < maxIterations; i++)
{
transform.set_localScale(_localScale);
Vector3 _lossyScale = transform.get_lossyScale();
Vector3 vector3 = new Vector3((_lossyScale.x != 0f ? targetLossyScale.x / _lossyScale.x : 1f), (_lossyScale.y != 0f ? targetLossyScale.y / _lossyScale.y : 1f), (_lossyScale.z != 0f ? targetLossyScale.z / _lossyScale.z : 1f));
_localScale = new Vector3(_localScale.x * vector3.x, _localScale.y * vector3.y, _localScale.z * vector3.z);
}
}
public static void TextureSetReadWrite(Texture texture, bool enabled)
{
}
public static Vector3 TransformPoint(Vector3 point, Vector3 position, Quaternion rotation, Vector3 scale)
{
Vector3 vector3 = (rotation * Vector3.Scale(point, scale)) + position;
return vector3;
}
}
}