Beispiel #1
0
 public void CrossFade(string clipName, float fadeLength)
 {
     if (playingClip == null)
     {
         Play(clipName);
     }
     else
     {
         List <GPUSkinClip> clips = animData.clips;
         int numClips             = clips == null ? 0 : clips.Count;
         for (int i = 0; i < numClips; ++i)
         {
             GPUSkinClip clip = clips[i];
             if (clip.name == clipName)
             {
                 if (playingClip != clip)
                 {
                     crossFadeProgress = 0;
                     crossFadeTime     = fadeLength;
                     SetNewPlayingClip(clip);
                     return;
                 }
                 if ((playingClip.wrapMode == GPUSkinWrapMode.Once && IsTimeAtTheEndOfLoop) || !isPlaying)
                 {
                     SetNewPlayingClip(clip);
                     return;
                 }
             }
         }
     }
 }
Beispiel #2
0
    public void Play(string clipName)
    {
        if (animData == null)
        {
            return;
        }

        List <GPUSkinClip> clips = animData.clips;
        int numClips             = clips == null ? 0 : clips.Count;

        for (int i = 0; i < numClips; ++i)
        {
            GPUSkinClip clip = clips[i];
            if (clip.name == clipName)
            {
                if (playingClip != clip ||
                    (playingClip != null && playingClip.wrapMode == GPUSkinWrapMode.Once && IsTimeAtTheEndOfLoop) ||
                    (playingClip != null && !isPlaying))
                {
                    SetNewPlayingClip(clip);
                    crossFadeTime = 0;
                }
                return;
            }
        }
    }
Beispiel #3
0
    private void UpdateMaterial(float deltaTime)
    {
        int frameIndex = GetFrameIndex();

        if (lastPlayingClip == playingClip && lastPlayingFrameIndex == frameIndex)
        {
            return;
        }
        lastPlayingClip       = playingClip;
        lastPlayingFrameIndex = frameIndex;

        bool         isCrossBlending      = IsCrossFadeBlending(lastPlayedClip, crossFadeTime, crossFadeProgress);
        int          frameIndexCrossFade  = -1;
        GPUSkinFrame frameCrossFade       = null;
        float        crossFadeBlendFactor = 1;
        bool         isRootMotion         = playingClip.rootMotionEnabled && RootMotionEnabled;
        GPUSkinFrame frame = playingClip.frames[frameIndex];

        if (isCrossBlending)
        {
            frameIndexCrossFade  = GetCrossFadeFrameIndex();
            frameCrossFade       = lastPlayedClip.frames[frameIndexCrossFade];
            crossFadeBlendFactor = Mathf.Clamp01(crossFadeProgress / crossFadeTime);
        }

        if (Visible || CullingMode == GPUSkinCullingMode.AlwaysAnimate)
        {
            mpb.SetVector(shaderPorpID_GPUSkin_FrameIndex_PixelSegmentation, new Vector4(frameIndex, playingClip.pixelSegmentation, 0, 0));
            if (isRootMotion)
            {
                Matrix4x4 rootMotionInv = animData.rootTransformMatrix * frame.RootMotionInv(animData.rootBoneIndex);
                //Matrix4x4 rootMotionInv = frame.RootMotionInv(animData.rootBoneIndex);
                mpb.SetMatrix(shaderPorpID_GPUSkin_RootMotion, rootMotionInv);
            }
            else
            {
                mpb.SetMatrix(shaderPorpID_GPUSkin_RootMotion, Matrix4x4.identity);
            }

            if (isCrossBlending)
            {
                mpb.SetVector(shaderPorpID_GPUSkin_FrameIndex_PixelSegmentation_Blend_CrossFade, new Vector4(frameIndexCrossFade, lastPlayedClip.pixelSegmentation, crossFadeBlendFactor));
            }
            else
            {
                mpb.SetVector(shaderPorpID_GPUSkin_FrameIndex_PixelSegmentation_Blend_CrossFade, new Vector4(0, 0, 1));
            }

            meshRender.SetPropertyBlock(mpb);
        }

        if (isRootMotion && deltaTime > 0)
        {
            if (CullingMode != GPUSkinCullingMode.CullCompletely)
            {
                DoRootMotion(deltaTime);
            }
        }
    }
Beispiel #4
0
    private void SetNewPlayingClip(GPUSkinClip clip)
    {
        lastPlayedClip = playingClip;
        lastPlayedTime = GetCurrentTime();

        isPlaying            = true;
        playingClip          = clip;
        time                 = 0;
        rootMotionFrameIndex = -1;

        rootMotionDeltaPosition = Vector3.zero;
        rootMotionDeltaQuat     = Quaternion.identity;
    }
