예제 #1
0
        // add a new key
        public void addKey(ITarget itarget, int _frame, Vector3 _position, Key.Interpolation _interp, Ease _easeType)
        {
            foreach (TranslationKey key in keys)
            {
                // if key exists on frame, update key
                if (key.frame == _frame)
                {
                    key.position = _position;
                    key.interp   = _interp;
                    key.easeType = _easeType;
                    // update cache
                    updateCache(itarget);
                    return;
                }
            }
            TranslationKey a = new TranslationKey();

            a.frame    = _frame;
            a.position = _position;
            a.interp   = _interp;
            a.easeType = _easeType;

            // add a new key
            keys.Add(a);
            // update cache
            updateCache(itarget);
        }
예제 #2
0
        public static PathData GenerateLinear(List <Key> keys, int _startIndex)
        {
            PathData newPath = new PathData();

            // sort the keys by frame
            List <Vector3> _path = new List <Vector3>();

            newPath.startIndex = _startIndex;
            newPath.endIndex   = _startIndex;
            newPath.endFrame   = keys[_startIndex].frame;

            _path.Add((keys[_startIndex] as TranslationKey).position);

            int nextIndex = _startIndex + 1;

            if (nextIndex < keys.Count)
            {
                TranslationKey key = keys[nextIndex] as TranslationKey;
                _path.Add(key.position);
                newPath.endFrame = keys[nextIndex].frame;
                newPath.endIndex = nextIndex;
            }

            newPath.interp = Key.Interpolation.Linear;
            newPath.path   = _path.ToArray();

            return(newPath);
        }
예제 #3
0
        public int               endIndex;   // ending key index

        public static PathData GenerateCurve(List <Key> keys, int _startIndex)
        {
            PathData newPath = new PathData();

            // sort the keys by frame
            List <Vector3> _path = new List <Vector3>();

            newPath.startIndex = _startIndex;
            newPath.endIndex   = _startIndex;
            newPath.endFrame   = keys[_startIndex].frame;

            _path.Add((keys[_startIndex] as TranslationKey).position);

            // get path from startIndex until the next linear interpolation key (inclusive)
            for (int i = _startIndex + 1; i < keys.Count; i++)
            {
                TranslationKey key = keys[i] as TranslationKey;
                _path.Add(key.position);
                newPath.endFrame = keys[i].frame;
                newPath.endIndex = i;
                if (!keys[_startIndex].canTween ||
                    key.interp != Key.Interpolation.Curve)
                {
                    break;
                }
            }

            newPath.interp = Key.Interpolation.Curve;
            newPath.path   = _path.ToArray();

            return(newPath);
        }
예제 #4
0
        // copy properties from key
        public override void CopyTo(Key key)
        {
            base.CopyTo(key);

            TranslationKey a = key as TranslationKey;

            a.position = position;

            a.isConstSpeed = isConstSpeed;
        }
예제 #5
0
        // copy properties from key
        public override void CopyTo(Key key)
        {
            base.CopyTo(key);

            TranslationKey a = (TranslationKey)key;

            a.position       = position;
            a.orientMode     = orientMode;
            a.orientLockAxis = orientLockAxis;
        }
예제 #6
0
        public void DrawGizmos(TranslationKey nextKey, Transform transform, float ptSize)
        {
            Matrix4x4 mtx = transform.parent ? transform.parent.localToWorldMatrix : Matrix4x4.identity;

            if (interp == Interpolation.None)
            {
                Gizmos.color = Color.green;
                Gizmos.DrawSphere(mtx.MultiplyPoint3x4(position), ptSize);
            }
            else if (interp == Interpolation.Linear || path == null)
            {
                if (nextKey == null)
                {
                    Gizmos.color = Color.green;
                    Gizmos.DrawSphere(mtx.MultiplyPoint3x4(position), ptSize);
                }
                else
                {
                    Vector3 pt1 = mtx.MultiplyPoint3x4(position), pt2 = mtx.MultiplyPoint3x4(nextKey.position);

                    Gizmos.color = new Color(0.6f, 0.6f, 0.6f, 0.6f);

                    Gizmos.DrawLine(pt1, pt2);

                    Gizmos.color = Color.green;

                    Gizmos.DrawSphere(pt1, ptSize);
                    Gizmos.DrawSphere(pt2, ptSize);
                }
            }
            else if (interp == Interpolation.Curve)
            {
                Gizmos.color = new Color(0.6f, 0.6f, 0.6f, 0.6f);

                int subdivisions = pathResolution * keyCount;
                for (int i = 0; i < subdivisions; i++)
                {
                    var pt  = path.GetPoint(i / (float)subdivisions);
                    var pt1 = pt.valueVector3;

                    pt = path.GetPoint((i + 1) / (float)subdivisions);
                    var pt2 = pt.valueVector3;

                    Gizmos.DrawLine(mtx.MultiplyPoint3x4(pt1), mtx.MultiplyPoint3x4(pt2));
                }

                Gizmos.color = Color.green;

                for (int i = 0; i < path.wps.Length; i++)
                {
                    Gizmos.DrawSphere(mtx.MultiplyPoint3x4(path.wps[i].valueVector3), ptSize);
                }
            }
        }
