Esempio n. 1
0
        void OnEnable()
        {
            FacePlus.StartUp();

            if (Application.HasProLicense())        // TODO: report pro license required
            {
                record      = Resources.Load("Record Button") as Texture;
                stop        = Resources.Load("Stop Button") as Texture;
                play        = Resources.Load("Play Button") as Texture;
                stopPlaying = Resources.Load("Stop Button - Gray") as Texture;
            }


            options = new Options()
            {
                mode                 = (Mode)EditorPrefs.GetInt("FacePlus.Options.Mode", (int)Mode.Realtime),
                recordAudio          = EditorPrefs.GetBool("FacePlus.Options.RecordAudio", true),
                spacebarRecord       = EditorPrefs.GetBool("FacePlus.Options.SpacebarRecord", true),
                warnBeforeDelete     = EditorPrefs.GetBool("FacePlus.Options.WarnBeforeDelete", true),
                requiresConfirmation = EditorPrefs.GetBool("FacePlus.Options.RequiresConfirmation", true),
                keyframeReduction    = EditorPrefs.GetBool("FacePlus.Options.KeyframeReduction", false),
                smoothTangents       = EditorPrefs.GetBool("FacePlus.Options.SmoothTangents", false),
                changeCamera         = EditorPrefs.GetBool("FacePlus.Options.ChangeCamera", false), //flag to change capture device
                cameraLost           = EditorPrefs.GetBool("FacePlus.Options.CameraLost", false)    //flag to change capture device
            };

            recordButtonTexture = record;
        }
            public void RecordModule()
            {
                for (int i = 0; i < affectedBlendshapes.Length; i++)
                {
                    string shape = affectedBlendshapes[i];

                    float[] channelVector = FacePlus.GetCurrentVector();
                    for (int j = 0; j < channelVector.Length; j++)
                    {
                        string channel = FacePlus.GetChannelName(j);
                        if (shape == channel)
                        {
                            //shaper.channelMapping[channel].Offset *= sensitivity;
                            float amount = 100f / (channelVector[j] + shaper.channelMapping[channel].Offset / 100f);
                            //float s = Mathf.Clamp((amount-100f)/300f, 0f, 1f);
                            //amount = amount * s * s * (3 - 2 * s);
                            //amount = amount * s * s * s* (s*(6*s - 15)+10);

                            shaper.channelMapping[channel].Scale = amount;
                            Debug.Log("recorded " + shape + " scale: " + shaper.channelMapping[shape].Scale
                                      + " offset : " + shaper.channelMapping[shape].Offset);
                        }
                    }
                }
            }
    void SolveSetDrivenKeys()
    {
        foreach (Transform j in faceJoints)
        {
            Vector3 curTranslate = initialTranslation[j];
            Vector3 curRotate    = initialRotation[j];
            Vector3 curScale     = initialScale[j];

            for (int i = 0; i < FacePlus.ChannelCount; i++)
            {
                string channelName = FacePlus.GetChannelName(i);
                if (!channelName.Contains("Head_Joint::") && !channelName.Contains("_Eye_Joint::"))
                {
                    var map = FaceCapture.Instance.channelMapping;
                    if (!map.ContainsKey(channelName))
                    {
                        return;
                    }
                    curTranslate += Vector3.Lerp(Vector3.zero, (map[channelName] as SetDrivenKeyTarget).deltaTranslate[j], map[channelName].Amount / 100);
                    curRotate    += Vector3.Lerp(Vector3.zero, (map[channelName] as SetDrivenKeyTarget).deltaRotate[j], map[channelName].Amount / 100);
                    curScale     += Vector3.Lerp(Vector3.zero, (map[channelName] as SetDrivenKeyTarget).deltaScale[j], map[channelName].Amount / 100);
                }
            }
            j.localPosition = curTranslate;
            j.localRotation = Quaternion.Euler(curRotate);
            j.localScale    = curScale;
        }
    }
 void DoLogin()
 {
     FacePlus.StartUp();
     Authentication.Login(user, pass, (msg) => {
         Debug.Log("Logged in successfully");
         shouldStartTracking = true;
         _login_str          = msg;
     }, (error, message) => {
         shouldClearLogin    = true;
         login_error_message = error;
         _login_str          = message;
     }, "Demo");
 }
        void SetBaseline()
        {
            float[] channelVector = FacePlus.GetCurrentVector();


            for (int i = 0; i < channelVector.Length; i++)
            {
                string channel = FacePlus.GetChannelName(i);
                if (!channel.Contains("Mix::"))
                {
                    continue;
                }
                if (shaper.channelMapping.ContainsKey(channel))
                {
                    shaper.channelMapping[channel].Offset = -channelVector[i] * shaper.channelMapping[channel].Scale;
                    //Debug.Log ("set baseline for " + channel + " as  " + channelVector[i]);
                }
            }
        }
    void OnGUI()
    {
        //Error handling
        if (FacePlus.HasError && FacePlus.GetError() != "")
        {
            faceplus_error_message = FacePlus.GetError();
            GUILayout.Window(0, windowRect, ErrorWindow, "Mixamo Face Plus");
        }
        if (Authentication.CanUseFacePlus &&
            FacePlus.IsInitComplete)
        {
            return;
        }

        windowRect = new Rect(Screen.width / 2 - windowWidth / 2,
                              3 * Screen.height / 4 - windowHeight / 2,
                              windowWidth,
                              windowHeight);

        GUILayout.Window(0, windowRect, LoginWindow, "Mixamo Face Plus");
    }
