示例#1
0
        void OnDrawGizmos()
        {
            if (wrapper == null)
            {
                return;
            }

            if (!playing)
            {
                return;
            }

            float            t      = (Application.isPlaying ? Time.time : Time.realtimeSinceStartup) + movementSync;
            SplineLerpResult result = FollowLerp(t);

            Gizmos.color  = Color.green;
            Gizmos.matrix = Matrix4x4.TRS(result.worldPosition, Quaternion.Euler(result.worldRotation), Vector3.one * FollowScale(t));
            Gizmos.DrawWireCube(Vector3.zero, Vector3.one * 0.5f);
            Gizmos.matrix = Matrix4x4.identity;
        }
示例#2
0
        void FixedUpdate()
        {
            if (wrapper == null)
            {
                return;
            }

            if (!playing)
            {
                return;
            }

            t += Time.deltaTime;
            float scale = (Application.isPlaying ? FollowScale(t) : 1);

            result               = FollowLerp(t);
            currenSection        = result.section;
            currentSegment       = result.segment;
            transform.position   = result.worldPosition;
            transform.rotation   = Quaternion.Euler(result.worldRotation);
            transform.localScale = Vector3.one * scale;
        }
示例#3
0
        // ======================================================================================================================== GETTERS

        // This is the crucial function for splines: the one which lets outside objects query for interpolated data.
        // To do so, they pass in a root transform to use as the owner of the spline, as well as a SplineLerpQuery,
        // which contains the desired parametrized time [0-1] on the spline and some additional interpolation settings.
        // This function then returns a SplineLerpResult which contains all of the interpolated information.

        internal SplineLerpResult Lerp(Transform root, SplineLerpQuery query)
        {
            // Failsafe - if this spline is degenerate, just return the first point and don't do any other interpolation

            if (totalLength == 0)
            {
                SplineLerpResult degenerateResult = new SplineLerpResult();
                degenerateResult.worldPosition = Matrix4x4.TRS(root.position, root.rotation, root.lossyScale).MultiplyPoint3x4(vertices[0, 0]);
                return(degenerateResult);
            }

            // First, we need to find the section on the spline that contains the parametrized time being queried for.
            // Convert the parametrized time given into a time-position within the total length of the spline

            float p = Mathf.Clamp01(query.t) * totalLength;

            // If the query says to smooth along the entire spline, do that now

            if (query.movementSmoothing == SplineMovementSmoothing.WholeSpline)
            {
                p = Mathf.SmoothStep(0, totalLength, p / totalLength);
            }

            // Now, find the section of the spline that corresponds to that time-position, by using the total lengths
            // of each section. In doing so, make the time-position p local to that section

            int section;

            for (section = 0; section < sectionCount - 1; section++)
            {
                if (p > lengths[section, segmentCount - 1])
                {
                    p -= lengths[section, segmentCount - 1];
                }
                else
                {
                    break;
                }
            }

            // Now that p is located within a section (between two SplineNodes), we need to do more parameter calculation.
            // v is the [0-1] parameter which will lerp the non-positional values between the nodes, with optional value smoothing if the query says to
            // p is also updated so that it is smoothed between the nodes if the query says to

            float v = p / lengths[section, segmentCount - 1];

            if (query.movementSmoothing == SplineMovementSmoothing.BetweenNodes)
            {
                p = Mathf.SmoothStep(0, lengths[section, segmentCount - 1], v);
            }
            if (query.valueSmoothing)
            {
                v = Mathf.SmoothStep(0, 1, v);
            }

            // Finally, find the segment within the found section that corresponds to p, by using the
            // cumulative segment lengths. In doing so, make p local to that segment

            int segment;

            for (segment = 0; segment < segmentCount - 1; segment++)
            {
                float l1 = lengths[section, segment];
                float l2 = lengths[section, segment + 1];
                float r  = (p - l1) / (l2 - l1);

                if (r >= 0 && r <= 1 || segment == segmentCount - 2)
                {
                    p = r;
                    break;
                }
            }

            // Now that we finally know where we are in terms of sections and segments, we can do the interpolation.

            SplineLerpResult result = new SplineLerpResult();

            // Position

            Vector3   localPos = Vector3.Lerp(vertices[section, segment], vertices[section, segment + 1], p);
            Matrix4x4 m        = Matrix4x4.TRS(root.position, root.rotation, root.lossyScale);

            result.worldPosition = m.MultiplyPoint3x4(localPos);

            // Values
            SplineNode s = nodes[section];
            SplineNode e = nodes[section + 1];

            result.worldRotation = Vector3.Lerp(s.worldOrientation, e.worldOrientation, v);
            result.fieldOfView   = Mathf.Lerp(s.fieldOfView, e.fieldOfView, v);
            result.tangent       = (Tangent(vertices, section, segment, segmentCount, 0)
                                    + Tangent(vertices, section, segment, segmentCount, 1)) / 2;
            result.section = section;
            result.segment = segment;

            return(result);
        }