예제 #1
0
    /// <summary>
    /// 设置动画片段的Material->Shader属性,使用GPU计算动画片段数据
    /// </summary>
    /// <param name="mpb"> 需要设置的MaterialPropertyBlock </param>
    /// <param name="playingClip"> 当前播放的动画片段 </param>
    /// <param name="frameIndex"> 帧索引 </param>
    /// <param name="frame"> 帧数据 </param>
    /// <param name="rootMotionEnabled"> 是否应用RootMotion </param>
    /// <param name="lastPlayedClip"> 上一次播放的动画片段 </param>
    /// <param name="frameIndex_crossFade"> 需要CrossFade的上一个动画片段帧索引(上一次播放到的动画片段) </param>
    /// <param name="crossFadeTime"> CrossFade所花的时间 </param>
    /// <param name="crossFadeProgress"> CrossFade已经处理的时间 </param>
    public void UpdatePlayingData(
        MaterialPropertyBlock mpb, GPUSkinningClip playingClip, int frameIndex, GPUSkinningFrame frame, bool rootMotionEnabled,
        GPUSkinningClip lastPlayedClip, int frameIndex_crossFade, float crossFadeTime, float crossFadeProgress)
    {
        //Profiler.BeginSample("Res.UpdatePlayingData");

        //设置mpb的Vector属性
        mpb.SetVector(shaderPorpID_GPUSkinning_FrameIndex_PixelSegmentation, new Vector4(frameIndex, playingClip.pixelSegmentation, 0, 0));
        //如果开启RootMotion
        if (rootMotionEnabled)
        {
            Matrix4x4 rootMotionInv = frame.RootMotionInv(anim.rootBoneIndex);
            mpb.SetMatrix(shaderPropID_GPUSkinning_RootMotion, rootMotionInv);
        }

        //如果开启CrossFade
        if (IsCrossFadeBlending(lastPlayedClip, crossFadeTime, crossFadeProgress))
        {
            if (lastPlayedClip.rootMotionEnabled)
            {
                mpb.SetMatrix(shaderPropID_GPUSkinning_RootMotion_CrossFade, lastPlayedClip.frames[frameIndex_crossFade].RootMotionInv(anim.rootBoneIndex));
            }

            mpb.SetVector(shaderPorpID_GPUSkinning_FrameIndex_PixelSegmentation_Blend_CrossFade,
                          new Vector4(frameIndex_crossFade, lastPlayedClip.pixelSegmentation, CrossFadeBlendFactor(crossFadeProgress, crossFadeTime)));
        }


        //Profiler.EndSample();
    }
예제 #2
0
 public void UpdatePlayingData(MaterialPropertyBlock mpb, GPUSkinningClip playingClip, int frameIndex, GPUSkinningFrame frame, bool rootMotionEnabled)
 {
     mpb.SetFloat(shaderPorpID_GPUSkinning_FrameIndex, frameIndex);
     mpb.SetFloat(shaderPropID_GPUSkinning_PixelSegmentation, playingClip.pixelSegmentation);
     mpb.SetFloat(shaderPropID_GPUSkinning_RootMotionEnabled, rootMotionEnabled ? 1 : -1);
     if (rootMotionEnabled)
     {
         Matrix4x4 rootMotionInv = frame.RootMotionInv(anim.rootBoneIndex);
         mpb.SetMatrix(shaderPropID_GPUSkinning_RootMotion, rootMotionInv);
     }
 }
