Пример #1
0
    private void DoRootMotion(float deltaTime)
    {
        int          frameIndex = GetFrameIndex();
        GPUSkinFrame frame      = playingClip.frames[frameIndex];

        if (frame == null)
        {
            return;
        }

        Transform trans = transform;

        if (WrapMode == GPUSkinWrapMode.Once)
        {
            if (rootMotionFrameIndex != frameIndex)
            {
                Vector3 oldPos = rootMotionDeltaPosition;
                rootMotionDeltaPosition = frame.rootMotionDeltaPositionQ * trans.forward * frame.rootMotionDeltaPositionL;
                trans.Translate(rootMotionDeltaPosition - oldPos, Space.World);

                rootMotionFrameIndex = frameIndex;
            }
        }
        else
        {
            int totalFrameCount = Mathf.Max((int)(deltaTime * playingClip.frameRate), frameIndex - rootMotionFrameIndex);
            int lastFrameIndex  = GetTheLastFrameIndex(playingClip);

            while (totalFrameCount > 0)
            {
                if (rootMotionFrameIndex + totalFrameCount >= lastFrameIndex)
                {
                    var lastFrame = playingClip.frames[lastFrameIndex];

                    Vector3 oldPos = rootMotionDeltaPosition;
                    rootMotionDeltaPosition = lastFrame.rootMotionDeltaPositionQ * trans.forward * lastFrame.rootMotionDeltaPositionL;
                    trans.Translate(rootMotionDeltaPosition - oldPos, Space.World);

                    totalFrameCount        -= (lastFrameIndex - rootMotionFrameIndex);
                    rootMotionFrameIndex    = 0;
                    rootMotionDeltaPosition = Vector3.zero;
                }
                else
                {
                    Vector3 oldPos = rootMotionDeltaPosition;
                    rootMotionDeltaPosition = frame.rootMotionDeltaPositionQ * trans.forward * frame.rootMotionDeltaPositionL;
                    trans.Translate(rootMotionDeltaPosition - oldPos, Space.World);

                    totalFrameCount = 0;
                }
            }

            rootMotionFrameIndex = frameIndex;
        }

        //if (doRotate)
        //{
        //    transform.rotation *= frame.rootMotionDeltaRotation;
        //}
    }
Пример #2
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);
            }
        }
    }
Пример #3
0
    private IEnumerator SamplingCoroutine(GPUSkinFrame frame, int totalFrames)
    {
        yield return(new WaitForEndOfFrame());

        List <GPUSkinBone> bones = gpuSkinAnimData.bones;
        int numBones             = bones.Count;

        for (int i = 0; i < numBones; ++i)
        {
            Transform   boneTransform = bones[i].transform;
            GPUSkinBone currentBone   = GetBoneByTransform(boneTransform);
            frame.matrices[i] = Matrix4x4.identity;// currentBone.bindpose;
            do
            {
                Matrix4x4 mat = Matrix4x4.TRS(currentBone.transform.localPosition, currentBone.transform.localRotation, currentBone.transform.localScale);
                frame.matrices[i] = mat * frame.matrices[i];
                if (currentBone.parentBoneIndex == -1)
                {
                    break;
                }
                else
                {
                    currentBone = bones[currentBone.parentBoneIndex];
                }
            }while (true);
        }

        int rootBoneIndex = gpuSkinAnimData.rootBoneIndex;

        if (samplingFrameIndex == 0)
        {
            rootMotionPosition = bones[rootBoneIndex].transform.localPosition;
            rootMotionRotation = bones[rootBoneIndex].transform.localRotation;
        }
        else
        {
            Vector3    newPosition   = bones[rootBoneIndex].transform.localPosition;
            Quaternion newRotation   = bones[rootBoneIndex].transform.localRotation;
            Vector3    deltaPosition = newPosition - rootMotionPosition;
            frame.rootMotionDeltaPositionQ = Quaternion.Inverse(Quaternion.Euler(transform.forward.normalized)) * Quaternion.Euler(deltaPosition.normalized);
            frame.rootMotionDeltaPositionL = deltaPosition.magnitude;
            frame.rootMotionDeltaRotation  = Quaternion.Inverse(rootMotionRotation) * newRotation;

            if (samplingFrameIndex == 1)
            {
                gpuSkinClip.frames[0].rootMotionDeltaPositionQ = gpuSkinClip.frames[1].rootMotionDeltaPositionQ;
                gpuSkinClip.frames[0].rootMotionDeltaPositionL = gpuSkinClip.frames[1].rootMotionDeltaPositionL;
                gpuSkinClip.frames[0].rootMotionDeltaRotation  = gpuSkinClip.frames[1].rootMotionDeltaRotation;
            }
        }

        ++samplingFrameIndex;
    }
