Esempio n. 1
0
    // Get the Vector3 value for the given time
    public Vector3 GetValue(TimeSpan time)
    {
        // Check sizes
        if (m_nextFreeIndex == 0)
        {
            throw new Exception("Attempted to get value from TinyAnim but no keyframes had been added to the array yet!");
        }
        else if (m_nextFreeIndex == 1)
        {
            return(m_keyframes[0].vec);
        }
        else if (m_nextFreeIndex > 1)
        {
            int index = Array.BinarySearch(m_keyframes, 0, m_nextFreeIndex, new TinyKeyframe(new Vector3(0, 0, 0), time));
            if (index < 0)
            {
                // Not an exact match so fetch the closest index using bitwise complement
                index = ~index;

                if (index == 0)
                {
                    // Time < first keyframe time - Return first keyframe's value
                    return(m_keyframes[0].vec);
                }
                else if (index >= m_nextFreeIndex)
                {
                    // Time > last keyframe time - Return last keyframe's value
                    return(m_keyframes[m_nextFreeIndex - 1].vec);
                }
                else
                {
                    // Index will be the end boundary keyframe
                    TinyKeyframe startBound = m_keyframes[index - 1];
                    TinyKeyframe endBound   = m_keyframes[index];
                    if (startBound != null && endBound != null)
                    {
                        // We have found the correct two keyframes that we need to interpolate between
                        bool smooth = startBound.smooth && endBound.smooth;
                        return(TinyLerp(startBound, endBound, time, smooth));
                    }
                }
            }
            else
            {
                // Exact match - return that keyframe's value
                return(m_keyframes[index].vec);
            }
        }

        // This should never happen but it is here to catch anomolies and satisfy the compiler
        throw new Exception("Attempted to get value from TinyAnim but no Vector was returned!");
    }
Esempio n. 2
0
    // Interpolate between two TinyKeyframes
    private Vector3 TinyLerp(TinyKeyframe start, TinyKeyframe end, TimeSpan time, bool smoothStep)
    {
        // Calculate blend value depending on what is chosen (percentage or smooth step)
        float percent = 0f;

        if (smoothStep)
        {
            percent = SmoothStep(time, start.time, end.time);
        }
        else
        {
            percent = Percent(time, start.time, end.time);
        }

        return(new Vector3(start.vec.x + (percent * (end.vec.x - start.vec.x)),
                           start.vec.y + (percent * (end.vec.y - start.vec.y)),
                           start.vec.z + (percent * (end.vec.z - start.vec.z))));
    }
Esempio n. 3
0
    // Comparison for Array.Sort
    public int CompareTo(object other)
    {
        // Send all null keyframes to the back of the array
        if (other == null)
        {
            return(-1);
        }

        // Sort actual keyframes
        TinyKeyframe otherKf = other as TinyKeyframe;

        if (otherKf != null)
        {
            return(time.CompareTo(otherKf.time));
        }
        else
        {
            throw new ArgumentException("Comparison object is not a TinyKeyframe!");
        }
    }
Esempio n. 4
0
 // Add (or update) a keyframe to the array. This also sorts the array so that the keyframes remain in ascending time order.
 // If a keyframe already exists at the given time, update that keyframe instead.
 public void AddKeyframe(TinyKeyframe kf)
 {
     // Ensure keyframe array is not full
     if (m_nextFreeIndex < m_maxKeyframes)
     {
         // Does a keyframe already exists at the given time?
         TinyKeyframe existing = Array.Find(m_keyframes, o => o != null ? o.time.Equals(kf.time) : false);
         if (existing != null)
         {
             // Update the existing keyframe
             existing.vec = kf.vec;
         }
         else
         {
             // Add new keyframe
             m_keyframes[m_nextFreeIndex] = kf;
             m_nextFreeIndex++;
         }
     }
     else
     {
         throw new OverflowException("The keyframe array is full.");
     }
 }