refactor: using Coffee.Internal

pull/336/head
mob-sakai 2024-09-30 00:18:21 +09:00
parent a96b6915ef
commit 8c1bef4373
7 changed files with 81 additions and 479 deletions

View File

@ -7,7 +7,7 @@ using UnityEditorInternal;
using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.UI;
using Coffee.UIParticleExtensions;
using Coffee.UIParticleInternal;
#if UNITY_2021_2_OR_NEWER
using UnityEditor.Overlays;
#else

View File

@ -1,72 +0,0 @@
using System.Collections.Generic;
using UnityEngine;
namespace Coffee.UIParticleExtensions
{
internal class ModifiedMaterial
{
private static readonly List<MatEntry> s_Entries = new List<MatEntry>();
public static Material Add(Material baseMat, Texture texture, int id, int props)
{
MatEntry e;
for (var i = 0; i < s_Entries.Count; i++)
{
e = s_Entries[i];
if (e.baseMat != baseMat || e.texture != texture || e.id != id || e.props != props) continue;
++e.count;
return e.customMat;
}
e = new MatEntry
{
count = 1,
baseMat = baseMat,
texture = texture,
id = id,
props = props,
customMat = new Material(baseMat)
{
name = $"{baseMat.name}_{id}",
hideFlags = HideFlags.DontSave | HideFlags.NotEditable,
mainTexture = texture ? texture : baseMat.mainTexture
}
};
s_Entries.Add(e);
//Debug.LogFormat(">>>> ModifiedMaterial.Add -> count = count:{0}, mat:{1}, tex:{2}, id:{3}", s_Entries.Count, baseMat, texture, id);
return e.customMat;
}
public static void Remove(Material customMat)
{
if (!customMat) return;
for (var i = 0; i < s_Entries.Count; ++i)
{
var e = s_Entries[i];
if (e.customMat != customMat) continue;
if (--e.count == 0)
{
//Debug.LogFormat(">>>> ModifiedMaterial.Remove -> count:{0}, mat:{1}, tex:{2}, id:{3}", s_Entries.Count - 1, e.customMat, e.texture, e.id);
Misc.DestroyImmediate(e.customMat);
e.customMat = null;
e.baseMat = null;
e.texture = null;
s_Entries.RemoveAt(i);
}
break;
}
}
private class MatEntry
{
public Material baseMat;
public int count;
public Material customMat;
public int id;
public int props;
public Texture texture;
}
}
}

View File

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Coffee.UIParticleExtensions;
using Coffee.UIParticleInternal;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Serialization;
@ -119,7 +119,6 @@ namespace Coffee.UIExtensions
private readonly List<UIParticleRenderer> _renderers = new List<UIParticleRenderer>();
private Camera _bakeCamera;
private Canvas _canvas;
private int _groupId;
private bool _isScaleStored;
private Vector3 _storedScale;

View File

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using Coffee.UIParticleExtensions;
using Coffee.UIParticleInternal;
using UnityEngine;
using UnityEngine.Events;

View File

