示例#1
0
        /// <summary>
        /// Adds a new playing animation at the end of the list. It doesn't alter currently playing animations.
        /// </summary>
        /// <param name="clip">Animation clip to add to the list of playing animations</param>
        /// <param name="timeScale">Speed at which the animation should play</param>
        /// <param name="weight">Weight of the animation, in regard to all other playing animations.</param>
        /// <param name="startTime">Time, in seconds, at which the animation starts playing</param>
        /// <param name="blend">Blend mode - linear or additive</param>
        /// <param name="repeatMode">Repeat mode - play once or loop indefinitely</param>
        public void Add(AnimationClip clip, double startTime = 0, AnimationBlendOperation blend = AnimationBlendOperation.LinearBlend,
                        float timeScale = 1f, float weight = 1f, AnimationRepeatMode?repeatMode = null)
        {
            var playingAnimation = new PlayingAnimation("", clip)
            {
                TimeFactor     = timeScale,
                Weight         = weight,
                CurrentTime    = TimeSpan.FromSeconds(startTime),
                BlendOperation = blend,
                RepeatMode     = repeatMode ?? clip.RepeatMode,
            };

            playingAnimations.Add(playingAnimation);
        }
示例#2
0
 /// <summary>
 /// Creates a new animation blend operation.
 /// </summary>
 /// <param name="operation">The blend operation.</param>
 /// <param name="blendFactor">The blend factor.</param>
 /// <returns></returns>
 public static AnimationOperation NewBlend(AnimationBlendOperation operation, float blendFactor)
 {
     return new AnimationOperation { Type = AnimationOperationType.Blend, BlendOperation = operation, BlendFactor = blendFactor };
 }
示例#3
0
 /// <summary>
 /// Creates a new animation blend operation.
 /// </summary>
 /// <param name="operation">The blend operation.</param>
 /// <param name="blendFactor">The blend factor.</param>
 /// <returns></returns>
 public static AnimationOperation NewBlend(AnimationBlendOperation operation, float blendFactor)
 {
     return(new AnimationOperation {
         Type = AnimationOperationType.Blend, BlendOperation = operation, BlendFactor = blendFactor
     });
 }