Beispiel #5
0
    private void SetTextureInfo(GPUSkinAnimationData data)
    {
        int numPixels = 0;

        var clips    = data.clips;
        int numClips = clips.Count;

        for (int clipIndex = 0; clipIndex < numClips; ++clipIndex)
        {
            GPUSkinClip clip = clips[clipIndex];
            clip.pixelSegmentation = numPixels;

            numPixels += data.bones.Count * 3 /*treat 3 pixels as a float3x4*/ * clip.frames.Length;
        }

        CalculateTextureSize(numPixels, out data.textureWidth, out data.textureHeight);
    }
Beispiel #6
0
    public static Texture2D CreateTexture2D(GPUSkinAnimationData animData, out Color[] pixels)
    {
        pixels = null;
        if (animData == null)
        {
            return(null);
        }

        if (SystemInfo.SupportsTextureFormat(TextureFormat.RGBAHalf))
        {
            if (!bSwitchGpuSkinFloatTexture)
            {
                Shader.EnableKeyword("GPUSKIN_SUPPORT_FLOAT_TEXTURE");
                Shader.DisableKeyword("GPUSKIN_NOSUPPORT_FLOAT_TEXTURE");
                bSwitchGpuSkinFloatTexture = true;
            }

            Texture2D texture = new Texture2D(animData.textureWidth, animData.textureHeight, TextureFormat.RGBAHalf, false, true);
            texture.name       = "GPUSkinTextureMatrix";
            texture.filterMode = FilterMode.Point;

            pixels = texture.GetPixels();
            int pixelIndex = 0;
            int clipCount  = animData.clips.Count;
            for (int clipIndex = 0; clipIndex < clipCount; ++clipIndex)
            {
                GPUSkinClip clip      = animData.clips[clipIndex];
                var         frames    = clip.frames;
                int         numFrames = frames.Length;
                for (int frameIndex = 0; frameIndex < numFrames; ++frameIndex)
                {
                    GPUSkinFrame frame       = frames[frameIndex];
                    Matrix4x4[]  matrices    = frame.matrices;
                    int          numMatrices = matrices.Length;
                    for (int matrixIndex = 0; matrixIndex < numMatrices; ++matrixIndex)
                    {
                        Matrix4x4 matrix = matrices[matrixIndex];
                        pixels[pixelIndex++] = new Color(matrix.m00, matrix.m01, matrix.m02, matrix.m03);
                        pixels[pixelIndex++] = new Color(matrix.m10, matrix.m11, matrix.m12, matrix.m13);
                        pixels[pixelIndex++] = new Color(matrix.m20, matrix.m21, matrix.m22, matrix.m23);
                    }
                }
            }
            texture.SetPixels(pixels, 0);
            texture.Apply(false);

            return(texture);
        }
        else if (SystemInfo.SupportsTextureFormat(TextureFormat.RGBA32))
        {
            if (!bSwitchGpuSkinFloatTexture)
            {
                Shader.EnableKeyword("GPUSKIN_NOSUPPORT_FLOAT_TEXTURE");
                Shader.DisableKeyword("GPUSKIN_SUPPORT_FLOAT_TEXTURE");
                bSwitchGpuSkinFloatTexture = true;
            }

            Texture2D texture = new Texture2D(animData.textureWidth * 2, animData.textureHeight, TextureFormat.RGBA32, false, true);
            texture.name       = "GPUSkinTextureMatrix";
            texture.filterMode = FilterMode.Point;

            pixels = texture.GetPixels();
            int pixelIndex = 0;
            int clipCount  = animData.clips.Count;
            for (int clipIndex = 0; clipIndex < clipCount; ++clipIndex)
            {
                GPUSkinClip clip      = animData.clips[clipIndex];
                var         frames    = clip.frames;
                int         numFrames = frames.Length;
                for (int frameIndex = 0; frameIndex < numFrames; ++frameIndex)
                {
                    GPUSkinFrame frame       = frames[frameIndex];
                    Matrix4x4[]  matrices    = frame.matrices;
                    int          numMatrices = matrices.Length;
                    for (int matrixIndex = 0; matrixIndex < numMatrices; ++matrixIndex)
                    {
                        Matrix4x4 matrix = matrices[matrixIndex];
                        pixels[pixelIndex++] = Float2ToColor(matrix.m00, matrix.m01);
                        pixels[pixelIndex++] = Float2ToColor(matrix.m02, matrix.m03);

                        pixels[pixelIndex++] = Float2ToColor(matrix.m10, matrix.m11);
                        pixels[pixelIndex++] = Float2ToColor(matrix.m12, matrix.m13);

                        pixels[pixelIndex++] = Float2ToColor(matrix.m20, matrix.m21);
                        pixels[pixelIndex++] = Float2ToColor(matrix.m22, matrix.m23);
                    }
                }
            }
            texture.SetPixels(pixels, 0);
            texture.Apply(false);

            return(texture);
        }

        return(null);
    }