예제 #7
0
        // add a new key, default interpolation and easeType
        public void addKey(ITarget itarget, int _frame, Vector3 _position)
        {
            TranslationKey prevKey = null;

            foreach (TranslationKey key in keys)
            {
                // if key exists on frame, update key
                if (key.frame == _frame)
                {
                    key.position = _position;
                    // update cache
                    updateCache(itarget);
                    return;
                }
                else if (key.frame < _frame)
                {
                    prevKey = key;
                }
            }

            TranslationKey a = new TranslationKey();

            a.frame    = _frame;
            a.position = _position;

            // copy interpolation and ease type from previous
            if (prevKey != null)
            {
                a.interp       = prevKey.interp;
                a.easeType     = prevKey.easeType;
                a.easeCurve    = prevKey.easeCurve;
                a.isConstSpeed = prevKey.isConstSpeed;

                a.orientMode     = prevKey.orientMode;
                a.orientLockAxis = prevKey.orientLockAxis;
            }

            // add a new key
            keys.Add(a);
            // update cache
            updateCache(itarget);
        }
예제 #8
0
        // update cache (optimized)
        public override void updateCache(ITarget target)
        {
            base.updateCache(target);

            // get all paths and add them to the action list
            for (int i = 0; i < keys.Count; i++)
            {
                TranslationKey key = keys[i] as TranslationKey;

                var interp       = key.interp;
                var easeType     = key.easeType;
                var isConstSpeed = key.isConstSpeed;
                var orientMode   = key.orientMode;
                var lockAxis     = key.orientLockAxis;

                key.GeneratePath(this, i);

                //invalidate some keys in between
                if (key.path != null)
                {
                    int endInd = i + key.keyCount - 1;
                    if (endInd < keys.Count - 1 || key.interp != keys[endInd].interp) //don't count the last element if there are more keys ahead
                    {
                        endInd--;
                    }

                    for (int j = i + 1; j <= endInd; j++)
                    {
                        var _key = keys[j] as TranslationKey;

                        _key.interp         = interp;
                        _key.easeType       = easeType;
                        _key.isConstSpeed   = isConstSpeed;
                        _key.orientMode     = orientMode;
                        _key.orientLockAxis = lockAxis;
                        _key.Invalidate();
                    }

                    i = endInd;
                }
            }
        }
예제 #9
0
        // update cache (optimized)
        public override void updateCache(ITarget target)
        {
            base.updateCache(target);

            // get all paths and add them to the action list
            for (int i = 0; i < keys.Count; i++)
            {
                TranslationKey key = keys[i] as TranslationKey;

                var interp   = key.interp;
                var easeType = key.easeType;

                key.version = version;

                key.GeneratePath(this, i);
                key.ClearCache();

                //invalidate some keys in between
                if (key.path.Length > 1)
                {
                    int endInd = i + key.path.Length - 1;
                    if (endInd < keys.Count - 1 || key.interp != keys[endInd].interp) //don't count the last element if there are more keys ahead
                    {
                        endInd--;
                    }

                    for (int j = i + 1; j <= endInd; j++)
                    {
                        key = keys[j] as TranslationKey;

                        key.version  = version;
                        key.interp   = interp;
                        key.easeType = easeType;
                        key.endFrame = key.frame;
                        key.path     = new Vector3[0];
                    }

                    i = endInd;
                }
            }
        }
