Пример #1
0
    public void SaveMoCap(string filename = "MoCap.mocap")
    {
        var Data = new MoCapData();

        Data.BodyFrames = BodyFrames.ToArray();
        Data.FaceFrames = FaceFrames.ToArray();
        MoCapData.Serialize(ref Data, filename);
    }
Пример #2
0
    private void OnWizardCreate()
    {
        if (RootObject == null)
        {
            EditorUtility.DisplayDialog("Error!", "Please select a valid root object!", "OK");
            return;
        }

        var animator = RootObject.GetComponent <Animator>();

        if (animator == null)
        {
            EditorUtility.DisplayDialog("Error!", "Please attach a valid animator to the root object!", "OK");
            return;
        }

        if (!File.Exists(DataFile))
        {
            EditorUtility.DisplayDialog("Error!", "Please select a valid motion capture data file!", "OK");
            return;
        }

        if (Smoothness <= 0)
        {
            EditorUtility.DisplayDialog("Error!", "Please specify a valid smoothness factor!", "OK");
            return;
        }

        MoCapData.Deserialize(DataFile, out Data);
        if (EnableSmoothing)
        {
            MoCapData.Average(ref Data, Smoothness);
        }

        AssetDatabase.StartAssetEditing();

        var animationClip = GetAnimationClip(animator, RootObject, Data, ProcessBodyTransforms,
                                             ProcessFaceTransforms, ProcessFaceBlendShapes);

        AssetDatabase.CreateAsset(animationClip, "Assets/" + animationClip.name + ".anim");
        AssetDatabase.StopAssetEditing();
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
Пример #3
0
    private static AnimationClip GetAnimationClip(Animator animator, GameObject rootObject, MoCapData data,
                                                  bool processBodyTransforms, bool processFaceTransforms, bool processFaceBlendShapes)
    {
        var animationClip = new AnimationClip();

        animationClip.name      = Path.GetFileNameWithoutExtension(DataFile);
        animationClip.legacy    = true;
        animationClip.wrapMode  = WrapMode.Once;
        animationClip.frameRate = 25;

        animationClip.ClearCurves();

        if (data.BodyFrames != null && data.BodyFrames.Length > 0)
        {
            if (processBodyTransforms)
            {
                var transforms = new TransformTime[(int)MoCapKinectBone.Count][];

                for (var i = 0; i < (int)MoCapKinectBone.Count; i++)
                {
                    transforms[i] = new TransformTime[data.BodyFrames.Length];

                    for (var j = 0; j < data.BodyFrames.Length; j++)
                    {
                        transforms[i][j].Time     = data.BodyFrames[j].SkeletonTransforms[i].Time;
                        transforms[i][j].Position = Vector3.Zero;
                        transforms[i][j].Rotation = MoCapBoneMapper.LocalRotation(ref data.BodyFrames[j],
                                                                                  (MoCapKinectBone)i);
                        transforms[i][j].Scale = Vector3.One;
                    }
                }

                foreach (MoCapKinectBone kinectBone in Enum.GetValues(typeof(MoCapKinectBone)))
                {
                    if (MoCapBoneMapper.IsValidKinectBone(kinectBone))
                    {
                        var mecanimBone = MoCapBoneMapper.Kinect2Mecanim(kinectBone);
                        if (MoCapBoneMapper.IsValidMecanimBone(mecanimBone))
                        {
                            SetAnimationCurvesForBody(animator, rootObject, transforms[(int)kinectBone], animationClip,
                                                      mecanimBone, false, true, false);
                        }
                    }
                }
            }
        }

        if (data.FaceFrames != null && data.FaceFrames.Length > 0)
        {
            if (processFaceTransforms)
            {
                var transforms = new TransformTime[data.FaceFrames.Length];

                for (var i = 0; i < data.FaceFrames.Length; i++)
                {
                    transforms[i].Time     = data.FaceFrames[i].FaceTransform.Time;
                    transforms[i].Position = Vector3.Zero;
                    transforms[i].Rotation = new Quaternion(-data.FaceFrames[i].FaceTransform.Rotation.X,
                                                            data.FaceFrames[i].FaceTransform.Rotation.Y, data.FaceFrames[i].FaceTransform.Rotation.Z,
                                                            data.FaceFrames[i].FaceTransform.Rotation.W);
                    transforms[i].Scale = Vector3.One;
                }

                SetAnimationCurvesForBody(animator, rootObject, transforms, animationClip, MoCapMecanimBone.Head, false,
                                          true, false);
            }

            if (processFaceBlendShapes)
            {
                var weights =
                    new List <KeyValuePair <float, float> > [(int)MoCapMixamoFacialExpression.LastBlendShape];

                foreach (
                    MoCapKinectFacialExpression kinectFacialExpression in
                    Enum.GetValues(typeof(MoCapKinectFacialExpression)))
                {
                    if (MoCapFacialExpressionMapper.IsValidKinectFacialExpression(kinectFacialExpression))
                    {
                        for (var j = 0; j < data.FaceFrames.Length; j++)
                        {
                            MoCapMixamoFacialExpression mixamoFacialExpression;
                            float mixamoWeight;
                            MoCapFacialExpressionMapper.Kinect2Mixamo(kinectFacialExpression,
                                                                      data.FaceFrames[j].ExpressionWeights[(int)kinectFacialExpression],
                                                                      out mixamoFacialExpression, out mixamoWeight);

                            if (MoCapFacialExpressionMapper.IsValidMixamoFacialExpression(mixamoFacialExpression))
                            {
                                if (weights[(int)mixamoFacialExpression] == null)
                                {
                                    weights[(int)mixamoFacialExpression] =
                                        new List <KeyValuePair <float, float> >(data.FaceFrames.Length);
                                }

                                weights[(int)mixamoFacialExpression].Add(
                                    new KeyValuePair <float, float>(data.FaceFrames[j].FaceTransform.Time, mixamoWeight));
                            }
                        }
                    }
                }

                foreach (
                    MoCapMixamoFacialExpression mixamoFacialExpression in
                    Enum.GetValues(typeof(MoCapMixamoFacialExpression)))
                {
                    if (MoCapFacialExpressionMapper.IsValidMixamoFacialExpression(mixamoFacialExpression))
                    {
                        if (weights[(int)mixamoFacialExpression] != null &&
                            weights[(int)mixamoFacialExpression].Count > 0)
                        {
                            SetAnimationCurvesForFace(animator, rootObject,
                                                      weights[(int)mixamoFacialExpression].ToArray(), animationClip, mixamoFacialExpression);
                        }
                    }
                }
            }
        }

        animationClip.EnsureQuaternionContinuity();

        return(animationClip);
    }