protected virtual void OnSceneGUI()
    {
        float         size          = 0.1f;
        MotionMatcher motionMatcher = (MotionMatcher)target;

        currentMotionsData = motionMatcher.motionsData;
        if (currentMotionsData)
        {
            Transform   child  = motionMatcher.transform.Find(MotionMatchingBakeEditor.RootBoneName);
            Transform[] joints = child.GetComponentsInChildren <Transform>();

            for (int i = 0; i < currentMotionsData.motionDataList.Length; i++)
            {
                MotionData motionData = currentMotionsData.motionDataList[i];
                if (motionData.motionName == motionMatcher.bestMotionName ||
                    (string.IsNullOrEmpty(motionMatcher.bestMotionName) && motionData.motionName == defaultMotionName))
                {
                    for (int j = 0; j < motionData.motionFrameDataList.Length; j++)
                    {
                        MotionFrameData motionFrameData = motionData.motionFrameDataList[j];

                        for (int k = 0; k < motionFrameData.motionBoneDataList.Length; k++)
                        {
                            MotionBoneData motionBoneData = motionFrameData.motionBoneDataList[k];
                            Transform      bone           = joints[motionBoneData.boneIndex];
                            if (bone)
                            {
                                Vector3 bonePosition = motionBoneData.position;
                                Handles.color = Color.green;
                                Handles.SphereHandleCap(0, bonePosition, Quaternion.identity, size, EventType.Repaint);
                            }
                        }

                        for (int l = 0; l < motionFrameData.motionTrajectoryDataList.Length; l++)
                        {
                            MotionTrajectoryData motionTrajectoryData = motionFrameData.motionTrajectoryDataList[l];
                            Handles.color = Color.yellow;
                            Handles.SphereHandleCap(0, motionTrajectoryData.position, Quaternion.identity, size, EventType.Repaint);
                        }
                    }
                }
            }
        }
    }
