881 lines
26 KiB
C#
881 lines
26 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using FairyGUI.Utils;
|
||
using Object = UnityEngine.Object;
|
||
|
||
namespace FairyGUI
|
||
{
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public class NGraphics : IMeshFactory, IBatchable
|
||
{
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public GameObject gameObject { get; private set; }
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public MeshFilter meshFilter { get; private set; }
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public MeshRenderer meshRenderer { get; private set; }
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public Mesh mesh { get; private set; }
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public BlendMode blendMode;
|
||
|
||
/// <summary>
|
||
/// 不参与剪裁
|
||
/// </summary>
|
||
public bool dontClip;
|
||
|
||
/// <summary>
|
||
/// 当Mesh更新时触发
|
||
/// </summary>
|
||
public event Action meshModifier;
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public List<NGraphics> subInstances;
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public Vector4 userData;
|
||
|
||
NTexture _texture;
|
||
string _shader;
|
||
Material _material;
|
||
int _customMatarial; //0-none, 1-common, 2-support internal mask, 128-owns material
|
||
MaterialManager _manager;
|
||
string[] _shaderKeywords;
|
||
int _materialFlags;
|
||
IMeshFactory _meshFactory;
|
||
|
||
float _alpha;
|
||
Color _color;
|
||
bool _meshDirty;
|
||
Rect _contentRect;
|
||
FlipType _flip;
|
||
|
||
public class VertexMatrix
|
||
{
|
||
public Vector3 cameraPos;
|
||
public Matrix4x4 matrix;
|
||
}
|
||
VertexMatrix _vertexMatrix;
|
||
|
||
bool hasAlphaBackup;
|
||
List<byte> _alphaBackup; //透明度改变需要通过修改顶点颜色实现,但顶点颜色本身可能就带有透明度,所以这里要有一个备份
|
||
|
||
internal int _maskFlag;
|
||
StencilEraser _stencilEraser;
|
||
|
||
MaterialPropertyBlock _propertyBlock;
|
||
bool _blockUpdated;
|
||
|
||
internal BatchElement _batchElement;
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="gameObject"></param>
|
||
public NGraphics(GameObject gameObject)
|
||
{
|
||
this.gameObject = gameObject;
|
||
|
||
_alpha = 1f;
|
||
_shader = ShaderConfig.imageShader;
|
||
_color = Color.white;
|
||
_meshFactory = this;
|
||
|
||
meshFilter = gameObject.AddComponent<MeshFilter>();
|
||
meshRenderer = gameObject.AddComponent<MeshRenderer>();
|
||
meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
|
||
meshRenderer.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off;
|
||
meshRenderer.receiveShadows = false;
|
||
|
||
mesh = new Mesh();
|
||
mesh.name = gameObject.name;
|
||
mesh.MarkDynamic();
|
||
|
||
meshFilter.mesh = mesh;
|
||
|
||
meshFilter.hideFlags = DisplayObject.hideFlags;
|
||
meshRenderer.hideFlags = DisplayObject.hideFlags;
|
||
mesh.hideFlags = DisplayObject.hideFlags;
|
||
|
||
Stats.LatestGraphicsCreation++;
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public IMeshFactory meshFactory
|
||
{
|
||
get { return _meshFactory; }
|
||
set
|
||
{
|
||
if (_meshFactory != value)
|
||
{
|
||
_meshFactory = value;
|
||
_meshDirty = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <returns></returns>
|
||
public T GetMeshFactory<T>() where T : IMeshFactory, new()
|
||
{
|
||
if (!(_meshFactory is T))
|
||
{
|
||
_meshFactory = new T();
|
||
_meshDirty = true;
|
||
}
|
||
return (T)_meshFactory;
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public Rect contentRect
|
||
{
|
||
get { return _contentRect; }
|
||
set
|
||
{
|
||
_contentRect = value;
|
||
_meshDirty = true;
|
||
|
||
if (subInstances != null)
|
||
{
|
||
foreach (var sub in subInstances)
|
||
sub.contentRect = value;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public FlipType flip
|
||
{
|
||
get { return _flip; }
|
||
set
|
||
{
|
||
if (_flip != value)
|
||
{
|
||
_flip = value;
|
||
_meshDirty = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public NTexture texture
|
||
{
|
||
get { return _texture; }
|
||
set
|
||
{
|
||
if (_texture != value)
|
||
{
|
||
if (value != null)
|
||
value.AddRef();
|
||
if (_texture != null)
|
||
_texture.ReleaseRef();
|
||
|
||
_texture = value;
|
||
if (_customMatarial != 0 && _material != null)
|
||
_material.mainTexture = _texture != null ? _texture.nativeTexture : null;
|
||
_meshDirty = true;
|
||
UpdateManager();
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public string shader
|
||
{
|
||
get { return _shader; }
|
||
set
|
||
{
|
||
_shader = value;
|
||
UpdateManager();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="shader"></param>
|
||
/// <param name="texture"></param>
|
||
public void SetShaderAndTexture(string shader, NTexture texture)
|
||
{
|
||
_shader = shader;
|
||
if (_texture != texture)
|
||
this.texture = texture;
|
||
else
|
||
UpdateManager();
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public Material material
|
||
{
|
||
get
|
||
{
|
||
if (_customMatarial == 0 && _material == null && _manager != null)
|
||
_material = _manager.GetMaterial(_materialFlags, blendMode, 0);
|
||
return _material;
|
||
}
|
||
set
|
||
{
|
||
if ((_customMatarial & 128) != 0 && _material != null)
|
||
Object.DestroyImmediate(_material);
|
||
|
||
_material = value;
|
||
if (_material != null)
|
||
{
|
||
_customMatarial = 1;
|
||
if (_material.HasProperty(ShaderConfig.ID_Stencil) || _material.HasProperty(ShaderConfig.ID_ClipBox))
|
||
_customMatarial |= 2;
|
||
|
||
meshRenderer.sharedMaterial = _material;
|
||
if (_texture != null)
|
||
_material.mainTexture = _texture.nativeTexture;
|
||
}
|
||
else
|
||
{
|
||
_customMatarial = 0;
|
||
meshRenderer.sharedMaterial = null;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Same as material property except that ownership is transferred to this object.
|
||
/// </summary>
|
||
/// <param name="material"></param>
|
||
public void SetMaterial(Material material)
|
||
{
|
||
this.material = material;
|
||
_customMatarial |= 128;
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public string[] materialKeywords
|
||
{
|
||
get { return _shaderKeywords; }
|
||
set
|
||
{
|
||
_shaderKeywords = value;
|
||
UpdateMaterialFlags();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="keyword"></param>
|
||
/// <param name="enabled"></param>
|
||
public void ToggleKeyword(string keyword, bool enabled)
|
||
{
|
||
if (enabled)
|
||
{
|
||
if (_shaderKeywords == null)
|
||
{
|
||
_shaderKeywords = new string[] { keyword };
|
||
UpdateMaterialFlags();
|
||
}
|
||
else if (Array.IndexOf(_shaderKeywords, keyword) == -1)
|
||
{
|
||
Array.Resize(ref _shaderKeywords, _shaderKeywords.Length + 1);
|
||
_shaderKeywords[_shaderKeywords.Length - 1] = keyword;
|
||
UpdateMaterialFlags();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (_shaderKeywords != null)
|
||
{
|
||
int i = Array.IndexOf(_shaderKeywords, keyword);
|
||
if (i != -1)
|
||
{
|
||
_shaderKeywords[i] = null;
|
||
UpdateMaterialFlags();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void UpdateManager()
|
||
{
|
||
if (_texture != null)
|
||
_manager = _texture.GetMaterialManager(_shader);
|
||
else
|
||
_manager = null;
|
||
UpdateMaterialFlags();
|
||
}
|
||
|
||
void UpdateMaterialFlags()
|
||
{
|
||
if (_customMatarial != 0)
|
||
{
|
||
if (material != null)
|
||
material.shaderKeywords = _shaderKeywords;
|
||
}
|
||
else if (_shaderKeywords != null && _manager != null)
|
||
_materialFlags = _manager.GetFlagsByKeywords(_shaderKeywords);
|
||
else
|
||
_materialFlags = 0;
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public bool enabled
|
||
{
|
||
get { return meshRenderer.enabled; }
|
||
set { meshRenderer.enabled = value; }
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
[Obsolete("Use renderingOrder")]
|
||
public int sortingOrder
|
||
{
|
||
get { return meshRenderer.sortingOrder; }
|
||
set { meshRenderer.sortingOrder = value; }
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public int renderingOrder
|
||
{
|
||
get { return meshRenderer.sortingOrder; }
|
||
set { meshRenderer.sortingOrder = value; }
|
||
}
|
||
|
||
public void SetRenderingOrder(UpdateContext context, bool inBatch)
|
||
{
|
||
meshRenderer.sortingOrder = context.renderingOrder++;
|
||
|
||
if (subInstances != null && !inBatch)
|
||
{
|
||
foreach (var sub in subInstances)
|
||
{
|
||
sub.meshRenderer.sortingOrder = context.renderingOrder++;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="value"></param>
|
||
internal void _SetStencilEraserOrder(int value)
|
||
{
|
||
_stencilEraser.meshRenderer.sortingOrder = value;
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="value"></param>
|
||
public Color color
|
||
{
|
||
get { return _color; }
|
||
set { _color = value; }
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public void Tint()
|
||
{
|
||
if (_meshDirty)
|
||
return;
|
||
|
||
int vertCount = mesh.vertexCount;
|
||
if (vertCount == 0)
|
||
return;
|
||
|
||
VertexBuffer vb = VertexBuffer.Begin();
|
||
mesh.GetColors(vb.colors);
|
||
List<Color32> colors = vb.colors;
|
||
for (int i = 0; i < vertCount; i++)
|
||
{
|
||
Color32 col = _color;
|
||
col.a = (byte)(_alpha * (hasAlphaBackup ? _alphaBackup[i] : (byte)255));
|
||
colors[i] = col;
|
||
}
|
||
|
||
mesh.SetColors(vb.colors);
|
||
vb.End();
|
||
}
|
||
|
||
void ChangeAlpha(float value)
|
||
{
|
||
_alpha = value;
|
||
|
||
int vertCount = mesh.vertexCount;
|
||
if (vertCount == 0)
|
||
return;
|
||
|
||
VertexBuffer vb = VertexBuffer.Begin();
|
||
mesh.GetColors(vb.colors);
|
||
List<Color32> colors = vb.colors;
|
||
for (int i = 0; i < vertCount; i++)
|
||
{
|
||
Color32 col = colors[i];
|
||
col.a = (byte)(_alpha * (hasAlphaBackup ? _alphaBackup[i] : (byte)255));
|
||
colors[i] = col;
|
||
}
|
||
|
||
mesh.SetColors(vb.colors);
|
||
vb.End();
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public VertexMatrix vertexMatrix
|
||
{
|
||
get { return _vertexMatrix; }
|
||
set
|
||
{
|
||
_vertexMatrix = value;
|
||
_meshDirty = true;
|
||
|
||
if (subInstances != null)
|
||
{
|
||
foreach (var sub in subInstances)
|
||
sub._vertexMatrix = value;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public MaterialPropertyBlock materialPropertyBlock
|
||
{
|
||
get
|
||
{
|
||
if (_propertyBlock == null)
|
||
_propertyBlock = new MaterialPropertyBlock();
|
||
|
||
_blockUpdated = true;
|
||
return _propertyBlock;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public void SetMeshDirty()
|
||
{
|
||
_meshDirty = true;
|
||
|
||
if (subInstances != null)
|
||
{
|
||
foreach (var g in subInstances)
|
||
g._meshDirty = true;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public bool UpdateMesh()
|
||
{
|
||
bool ret = false;
|
||
if (_meshDirty)
|
||
{
|
||
UpdateMeshNow();
|
||
ret = true;
|
||
}
|
||
|
||
if (subInstances != null)
|
||
{
|
||
foreach (var g in subInstances)
|
||
{
|
||
if (g.UpdateMesh())
|
||
ret = true;
|
||
}
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
public void Dispose()
|
||
{
|
||
if (mesh != null)
|
||
{
|
||
if (Application.isPlaying)
|
||
Object.Destroy(mesh);
|
||
else
|
||
Object.DestroyImmediate(mesh);
|
||
mesh = null;
|
||
}
|
||
if ((_customMatarial & 128) != 0 && _material != null)
|
||
Object.DestroyImmediate(_material);
|
||
|
||
if (_texture != null)
|
||
{
|
||
_texture.ReleaseRef();
|
||
_texture = null;
|
||
}
|
||
|
||
_manager = null;
|
||
_material = null;
|
||
meshRenderer = null;
|
||
meshFilter = null;
|
||
_stencilEraser = null;
|
||
meshModifier = null;
|
||
|
||
if (subInstances != null)
|
||
{
|
||
foreach (var sub in subInstances)
|
||
sub.Dispose();
|
||
subInstances.Clear();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="context"></param>
|
||
/// <param name="alpha"></param>
|
||
/// <param name="grayed"></param>
|
||
public void Update(UpdateContext context, float alpha, bool grayed)
|
||
{
|
||
Stats.GraphicsCount++;
|
||
|
||
if (_meshDirty)
|
||
{
|
||
_alpha = alpha;
|
||
UpdateMeshNow();
|
||
}
|
||
else if (_alpha != alpha)
|
||
ChangeAlpha(alpha);
|
||
|
||
if (_propertyBlock != null && _blockUpdated)
|
||
{
|
||
meshRenderer.SetPropertyBlock(_propertyBlock);
|
||
_blockUpdated = false;
|
||
}
|
||
|
||
if (_customMatarial != 0)
|
||
{
|
||
if ((_customMatarial & 2) != 0 && _material != null)
|
||
context.ApplyClippingProperties(_material, false);
|
||
}
|
||
else
|
||
{
|
||
if (_manager != null)
|
||
{
|
||
if (_maskFlag == 1)
|
||
{
|
||
_material = _manager.GetMaterial((int)MaterialFlags.AlphaMask | _materialFlags, BlendMode.Normal, context.clipInfo.clipId);
|
||
context.ApplyAlphaMaskProperties(_material, false);
|
||
}
|
||
else
|
||
{
|
||
int matFlags = _materialFlags;
|
||
if (grayed)
|
||
matFlags |= (int)MaterialFlags.Grayed;
|
||
|
||
if (context.clipped)
|
||
{
|
||
if (context.stencilReferenceValue > 0)
|
||
matFlags |= (int)MaterialFlags.StencilTest;
|
||
if (context.rectMaskDepth > 0)
|
||
{
|
||
if (context.clipInfo.soft)
|
||
matFlags |= (int)MaterialFlags.SoftClipped;
|
||
else
|
||
matFlags |= (int)MaterialFlags.Clipped;
|
||
}
|
||
|
||
_material = _manager.GetMaterial(matFlags, blendMode, context.clipInfo.clipId);
|
||
if (_manager.firstMaterialInFrame)
|
||
context.ApplyClippingProperties(_material, true);
|
||
}
|
||
else
|
||
_material = _manager.GetMaterial(matFlags, blendMode, 0);
|
||
}
|
||
}
|
||
else
|
||
_material = null;
|
||
|
||
if (!Material.ReferenceEquals(_material, meshRenderer.sharedMaterial))
|
||
meshRenderer.sharedMaterial = _material;
|
||
}
|
||
|
||
if (_maskFlag != 0)
|
||
{
|
||
if (_maskFlag == 1)
|
||
_maskFlag = 2;
|
||
else
|
||
{
|
||
if (_stencilEraser != null)
|
||
_stencilEraser.enabled = false;
|
||
|
||
_maskFlag = 0;
|
||
}
|
||
}
|
||
|
||
if (subInstances != null)
|
||
{
|
||
foreach (var sub in subInstances)
|
||
sub.Update(context, alpha, grayed);
|
||
}
|
||
}
|
||
|
||
internal void _PreUpdateMask(UpdateContext context, uint maskId)
|
||
{
|
||
//_maskFlag: 0-new mask, 1-active mask, 2-mask complete
|
||
if (_maskFlag == 0)
|
||
{
|
||
if (_stencilEraser == null)
|
||
{
|
||
_stencilEraser = new StencilEraser(gameObject.transform);
|
||
_stencilEraser.meshFilter.mesh = mesh;
|
||
}
|
||
else
|
||
_stencilEraser.enabled = true;
|
||
}
|
||
|
||
_maskFlag = 1;
|
||
|
||
if (_manager != null)
|
||
{
|
||
//这里使用maskId而不是clipInfo.clipId,是因为遮罩有两个用途,一个是写入遮罩,一个是擦除,两个不能用同一个材质
|
||
Material mat = _manager.GetMaterial((int)MaterialFlags.AlphaMask | _materialFlags, BlendMode.Normal, maskId);
|
||
if (!Material.ReferenceEquals(mat, _stencilEraser.meshRenderer.sharedMaterial))
|
||
_stencilEraser.meshRenderer.sharedMaterial = mat;
|
||
|
||
context.ApplyAlphaMaskProperties(mat, true);
|
||
}
|
||
}
|
||
|
||
void UpdateMeshNow()
|
||
{
|
||
_meshDirty = false;
|
||
|
||
if (_texture == null || _meshFactory == null)
|
||
{
|
||
if (mesh.vertexCount > 0)
|
||
{
|
||
mesh.Clear();
|
||
|
||
if (meshModifier != null)
|
||
meshModifier();
|
||
}
|
||
return;
|
||
}
|
||
|
||
VertexBuffer vb = VertexBuffer.Begin();
|
||
vb.contentRect = _contentRect;
|
||
vb.uvRect = _texture.uvRect;
|
||
if (_texture != null)
|
||
vb.textureSize = new Vector2(_texture.width, _texture.height);
|
||
else
|
||
vb.textureSize = new Vector2(0, 0);
|
||
if (_flip != FlipType.None)
|
||
{
|
||
if (_flip == FlipType.Horizontal || _flip == FlipType.Both)
|
||
{
|
||
float tmp = vb.uvRect.xMin;
|
||
vb.uvRect.xMin = vb.uvRect.xMax;
|
||
vb.uvRect.xMax = tmp;
|
||
}
|
||
if (_flip == FlipType.Vertical || _flip == FlipType.Both)
|
||
{
|
||
float tmp = vb.uvRect.yMin;
|
||
vb.uvRect.yMin = vb.uvRect.yMax;
|
||
vb.uvRect.yMax = tmp;
|
||
}
|
||
}
|
||
vb.vertexColor = _color;
|
||
_meshFactory.OnPopulateMesh(vb);
|
||
|
||
int vertCount = vb.currentVertCount;
|
||
if (vertCount == 0)
|
||
{
|
||
if (mesh.vertexCount > 0)
|
||
{
|
||
mesh.Clear();
|
||
|
||
if (meshModifier != null)
|
||
meshModifier();
|
||
}
|
||
vb.End();
|
||
return;
|
||
}
|
||
|
||
if (_texture.rotated)
|
||
{
|
||
float xMin = _texture.uvRect.xMin;
|
||
float yMin = _texture.uvRect.yMin;
|
||
float yMax = _texture.uvRect.yMax;
|
||
float tmp;
|
||
for (int i = 0; i < vertCount; i++)
|
||
{
|
||
Vector2 vec = vb.uvs[i];
|
||
tmp = vec.y;
|
||
vec.y = yMin + vec.x - xMin;
|
||
vec.x = xMin + yMax - tmp;
|
||
vb.uvs[i] = vec;
|
||
}
|
||
}
|
||
|
||
hasAlphaBackup = vb._alphaInVertexColor;
|
||
if (hasAlphaBackup)
|
||
{
|
||
if (_alphaBackup == null)
|
||
_alphaBackup = new List<byte>();
|
||
else
|
||
_alphaBackup.Clear();
|
||
for (int i = 0; i < vertCount; i++)
|
||
{
|
||
Color32 col = vb.colors[i];
|
||
_alphaBackup.Add(col.a);
|
||
|
||
col.a = (byte)(col.a * _alpha);
|
||
vb.colors[i] = col;
|
||
}
|
||
}
|
||
else if (_alpha != 1)
|
||
{
|
||
for (int i = 0; i < vertCount; i++)
|
||
{
|
||
Color32 col = vb.colors[i];
|
||
col.a = (byte)(col.a * _alpha);
|
||
vb.colors[i] = col;
|
||
}
|
||
}
|
||
|
||
if (_vertexMatrix != null)
|
||
{
|
||
Vector3 camPos = _vertexMatrix.cameraPos;
|
||
Vector3 center = new Vector3(camPos.x, camPos.y, 0);
|
||
center -= _vertexMatrix.matrix.MultiplyPoint(center);
|
||
for (int i = 0; i < vertCount; i++)
|
||
{
|
||
Vector3 pt = vb.vertices[i];
|
||
pt = _vertexMatrix.matrix.MultiplyPoint(pt);
|
||
pt += center;
|
||
Vector3 vec = pt - camPos;
|
||
float lambda = -camPos.z / vec.z;
|
||
pt.x = camPos.x + lambda * vec.x;
|
||
pt.y = camPos.y + lambda * vec.y;
|
||
pt.z = 0;
|
||
|
||
vb.vertices[i] = pt;
|
||
}
|
||
}
|
||
|
||
mesh.Clear();
|
||
mesh.SetVertices(vb.vertices);
|
||
if (vb._isArbitraryQuad)
|
||
mesh.SetUVs(0, vb.FixUVForArbitraryQuad());
|
||
else
|
||
mesh.SetUVs(0, vb.uvs);
|
||
mesh.SetColors(vb.colors);
|
||
mesh.SetTriangles(vb.triangles, 0);
|
||
if (vb.uvs2.Count == vb.uvs.Count)
|
||
mesh.SetUVs(1, vb.uvs2);
|
||
vb.End();
|
||
|
||
if (meshModifier != null)
|
||
meshModifier();
|
||
}
|
||
|
||
public void OnPopulateMesh(VertexBuffer vb)
|
||
{
|
||
Rect rect = texture.GetDrawRect(vb.contentRect, flip);
|
||
|
||
vb.AddQuad(rect, vb.vertexColor, vb.uvRect);
|
||
vb.AddTriangles();
|
||
vb._isArbitraryQuad = _vertexMatrix != null;
|
||
}
|
||
|
||
public NGraphics CreateSubInstance(string name)
|
||
{
|
||
if (subInstances == null)
|
||
subInstances = new List<NGraphics>();
|
||
|
||
GameObject newGameObject = new GameObject(name);
|
||
newGameObject.transform.SetParent(gameObject.transform, false);
|
||
newGameObject.layer = gameObject.layer;
|
||
newGameObject.hideFlags = gameObject.hideFlags;
|
||
|
||
var newGraphics = new NGraphics(newGameObject);
|
||
newGraphics._vertexMatrix = _vertexMatrix;
|
||
return newGraphics;
|
||
}
|
||
|
||
class StencilEraser
|
||
{
|
||
public GameObject gameObject;
|
||
public MeshFilter meshFilter;
|
||
public MeshRenderer meshRenderer;
|
||
|
||
public StencilEraser(Transform parent)
|
||
{
|
||
gameObject = new GameObject("StencilEraser");
|
||
gameObject.transform.SetParent(parent, false);
|
||
|
||
meshFilter = gameObject.AddComponent<MeshFilter>();
|
||
meshRenderer = gameObject.AddComponent<MeshRenderer>();
|
||
meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
|
||
meshRenderer.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off;
|
||
meshRenderer.receiveShadows = false;
|
||
|
||
gameObject.layer = parent.gameObject.layer;
|
||
gameObject.hideFlags = parent.gameObject.hideFlags;
|
||
meshFilter.hideFlags = parent.gameObject.hideFlags;
|
||
meshRenderer.hideFlags = parent.gameObject.hideFlags;
|
||
}
|
||
|
||
public bool enabled
|
||
{
|
||
get { return meshRenderer.enabled; }
|
||
set { meshRenderer.enabled = value; }
|
||
}
|
||
}
|
||
}
|
||
}
|