Пример #4
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);
    }
Пример #5
0
    private void Update()
    {
        if (!isSampling)
        {
            return;
        }

        int totalFrams = (int)(gpuSkinClip.length * gpuSkinClip.frameRate);

        samplingTotalFrams = totalFrams;

        if (samplingFrameIndex >= totalFrams)
        {
            if (animator != null)
            {
                animator.StopPlayback();
            }

            string savePath = null;
            if (animData == null)
            {
                savePath = EditorUtility.SaveFolderPanel("GPUSkinning Animation Data Save", GetUserPreferDir(), string.Empty);
            }
            else
            {
                string animPath = AssetDatabase.GetAssetPath(animData);
                savePath = new FileInfo(animPath).Directory.FullName.Replace('\\', '/');
            }

            if (!string.IsNullOrEmpty(savePath))
            {
                if (!savePath.Contains(Application.dataPath.Replace('\\', '/')))
                {
                    ShowDialog("Must select a directory in the project's Asset folder.");
                }
                else
                {
                    SaveUserPreferDir(savePath);

                    string dir = "Assets" + savePath.Substring(Application.dataPath.Length);

                    string savedAnimPath = dir + "/GPUSKinAnimData_" + animName + ".asset";
                    SetTextureInfo(gpuSkinAnimData);
                    EditorUtility.SetDirty(gpuSkinAnimData);
                    if (animData != gpuSkinAnimData)
                    {
                        AssetDatabase.CreateAsset(gpuSkinAnimData, savedAnimPath);
                    }
                    WriteTempData(TEMP_SAVED_ANIM_PATH, savedAnimPath);
                    animData = gpuSkinAnimData;

                    if (samplingClipIndex == 0)
                    {
                        Mesh newMesh = CreateNewMesh(smr.sharedMesh, "GPUSkinMesh");
                        if (savedMesh != null)
                        {
                            newMesh.bounds = savedMesh.bounds;
                        }
                        string savedMeshPath = dir + "/GPUSKinMesh_" + animName + ".asset";
                        AssetDatabase.CreateAsset(newMesh, savedMeshPath);
                        WriteTempData(TEMP_SAVED_MESH_PATH, savedMeshPath);
                        savedMesh = newMesh;

                        //    CreateShaderAndMaterial(dir);

                        //    CreateLODMeshes(newMesh.bounds, dir);
                    }

                    AssetDatabase.Refresh();
                    AssetDatabase.SaveAssets();
                }
            }

            isSampling = false;
            return;
        }


        float        time  = gpuSkinClip.length * ((float)samplingFrameIndex / totalFrams);
        GPUSkinFrame frame = new GPUSkinFrame();

        gpuSkinClip.frames[samplingFrameIndex] = frame;
        frame.matrices = new Matrix4x4[gpuSkinAnimData.bones.Count];
        if (animation == null)
        {
            animator.playbackTime = time;
            animator.Update(0);
        }
        else
        {
            animation.Stop();
            AnimationState animState = animation[animClip.name];
            if (animState != null)
            {
                animState.time = time;
                animation.Sample();
                animation.Play();
            }
        }
        StartCoroutine(SamplingCoroutine(frame, totalFrams));
    }