/// <summary> /// Ensures the mesh data for the renderer is created, and updates it if neccessary /// </summary> /// <param name="force">Whether or not to force a full rebuild of the mesh data</param> /// <returns>True if an initialization occurred, false if it was skipped</returns> protected bool Initialize(bool force = false) { if (m_Positions == null) { return(false); } var performFullInitialize = force; // For a line renderer we assume one big chain // We need a control point for each billboard and a control point for each pipe connecting them together // Except for the end, which must be capped with another billboard. This gives us (positions * 2) - 1 var neededPoints = Mathf.Max((m_Positions.Length * 2) - 1, 0); if (m_MeshData == null) { m_MeshData = new VRLineRendererInternal.MeshChain(); } if (m_MeshData.reservedElements != neededPoints) { m_MeshData.worldSpaceData = useWorldSpace; m_MeshData.GenerateMesh(gameObject, true, neededPoints); performFullInitialize = true; } if (performFullInitialize == false) { return(false); } if (neededPoints == 0) { return(true); } var pointCounter = 0; var elementCounter = 0; // Initialize the single starting point m_MeshData.SetElementSize(elementCounter, m_WidthStart); m_MeshData.SetElementPosition(elementCounter, ref m_Positions[pointCounter]); m_MeshData.SetElementColor(elementCounter, ref m_ColorStart); elementCounter++; pointCounter++; float stepSize = 1.0f / Mathf.Max((m_Positions.Length - 1.0f), 1.0f); float stepPercent = stepSize; var lastWidth = m_WidthStart; var lastColor = m_ColorStart; // Now do the chain while (pointCounter < m_Positions.Length) { var currentWidth = Mathf.Lerp(m_WidthStart, m_WidthEnd, stepPercent); var currentColor = Color.Lerp(m_ColorStart, m_ColorEnd, stepPercent); // Create a pipe from the previous point to here m_MeshData.SetElementSize(elementCounter, lastWidth, currentWidth); m_MeshData.SetElementPipe(elementCounter, ref m_Positions[pointCounter - 1], ref m_Positions[pointCounter]); m_MeshData.SetElementColor(elementCounter, ref lastColor, ref currentColor); elementCounter++; // Now record our own point data m_MeshData.SetElementSize(elementCounter, currentWidth); m_MeshData.SetElementPosition(elementCounter, ref m_Positions[pointCounter]); m_MeshData.SetElementColor(elementCounter, ref currentColor); // Go onto the next point while retaining previous values we might need to lerp between lastWidth = currentWidth; lastColor = currentColor; elementCounter++; pointCounter++; stepPercent += stepSize; } // Dirty all the MeshChain flags so everything gets refreshed m_MeshData.SetMeshDataDirty(VRLineRendererInternal.MeshChain.MeshRefreshFlag.All); m_MeshNeedsRefreshing = true; return(true); }
/// <summary> /// Ensures the mesh data for the renderer is created, and updates it if neccessary /// </summary> /// <param name="force">Whether or not to force a full rebuild of the mesh data</param> /// <returns>True if an initialization occurred, false if it was skipped</returns> protected bool Initialize() { m_MaxTrailPoints = Mathf.Max(m_MaxTrailPoints, 3); // If we have a point mismatch, we force this operation if (m_Points != null && m_MaxTrailPoints == m_Points.Length) { return(false); } m_Points = new Vector3[m_MaxTrailPoints]; m_PointTimes = new float[m_MaxTrailPoints]; Clear(); if (m_Colors == null || m_Colors.Length == 0) { m_Colors = new Color[1]; m_Colors[0] = Color.white; } // For a trail renderer we assume one big chain // We need a control point for each billboard and a control point for each pipe connecting them together // We make this a circular trail so the update logic is easier. This gives us (position * 2) var neededPoints = Mathf.Max((m_MaxTrailPoints * 2), 0); if (m_MeshData == null) { m_MeshData = new VRLineRendererInternal.MeshChain(); } if (m_MeshData.reservedElements != neededPoints) { m_MeshData.worldSpaceData = true; m_MeshData.GenerateMesh(gameObject, true, neededPoints); if (neededPoints == 0) { return(true); } var pointCounter = 0; var elementCounter = 0; var zeroVec = Vector3.zero; var zeroColor = new Color(0, 0, 0, 0); // Initialize everything to 0 so we don't render any trails at first m_MeshData.SetElementColor(0, ref zeroColor); while (pointCounter < m_Points.Length) { // Start point m_MeshData.SetElementSize(elementCounter, 0); m_MeshData.SetElementPosition(elementCounter, ref zeroVec); elementCounter++; // Pipe to the next point m_MeshData.SetElementSize(elementCounter, 0); m_MeshData.SetElementPipe(elementCounter, ref zeroVec, ref zeroVec); // Go onto the next point while retaining previous values we might need to lerp between elementCounter++; pointCounter++; } // Dirty all the MeshChain flags so everything gets refreshed m_MeshRenderer.enabled = false; m_MeshData.SetMeshDataDirty(VRLineRendererInternal.MeshChain.MeshRefreshFlag.All); m_MeshNeedsRefreshing = true; } return(true); }