Esempio n. 7
0
        void CameraSelectGUI()  //handles camera selection
        {
            bool changeFlag = false;

            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("Camera:", GUILayout.Width(100));

            //Camera selection dropdown
            int cameraCount = FacePlus.GetCameraCount();

            cams = new string[cameraCount];
            for (int j = 0; j < cameraCount; j++)
            {
                cams[j] = FacePlus.GetCameraDeviceName(j);
            }
            if (cams == null || cams.Length < 1)
            {
                cams = new string[] { "No Cameras detected" }
            }
            ;
            if (currentCamIndex > cams.Length - 1)
            {
                currentCamIndex = 0;
            }

            //check for changes in status
            if (!string.IsNullOrEmpty(currentCam))
            {
                if (currentCam.CompareTo(cams[currentCamIndex]) != 0)
                {
                    int j;
                    for (j = 0; j < cameraCount; j++)
                    {
                        if (cams[j].CompareTo(currentCam) == 0)
                        {
                            currentCamIndex = j;
                            break;
                        }
                    }
                    //camera no longer exists
                    if (j == cameraCount)
                    {
                        options.cameraLost = true;
                    }
                }
            }

            int index = EditorGUILayout.Popup(currentCamIndex, cams);

            currentCam = cams[index];
            if (index < cams.Length + 1)
            {
                //if the camera has changed or been lost
                if ((index != currentCamIndex) || options.cameraLost)
                {
                    options.cameraLost   = false;
                    options.changeCamera = true;
                    Debug.Log("New Camera Device Selected.");
                }
                currentCamIndex = index;
            }
            FacePlus.DeviceID = index;
            EditorGUILayout.EndHorizontal();
        }

        void RealtimeCaptureGUI()
        {
            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("Microphone:", GUILayout.Width(100));
            //Microphone selection dropdown
            string[] devices = Microphone.devices;
            mics    = new string[devices.Length + 1];
            mics[0] = "Disabled";
            for (int i = 0; i < devices.Length; i++)
            {
                mics[i + 1] = devices[i];
            }
            if (mics == null || mics.Length <= 1)
            {
                mics = new string[] { "No microphones detected" }
            }
            ;
            if (EditorPrefs.HasKey("FacePlus.Microphone"))
            {
                currentMicIndex = EditorPrefs.GetInt("FacePlus.Microphone");
            }
            if (currentMicIndex > mics.Length - 1)
            {
                currentMicIndex = 0;
            }
            int index = EditorGUILayout.Popup(currentMicIndex, mics);

            if (index < mics.Length)
            {
                currentMic      = mics[index];
                currentMicIndex = index;
            }
            EditorPrefs.SetInt("FacePlus.Microphone", currentMicIndex);
            if (currentMic == "No microphones detected" || currentMic == "Disabled")
            {
                options.recordAudio = false;
            }
            else
            {
                options.recordAudio = true;
            }

            EditorGUILayout.EndHorizontal();

            //camera selection GUI
            CameraSelectGUI();

            //  track
            EditorGUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));

            // record or stop recording
            if (character.State == CaptureState.Recording)
            {
                if (GUILayout.Button(stop, GUILayout.Width(60)) || SpacePressed())
                {
                    if (options.recordAudio)
                    {
                        Microphone.End(currentMic);
                    }

                    character.StopRecording(() => {
                        SaveClip();
                        SaveAudioClip();
                        Repaint();
                    });
                }
            }
            else
            {
                GUI.enabled = character.CanRecord;
                if (GUILayout.Button(record, GUILayout.Width(60)) || SpacePressed())
                {
                    if (!character.Live)
                    {
                        character.StartLiveTracking();
                    }
                    if (clip != null && clip.length > 1.00f && options.requiresConfirmation)
                    {
                        overwrite = EditorUtility.DisplayDialog("This take will be overwritten!", "You can create a new take to avoid overwriting.",
                                                                "Record anyway", "Cancel");
                        if (!overwrite)
                        {
                            return;
                        }
                        overwrite = false;
                    }
                    character.OnStartRecording += StartRecordAudio;             //add audiorecord to event so it doesn't go too early
                    character.StartRecording();
                    Repaint();
                }
            }

            if (character.State == CaptureState.Playing)
            {
                if (GUILayout.Button(stopPlaying, GUILayout.Width(60)))
                {
                    character.StopPlayback();
                    PlayBackAudio(false);
                    Repaint();
                }
            }
            else
            {
                GUI.enabled = character.CanPlay;
                if (GUILayout.Button(play, GUILayout.Width(60)))
                {
                    character.StartPlayback();
                    PlayBackAudio(true);
                    Repaint();
                }
            }

            if (options.changeCamera)
            {
                options.changeCamera = false;
                if (character.State == CaptureState.Live)
                {
                    FacePlus.StopTracking();
                }
                character.StartLiveTracking();
            }

            if (character != null && character.State == CaptureState.BakingAnimation)
            {
                ProgressBar(character.Progress, "Baking Animation");
            }
            else
            {
                TimeSliderGUI();
            }

            GUI.enabled = true;

            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();

            //	GUILayout.Label ("Record Audio:");
            //	options.recordAudio = EditorGUILayout.Toggle (options.recordAudio, GUILayout.Width (15));
            if (character != null)
            {
                if (options.mode == Mode.Realtime && !character.Live && Authentication.CanUseFacePlus)
                {
                    Logger.Info("start live tracking - toggled checkbox");
                    if (character.Movie != null)
                    {
                        character.Movie.Dispose();
                    }
                    character.StartLiveTracking();
                    Logger.Info("done calling startlivetracking");
                }
            }
            EditorGUILayout.EndHorizontal();

            if (GUILayout.Button("Check Minimum Requirements"))
            {
                Application.OpenURL("http://hubs.ly/y02VLJ0");
            }
        }

        void OfflineCaptureGUI()
        {
            /*EditorGUILayout.BeginHorizontal(); //Titles Grouping Start
             * EditorGUILayout.LabelField("Animate from imported movie", EditorStyles.boldLabel);
             * EditorGUILayout.EndHorizontal(); // Titles Grouping End
             */

            EditorGUILayout.BeginHorizontal();     // Video Select Grouping Start
            GUILayout.Label("Video:", GUILayout.Width(100));
            if (GUILayout.Button("Browse...", GUILayout.Width(70)))
            {
                videoPath = EditorUtility.OpenFilePanel("Select your Video", "", "");
            }
            GUILayout.Label(Path.GetFileName(videoPath)); // TODO: Clip the path!
            EditorGUILayout.EndHorizontal();              // Video Select Grouping End

            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("Frame Rate: ", GUILayout.Width(100));
            frameRate = EditorGUILayout.FloatField(frameRate, GUILayout.Width(35));
            EditorGUILayout.EndHorizontal();


            EditorGUILayout.BeginHorizontal();


            if (character.State == CaptureState.RecordingFromVideo)
            {
                if (GUILayout.Button(stop, GUILayout.Width(60)) || SpacePressed() || character.videoFinished)              //if video finishes
                {
                    character.StopRecordingFromVideo(() => {
                        character.videoFinished = false;
                        SaveClip();
                        Repaint();
                    });
                }
            }
            else
            {
                GUI.enabled = character.CanRecord;
                if (GUILayout.Button(record, GUILayout.Width(60)) || SpacePressed())
                {
                    if (clip != null && clip.length > 0f && options.requiresConfirmation)
                    {
                        Logger.Info("overwriting");

                        overwrite = EditorUtility.DisplayDialog("This take will be overwritten!", "You can create a new take to avoid overwriting",
                                                                "Record anyway", "Cancel");
                        if (!overwrite)
                        {
                            return;
                        }
                        overwrite = false;
                    }
                    if (!string.IsNullOrEmpty(videoPath))
                    {
                        var videoFolder   = Path.GetDirectoryName(videoPath);
                        var videoFilename = Path.GetFileName(videoPath);

                        character.SetImportMovie(videoFolder, videoFilename);
                    }
                    else                 // TODO: error about no file selected
                    {
                    }
                    Repaint();
                }
            }

            if (character.State == CaptureState.PlayingWithVideo)
            {
                if (GUILayout.Button(stopPlaying, GUILayout.Width(60)))
                {
                    character.StopPlaybackWithVideo();
                    Repaint();
                }
            }
            else
            {
                GUI.enabled = character.CanPlayWithVideo;
                if (GUILayout.Button(play, GUILayout.Width(60)))
                {
                    character.StartPlaybackWithVideo();
                    Repaint();
                }
            }


            if (character != null && character.State == CaptureState.RecordingFromVideo)
            {
                GUI.enabled = true;
                ProgressBar(character.Progress, "Processing Video: " + character.CurrentVideoFrame + " / " + character.TotalVideoFrames);
            }
            else if (character != null && character.State == CaptureState.BakingAnimation)
            {
                GUI.enabled = true;
                ProgressBar(character.Progress, "Baking Animation");
            }
            else
            {
                TimeSliderGUI();
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.Space();
            GUI.enabled = true;
        }

        void TimeSliderGUI()
        {
            GUILayout.BeginVertical();
            timeSlider = character.Progress;
            timeSlider = GUILayout.HorizontalSlider(timeSlider, 0.0f, 1.0f);      // 0 - 1 so you can force normalized playback across the timeline
            GUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();
            var tmp = GUI.enabled;

            GUI.enabled = true;
            GUILayout.Label(string.Format("Time: {0,5:##0.0} / {1,2:0.0}",
                                          character.ClipPosition,
                                          character.ClipLength));
            GUI.enabled = tmp;
            GUILayout.EndHorizontal();
            GUILayout.EndVertical();
        }

        void FacePlusErrorGUI()
        {
            Color previousContent = GUI.contentColor;

            EditorGUILayout.BeginHorizontal();
            GUI.contentColor = Color.red;
            GUILayout.Label("Faceplus Error: " + FacePlus.GetError());
            EditorGUILayout.EndHorizontal();
            GUI.contentColor = previousContent;
        }

        void FacePlusMessageGUI()
        {
            GUILayout.BeginHorizontal();
            GUIStyle style = new GUIStyle(EditorStyles.label);

            style.wordWrap = true;
            style.padding  = new RectOffset(5, 5, 5, 5);
            GUILayout.Label(_login_str, style);
            if (GUILayout.Button("Dismiss"))
            {
                _login_str = null;
            }
            GUILayout.EndHorizontal();
            Divider();
            EditorGUILayout.Space();
        }

        void MainGUI()
        {
            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();

            if (GUILayout.Button(displayName, EditorStyles.miniButton))
            {
                Authentication.Logout();
                _login_str = null;
                EditorPrefs.DeleteKey("FacePlus.Password");
                password = "";
                if (character.State == CaptureState.Live)
                {
                    character.StopLiveTracking();
                }
                needsRepainting = true;
            }

            EditorGUILayout.EndHorizontal();

            Divider();
            EditorGUILayout.Space();
            //Errors
            if (FacePlus.HasError && FacePlus.GetError() != "")
            {
                FacePlusErrorGUI();
            }
            //Messages
            if (_login_str != null && _login_str != "")
            {
                FacePlusMessageGUI();
            }
            //Takes
            GUILayout.BeginHorizontal();
            GUILayout.Label("Current Take:", GUILayout.Width(100));
            var newClip = (AnimationClip)EditorGUILayout.ObjectField(clip, typeof(AnimationClip));

            GUILayout.EndHorizontal();

            // load a clip if the clip changes
            if (newClip != clip && newClip != null)
            {
                clip = newClip;
                if (character != null && character.channelMapping != null)
                {
                    character.Load(clip);
                }
            }


            // load a clip if we don't have one already
            if (character != null && clip != null && !character.HasClip && character.channelMapping != null)
            {
                character.Load(clip);
            }

            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("", GUILayout.Width(100));
            if (GUILayout.Button("Create New"))
            {
                clip = CreateClip();
            }

            // Disable following buttons when there's no clip.
            GUI.enabled = clip != null;
            if (GUILayout.Button("Find in Assets"))
            {
                //Find the clip within the Project window in Unity.
                EditorGUIUtility.PingObject(clip);
            }

            GUI.enabled = true;

            EditorGUILayout.EndHorizontal();

            GUILayout.EndVertical();

            EditorGUILayout.BeginVertical();     //Super V
            EditorGUILayout.Space();

            if (!EditorApplication.isPlaying)
            {
                needsLoginStringCleared = true;
                if (GUILayout.Button("Start Scene"))
                {
                    EditorApplication.isPlaying = true;
                    Repaint();
                }
                EditorGUILayout.Space();
            }
            else if (character == null)
            {
                GUILayout.Label("Please attach a FaceCapture component to your Character.");
            }
            else
            {
                Divider();

                // Mode Selection Dropdown
                EditorGUILayout.Space();
                EditorGUILayout.BeginHorizontal();

                GUILayout.Label("Capture Mode:", GUILayout.Width(100));
                int newMode = EditorGUILayout.Popup((int)options.mode, modes);
                if ((Mode)newMode != options.mode)
                {
                    // TODO: do cleanup when switching modes
                    if (newMode != (int)Mode.Realtime)
                    {
                        character.StopLiveTracking();
                    }
                    options.mode = (Mode)newMode;
                }
                EditorGUILayout.EndHorizontal();

                if (options.mode == Mode.Realtime)
                {
                    /*if(character.State != CaptureState.Live){
                     *              character.Movie.Dispose();
                     *      }*/
                    RealtimeCaptureGUI();
                }
                else
                {
                    OfflineCaptureGUI();
                }
                EditorGUILayout.Space();
            }

            //Divider();
            OptionsGUI();
            EditorGUILayout.Space();
            Divider();
            CalibrateGUI();
            FuseGUI();

            LinkGUI();
        }

        void OnGUI()
        {
            autoRepaintOnSceneChange = true;


            var c = FaceCapture.Instance;

            if (character == null && c != null && Authentication.CanUseFacePlus)
            {
                if (options.mode == Mode.Realtime)
                {
                    Logger.Info("Starting tracking...");
                    c.StartLiveTracking();
                }
            }
            character = c;


            if (character)
            {
                character.OnStopPlayback -= OnPlaybackStopped;
                character.OnStopPlayback += OnPlaybackStopped;
            }

            EditorGUILayout.Space();
            GUILayout.BeginVertical();      // 1

            if (!Authentication.CanUseFacePlus)
            {
                LoginWindow();
            }
            else
            {
                MainGUI();
            }

            EditorGUILayout.EndVertical();
        }

        private AnimationClip CreateClip()
        {
            string path = EditorUtility.SaveFilePanelInProject("New Animation Clip",
                                                               FirstAvailableClipName(), "anim", "Where would you like to save this?");

            Logger.Info("Got this path to create clip in: " + path);

            if (!string.IsNullOrEmpty(path))
            {
                AnimationClip emptyClip = new AnimationClip();

                        #if !UNITY_4_2
                AnimationUtility.SetAnimationType(emptyClip, ModelImporterAnimationType.Generic);
                        #endif

                AssetDatabase.CreateAsset(emptyClip, path);
                AssetDatabase.Refresh();

                Logger.Info("Clip is null? " + (emptyClip == null));
                return(emptyClip);
            }

            return(null);
        }
    public Dictionary <string, AnimationTarget> CreateMap()
    {
        var channelMapping = new Dictionary <string, AnimationTarget>();

        //create empty targets for all face joints
        for (int i = 0; i < FacePlus.ChannelCount; i++)
        {
            string channelName = FacePlus.GetChannelName(i);
            if (!channelName.Contains("Head_Joint::") && !channelName.Contains("_Eye_Joint::"))
            {
                Debug.Log("Mapped channel to SDK: " + channelName + " => " + faceJoints);
                channelMapping.Add(channelName, new SetDrivenKeyTarget(faceJoints));
            }
        }


        //read preset if any
        Hashtable sdkDefinition = (Hashtable)JSON.JsonDecode(SDK_Definition.text);

        if (sdkDefinition != null)
        {
            foreach (var sdkKey in sdkDefinition.Keys)
            {
                var    sdk     = (Hashtable)sdkDefinition[sdkKey];
                string sdkName = "Mix::" + sdkKey;
                foreach (var jointKey in sdk.Keys)
                {
                    var joint = (Hashtable)sdk[jointKey];
                    //find matching transform
                    Transform jointXform = faceJoints.Where((j) => j.name.ToString() == jointKey.ToString())
                                           .DefaultIfEmpty(null)
                                           .LastOrDefault();
                    if (jointXform == null)
                    {
                        continue;
                    }

                    float dtx = 0f;
                    float dty = 0f;
                    float dtz = 0f;
                    float drx = 0f;
                    float dry = 0f;
                    float drz = 0f;
                    float dsx = 0f;
                    float dsy = 0f;
                    float dsz = 0f;
                    foreach (var attrKey in joint.Keys)
                    {
                        var val = float.Parse(joint[attrKey].ToString());
                        switch ((attrKey as string))
                        {
                        case "dtx":
                            dtx = val;
                            break;

                        case "dty":
                            dty = val;
                            break;

                        case "dtz":
                            dtz = val;
                            break;

                        case "drx":
                            drx = val;
                            break;

                        case "dry":
                            dry = val;
                            break;

                        case "drz":
                            drz = val;
                            break;

                        case "dsx":
                            dsx = val;
                            break;

                        case "dsy":
                            dsy = val;
                            break;

                        case "dsz":
                            dsz = val;
                            break;
                        }
                    }
                    //set mapping
                    (channelMapping[sdkName] as SetDrivenKeyTarget).deltaTranslate[jointXform] = new Vector3(dtx, dty, dtz);
                    (channelMapping[sdkName] as SetDrivenKeyTarget).deltaRotate[jointXform]    = new Vector3(drx, dry, drz);
                    (channelMapping[sdkName] as SetDrivenKeyTarget).deltaScale[jointXform]     = new Vector3(dsx, dsy, dsz);
                }
            }
        }


        // Head rotation

        if (headJoint != null)
        {
            channelMapping.Add("Head_Joint::Rotation_X",
                               new JointTarget("Head_Joint::Rotation_X", TransformComponent.LocalRotationX, headJoint));
            channelMapping.Add("Head_Joint::Rotation_Y",
                               new JointTarget("Head_Joint::Rotation_Y", TransformComponent.LocalRotationY, headJoint, -1.0f));
            channelMapping.Add("Head_Joint::Rotation_Z",
                               new JointTarget("Head_Joint::Rotation_Z", TransformComponent.LocalRotationZ, headJoint, -1.0f));
            // animation requires the w component, but we are animating with euler angles,
            // so need to add a dummy channel to capture w
            channelMapping.Add("Head Joint W",
                               new JointTarget("Head Joint W", TransformComponent.LocalRotationW, headJoint));
        }

        // Left Eye
        if (leftEye != null)
        {
            channelMapping.Add("Left_Eye_Joint::Rotation_X",
                               new JointTarget("Left_Eye_Joint::Rotation_X", TransformComponent.LocalRotationX, leftEye));
            channelMapping.Add("Left_Eye_Joint::Rotation_Y",
                               new JointTarget("Left_Eye_Joint::Rotation_Y", TransformComponent.LocalRotationY, leftEye, -1.0f));
            channelMapping.Add("Left Eye Z",
                               new JointTarget("Left Eye Z", TransformComponent.LocalRotationZ, leftEye));
            channelMapping.Add("Left Eye W",
                               new JointTarget("Left Eye W", TransformComponent.LocalRotationW, leftEye));
        }

        // Right Eye
        if (rightEye != null)
        {
            channelMapping.Add("Right_Eye_Joint::Rotation_X",
                               new JointTarget("Right_Eye_Joint::Rotation_X", TransformComponent.LocalRotationX, rightEye));
            channelMapping.Add("Right_Eye_Joint::Rotation_Y",
                               new JointTarget("Right_Eye_Joint::Rotation_Y", TransformComponent.LocalRotationY, rightEye, -1.0f));
            channelMapping.Add("Right Eye Z",
                               new JointTarget("Right Eye Z", TransformComponent.LocalRotationZ, rightEye));
            channelMapping.Add("Right Eye W",
                               new JointTarget("Right Eye W", TransformComponent.LocalRotationW, rightEye));
        }


        // Add all the face joints, so their values get recorded
        foreach (var joint in faceJoints)
        {
            channelMapping.Add(joint.name + " r.x",
                               new JointTarget(joint.name + " r.x", TransformComponent.LocalRotationX, joint));
            channelMapping.Add(joint.name + " r.y",
                               new JointTarget(joint.name + " r.y", TransformComponent.LocalRotationY, joint));
            channelMapping.Add(joint.name + " r.z",
                               new JointTarget(joint.name + " r.z", TransformComponent.LocalRotationZ, joint));
            channelMapping.Add(joint.name + " r.w",
                               new JointTarget(joint.name + " r.w", TransformComponent.LocalRotationW, joint));

            /*
             * channelMapping.Add (joint.name + " s.x",
             *                  new JointTarget(joint.name + " s.x", TransformComponent.LocalScaleX, joint));
             * channelMapping.Add (joint.name + " s.y",
             *                  new JointTarget(joint.name + " s.y", TransformComponent.LocalScaleY, joint));
             * channelMapping.Add (joint.name + " s.z",
             *                  new JointTarget(joint.name + " s.z", TransformComponent.LocalScaleZ, joint));
             */
            channelMapping.Add(joint.name + " p.x",
                               new JointTarget(joint.name + " p.x", TransformComponent.LocalPositionX, joint));
            channelMapping.Add(joint.name + " p.y",
                               new JointTarget(joint.name + " p.y", TransformComponent.LocalPositionY, joint));
            channelMapping.Add(joint.name + " p.z",
                               new JointTarget(joint.name + " p.z", TransformComponent.LocalPositionZ, joint));
            /**/
        }


        return(channelMapping);
    }