示例#1
0
    /// <summary>
    /// Sets the position of the vertex in the line.
    /// </summary>
    public void SetPosition(int index, Vector3 position)
    {
        // Update internal data
        m_Positions[index] = position;

        // See if the data needs initializing
        if (Initialize())
        {
            return;
        }

        // Otherwise, do fast setting
        if (index > 0)
        {
            m_MeshData.SetElementPipe((index * 2) - 1, ref m_Positions[index - 1], ref m_Positions[index]);
        }
        m_MeshData.SetElementPosition(index * 2, ref m_Positions[index]);
        if (index < (m_Positions.Length - 1))
        {
            m_MeshData.SetElementPipe((index * 2) + 1, ref m_Positions[index], ref m_Positions[index + 1]);
        }
        m_MeshData.SetMeshDataDirty(VRLineRendererInternal.MeshChain.MeshRefreshFlag.Positions);
        m_MeshNeedsRefreshing = true;
    }
    /// <summary>
    /// Updates the built-in mesh data for each control point of the trail
    /// </summary>
    void LateUpdate()
    {
        // We do  the actual internal mesh updating as late as possible so nothing ends up a frame behind
        var deltaTime = Time.deltaTime;

        // We give the editor a little help with handling delta time in edit mode
        if (Application.isPlaying == false)
        {
            deltaTime           = Time.realtimeSinceStartup - m_EditorDeltaHelper;
            m_EditorDeltaHelper = Time.realtimeSinceStartup;
        }

        // Get the current position of the renderer
        var currentPoint  = transform.position;
        var pointDistance = (currentPoint - m_LastRecordedPoint).sqrMagnitude;

        // Is it more than minVertexDistance from the last position?
        if (pointDistance > (m_MinVertexDistance * m_MinVertexDistance))
        {
            // In the situation we have no points, we need to record the start point as well
            if (m_PointIndexStart == m_PointIndexEnd)
            {
                m_Points[m_PointIndexStart]     = m_LastRecordedPoint;
                m_PointTimes[m_PointIndexStart] = m_Time;
            }

            // Make space for a new point
            var newEndIndex = (m_PointIndexEnd + 1) % m_MaxTrailPoints;

            // In the situation that we are rendering all available vertices
            // We can either keep using the current point, or take the last point, depending on the user's preference
            if (newEndIndex != m_PointIndexStart)
            {
                m_PointIndexEnd = newEndIndex;
                m_PointTimes[m_PointIndexEnd] = 0;
                m_UsedPoints++;
            }
            else
            {
                if (m_StealLastPointWhenEmpty)
                {
                    m_MeshData.SetElementSize(m_PointIndexStart * 2, 0);
                    m_MeshData.SetElementSize((m_PointIndexStart * 2) + 1, 0);
                    m_PointIndexStart             = (m_PointIndexStart + 1) % m_MaxTrailPoints;
                    m_PointIndexEnd               = newEndIndex;
                    m_PointTimes[m_PointIndexEnd] = 0;
                    m_LastPointTime               = m_PointTimes[m_PointIndexStart];
                }
            }

            m_Points[m_PointIndexEnd] = currentPoint;

            // Update the last recorded point
            m_LastRecordedPoint = currentPoint;
        }
        // Do time processing
        // The end point counts up to a maximum of 'time'
        m_PointTimes[m_PointIndexEnd] = Mathf.Min(m_PointTimes[m_PointIndexEnd] + deltaTime, m_Time);

        if (m_PointIndexStart != m_PointIndexEnd)
        {
            // Run down the counter on the start point
            m_PointTimes[m_PointIndexStart] -= deltaTime;

            // If we've hit 0, this point is done for
            if (m_PointTimes[m_PointIndexStart] <= 0.0f)
            {
                m_MeshData.SetElementSize(m_PointIndexStart * 2, 0);
                m_MeshData.SetElementSize((m_PointIndexStart * 2) + 1, 0);
                m_PointIndexStart = (m_PointIndexStart + 1) % m_MaxTrailPoints;
                m_LastPointTime   = m_PointTimes[m_PointIndexStart];
                m_UsedPoints--;
            }
        }

        if (m_PointIndexStart != m_PointIndexEnd)
        {
            m_MeshNeedsRefreshing  = true;
            m_MeshRenderer.enabled = true;
        }
        else
        {
            m_MeshNeedsRefreshing  = false;
            m_MeshRenderer.enabled = false;
        }
        if (m_MeshNeedsRefreshing == true)
        {
            m_MeshRenderer.enabled = true;

            // Update first and last points position-wise
            var nextIndex = (m_PointIndexStart + 1) % m_MaxTrailPoints;
            if (m_SmoothInterpolation)
            {
                var toNextPoint = 1.0f - (m_PointTimes[m_PointIndexStart] / m_LastPointTime);
                var lerpPoint   = Vector3.Lerp(m_Points[m_PointIndexStart], m_Points[nextIndex], toNextPoint);
                m_MeshData.SetElementPosition((m_PointIndexStart * 2), ref lerpPoint);
                m_MeshData.SetElementPipe((m_PointIndexStart * 2) + 1, ref lerpPoint, ref m_Points[nextIndex]);
            }
            else
            {
                m_MeshData.SetElementPosition((m_PointIndexStart * 2), ref m_Points[m_PointIndexStart]);
                m_MeshData.SetElementPipe((m_PointIndexStart * 2) + 1, ref m_Points[m_PointIndexStart], ref m_Points[nextIndex]);
            }

            var prevIndex = m_PointIndexEnd - 1;
            if (prevIndex < 0)
            {
                prevIndex = m_MaxTrailPoints - 1;
            }

            m_MeshData.SetElementPipe((prevIndex * 2) + 1, ref m_Points[prevIndex], ref m_Points[m_PointIndexEnd]);
            m_MeshData.SetElementPosition((m_PointIndexEnd * 2), ref m_Points[m_PointIndexEnd]);


            // Go through all points and update size and color
            var pointUpdateCounter = m_PointIndexStart;
            var pointCount         = 0;
            var blendStep          = 1.0f / m_UsedPoints;
            var colorValue         = 1.0f;

            while (pointUpdateCounter != m_PointIndexEnd)
            {
                var currentBlend = blendStep * pointCount;
                var nextBlend    = blendStep * (pointCount + 1.0f);

                var currentWidth = Mathf.Lerp(m_EndWidth, m_StartWidth, currentBlend);
                var nextWidth    = Mathf.Lerp(m_EndWidth, m_StartWidth, nextBlend);

                m_MeshData.SetElementSize(pointUpdateCounter * 2, currentWidth);
                m_MeshData.SetElementSize((pointUpdateCounter * 2) + 1, currentWidth, nextWidth);

                var currentColor = GetLerpedColor(colorValue);
                var nextColor    = GetLerpedColor(colorValue - blendStep);

                m_MeshData.SetElementColor(pointUpdateCounter * 2, ref currentColor);
                m_MeshData.SetElementColor((pointUpdateCounter * 2) + 1, ref currentColor, ref nextColor);

                pointUpdateCounter = (pointUpdateCounter + 1) % m_MaxTrailPoints;
                pointCount++;
                colorValue -= blendStep;
            }

            m_MeshData.SetElementSize((m_PointIndexEnd * 2), m_StartWidth);
            m_MeshData.SetElementColor((m_PointIndexEnd * 2), ref m_Colors[0]);

            m_MeshData.SetMeshDataDirty(VRLineRendererInternal.MeshChain.MeshRefreshFlag.All);

            m_MeshData.RefreshMesh();
        }
    }