@ -6,7 +6,7 @@
#endif
using System;
using System.Collections.Generic;
using Coffee.UIParticleExtensions;
using Coffee.UIParticleInternal;
using UnityEditor;
using UnityEngine;
using UnityEngine.Profiling;
@ -21,19 +21,17 @@ namespace Coffee.UIExtensions
[AddComponentMenu("")]
internal class UIParticleRenderer : MaskableGraphic
{
private static readonly List<Component> s_Components = new List<Component>();
private static readonly CombineInstance[] s_CombineInstances = { new CombineInstance() };
private static readonly List<Material> s_Materials = new List<Material>(2);
private static MaterialPropertyBlock s_Mpb;
private static readonly List<UIParticleRenderer> s_Renderers = new List<UIParticleRenderer>();
private static readonly List<Color32> s_Colors = new List<Color32>();
private static readonly Vector3[] s_Corners = new Vector3[4];
private Material _currentMaterialForRendering;
private bool _delay;
private int _index;
private bool _isPrevStored;
private bool _isTrail;
private Bounds _lastBounds;
private Material _materialForRendering;
private Material _modifiedMaterial;
private UIParticle _parent;
private ParticleSystem _particleSystem;
@ -92,6 +90,19 @@ namespace Coffee.UIExtensions
}
}
public override Material materialForRendering
{
get
{
if (!_materialForRendering)
{
_materialForRendering = base.materialForRendering;
}
return _materialForRendering;
}
}
public void Reset(int index = -1)
{
if (_renderer)
@ -117,9 +128,8 @@ namespace Coffee.UIExtensions
}
else
{
ModifiedMaterial.Remove(_modifiedMaterial);
_modifiedMaterial = null;
_currentMaterialForRendering = null;
MaterialRepository.Release(ref _modifiedMaterial);
_materialForRendering = null;
}
}
@ -135,17 +145,14 @@ namespace Coffee.UIExtensions
hideFlags = HideFlags.HideAndDontSave
};
}
_currentMaterialForRendering = null;
}
protected override void OnDisable()
{
base.OnDisable();
ModifiedMaterial.Remove(_modifiedMaterial);
_modifiedMaterial = null;
_currentMaterialForRendering = null;
MaterialRepository.Release(ref _modifiedMaterial);
_materialForRendering = null;
_isPrevStored = false;
}
@ -178,11 +185,9 @@ namespace Coffee.UIExtensions
/// </summary>
public override Material GetModifiedMaterial(Material baseMaterial)
{
_currentMaterialForRendering = null;
if (!IsActive() || !_parent)
{
ModifiedMaterial.Remove(_modifiedMaterial);
MaterialRepository.Release(ref _modifiedMaterial);
_modifiedMaterial = null;
return baseMaterial;
}
@ -193,23 +198,29 @@ namespace Coffee.UIExtensions
var texture = mainTexture;
if (texture == null && _parent.m_AnimatableProperties.Length == 0)
{
ModifiedMaterial.Remove(_modifiedMaterial);
_modifiedMaterial = null;
MaterialRepository.Release(ref _modifiedMaterial);
return modifiedMaterial;
}
//
var id = _parent.m_AnimatableProperties.Length == 0 ? 0 : GetInstanceID();
var hash = new Hash128(
modifiedMaterial ? (uint)modifiedMaterial.GetInstanceID() : 0,
texture ? (uint)texture.GetInstanceID() : 0,
0 < _parent.m_AnimatableProperties.Length ? (uint)GetInstanceID() : 0,
#if UNITY_EDITOR
var props = EditorJsonUtility.ToJson(modifiedMaterial).GetHashCode();
(uint)EditorJsonUtility.ToJson(modifiedMaterial).GetHashCode()
#else
var props = 0;
0
#endif
modifiedMaterial = ModifiedMaterial.Add(modifiedMaterial, texture, id, props);
ModifiedMaterial.Remove(_modifiedMaterial);
_modifiedMaterial = modifiedMaterial;
);
if (!MaterialRepository.Valid(hash, _modifiedMaterial))
{
MaterialRepository.Get(hash, ref _modifiedMaterial, () => new Material(modifiedMaterial)
{
hideFlags = HideFlags.HideAndDontSave
});
}
return modifiedMaterial;
return _modifiedMaterial;
}
public void Set(UIParticle parent, ParticleSystem ps, bool isTrail)
@ -405,95 +416,67 @@ namespace Coffee.UIExtensions
_lastBounds = bounds;
// Convert linear color to gamma color.
if (QualitySettings.activeColorSpace == ColorSpace.Linear)
if (canvas.ShouldGammaToLinearInMesh())
{
Profiler.BeginSample("[UIParticleRenderer] Convert Linear to Gamma");
workerMesh.GetColors(s_Colors);
var count_c = s_Colors.Count;
for (var i = 0; i < count_c; i++)
{
var c = s_Colors[i];
c.r = c.r.LinearToGamma();
c.g = c.g.LinearToGamma();
c.b = c.b.LinearToGamma();
s_Colors[i] = c;
}
workerMesh.SetColors(s_Colors);
Profiler.EndSample();
workerMesh.LinearToGamma();
}
GetComponents(typeof(IMeshModifier), s_Components);
for (var i = 0; i < s_Components.Count; i++)
var components = ListPool<Component>.Rent();
GetComponents(typeof(IMeshModifier), components);
for (var i = 0; i < components.Count; i++)
{
#pragma warning disable CS0618 // Type or member is obsolete
((IMeshModifier)s_Components[i]).ModifyMesh(workerMesh);
((IMeshModifier)components[i]).ModifyMesh(workerMesh);
#pragma warning restore CS0618 // Type or member is obsolete
}
s_Components.Clear();
ListPool<Component>.Return(ref components);
}
Profiler.EndSample();
// Get grouped renderers.
s_Renderers.Clear();
if (_parent.useMeshSharing)
{
UIParticleUpdater.GetGroupedRenderers(_parent.groupId, _index, s_Renderers);
}
// Set mesh to the CanvasRenderer.
Profiler.BeginSample("[UIParticleRenderer] Set Mesh");
for (var i = 0; i < s_Renderers.Count; i++)
{
if (s_Renderers[i] == this) continue;
s_Renderers[i].canvasRenderer.SetMesh(workerMesh);
s_Renderers[i]._lastBounds = _lastBounds;
}
if (!_parent.canRender)
{
workerMesh.Clear();
}
canvasRenderer.SetMesh(workerMesh);
Profiler.EndSample();
// Update animatable material properties.
Profiler.BeginSample("[UIParticleRenderer] Update Animatable Material Properties");
#if UNITY_EDITOR
if (_modifiedMaterial != material)
{
_renderer.GetSharedMaterials(s_Materials);
material = s_Materials[_isTrail ? 1 : 0];
s_Materials.Clear();
SetMaterialDirty();
}
#endif
UpdateMaterialProperties();
Profiler.EndSample();
// Get grouped renderers.
Profiler.BeginSample("[UIParticleRenderer] Set Mesh");
var renderers = ListPool<UIParticleRenderer>.Rent();
if (_parent.useMeshSharing)
{
if (!_currentMaterialForRendering)
{
_currentMaterialForRendering = materialForRendering;
}
UIParticleUpdater.GetGroupedRenderers(_parent.groupId, _index, renderers);
}
for (var i = 0; i < s_Renderers.Count; i++)
{
if (s_Renderers[i] == this) continue;
for (var i = 0; i < renderers.Count; i++)
{
var r = renderers[i];
if (r == this) continue;
s_Renderers[i].canvasRenderer.materialCount = 1;
s_Renderers[i].canvasRenderer.SetMaterial(_currentMaterialForRendering, 0);
}
r.canvasRenderer.SetMesh(workerMesh);
r._lastBounds = _lastBounds;
r.canvasRenderer.materialCount = 1;
r.canvasRenderer.SetMaterial(materialForRendering, 0);
}
ListPool<UIParticleRenderer>.Return(ref renderers);
if (_parent.canRender)
{
canvasRenderer.SetMesh(workerMesh);
}
else
{
workerMesh.Clear();
}
Profiler.EndSample();
}
s_Renderers.Clear();
public override void SetMaterialDirty()
{
_materialForRendering = null;
base.SetMaterialDirty();
}
/// <summary>
@ -701,12 +684,12 @@ namespace Coffee.UIExtensions
if (s_Mpb.isEmpty) return;
// #41: Copy the value from MaterialPropertyBlock to CanvasRenderer
if (!_modifiedMaterial) return;
if (!materialForRendering) return;
for (var i = 0; i < _parent.m_AnimatableProperties.Length; i++)
{
var ap = _parent.m_AnimatableProperties[i];
ap.UpdateMaterialProperties(_modifiedMaterial, s_Mpb);
ap.UpdateMaterialProperties(materialForRendering, s_Mpb);
}
s_Mpb.Clear();

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using Coffee.UIParticleInternal;
using UnityEditor;
using UnityEngine;
@ -44,8 +45,7 @@ namespace Coffee.UIExtensions
#endif
private static void InitializeOnLoad()
{
Canvas.willRenderCanvases -= Refresh;
Canvas.willRenderCanvases += Refresh;
UIExtraCallbacks.onAfterCanvasRebuild += Refresh;
}
private static void Refresh()