Beispiel #7
0
 public bool IsCrossFadeBlending(GPUSkinClip lastPlayedClip, float crossFadeTime, float crossFadeProgress)
 {
     return(lastPlayedClip != null && crossFadeTime > 0 && crossFadeProgress <= crossFadeTime);
 }
Beispiel #8
0
 private int GetFrameIndex(GPUSkinClip clip, float time)
 {
     return((int)(time * clip.frameRate) % (int)(clip.length * clip.frameRate));
 }
Beispiel #9
0
 private int GetTheLastFrameIndex(GPUSkinClip clip)
 {
     return((int)(clip.length * clip.frameRate) - 1);
 }
Beispiel #10
0
    public void StartSample()
    {
        if (isSampling)
        {
            return;
        }

        if (string.IsNullOrEmpty(animName.Trim()))
        {
            ShowDialog("Animation name is empty.");
            return;
        }

        if (rootBoneTransform == null)
        {
            ShowDialog("Please set Root Bone.");
            return;
        }

        if (animClips.Count == 0)
        {
            ShowDialog("Please set Animation Clips.");
            return;
        }

        animClip = animClips[samplingClipIndex].clip;
        if (animClip == null)
        {
            isSampling = false;
            return;
        }

        int numFrames = (int)(GetClipFrameRate(animClip, samplingClipIndex) * animClip.length);

        if (numFrames == 0)
        {
            isSampling = false;
            return;
        }

        smr = GetComponentInChildren <SkinnedMeshRenderer>();
        if (smr == null)
        {
            ShowDialog("Cannot find SkinnedMeshRenderer.");
            return;
        }
        Mesh mesh = smr.sharedMesh;

        if (mesh == null)
        {
            ShowDialog("Missing Mesh");
            return;
        }

        samplingFrameIndex = 0;

        gpuSkinAnimData = animData == null?ScriptableObject.CreateInstance <GPUSkinAnimationData>() : animData;

        gpuSkinAnimData.name = animName;

        List <GPUSkinBone> bones_result = new List <GPUSkinBone>();

        CollectBones(bones_result, smr.bones, mesh.bindposes, null, rootBoneTransform, 0);
        gpuSkinAnimData.bones               = bones_result;
        gpuSkinAnimData.rootBoneIndex       = 0;
        gpuSkinAnimData.rootTransformMatrix = rootTransformMatrix;

        int numClips          = gpuSkinAnimData.clips == null ? 0 : gpuSkinAnimData.clips.Count;
        int overrideClipIndex = -1;

        for (int i = 0; i < numClips; ++i)
        {
            if (gpuSkinAnimData.clips[i].name == animClips[samplingClipIndex].name)
            {
                overrideClipIndex = i;
                break;
            }
        }

        gpuSkinClip                   = new GPUSkinClip();
        gpuSkinClip.name              = animClips[samplingClipIndex].name;
        gpuSkinClip.frameRate         = GetClipFrameRate(animClip, samplingClipIndex);
        gpuSkinClip.length            = animClip.length;
        gpuSkinClip.wrapMode          = animClips[samplingClipIndex].wrapMode;
        gpuSkinClip.frames            = new GPUSkinFrame[numFrames];
        gpuSkinClip.rootMotionEnabled = animClips[samplingClipIndex].rootMotion;

        if (gpuSkinAnimData.clips == null)
        {
            gpuSkinAnimData.clips = new List <GPUSkinClip>();
            gpuSkinAnimData.clips.Add(gpuSkinClip);
        }
        else
        {
            if (overrideClipIndex == -1)
            {
                gpuSkinAnimData.clips.Add(gpuSkinClip);
            }
            else
            {
                GPUSkinClip overridedClip = gpuSkinAnimData.clips[overrideClipIndex];
                //RestoreCustomClipData(overridedClip, gpuSkinningClip);
                gpuSkinAnimData.clips[overrideClipIndex] = gpuSkinClip;
            }
        }

        SetCurrentAnimationClip();
        PrepareRecordAnimator();

        isSampling = true;
    }