// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.Collections.Generic;
using UnityEngine;
namespace Microsoft.MixedReality.Toolkit.Utilities
{
///
/// Creates instances of a mesh along the line
///
[AddComponentMenu("Scripts/MRTK/Core/MeshLineRenderer")]
public class MeshLineRenderer : BaseMixedRealityLineRenderer
{
[Header("Instanced Mesh Settings")]
[SerializeField]
private Mesh lineMesh = null;
public Mesh LineMesh
{
get { return lineMesh; }
set
{
enabled = false;
lineMesh = value;
enabled = true;
}
}
[SerializeField]
private Material lineMaterial = null;
public Material LineMaterial
{
get { return lineMaterial; }
set
{
enabled = false;
lineMaterial = value;
enabled = true;
}
}
[SerializeField]
private string colorProperty = "_Color";
[SerializeField]
[Tooltip("How many line steps to skip before a mesh is drawn")]
[Range(0, 10)]
private int lineStepSkip = 0;
[SerializeField]
private bool useVertexColors = true;
public string ColorProperty
{
get { return colorProperty; }
set
{
enabled = false;
colorProperty = value;
if (!lineMaterial.HasProperty(value))
{
Debug.LogError($"Unable to find the property {value} for the line material");
return;
}
enabled = true;
}
}
private bool IsInitialized
{
get
{
if (lineMaterial != null && lineMesh != null && lineMaterial.HasProperty(colorProperty))
return true;
Debug.Assert(lineMesh != null, "Missing assigned line mesh.");
Debug.Assert(lineMaterial != null, "Missing assigned line material.");
Debug.Assert((lineMaterial != null && lineMaterial.HasProperty(colorProperty)), $"Unable to find the property \"{colorProperty}\" for the line material");
return false;
}
}
private int colorId;
private List colorValues = new List();
private List meshTransforms = new List();
private MaterialPropertyBlock linePropertyBlock;
protected virtual void OnEnable()
{
if (!IsInitialized)
{
enabled = false;
return;
}
if (linePropertyBlock == null)
{
linePropertyBlock = new MaterialPropertyBlock();
}
lineMaterial.enableInstancing = true;
}
protected override void UpdateLine()
{
if (!Application.isPlaying)
{ // This check is only necessary in edit mode.
if (!IsInitialized)
{
enabled = false;
return;
}
}
if (LineDataSource.enabled)
{
meshTransforms.Clear();
colorValues.Clear();
linePropertyBlock.Clear();
int skipCount = 0;
for (int i = 0; i < LineStepCount; i++)
{
if (lineStepSkip > 0)
{
skipCount++;
if (skipCount < lineStepSkip)
continue;
skipCount = 0;
}
float normalizedDistance = GetNormalizedPointAlongLine(i);
colorValues.Add(GetColor(normalizedDistance));
meshTransforms.Add(Matrix4x4.TRS(LineDataSource.GetPoint(normalizedDistance), LineDataSource.GetRotation(normalizedDistance), Vector3.one * GetWidth(normalizedDistance)));
}
if (useVertexColors)
{
colorId = Shader.PropertyToID(colorProperty);
linePropertyBlock.SetVectorArray(colorId, colorValues);
}
Graphics.DrawMeshInstanced(lineMesh, 0, lineMaterial, meshTransforms, linePropertyBlock);
}
}
}
}