예제 #3
0
    private void UpdateJoints(GPUSkinningFrame frame)
    {
        if (joints == null)
        {
            return;
        }

        //fzy delete:never used
        //Matrix4x4[] matrices = frame.matrices;
        GPUSkinningBone[] bones = res.anim.bones;
        int numJoints           = joints.Count;

        for (int i = 0; i < numJoints; ++i)
        {
            GPUSkinningPlayerJoint joint = joints[i];
            Transform jointTransform     = Application.isPlaying ? joint.Transform : joint.transform;
            if (jointTransform != null)
            {
                // TODO: Update Joint when Animation Blend

                Matrix4x4 jointMatrix = frame.matrices[joint.BoneIndex] * bones[joint.BoneIndex].BindposeInv;
                if (playingClip.rootMotionEnabled && rootMotionEnabled)
                {
                    jointMatrix = frame.RootMotionInv(res.anim.rootBoneIndex) * jointMatrix;
                }

                jointTransform.localPosition = jointMatrix.MultiplyPoint(Vector3.zero);

                Vector3    jointDir      = jointMatrix.MultiplyVector(Vector3.right);
                Quaternion jointRotation = Quaternion.FromToRotation(Vector3.right, jointDir);
                jointTransform.localRotation = jointRotation;
            }
            else
            {
                joints.RemoveAt(i);
                --i;
                --numJoints;
            }
        }
    }
    /// <summary>
    /// 根据当前动画片段播放状态设置Material
    /// fzy remak:CPU资源消耗过多
    /// </summary>
    /// <param name="deltaTime">本帧Update消耗的时间</param>
    private void UpdateMaterial(float deltaTime)
    {
        //Profiler.BeginSample("UpdateMaterial.Other");
        int frameIndex = GetFrameIndex();

        //动画片段(WrapMode.Once)播放完毕
        if (lastPlayingClip == playingClip && lastPlayingFrameIndex == frameIndex)
        {
            //res.Update(deltaTime);
            resTime += deltaTime;
            //for (int i = 0; i < playerMonosCount; i++)
            //    playerMonos[i].UpdateMaterial(deltaTime);
            return;
        }

        //记录上一帧播放的动画片段
        lastPlayingClip = playingClip;
        //记录上一次播放的动画片段帧数(有可能跳帧)
        lastPlayingFrameIndex = frameIndex;

        blend_crossFade      = 1;
        frameIndex_crossFade = -1;
        // 新建动画帧,用于crossFade
        GPUSkinningFrame frame_crossFade = null;

        if (IsCrossFadeBlending(lastPlayedClip, crossFadeTime, crossFadeProgress))
        {
            frameIndex_crossFade = GetCrossFadeFrameIndex();
            frame_crossFade      = lastPlayedClip.frames[frameIndex_crossFade];
            blend_crossFade      = CrossFadeBlendFactor(crossFadeProgress, crossFadeTime);
        }

        GPUSkinningFrame frame = playingClip.frames[frameIndex];

        //Profiler.EndSample();

        //模型可以被看见(Culling)或者CullingMode为AlwaysAnimate
        if (Visible ||
            CullingMode == GPUSKinningCullingMode.AlwaysAnimate)
        {
            //author version
            //res.Update(deltaTime);
            resTime += deltaTime;
            //fzy remark:不需要每帧调用,已在初始化时设置属性
            //for (int i = 0; i < playerMonosCount; i++)
            //{
            //    playerMonos[i].UpdateMaterial(deltaTime);
            //}

            /*author version
             * res.UpdatePlayingData(
             *  mpb, playingClip, frameIndex, frame, playingClip.rootMotionEnabled && rootMotionEnabled,
             *  lastPlayedClip, GetCrossFadeFrameIndex(), crossFadeTime, crossFadeProgress
             * );
             * mr.SetPropertyBlock(mpb);*/

            //if (Time.frameCount % updatePreFrame != updateRemark) return;
            //Profiler.BeginSample("UpdatePlayingData");

            //计算临时变量
            isRootMotionEnabled    = playingClip.rootMotionEnabled && rootMotionEnabled;
            framePixelSegmentation = new Vector4(frameIndex, playingClip.pixelSegmentation, 0, 0);
            rootMotionInv          = frame.RootMotionInv(anim.rootBoneIndex);
            if (lastPlayedClip != null && frameIndex_crossFade >= 0)
            {
                framePixelSegmentation_Blend_CrossFade = new Vector4(frameIndex_crossFade, lastPlayedClip.pixelSegmentation, CrossFadeBlendFactor(crossFadeProgress, crossFadeTime));
                rootMotionInv_Last = lastPlayedClip.frames[frameIndex_crossFade].RootMotionInv(anim.rootBoneIndex);
            }

            //设置动画播放的Material数据
            //UpdatePlayingData(framePixelSegmentation, rootMotionInv, isRootMotionEnabled, rootMotionInv_Last, framePixelSegmentation_Blend_CrossFade);
            UpdatePlayingData();


            //Profiler.EndSample();

            //bone.isExposed
            //UpdateJoints(frame);
        }

        //Profiler.BeginSample("RootMotion");

        /*
         * if (playingClip.rootMotionEnabled && rootMotionEnabled && frameIndex != rootMotionFrameIndex)
         * {
         *  if (CullingMode != GPUSKinningCullingMode.CullCompletely)
         *  {
         *      rootMotionFrameIndex = frameIndex;
         *      DoRootMotion(frame_crossFade, 1 - blend_crossFade, false);
         *      DoRootMotion(frame, blend_crossFade, true);
         *  }
         * }*/
        //Profiler.EndSample();

        //UpdateEvents(playingClip, frameIndex, frame_crossFade == null ? null : lastPlayedClip, frameIndex_crossFade);
    }