예제 #10
0
        // add a new key, default interpolation and easeType
        public void addKey(ITarget itarget, int _frame, Vector3 _position)
        {
            foreach (TranslationKey key in keys)
            {
                // if key exists on frame, update key
                if (key.frame == _frame)
                {
                    key.position = _position;
                    // update cache
                    updateCache(itarget);
                    return;
                }
            }
            TranslationKey a = new TranslationKey();

            a.frame    = _frame;
            a.position = _position;

            // add a new key
            keys.Add(a);
            // update cache
            updateCache(itarget);
        }
예제 #11
0
        public Vector3 getPositionAtFrame(Transform t, float frame, int frameRate, bool forceWorld)
        {
            int keyCount = keys.Count;

            if (keyCount <= 0)
            {
                return(GetPosition(t));
            }

            int iFrame = Mathf.RoundToInt(frame);

            TranslationKey firstKey = keys[0] as TranslationKey;

            //check if only key or behind first key
            if (keyCount == 1 || iFrame <= firstKey.frame)
            {
                return(convertPosition(t, firstKey.position, forceWorld));
            }

            //check in-between
            for (int i = 0; i < keyCount; i++)
            {
                TranslationKey key = keys[i] as TranslationKey;

                if (key.canTween && key.path.Length <= 1) //invalid
                {
                    continue;
                }

                if (iFrame >= key.endFrame)
                {
                    if (key.path.Length > 0 && i + key.path.Length == keyCount) //end of last path in track?
                    {
                        return(convertPosition(t, key.path[key.path.Length - 1], forceWorld));
                    }
                    else if (i + 1 == keyCount) //last non-tween key in track?
                    {
                        return(convertPosition(t, key.position, forceWorld));
                    }
                    else
                    {
                        continue;
                    }
                }

                if (!key.canTween)
                {
                    return(convertPosition(t, key.position, forceWorld));
                }
                else if (key.path.Length <= 1) //invalid key
                {
                    return(GetPosition(t));
                }

                float _value = Mathf.Clamp01((frame - key.frame) / key.getNumberOfFrames(frameRate));

                return(convertPosition(t, key.GetPoint(t, frameRate, Mathf.Clamp01(_value)), forceWorld));
            }

            return(GetPosition(t)); //last key is impartial tween
        }
예제 #12
0
        // update cache (optimized)
        public override void updateCache(ITarget target)
        {
            base.updateCache(target);

            // get all paths and add them to the action list
            for (int i = 0; i < keys.Count; i++)
            {
                TranslationKey key = keys[i] as TranslationKey;

                var interp   = key.interp;
                var easeType = key.easeType;

                key.version = version;

                PathData path;
                switch (key.interp)
                {
                case Key.Interpolation.Curve:
                    path = PathData.GenerateCurve(keys, i);
                    break;

                case Key.Interpolation.Linear:
                    path = PathData.GenerateLinear(keys, i);
                    break;

                default:
                    int singleEndFrame = i < keys.Count - 1 ? keys[i + 1].frame : keys[i].frame;
                    path = PathData.GenerateSingle(keys[i], i, singleEndFrame);
                    break;
                }

                key.endFrame    = path.endFrame;
                key.pathPreview = null;

                if (!key.canTween)
                {
                    if (path.endIndex == keys.Count - 1)
                    {
                        TranslationKey lastKey = keys[path.endIndex] as TranslationKey;
                        lastKey.interp   = Key.Interpolation.None;
                        lastKey.endFrame = lastKey.frame;
                        lastKey.path     = new Vector3[0];
                    }
                }
                else
                {
                    key.path = path.path;
                }

                //invalidate some keys in between
                if (path.startIndex < keys.Count - 1)
                {
                    int _endInd = path.endIndex;
                    if (_endInd < keys.Count - 1)
                    {
                        _endInd--;
                    }

                    if (i < _endInd)
                    {
                        for (i = path.startIndex + 1; i <= _endInd; i++)
                        {
                            key = keys[i] as TranslationKey;

                            key.version  = version;
                            key.interp   = interp;
                            key.easeType = easeType;
                            key.endFrame = key.frame;
                            key.path     = new Vector3[0];
                        }

                        i = _endInd;
                    }
                }
            }
        }
