using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Pool;
using UnityEngine.UI;
namespace XericLibrary.Runtime.UIGraph
{
///
/// 自定义渲染组件
///
[RequireComponent(typeof(CanvasRenderer))]
public class XericRendererComponent : MaskableGraphic
{
public virtual string ShaderName => "Hidden/Texture2D";
#region 字段属性
// 原始数据
private readonly List _vertexList = new List();
private readonly List _indexList = new List();
// 阵列原点
private List _arrayTransformList = new List();
// 中间数据
private List _temp_vertexList = new List();
private List _temp_indexList = new List();
private bool _dirty;
#endregion
#if UNITY_EDITOR
protected override void OnValidate()
{
base.OnValidate();
if (m_Material == null)
material = new Material(Shader.Find(ShaderName));
}
#endif
#region 绘制
///
/// 刷新
///
public virtual void Refresh()
{
SetVerticesDirty();
}
///
/// ui模型填充流程
///
///
protected override void OnPopulateMesh(VertexHelper vh)
{
if (vh == null) return;
vh.Clear();
ClearCache();
// 填充图元
OnPopulatePrefabricateVertex(_vertexList, _indexList);
// 阵列
ArrayVertexList(_arrayTransformList);
// 将顶点填充到mesh
vh.AddUIVertexStream(_temp_vertexList, _temp_indexList);
}
///
/// 填充预制顶点
///
/// 顶点列表
/// 三角面索引
protected virtual void OnPopulatePrefabricateVertex(List vertexList, List indexList)
{
}
///
/// 清除所有缓存
///
protected void ClearCache()
{
_vertexList.Clear();
_indexList.Clear();
}
///
/// 添加一个阵列节点
///
/// 偏移
/// 角度
public int AddArrayModifier(Vector3 offset, float angle)
{
var index = _arrayTransformList.Count;
_arrayTransformList.Add(new Vector4(offset.x, offset.y, offset.z, angle));
Refresh();
return index;
}
///
/// 清空阵列节点
///
public void ClearArrayModifier()
{
_arrayTransformList.Clear();
Refresh();
}
public bool ModifyArrayModifier(int index, Vector3 offset, float angle)
{
if (index < 0 || index >= _arrayTransformList.Count)
return false;
_arrayTransformList[index] = new Vector4(offset.x, offset.y, offset.z, angle);
Refresh();
return true;
}
#endregion
#region 阵列
///
/// 根据原点阵列
///
///
///
protected void ArrayVertexList(List trans)
{
_temp_vertexList.Clear();
_temp_indexList.Clear();
if (trans == null || trans.Count == 0)
{
Copy();
return;
}
for (int i = 0; i < trans.Count; i++)
Copy2(i, trans[i]);
void Copy()
{
_temp_vertexList.AddRange(_vertexList.GetRange(0, _vertexList.Count));
_temp_indexList.AddRange(_indexList.GetRange(0, _indexList.Count));
}
void Copy2(int index, Vector4 transform)
{
_temp_vertexList.AddRange(_vertexList.Select(a =>
{
var newPos = a.position;
if (transform.w != 0)
{
var rot = Quaternion.Euler(0, 0, transform.w);
newPos = rot * newPos;
}
newPos += (Vector3)transform;
return new UIVertex()
{
position = newPos,
normal = a.normal,
tangent = a.tangent,
color = a.color,
uv0 = a.uv0,
uv1 = a.uv1,
uv2 = a.uv2,
uv3 = a.uv3,
};
}));
_temp_indexList.AddRange(_indexList.Select(a => index * _vertexList.Count + a));
}
}
#endregion
}
}