View File

@ -1,308 +0,0 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Coffee.UIParticleExtensions
{
public static class Color32Extensions
{
private static byte[] s_LinearToGammaLut;
public static byte LinearToGamma(this byte self)
{
if (s_LinearToGammaLut == null)
{
s_LinearToGammaLut = new byte[256];
for (var i = 0; i < 256; i++)
{
s_LinearToGammaLut[i] = (byte)(Mathf.LinearToGammaSpace(i / 255f) * 255f);
}
}
return s_LinearToGammaLut[self];
}
}
public static class Vector3Extensions
{
public static Vector3 Inverse(this Vector3 self)
{
self.x = Mathf.Approximately(self.x, 0) ? 1 : 1 / self.x;
self.y = Mathf.Approximately(self.y, 0) ? 1 : 1 / self.y;
self.z = Mathf.Approximately(self.z, 0) ? 1 : 1 / self.z;
return self;
}
public static Vector3 GetScaled(this Vector3 self, Vector3 other1)
{
self.Scale(other1);
return self;
}
public static Vector3 GetScaled(this Vector3 self, Vector3 other1, Vector3 other2)
{
self.Scale(other1);
self.Scale(other2);
return self;
}
public static Vector3 GetScaled(this Vector3 self, Vector3 other1, Vector3 other2, Vector3 other3)
{
self.Scale(other1);
self.Scale(other2);
self.Scale(other3);
return self;
}
public static bool IsVisible(this Vector3 self)
{
return 0 < Mathf.Abs(self.x * self.y * self.z);
}
}
internal static class SpriteExtensions
{
#if UNITY_EDITOR
private static readonly Type s_SpriteEditorExtensionType =
Type.GetType("UnityEditor.Experimental.U2D.SpriteEditorExtension, UnityEditor")
?? Type.GetType("UnityEditor.U2D.SpriteEditorExtension, UnityEditor");
private static readonly MethodInfo s_GetActiveAtlasTextureMethodInfo = s_SpriteEditorExtensionType
.GetMethod("GetActiveAtlasTexture", BindingFlags.Static | BindingFlags.NonPublic);
public static Texture2D GetActualTexture(this Sprite self)
{
if (!self) return null;
if (Application.isPlaying) return self.texture;
var ret = s_GetActiveAtlasTextureMethodInfo.Invoke(null, new object[] { self }) as Texture2D;
return ret
? ret
: self.texture;
}
#else
internal static Texture2D GetActualTexture(this Sprite self)
{
return self ? self.texture : null;
}
#endif
}
public static class ParticleSystemExtensions
{
private static ParticleSystem.Particle[] s_TmpParticles = new ParticleSystem.Particle[2048];
public static ParticleSystem.Particle[] GetParticleArray(int size)
{
if (s_TmpParticles.Length < size)
{
while (s_TmpParticles.Length < size)
{
size = Mathf.NextPowerOfTwo(size);
}
s_TmpParticles = new ParticleSystem.Particle[size];
}
return s_TmpParticles;
}
public static void ValidateShape(this ParticleSystem self)
{
var shape = self.shape;
if (shape.enabled && shape.alignToDirection)
{
if (Mathf.Approximately(shape.scale.x * shape.scale.y * shape.scale.z, 0))
{
if (Mathf.Approximately(shape.scale.x, 0))
{
shape.scale.Set(0.0001f, shape.scale.y, shape.scale.z);
}
else if (Mathf.Approximately(shape.scale.y, 0))
{
shape.scale.Set(shape.scale.x, 0.0001f, shape.scale.z);
}
else if (Mathf.Approximately(shape.scale.z, 0))
{
shape.scale.Set(shape.scale.x, shape.scale.y, 0.0001f);
}
}
}
}
public static bool CanBakeMesh(this ParticleSystemRenderer self)
{
// #69: Editor crashes when mesh is set to null when `ParticleSystem.RenderMode = Mesh`
if (self.renderMode == ParticleSystemRenderMode.Mesh && self.mesh == null) return false;
// #61: When `ParticleSystem.RenderMode = None`, an error occurs
if (self.renderMode == ParticleSystemRenderMode.None) return false;
return true;
}
public static ParticleSystemSimulationSpace GetActualSimulationSpace(this ParticleSystem self)
{
var main = self.main;
var space = main.simulationSpace;
if (space == ParticleSystemSimulationSpace.Custom && !main.customSimulationSpace)
{
space = ParticleSystemSimulationSpace.Local;
}
return space;
}
public static bool IsLocalSpace(this ParticleSystem self)
{
return GetActualSimulationSpace(self) == ParticleSystemSimulationSpace.Local;
}
public static bool IsWorldSpace(this ParticleSystem self)
{
return GetActualSimulationSpace(self) == ParticleSystemSimulationSpace.World;
}
public static void SortForRendering(this List<ParticleSystem> self, Transform transform, bool sortByMaterial)
{
self.Sort((a, b) =>
{
var aRenderer = a.GetComponent<ParticleSystemRenderer>();
var bRenderer = b.GetComponent<ParticleSystemRenderer>();
// Render queue: ascending
var aMat = aRenderer.sharedMaterial ? aRenderer.sharedMaterial : aRenderer.trailMaterial;
var bMat = bRenderer.sharedMaterial ? bRenderer.sharedMaterial : bRenderer.trailMaterial;
if (!aMat && !bMat) return 0;
if (!aMat) return -1;
if (!bMat) return 1;
if (sortByMaterial)
{
return aMat.GetInstanceID() - bMat.GetInstanceID();
}
if (aMat.renderQueue != bMat.renderQueue)
{
return aMat.renderQueue - bMat.renderQueue;
}
// Sorting layer: ascending
if (aRenderer.sortingLayerID != bRenderer.sortingLayerID)
{
return SortingLayer.GetLayerValueFromID(aRenderer.sortingLayerID) -
SortingLayer.GetLayerValueFromID(bRenderer.sortingLayerID);
}
// Sorting order: ascending
if (aRenderer.sortingOrder != bRenderer.sortingOrder)
{
return aRenderer.sortingOrder - bRenderer.sortingOrder;
}
// Z position & sortingFudge: descending
var aTransform = a.transform;
var bTransform = b.transform;
var aPos = transform.InverseTransformPoint(aTransform.position).z + aRenderer.sortingFudge;
var bPos = transform.InverseTransformPoint(bTransform.position).z + bRenderer.sortingFudge;
if (!Mathf.Approximately(aPos, bPos))
{
return (int)Mathf.Sign(bPos - aPos);
}
return (int)Mathf.Sign(GetIndex(self, a) - GetIndex(self, b));
});
}
private static int GetIndex(IList<ParticleSystem> list, Object ps)
{
for (var i = 0; i < list.Count; i++)
{
if (list[i].GetInstanceID() == ps.GetInstanceID())
{
return i;
}
}
return 0;
}
public static Texture2D GetTextureForSprite(this ParticleSystem self)
{
if (!self) return null;
// Get sprite's texture.
var tsaModule = self.textureSheetAnimation;
if (!tsaModule.enabled || tsaModule.mode != ParticleSystemAnimationMode.Sprites) return null;
for (var i = 0; i < tsaModule.spriteCount; i++)
{
var sprite = tsaModule.GetSprite(i);
if (!sprite) continue;
return sprite.GetActualTexture();
}
return null;
}
public static void Exec(this List<ParticleSystem> self, Action<ParticleSystem> action)
{
self.RemoveAll(p => !p);
self.ForEach(action);
}
}
internal static class Misc
{
public static void Destroy(Object obj)
{
if (!obj) return;
#if UNITY_EDITOR
if (!Application.isPlaying)
{
Object.DestroyImmediate(obj);
}
else
#endif
{
Object.Destroy(obj);
}
}
public static void DestroyImmediate(Object obj)
{
if (!obj) return;
#if UNITY_EDITOR
if (Application.isEditor)
{
Object.DestroyImmediate(obj);
}
else
#endif
{
Object.Destroy(obj);
}
}
#if !UNITY_2021_2_OR_NEWER && !UNITY_2020_3_45 && !UNITY_2020_3_46 && !UNITY_2020_3_47 && !UNITY_2020_3_48
public static T GetComponentInParent<T>(this Component self, bool includeInactive) where T : Component
{
if (!self) return null;
if (!includeInactive) return self.GetComponentInParent<T>();
var current = self.transform;
while (current)
{
var component = current.GetComponent<T>();
if (component) return component;
current = current.parent;
}
return null;
}
#endif
}
}