예제 #13
0
        public Vector3 getPositionAtFrame(Transform t, int frame, int frameRate, bool forceWorld)
        {
            int keyCount = keys.Count;

            if (keyCount <= 0)
            {
                return(GetPosition(t));
            }

            TranslationKey firstKey = keys[0] as TranslationKey;

            //check if behind first key
            if (frame <= firstKey.frame && (!firstKey.canTween || firstKey.path.Length == 1))
            {
                return(convertPosition(t, firstKey.position, forceWorld));
            }

            TranslationKey lastKey = keyCount == 1 ? firstKey : keys[keyCount - 1] as TranslationKey;

            //check if past last key
            if (frame >= lastKey.endFrame && !lastKey.canTween)
            {
                return(convertPosition(t, lastKey.position, forceWorld));
            }

            //check in-between
            for (int i = 0; i < keyCount; i++)
            {
                TranslationKey key     = keys[i] as TranslationKey;
                TranslationKey keyNext = i < keyCount - 1 ? keys[i + 1] as TranslationKey : null;

                if (frame >= key.endFrame && keyNext != null && (!keyNext.canTween || keyNext.path.Length > 1))
                {
                    continue;
                }

                if (!key.canTween || key.path.Length == 1)
                {
                    return(convertPosition(t, key.position, forceWorld));
                }
                else if (key.path.Length == 0)
                {
                    continue;
                }

                float fNumFrames = (float)key.getNumberOfFrames(frameRate);

                float _value;

                float framePositionInPath = Mathf.Clamp(frame - (float)key.frame, 0f, fNumFrames);

                if (key.hasCustomEase())
                {
                    _value = Utility.EaseCustom(0.0f, 1.0f, framePositionInPath / fNumFrames, key.easeCurve);
                }
                else
                {
                    var ease = Utility.GetEasingFunction((Ease)key.easeType);
                    _value = ease(framePositionInPath, fNumFrames, key.amplitude, key.period);
                    if (float.IsNaN(_value)) //this really shouldn't happen...
                    {
                        break;
                    }
                }

                return(convertPosition(t, key.GetPoint(Mathf.Clamp01(_value)), forceWorld));
            }

            Debug.LogError("Animator: Could not get " + t.name + " position at frame '" + frame + "'");
            return(GetPosition(t));
        }
예제 #14
0
        // preview a frame in the scene view
        public override void previewFrame(ITarget itarget, float frame, int frameRate, bool play, float playSpeed)
        {
            Transform t = GetTarget(itarget) as Transform;

            if (!t)
            {
                return;
            }

            int keyCount = keys.Count;

            if (keys == null || keyCount <= 0)
            {
                return;
            }

            int iFrame = Mathf.RoundToInt(frame);

            TranslationKey firstKey = keys[0] as TranslationKey;

            //check if behind first key
            if (iFrame <= firstKey.frame && (!firstKey.canTween || firstKey.path.Length == 1))
            {
                SetPosition(t, firstKey.position);
                return;
            }

            TranslationKey lastKey = keyCount == 1 ? firstKey : keys[keyCount - 1] as TranslationKey;

            //check if past last key
            if (iFrame >= lastKey.endFrame)
            {
                SetPosition(t, lastKey.position);
                return;
            }

            //check in-between
            for (int i = 0; i < keyCount; i++)
            {
                TranslationKey key = keys[i] as TranslationKey;

                if (key.path == null)
                {
                    continue;
                }

                if (iFrame >= key.endFrame && i < keyCount - 1)
                {
                    continue;
                }

                if ((!key.canTween || key.path.Length <= 1))
                {
                    SetPosition(t, key.position);
                    return;
                }

                float fNumFrames = (float)key.getNumberOfFrames(frameRate);

                float _value;

                float framePositionInPath = Mathf.Clamp(frame - (float)key.frame, 0f, fNumFrames);

                if (key.hasCustomEase())
                {
                    _value = Utility.EaseCustom(0.0f, 1.0f, framePositionInPath / fNumFrames, key.easeCurve);
                }
                else
                {
                    var ease = Utility.GetEasingFunction((Ease)key.easeType);
                    _value = ease(framePositionInPath, fNumFrames, key.amplitude, key.period);
                    if (float.IsNaN(_value)) //this really shouldn't happen...
                    {
                        return;
                    }
                }

                SetPosition(t, key.GetPoint(Mathf.Clamp01(_value)));

                return;
            }
        }
