コード例 #1
0
ファイル: AnimationBlender.cs プロジェクト: vvvv/stride
        public static unsafe void Blend(CoreAnimationOperation 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 CoreAnimationOperation.Blend:
                        // 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.Float1:
                            *resultData = MathUtil.Lerp(*sourceLeftData, *sourceRightData, blendFactor);
                            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 CoreAnimationOperation.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 CoreAnimationOperation.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");
                    }
                }
            }
        }
コード例 #2
0
ファイル: AnimationOperation.cs プロジェクト: vol16bit/xenko
 /// <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(CoreAnimationOperation operation, float blendFactor)
 {
     return(new AnimationOperation {
         Type = AnimationOperationType.Blend, CoreBlendOperation = operation, BlendFactor = blendFactor
     });
 }
コード例 #3
0
        public static unsafe void Blend(CoreAnimationOperation 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 CoreAnimationOperation.Blend:
                            // 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 CoreAnimationOperation.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 CoreAnimationOperation.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");
                    }
                }
            }
        }
コード例 #4
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(CoreAnimationOperation operation, float blendFactor)
 {
     return new AnimationOperation { Type = AnimationOperationType.Blend, CoreBlendOperation = operation, BlendFactor = blendFactor };
 }