示例#4
0
        public static unsafe void Blend(AnimationBlendOperation blendOperation, float blendFactor, AnimationClipResult sourceLeft, AnimationClipResult sourceRight, AnimationClipResult result)
        {
            fixed(byte *sourceLeftDataStart = sourceLeft.Data)
            fixed(byte *sourceRightDataStart = sourceRight.Data)
            fixed(byte *resultDataStart      = result.Data)
            {
                foreach (var channel in sourceLeft.Channels)
                {
                    int offset          = channel.Offset;
                    var sourceLeftData  = (float *)(sourceLeftDataStart + offset);
                    var sourceRightData = (float *)(sourceRightDataStart + offset);
                    var resultData      = (float *)(resultDataStart + offset);

                    float factorLeft  = *sourceLeftData++;
                    float factorRight = *sourceRightData++;

                    // Ignore this channel
                    if (factorLeft == 0.0f && factorRight == 0.0f)
                    {
                        *resultData++ = 0.0f;
                        continue;
                    }

                    // Use left value
                    if (factorLeft > 0.0f && factorRight == 0.0f)
                    {
                        *resultData++ = 1.0f;
                        Utilities.CopyMemory((IntPtr)resultData, (IntPtr)sourceLeftData, channel.Size);
                        continue;
                    }

                    // Use right value
                    if (factorRight > 0.0f && factorLeft == 0.0f)
                    {
                        *resultData++ = 1.0f;
                        Utilities.CopyMemory((IntPtr)resultData, (IntPtr)sourceRightData, channel.Size);
                        continue;
                    }

                    // Blending
                    *resultData++ = 1.0f;

                    switch (blendOperation)
                    {
                    case AnimationBlendOperation.LinearBlend:
                        // Perform linear blending
                        // It will blend between left (0.0) and right (1.0)
                        switch (channel.BlendType)
                        {
                        case BlendType.None:
                            Utilities.CopyMemory((IntPtr)resultData, (IntPtr)sourceLeftData, channel.Size);
                            break;

                        case BlendType.Float2:
                            Vector2.Lerp(ref *(Vector2 *)sourceLeftData, ref *(Vector2 *)sourceRightData, blendFactor, out *(Vector2 *)resultData);
                            break;

                        case BlendType.Float3:
                            Vector3.Lerp(ref *(Vector3 *)sourceLeftData, ref *(Vector3 *)sourceRightData, blendFactor, out *(Vector3 *)resultData);
                            break;

                        case BlendType.Quaternion:
                            Quaternion.Slerp(ref *(Quaternion *)sourceLeftData, ref *(Quaternion *)sourceRightData, blendFactor, out *(Quaternion *)resultData);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                        break;

                    case AnimationBlendOperation.Add:
                        // Perform additive blending
                        // It will blend between left (0.0) and left + right (1.0).
                        switch (channel.BlendType)
                        {
                        case BlendType.None:
                            Utilities.CopyMemory((IntPtr)resultData, (IntPtr)sourceLeftData, channel.Size);
                            break;

                        case BlendType.Float2:
                            Vector2 rightValue2;
                            Vector2.Add(ref *(Vector2 *)sourceLeftData, ref *(Vector2 *)sourceRightData, out rightValue2);
                            Vector2.Lerp(ref *(Vector2 *)sourceLeftData, ref rightValue2, blendFactor, out *(Vector2 *)resultData);
                            break;

                        case BlendType.Float3:
                            Vector3 rightValue3;
                            Vector3.Add(ref *(Vector3 *)sourceLeftData, ref *(Vector3 *)sourceRightData, out rightValue3);
                            Vector3.Lerp(ref *(Vector3 *)sourceLeftData, ref rightValue3, blendFactor, out *(Vector3 *)resultData);
                            break;

                        case BlendType.Quaternion:
                            Quaternion rightValueQ;
                            Quaternion.Multiply(ref *(Quaternion *)sourceLeftData, ref *(Quaternion *)sourceRightData, out rightValueQ);
                            Quaternion.Normalize(ref rightValueQ, out rightValueQ);
                            Quaternion.Slerp(ref *(Quaternion *)sourceLeftData, ref rightValueQ, blendFactor, out *(Quaternion *)resultData);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                        break;

                    case AnimationBlendOperation.Subtract:
                        // Perform subtractive blending
                        // It will blend between left (0.0) and left - right (1.0).
                        switch (channel.BlendType)
                        {
                        case BlendType.None:
                            Utilities.CopyMemory((IntPtr)resultData, (IntPtr)sourceLeftData, channel.Size);
                            break;

                        case BlendType.Float2:
                            Vector2 rightValue2;
                            Vector2.Subtract(ref *(Vector2 *)sourceLeftData, ref *(Vector2 *)sourceRightData, out rightValue2);
                            Vector2.Lerp(ref *(Vector2 *)sourceLeftData, ref rightValue2, blendFactor, out *(Vector2 *)resultData);
                            break;

                        case BlendType.Float3:
                            Vector3 rightValue3;
                            Vector3.Subtract(ref *(Vector3 *)sourceLeftData, ref *(Vector3 *)sourceRightData, out rightValue3);
                            Vector3.Lerp(ref *(Vector3 *)sourceLeftData, ref rightValue3, blendFactor, out *(Vector3 *)resultData);
                            break;

                        case BlendType.Quaternion:
                            Quaternion rightValueQ;
                            // blend between left (0.0) and left * conjugate(right) (1.0)
                            Quaternion.Invert(ref *(Quaternion *)sourceRightData, out rightValueQ);
                            Quaternion.Multiply(ref rightValueQ, ref *(Quaternion *)sourceLeftData, out rightValueQ);
                            Quaternion.Normalize(ref rightValueQ, out rightValueQ);
                            //throw new NotImplementedException();
                            Quaternion.Slerp(ref *(Quaternion *)sourceLeftData, ref rightValueQ, blendFactor, out *(Quaternion *)resultData);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException();
                        }
                        break;

                    default:
                        throw new ArgumentOutOfRangeException("blendOperation");
                    }
                }
            }
        }
示例#5
0
        public static unsafe void Blend(AnimationBlendOperation blendOperation, float blendFactor, AnimationClipResult sourceLeft, AnimationClipResult sourceRight, AnimationClipResult result)
        {
            fixed (byte* sourceLeftDataStart = sourceLeft.Data)
            fixed (byte* sourceRightDataStart = sourceRight.Data)
            fixed (byte* resultDataStart = result.Data)
            {
                foreach (var channel in sourceLeft.Channels)
                {
                    int offset = channel.Offset;
                    var sourceLeftData = (float*)(sourceLeftDataStart + offset);
                    var sourceRightData = (float*)(sourceRightDataStart + offset);
                    var resultData = (float*)(resultDataStart + offset);

                    float factorLeft = *sourceLeftData++;
                    float factorRight = *sourceRightData++;

                    // Ignore this channel
                    if (factorLeft == 0.0f && factorRight == 0.0f)
                    {
                        *resultData++ = 0.0f;
                        continue;
                    }

                    // Use left value
                    if (factorLeft > 0.0f && factorRight == 0.0f)
                    {
                        *resultData++ = 1.0f;
                        Utilities.CopyMemory((IntPtr)resultData, (IntPtr)sourceLeftData, channel.Size);
                        continue;
                    }

                    // Use right value
                    if (factorRight > 0.0f && factorLeft == 0.0f)
                    {
                        *resultData++ = 1.0f;
                        Utilities.CopyMemory((IntPtr)resultData, (IntPtr)sourceRightData, channel.Size);
                        continue;
                    }

                    // Blending
                    *resultData++ = 1.0f;

                    switch (blendOperation)
                    {
                        case AnimationBlendOperation.LinearBlend:
                            // Perform linear blending
                            // It will blend between left (0.0) and right (1.0)
                            switch (channel.BlendType)
                            {
                                case BlendType.Blit:
                                    Utilities.CopyMemory((IntPtr)resultData, (IntPtr)(blendFactor < 0.5f ? sourceLeftData : sourceRightData), channel.Size);
                                    break;
                                case BlendType.Float2:
                                    Vector2.Lerp(ref *(Vector2*)sourceLeftData, ref *(Vector2*)sourceRightData, blendFactor, out *(Vector2*)resultData);
                                    break;
                                case BlendType.Float3:
                                    Vector3.Lerp(ref *(Vector3*)sourceLeftData, ref *(Vector3*)sourceRightData, blendFactor, out *(Vector3*)resultData);
                                    break;
                                case BlendType.Quaternion:
                                    Quaternion.Slerp(ref *(Quaternion*)sourceLeftData, ref *(Quaternion*)sourceRightData, blendFactor, out *(Quaternion*)resultData);
                                    break;
                                default:
                                    throw new ArgumentOutOfRangeException();
                            }
                            break;
                        case AnimationBlendOperation.Add:
                            // Perform additive blending
                            // It will blend between left (0.0) and left + right (1.0).
                            switch (channel.BlendType)
                            {
                                case BlendType.Blit:
                                    Utilities.CopyMemory((IntPtr)resultData, (IntPtr)sourceLeftData, channel.Size);
                                    break;
                                case BlendType.Float2:
                                    Vector2 rightValue2;
                                    Vector2.Add(ref *(Vector2*)sourceLeftData, ref *(Vector2*)sourceRightData, out rightValue2);
                                    Vector2.Lerp(ref *(Vector2*)sourceLeftData, ref rightValue2, blendFactor, out *(Vector2*)resultData);
                                    break;
                                case BlendType.Float3:
                                    Vector3 rightValue3;
                                    Vector3.Add(ref *(Vector3*)sourceLeftData, ref *(Vector3*)sourceRightData, out rightValue3);
                                    Vector3.Lerp(ref *(Vector3*)sourceLeftData, ref rightValue3, blendFactor, out *(Vector3*)resultData);
                                    break;
                                case BlendType.Quaternion:
                                    Quaternion rightValueQ;
                                    Quaternion.Multiply(ref *(Quaternion*)sourceLeftData, ref *(Quaternion*)sourceRightData, out rightValueQ);
                                    Quaternion.Normalize(ref rightValueQ, out rightValueQ);
                                    Quaternion.Slerp(ref *(Quaternion*)sourceLeftData, ref rightValueQ, blendFactor, out *(Quaternion*)resultData);
                                    break;
                                default:
                                    throw new ArgumentOutOfRangeException();
                            }
                            break;
                        case AnimationBlendOperation.Subtract:
                            // Perform subtractive blending
                            // It will blend between left (0.0) and left - right (1.0).
                            switch (channel.BlendType)
                            {
                                case BlendType.Blit:
                                    Utilities.CopyMemory((IntPtr)resultData, (IntPtr)sourceLeftData, channel.Size);
                                    break;
                                case BlendType.Float2:
                                    Vector2 rightValue2;
                                    Vector2.Subtract(ref *(Vector2*)sourceLeftData, ref *(Vector2*)sourceRightData, out rightValue2);
                                    Vector2.Lerp(ref *(Vector2*)sourceLeftData, ref rightValue2, blendFactor, out *(Vector2*)resultData);
                                    break;
                                case BlendType.Float3:
                                    Vector3 rightValue3;
                                    Vector3.Subtract(ref *(Vector3*)sourceLeftData, ref *(Vector3*)sourceRightData, out rightValue3);
                                    Vector3.Lerp(ref *(Vector3*)sourceLeftData, ref rightValue3, blendFactor, out *(Vector3*)resultData);
                                    break;
                                case BlendType.Quaternion:
                                    Quaternion rightValueQ;
                                    // blend between left (0.0) and left * conjugate(right) (1.0)
                                    Quaternion.Invert(ref *(Quaternion*)sourceRightData, out rightValueQ);
                                    Quaternion.Multiply(ref rightValueQ, ref *(Quaternion*)sourceLeftData, out rightValueQ);
                                    Quaternion.Normalize(ref rightValueQ, out rightValueQ);
                                    //throw new NotImplementedException();
                                    Quaternion.Slerp(ref *(Quaternion*)sourceLeftData, ref rightValueQ, blendFactor, out *(Quaternion*)resultData);
                                    break;
                                default:
                                    throw new ArgumentOutOfRangeException();
                            }
                            break;
                        default:
                            throw new ArgumentOutOfRangeException("blendOperation");
                    }
                }
            }
        }