예제 #15
0
        public Vector3 getPositionAtFrame(Transform t, float frame, int frameRate, bool forceWorld)
        {
            int keyCount = keys.Count;

            if (keyCount <= 0)
            {
                return(GetPosition(t));
            }

            int iFrame = Mathf.RoundToInt(frame);

            TranslationKey firstKey = keys[0] as TranslationKey;

            //check if only key or behind first key
            if (keyCount == 1 || iFrame <= firstKey.frame)
            {
                return(convertPosition(t, firstKey.position, forceWorld));
            }

            //check in-between
            for (int i = 0; i < keyCount; i++)
            {
                TranslationKey key = keys[i] as TranslationKey;

                if (key.endFrame == -1) //invalid
                {
                    continue;
                }

                //end of last path in track?
                if (iFrame >= key.endFrame)
                {
                    if (key.interp == Key.Interpolation.None)
                    {
                        if (i + 1 == keyCount)
                        {
                            return(convertPosition(t, key.position, forceWorld));
                        }
                    }
                    else if (key.interp == Key.Interpolation.Linear || key.path == null)
                    {
                        if (i + 1 == keyCount - 1)
                        {
                            var pt = ((TranslationKey)keys[i + 1]).position;
                            return(convertPosition(t, pt, forceWorld));
                        }
                    }
                    else if (key.interp == Key.Interpolation.Curve)
                    {
                        if (i + key.keyCount == keyCount) //end of last path in track?
                        {
                            return(convertPosition(t, ((TranslationKey)keys[i + key.keyCount - 1]).position, forceWorld));
                        }
                    }

                    continue;
                }

                if (key.interp == Key.Interpolation.None)
                {
                    return(convertPosition(t, key.position, forceWorld));
                }
                else if (key.interp == Key.Interpolation.Linear || key.path == null)
                {
                    var keyNext = keys[i + 1] as TranslationKey;

                    float numFrames = (float)key.getNumberOfFrames(frameRate);

                    float framePositionInAction = Mathf.Clamp(frame - (float)key.frame, 0f, numFrames);

                    var start = key.position;
                    var end   = keyNext.position;

                    if (key.hasCustomEase())
                    {
                        return(convertPosition(t, Vector3.Lerp(start, end, Utility.EaseCustom(0.0f, 1.0f, framePositionInAction / numFrames, key.easeCurve)), forceWorld));
                    }
                    else
                    {
                        var ease = Utility.GetEasingFunction((Ease)key.easeType);
                        return(convertPosition(t, Vector3.Lerp(start, end, ease(framePositionInAction, numFrames, key.amplitude, key.period)), forceWorld));
                    }
                }
                else
                {
                    float _value = Mathf.Clamp01((frame - key.frame) / key.getNumberOfFrames(frameRate));

                    var pt = key.GetPoint(_value);

                    return(convertPosition(t, pt, forceWorld));
                }
            }

            return(GetPosition(t)); //last key is impartial tween
        }
