Files
SVSimServer/SVSim.BattleEngine/Engine/UIDrawCall.cs
gamer147 0d9d8acae0 feat(battle-engine): M1 auto-copy closure (782 battle-logic files)
Compile-driven bulk-copy loop (tools/engine-port/m1_copy_loop.py) pulled the precise reference closure of the battle-core roots, stopping at the classify god-object/View-VFX-UI boundary. 782 files; no re-explosion (M0 had estimated ~order 1000). Residual frontier = 52 shim-classified + 80 external (Unity/BCL) types to author next.
2026-06-05 16:57:20 -04:00

815 lines
18 KiB
C#

using System;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
[AddComponentMenu("NGUI/Internal/Draw Call")]
public class UIDrawCall : MonoBehaviour
{
public enum Clipping
{
None = 0,
TextureMask = 1,
SoftClip = 3,
ConstrainButDontClip = 4
}
public delegate void OnRenderCallback(Material mat);
private static BetterList<UIDrawCall> mActiveList = new BetterList<UIDrawCall>();
private static BetterList<UIDrawCall> mInactiveList = new BetterList<UIDrawCall>();
[NonSerialized]
[HideInInspector]
public int widgetCount;
[NonSerialized]
[HideInInspector]
public int depthStart = int.MaxValue;
[NonSerialized]
[HideInInspector]
public int depthEnd = int.MinValue;
[NonSerialized]
[HideInInspector]
public UIPanel manager;
[NonSerialized]
[HideInInspector]
public UIPanel panel;
[NonSerialized]
[HideInInspector]
public Texture2D clipTexture;
[NonSerialized]
[HideInInspector]
public bool alwaysOnScreen;
[NonSerialized]
[HideInInspector]
public BetterList<Vector3> verts = new BetterList<Vector3>();
[NonSerialized]
[HideInInspector]
public BetterList<Vector3> norms = new BetterList<Vector3>();
[NonSerialized]
[HideInInspector]
public BetterList<Vector4> tans = new BetterList<Vector4>();
[NonSerialized]
[HideInInspector]
public BetterList<Vector2> uvs = new BetterList<Vector2>();
[NonSerialized]
[HideInInspector]
public BetterList<Color32> cols = new BetterList<Color32>();
private Material mMaterial;
private Texture mTexture;
private Shader mShader;
private int mClipCount;
private Transform mTrans;
private Mesh mMesh;
private MeshFilter mFilter;
private MeshRenderer mRenderer;
private Material mDynamicMat;
private int[] mIndices;
private bool mRebuildMat = true;
private bool mLegacyShader;
private int mRenderQueue = 3000;
private int mTriangles;
[NonSerialized]
public bool isDirty;
[NonSerialized]
private bool mTextureClip;
public OnRenderCallback onRender;
private const int maxIndexBufferCache = 10;
private static List<int[]> mCache = new List<int[]>(10);
private static int[] ClipRange = null;
private static int[] ClipArgs = null;
[Obsolete("Use UIDrawCall.activeList")]
public static BetterList<UIDrawCall> list => mActiveList;
public static BetterList<UIDrawCall> activeList => mActiveList;
public static BetterList<UIDrawCall> inactiveList => mInactiveList;
public int renderQueue
{
get
{
return mRenderQueue;
}
set
{
if (mRenderQueue != value)
{
mRenderQueue = value;
if (mDynamicMat != null)
{
mDynamicMat.renderQueue = value;
}
}
}
}
public int sortingOrder
{
get
{
if (!(mRenderer != null))
{
return 0;
}
return mRenderer.sortingOrder;
}
set
{
if (mRenderer != null && mRenderer.sortingOrder != value)
{
mRenderer.sortingOrder = value;
}
}
}
public int finalRenderQueue
{
get
{
if (!(mDynamicMat != null))
{
return mRenderQueue;
}
return mDynamicMat.renderQueue;
}
}
public Transform cachedTransform
{
get
{
if (mTrans == null)
{
mTrans = base.transform;
}
return mTrans;
}
}
public Material baseMaterial
{
get
{
return mMaterial;
}
set
{
if (mMaterial != value)
{
mMaterial = value;
mRebuildMat = true;
}
}
}
public Material dynamicMaterial => mDynamicMat;
public Texture mainTexture
{
get
{
return mTexture;
}
set
{
mTexture = value;
if (mDynamicMat != null)
{
mDynamicMat.mainTexture = value;
}
}
}
public Shader shader
{
get
{
return mShader;
}
set
{
if (mShader != value)
{
mShader = value;
mRebuildMat = true;
}
}
}
public int triangles
{
get
{
if (!(mMesh != null))
{
return 0;
}
return mTriangles;
}
}
public bool isClipped => mClipCount != 0;
private void CreateMaterial()
{
mTextureClip = false;
mLegacyShader = false;
mClipCount = ((panel != null) ? panel.clipCount : 0);
string text = ((mShader != null) ? mShader.name : ((mMaterial != null) ? mMaterial.shader.name : "Unlit/Transparent Colored"));
text = text.Replace("GUI/Text Shader", "Unlit/Text");
if (text.Length > 2 && text[text.Length - 2] == ' ')
{
int num = text[text.Length - 1];
if (num > 48 && num <= 57)
{
text = text.Substring(0, text.Length - 2);
}
}
if (text.StartsWith("Hidden/"))
{
text = text.Substring(7);
}
text = text.Replace(" (SoftClip)", "");
text = text.Replace(" (TextureClip)", "");
if (panel != null && panel.clipping == Clipping.TextureMask)
{
mTextureClip = true;
shader = Shader.Find("Hidden/" + text + " (TextureClip)");
}
else if (mClipCount != 0)
{
shader = Shader.Find("Hidden/" + text + " " + mClipCount);
if (shader == null)
{
shader = Shader.Find(text + " " + mClipCount);
}
if (shader == null && mClipCount == 1)
{
mLegacyShader = true;
shader = Shader.Find(text + " (SoftClip)");
}
}
else
{
shader = Shader.Find(text);
}
if (shader == null)
{
shader = Shader.Find("Unlit/Transparent Colored");
}
if (mMaterial != null)
{
if (IsWizardMaterial())
{
mDynamicMat = new Material(mMaterial);
mDynamicMat.EnableKeyword("USE_VERTEX_COLOR");
mDynamicMat.SetFloat("_SleeveSrcFactor", 5f);
mDynamicMat.SetFloat("_SleeveDstFactor", 10f);
mDynamicMat.SetFloat("_CullMode", 0f);
mDynamicMat.SetFloat("_ZWriteMode", 0f);
mLegacyShader = false;
if (isClipped)
{
mDynamicMat.EnableKeyword("USE_CLIP");
}
if (IsSleeveMaterial())
{
mDynamicMat.EnableKeyword("USE_SLEEVE");
}
mDynamicMat.shader = Shader.Find(mMaterial.shader.name);
}
else
{
mDynamicMat = new Material(mMaterial);
mDynamicMat.name = "[NGUI] " + mMaterial.name;
mDynamicMat.hideFlags = HideFlags.DontSave | HideFlags.NotEditable;
mDynamicMat.CopyPropertiesFromMaterial(mMaterial);
string[] shaderKeywords = mMaterial.shaderKeywords;
for (int i = 0; i < shaderKeywords.Length; i++)
{
mDynamicMat.EnableKeyword(shaderKeywords[i]);
}
if (shader != null)
{
mDynamicMat.shader = shader;
}
else if (mClipCount != 0)
{
Debug.LogError(text + " shader doesn't have a clipped shader version for " + mClipCount + " clip regions");
}
}
}
else
{
mDynamicMat = new Material(shader);
mDynamicMat.name = "[NGUI] " + shader.name;
mDynamicMat.hideFlags = HideFlags.DontSave | HideFlags.NotEditable;
}
}
private bool IsWizardMaterial()
{
if (mMaterial.shader.name == "Wizard/VariantSleeveShader")
{
return true;
}
return false;
}
private bool IsSleeveMaterial()
{
if (mMaterial.name.Contains("sleeve"))
{
return true;
}
return false;
}
public void SetDisableLegacyShader()
{
mLegacyShader = false;
}
private Material RebuildMaterial()
{
NGUITools.DestroyImmediate(mDynamicMat);
CreateMaterial();
mDynamicMat.renderQueue = mRenderQueue;
if (mTexture != null)
{
mDynamicMat.mainTexture = mTexture;
}
if (mRenderer != null)
{
mRenderer.sharedMaterials = new Material[1] { mDynamicMat };
}
return mDynamicMat;
}
private void UpdateMaterials()
{
if (!(panel == null))
{
if (mRebuildMat || mDynamicMat == null || mClipCount != panel.clipCount || mTextureClip != (panel.clipping == Clipping.TextureMask))
{
RebuildMaterial();
mRebuildMat = false;
}
else if (mRenderer.sharedMaterial != mDynamicMat)
{
mRenderer.sharedMaterials = new Material[1] { mDynamicMat };
}
}
}
public void UpdateGeometry(int widgetCount)
{
this.widgetCount = widgetCount;
int size = verts.size;
if (size > 0 && size == uvs.size && size == cols.size && size % 4 == 0)
{
if (mFilter == null)
{
mFilter = base.gameObject.GetComponent<MeshFilter>();
}
if (mFilter == null)
{
mFilter = base.gameObject.AddComponent<MeshFilter>();
}
if (verts.size < 65000)
{
int num = (size >> 1) * 3;
bool flag = mIndices == null || mIndices.Length != num;
if (mMesh == null)
{
mMesh = new Mesh();
mMesh.hideFlags = HideFlags.DontSave;
mMesh.name = ((mMaterial != null) ? ("[NGUI] " + mMaterial.name) : "[NGUI] Mesh");
mMesh.MarkDynamic();
flag = true;
}
bool flag2 = uvs.buffer.Length != verts.buffer.Length || cols.buffer.Length != verts.buffer.Length || (norms.buffer != null && norms.buffer.Length != verts.buffer.Length) || (tans.buffer != null && tans.buffer.Length != verts.buffer.Length);
if (!flag2 && panel != null && panel.renderQueue != UIPanel.RenderQueue.Automatic)
{
flag2 = mMesh == null || mMesh.vertexCount != verts.buffer.Length;
}
if (!flag2 && verts.size << 1 < verts.buffer.Length)
{
flag2 = true;
}
mTriangles = verts.size >> 1;
if (flag2 || verts.buffer.Length > 65000)
{
if (flag2 || mMesh.vertexCount != verts.size)
{
mMesh.Clear();
flag = true;
}
mMesh.vertices = verts.ToArray();
mMesh.uv = uvs.ToArray();
mMesh.colors32 = cols.ToArray();
if (norms != null)
{
mMesh.normals = norms.ToArray();
}
if (tans != null)
{
mMesh.tangents = tans.ToArray();
}
}
else
{
if (mMesh.vertexCount != verts.buffer.Length)
{
mMesh.Clear();
flag = true;
}
mMesh.vertices = verts.buffer;
mMesh.uv = uvs.buffer;
mMesh.colors32 = cols.buffer;
if (norms != null)
{
mMesh.normals = norms.buffer;
}
if (tans != null)
{
mMesh.tangents = tans.buffer;
}
}
if (flag)
{
mIndices = GenerateCachedIndexBuffer(size, num);
mMesh.triangles = mIndices;
}
if (flag2 || !alwaysOnScreen)
{
mMesh.RecalculateBounds();
}
mFilter.mesh = mMesh;
}
else
{
mTriangles = 0;
if (mFilter.mesh != null)
{
mFilter.mesh.Clear();
}
Debug.LogError("Too many vertices on one panel: " + verts.size);
}
if (mRenderer == null)
{
mRenderer = base.gameObject.GetComponent<MeshRenderer>();
}
if (mRenderer == null)
{
mRenderer = base.gameObject.AddComponent<MeshRenderer>();
}
UpdateMaterials();
}
else
{
if (mFilter.mesh != null)
{
mFilter.mesh.Clear();
}
Debug.LogError("UIWidgets must fill the buffer with 4 vertices per quad. Found " + size);
}
verts.Clear();
uvs.Clear();
cols.Clear();
norms.Clear();
tans.Clear();
}
private int[] GenerateCachedIndexBuffer(int vertexCount, int indexCount)
{
int i = 0;
for (int count = mCache.Count; i < count; i++)
{
int[] array = mCache[i];
if (array != null && array.Length == indexCount)
{
return array;
}
}
int[] array2 = new int[indexCount];
int num = 0;
for (int j = 0; j < vertexCount; j += 4)
{
array2[num++] = j;
array2[num++] = j + 1;
array2[num++] = j + 2;
array2[num++] = j + 2;
array2[num++] = j + 3;
array2[num++] = j;
}
if (mCache.Count > 10)
{
mCache.RemoveAt(0);
}
mCache.Add(array2);
return array2;
}
private void OnWillRenderObject()
{
UpdateMaterials();
if (onRender != null)
{
onRender(mDynamicMat ?? mMaterial);
}
if (mDynamicMat == null || mClipCount == 0)
{
return;
}
if (mTextureClip)
{
Vector4 drawCallClipRange = panel.drawCallClipRange;
Vector2 clipSoftness = panel.clipSoftness;
Vector2 vector = new Vector2(1000f, 1000f);
if (clipSoftness.x > 0f)
{
vector.x = drawCallClipRange.z / clipSoftness.x;
}
if (clipSoftness.y > 0f)
{
vector.y = drawCallClipRange.w / clipSoftness.y;
}
mDynamicMat.SetVector(ClipRange[0], new Vector4((0f - drawCallClipRange.x) / drawCallClipRange.z, (0f - drawCallClipRange.y) / drawCallClipRange.w, 1f / drawCallClipRange.z, 1f / drawCallClipRange.w));
mDynamicMat.SetTexture("_ClipTex", clipTexture);
}
else if (!mLegacyShader)
{
UIPanel parentPanel = panel;
int num = 0;
while (parentPanel != null)
{
if (parentPanel.hasClipping)
{
float angle = 0f;
Vector4 drawCallClipRange2 = parentPanel.drawCallClipRange;
if (parentPanel != panel)
{
Vector3 vector2 = parentPanel.cachedTransform.InverseTransformPoint(panel.cachedTransform.position);
drawCallClipRange2.x -= vector2.x;
drawCallClipRange2.y -= vector2.y;
Vector3 eulerAngles = panel.cachedTransform.rotation.eulerAngles;
Vector3 vector3 = parentPanel.cachedTransform.rotation.eulerAngles - eulerAngles;
vector3.x = NGUIMath.WrapAngle(vector3.x);
vector3.y = NGUIMath.WrapAngle(vector3.y);
vector3.z = NGUIMath.WrapAngle(vector3.z);
if (!(Mathf.Abs(vector3.x) > 0.001f))
{
Mathf.Abs(vector3.y);
_ = 0.001f;
}
angle = vector3.z;
}
SetClipping(num++, drawCallClipRange2, parentPanel.clipSoftness, angle);
}
parentPanel = parentPanel.parentPanel;
}
}
else
{
Vector2 clipSoftness2 = panel.clipSoftness;
Vector4 drawCallClipRange3 = panel.drawCallClipRange;
Vector2 mainTextureOffset = new Vector2((0f - drawCallClipRange3.x) / drawCallClipRange3.z, (0f - drawCallClipRange3.y) / drawCallClipRange3.w);
Vector2 mainTextureScale = new Vector2(1f / drawCallClipRange3.z, 1f / drawCallClipRange3.w);
Vector2 vector4 = new Vector2(1000f, 1000f);
if (clipSoftness2.x > 0f)
{
vector4.x = drawCallClipRange3.z / clipSoftness2.x;
}
if (clipSoftness2.y > 0f)
{
vector4.y = drawCallClipRange3.w / clipSoftness2.y;
}
mDynamicMat.mainTextureOffset = mainTextureOffset;
mDynamicMat.mainTextureScale = mainTextureScale;
mDynamicMat.SetVector("_ClipSharpness", vector4);
}
}
private void SetClipping(int index, Vector4 cr, Vector2 soft, float angle)
{
angle *= -(float)Math.PI / 180f;
Vector2 vector = new Vector2(1000f, 1000f);
if (soft.x > 0f)
{
vector.x = cr.z / soft.x;
}
if (soft.y > 0f)
{
vector.y = cr.w / soft.y;
}
if (index < ClipRange.Length)
{
mDynamicMat.SetVector(ClipRange[index], new Vector4((0f - cr.x) / cr.z, (0f - cr.y) / cr.w, 1f / cr.z, 1f / cr.w));
mDynamicMat.SetVector(ClipArgs[index], new Vector4(vector.x, vector.y, Mathf.Sin(angle), Mathf.Cos(angle)));
}
}
private void Awake()
{
if (ClipRange == null)
{
ClipRange = new int[4]
{
Shader.PropertyToID("_ClipRange0"),
Shader.PropertyToID("_ClipRange1"),
Shader.PropertyToID("_ClipRange2"),
Shader.PropertyToID("_ClipRange4")
};
}
if (ClipArgs == null)
{
ClipArgs = new int[4]
{
Shader.PropertyToID("_ClipArgs0"),
Shader.PropertyToID("_ClipArgs1"),
Shader.PropertyToID("_ClipArgs2"),
Shader.PropertyToID("_ClipArgs3")
};
}
}
private void OnEnable()
{
mRebuildMat = true;
}
private void OnDisable()
{
depthStart = int.MaxValue;
depthEnd = int.MinValue;
panel = null;
manager = null;
mMaterial = null;
mTexture = null;
clipTexture = null;
if (mRenderer != null)
{
mRenderer.sharedMaterials = new Material[0];
}
NGUITools.DestroyImmediate(mDynamicMat);
mDynamicMat = null;
}
private void OnDestroy()
{
NGUITools.DestroyImmediate(mMesh);
mMesh = null;
}
public static UIDrawCall Create(UIPanel panel, Material mat, Texture tex, Shader shader)
{
return Create(null, panel, mat, tex, shader);
}
private static UIDrawCall Create(string name, UIPanel pan, Material mat, Texture tex, Shader shader)
{
UIDrawCall uIDrawCall = Create(name);
uIDrawCall.gameObject.layer = pan.cachedGameObject.layer;
uIDrawCall.baseMaterial = mat;
uIDrawCall.mainTexture = tex;
uIDrawCall.shader = shader;
uIDrawCall.renderQueue = pan.startingRenderQueue;
uIDrawCall.sortingOrder = pan.sortingOrder;
uIDrawCall.manager = pan;
return uIDrawCall;
}
private static UIDrawCall Create(string name)
{
if (mInactiveList.size > 0)
{
UIDrawCall uIDrawCall = mInactiveList.Pop();
mActiveList.Add(uIDrawCall);
if (name != null)
{
uIDrawCall.name = name;
}
NGUITools.SetActive(uIDrawCall.gameObject, state: true);
return uIDrawCall;
}
GameObject obj = new GameObject(name);
UnityEngine.Object.DontDestroyOnLoad(obj);
UIDrawCall uIDrawCall2 = obj.AddComponent<UIDrawCall>();
mActiveList.Add(uIDrawCall2);
return uIDrawCall2;
}
public static void ClearAll()
{
bool isPlaying = Application.isPlaying;
int num = mActiveList.size;
while (num > 0)
{
UIDrawCall uIDrawCall = mActiveList[--num];
if ((bool)uIDrawCall)
{
if (isPlaying)
{
NGUITools.SetActive(uIDrawCall.gameObject, state: false);
}
else
{
NGUITools.DestroyImmediate(uIDrawCall.gameObject);
}
}
}
mActiveList.Clear();
}
public static void ReleaseAll()
{
ClearAll();
ReleaseInactive();
}
public static void ReleaseInactive()
{
int num = mInactiveList.size;
while (num > 0)
{
UIDrawCall uIDrawCall = mInactiveList[--num];
if ((bool)uIDrawCall)
{
NGUITools.DestroyImmediate(uIDrawCall.gameObject);
}
}
mInactiveList.Clear();
}
public static int Count(UIPanel panel)
{
int num = 0;
for (int i = 0; i < mActiveList.size; i++)
{
if (mActiveList[i].manager == panel)
{
num++;
}
}
return num;
}
public static void Destroy(UIDrawCall dc)
{
if (!dc)
{
return;
}
dc.onRender = null;
if (Application.isPlaying)
{
if (mActiveList.Remove(dc))
{
NGUITools.SetActive(dc.gameObject, state: false);
mInactiveList.Add(dc);
}
}
else
{
mActiveList.Remove(dc);
NGUITools.DestroyImmediate(dc.gameObject);
}
}
}