Example #2
0
    private void CreateSnapshots()
    {
        UnityEditor.Animations.AnimatorController bakeController = null;

        string assetPath = GetPrefabPath();

        if (string.IsNullOrEmpty(assetPath))
        {
            EditorUtility.DisplayDialog("Mesh Animator", "Unable to locate the asset path for prefab: " + prefab.name, "OK");
            return;
        }

        HashSet <string> allAssets = new HashSet <string>();

        List <AnimationClip> clips = GetClips();

        foreach (var clip in clips)
        {
            allAssets.Add(AssetDatabase.GetAssetPath(clip));
        }

        string[] split = assetPath.Split("/".ToCharArray());

        string assetFolder = string.Empty;

        for (int s = 0; s < split.Length - 1; s++)
        {
            assetFolder += split[s] + "/";
        }

        var sampleGO = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity) as GameObject;

        sampleGO.name = prefab.name;

        animator = sampleGO.GetComponent <Animator>();
        if (animator == null)
        {
            animator = sampleGO.GetComponentInChildren <Animator>();
        }
        InitAnimationBones(sampleGO);
        if (requiresAnimator)
        {
            bakeController = CreateBakeController();
            if (animator == null)
            {
                animator = sampleGO.AddComponent <Animator>();
                animator.runtimeAnimatorController = bakeController;
                animator.avatar = GetAvatar();
            }
            else
            {
                animator.runtimeAnimatorController = bakeController;
                animator.avatar = GetAvatar();
            }
            animator.cullingMode     = AnimatorCullingMode.AlwaysAnimate;
            animator.applyRootMotion = true;
        }

        MotionsData meshAnimationList = ScriptableObject.CreateInstance <MotionsData>();

        meshAnimationList.motionDataList = new MotionData[clips.Count];

        Transform rootMotionBaker = new GameObject().transform;

        for (int x = 0; x < clips.Count; x++)
        {
            AnimationClip animClip = clips[x];

            if (bakeAnims.ContainsKey(animClip.name) && bakeAnims[animClip.name] == false)
            {
                continue;
            }
            if (frameSkips.ContainsKey(animClip.name) == false)
            {
                Debug.LogWarningFormat("No animation with name {0} in frame skips", animClip.name);
                continue;
            }
            string meshAnimationPath = string.Format("{0}{1}.asset", assetFolder, FormatClipName(animClip.name));

            int bakeFrames = Mathf.CeilToInt(animClip.length * fps);
            meshAnimationList.motionDataList[x] = new MotionData();
            MotionData motionData = meshAnimationList.motionDataList[x];
            motionData.motionName = animClip.name;

            int totalFrame = 0;
            for (int i = 0; i < bakeFrames; i += frameSkips[animClip.name])
            {
                totalFrame++;
            }
            motionData.motionFrameDataList = new MotionFrameData[totalFrame];

            int frame = 0;
            for (int i = 0; i < bakeFrames; i += frameSkips[animClip.name])
            {
                motionData.motionFrameDataList[frame] = new MotionFrameData();
                motionData.motionFrameDataList[frame].motionBoneDataList       = new MotionBoneData[bonesMap.Count];
                motionData.motionFrameDataList[frame].motionTrajectoryDataList = new MotionTrajectoryData[predictionTrajectoryTimeList.Length];
                for (int i1 = 0; i1 < bonesMap.Count; i1++)
                {
                    motionData.motionFrameDataList[frame].motionBoneDataList[i1] = new MotionBoneData();
                }
                for (int i2 = 0; i2 < predictionTrajectoryTimeList.Length; i2++)
                {
                    motionData.motionFrameDataList[frame].motionTrajectoryDataList[i2] = new MotionTrajectoryData();
                }
                frame++;
            }
        }

        int animCount = 0;

        for (int j = 0; j < clips.Count; j++)
        {
            //Vector3.zero, Quaternion.identity
            sampleGO.transform.position = Vector3.zero;
            sampleGO.transform.rotation = Quaternion.identity;
            AnimationClip animClip   = clips[j];
            MotionData    motionData = meshAnimationList.motionDataList[j];
            int           bakeFrames = Mathf.CeilToInt(animClip.length * fps);

            int frame = 0;
            for (int i = 0; i < bakeFrames; i += frameSkips[animClip.name])
            {
                float bakeDelta = Mathf.Clamp01(((float)i / bakeFrames));
                EditorUtility.DisplayProgressBar("Baking Animation", string.Format("Processing: {0} Frame: {1}", animClip.name, i), bakeDelta);
                float           animationTime       = bakeDelta * animClip.length;
                MotionFrameData motionFrameData     = motionData.motionFrameDataList[frame];
                MotionFrameData lastMotionFrameData = frame > 0 ? motionData.motionFrameDataList[frame - 1] : null;

                CaptureBoneSnapShot(animClip, motionFrameData, lastMotionFrameData, sampleGO, bakeFrames, i);
                CaptureTrajectorySnapShot(animClip, motionFrameData, lastMotionFrameData, sampleGO, bakeFrames, i);

                frame++;
            }
            animCount++;
        }

        //string TargetPath = Application.dataPath + "/Resources/" + sampleGO.name + "_MotionField1.asset";
        //AssetDatabase.DeleteAsset(TargetPath);
        //AssetDatabase.CreateAsset(meshAnimationList, TargetPath);

        AssetDatabase.CreateAsset(meshAnimationList, assetFolder + sampleGO.name + "_MotionField.asset");

        GameObject.DestroyImmediate(sampleGO);
        EditorUtility.ClearProgressBar();
        EditorUtility.DisplayDialog("MotionField", string.Format("Baked {0} motionField {1} successfully!", clips.Count, clips.Count > 1 ? "s" : string.Empty), "OK");

        try
        {
            //Wait
        }
        catch (System.Exception e)
        {
            EditorUtility.ClearProgressBar();
            EditorUtility.DisplayDialog("Bake Error", string.Format("There was a problem baking the animations.", e), "OK");
        }
        finally
        {
            if (bakeController)
            {
                AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(bakeController));
            }
        }
    }