예제 #16
0
        // preview a frame in the scene view
        public override void previewFrame(ITarget itarget, float frame, int frameRate, bool play, float playSpeed)
        {
            Transform t = GetTarget(itarget) as Transform;

            if (!t)
            {
                return;
            }

            int keyCount = keys.Count;

            if (keyCount <= 0)
            {
                return;
            }

            int iFrame = Mathf.RoundToInt(frame);

            TranslationKey firstKey = keys[0] as TranslationKey;

            //check if only key or behind first key
            if (keyCount == 1 || iFrame < firstKey.frame)
            {
                t.localPosition = convertPosition(t, firstKey.position, false);
                return;
            }
            else if (iFrame == firstKey.frame)
            {
                if (firstKey.interp == Key.Interpolation.Linear || firstKey.path == null)  //apply orientation
                {
                    t.localPosition = convertPosition(t, firstKey.position, false);

                    if (firstKey.orientMode != OrientMode.None)
                    {
                        var nextPt = ((TranslationKey)keys[1]).position;
                        if (t.parent)
                        {
                            nextPt = t.parent.TransformPoint(nextPt);
                        }

                        t.rotation = firstKey.GetOrientation(t, nextPt);
                    }
                }
                else if (firstKey.interp == Key.Interpolation.Curve)  //apply orientation
                {
                    t.localPosition = convertPosition(t, firstKey.position, false);

                    if (firstKey.orientMode != OrientMode.None)
                    {
                        t.rotation = firstKey.GetOrientation(t, 0f);
                    }
                }
                else
                {
                    t.localPosition = convertPosition(t, firstKey.position, false);
                }

                return;
            }

            //check in-between
            for (int i = 0; i < keyCount; i++)
            {
                TranslationKey key = keys[i] as TranslationKey;

                if (key.endFrame == -1) //invalid
                {
                    continue;
                }

                //end of last path in track?
                if (iFrame >= key.endFrame)
                {
                    if (key.interp == Key.Interpolation.None)
                    {
                        if (i + 1 == keyCount)
                        {
                            t.localPosition = convertPosition(t, key.position, false);
                            return;
                        }
                    }
                    else if (key.interp == Key.Interpolation.Linear || key.path == null)
                    {
                        if (i + 1 == keyCount - 1)
                        {
                            var pt = ((TranslationKey)keys[i + 1]).position;

                            t.localPosition = convertPosition(t, pt, false);

                            if (key.orientMode != OrientMode.None && iFrame == key.endFrame) //only apply rotation if we are at end of frame
                            {
                                Vector3 ptW, prevPtW;
                                if (t.parent)
                                {
                                    ptW     = t.parent.TransformPoint(pt);
                                    prevPtW = t.parent.TransformPoint(key.position);
                                }
                                else
                                {
                                    ptW     = pt;
                                    prevPtW = key.position;
                                }
                                var dir = (ptW - prevPtW).normalized;

                                t.rotation = key.GetOrientation(t, ptW + dir);
                            }

                            return;
                        }
                    }
                    else if (key.interp == Key.Interpolation.Curve)
                    {
                        if (i + key.keyCount == keyCount) //end of last path in track?
                        {
                            t.localPosition = convertPosition(t, ((TranslationKey)keys[i + key.keyCount - 1]).position, false);

                            if (key.orientMode != OrientMode.None && iFrame == key.endFrame) //only apply rotation if we are at end of frame
                            {
                                t.rotation = key.GetOrientation(t, 1f);
                            }

                            return;
                        }
                    }

                    continue;
                }

                if (key.interp == Key.Interpolation.None)
                {
                    t.localPosition = convertPosition(t, key.position, false);
                }
                else if (key.interp == Key.Interpolation.Linear || key.path == null)
                {
                    var keyNext = keys[i + 1] as TranslationKey;

                    float numFrames = (float)key.getNumberOfFrames(frameRate);

                    float framePositionInAction = Mathf.Clamp(frame - (float)key.frame, 0f, numFrames);

                    var start = key.position;
                    var end   = keyNext.position;

                    if (key.hasCustomEase())
                    {
                        t.localPosition = convertPosition(t, Vector3.Lerp(start, end, Utility.EaseCustom(0.0f, 1.0f, framePositionInAction / numFrames, key.easeCurve)), false);
                    }
                    else
                    {
                        var ease = Utility.GetEasingFunction((Ease)key.easeType);
                        t.localPosition = convertPosition(t, Vector3.Lerp(start, end, ease(framePositionInAction, numFrames, key.amplitude, key.period)), false);
                    }

                    if (key.orientMode != OrientMode.None)
                    {
                        t.rotation = key.GetOrientation(t, t.parent ? t.parent.TransformPoint(end) : end);
                    }
                }
                else
                {
                    float _value = Mathf.Clamp01((frame - key.frame) / key.getNumberOfFrames(frameRate));

                    var pt = key.GetPoint(_value);
                    t.localPosition = convertPosition(t, pt, false);

                    if (key.orientMode != OrientMode.None)
                    {
                        t.rotation = key.GetOrientation(t, _value);
                    }
                }

                return;
            }

            //var lpos = getPositionAtFrame(t, frame, frameRate, false);

            //t.localPosition = lpos;
        }