Пример #1
0
        /// <param name="t">Параметр прогресса между p1 и p2. Принимает значение в диапазоне от 0 до 1</param>
        /// <param name="p0"></param>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        /// <returns></returns>
        public static Snapshot Interpolate(float t, Snapshot p0, Snapshot p1, Snapshot p2, Snapshot p3)
        {
            if (t < 0 || 1 < t)
            {
                throw new ArgumentOutOfRangeException($"t was {t}");
            }

            Snapshot result = new Snapshot();

            foreach (ushort entityId in p2.transforms.Keys)
            {
                bool v0Exists = p0.transforms.TryGetValue(entityId, out var v0);
                bool v1Exists = p1.transforms.TryGetValue(entityId, out var v1);
                //always true
                bool v2Exists = p2.transforms.TryGetValue(entityId, out var v2);
                bool v3Exists = p3.transforms.TryGetValue(entityId, out var v3);

                ViewTransformCompressed interpolated;
                //Сколько точек есть для интерполяции?
                if (v0Exists && v1Exists && v2Exists && v3Exists)
                {
                    //интерполяция между черытьмя точками
                    Vector3 position = CatmullRomSpline
                                       .GetCatmullRomPosition(t, v0.GetPosition(), v1.GetPosition(),
                                                              v2.GetPosition(), v3.GetPosition());
                    float angle = Mathf.LerpAngle(v1.Angle, v2.Angle, t);
                    interpolated = new ViewTransformCompressed(position.x, position.z, angle, v2.viewTypeEnum);
                }
                else if (v1Exists && v2Exists)
                {
                    //интерполяция между двумя точками
                    Vector3 position = v1.GetPosition() * (1 - t) + v2.GetPosition() * t;
                    float   angle    = Mathf.LerpAngle(v1.Angle, v2.Angle, t);
                    interpolated = new ViewTransformCompressed(position.x, position.z, angle, v2.viewTypeEnum);
                }
                else
                {
                    //сущность была создана на этом кадре. интерполяция невозможна
                    interpolated = v2;
                }

                result.transforms.Add(entityId, interpolated);
            }

            return(result);
        }
Пример #2
0
    IEnumerator Mover()
    {
        coroutineAllowed = false;

        if (controlPointsIndex == 4)
        {
            controlPointsIndex = 0;
        }

        Vector3 p0 = controlPointsList[CatmullRomSpline.ClampListPos(controlPointsIndex - 1, controlPointsList)].position;
        Vector3 p1 = controlPointsList[controlPointsIndex].position;
        Vector3 p2 = controlPointsList[CatmullRomSpline.ClampListPos(controlPointsIndex + 1, controlPointsList)].position;
        Vector3 p3 = controlPointsList[CatmullRomSpline.ClampListPos(controlPointsIndex + 2, controlPointsList)].position;

        controlPointsIndex += 1;
        float travelled = 0;

        while (t < 1)
        {
            t  += Time.deltaTime * speed;
            pos = CatmullRomSpline.GetCatmullRomPosition(t, p0, p1, p2, p3);

            // Numerical Methods for Arc Length
            while (travelled < distance_to_travel)
            {
                t         += very_small_amount;
                travelled += (CatmullRomSpline.GetCatmullRomPosition(t, p0, p1, p2, p3) - pos).magnitude;
                pos        = CatmullRomSpline.GetCatmullRomPosition(t, p0, p1, p2, p3);
            }

            Vector3 newDir = Vector3.RotateTowards(transform.forward, (pos - transform.position).normalized, Time.deltaTime * speed * 10, 0.0f);
            transform.rotation = Quaternion.LookRotation(newDir);
            transform.position = pos;
            Debug.DrawRay(transform.position, newDir, Color.green);
            yield return(new WaitForEndOfFrame());
        }

        t = 0;

        coroutineAllowed = true;
    }