Exemple #1
0
        public override void SaveAnimation(NUIHumanoidAnimation animation)
        {
            // Check if there is capture data
            if (animation == null)
            {
                UnityEngine.Debug.LogWarning("No capture data was found.");
                return;
            }

            // Map captured data to Collada data
            ColladaAnimationData data = GetColladaAnimation(animation);

            // Check filename
            string appendedFileName = string.Format("MoCapHumanoid@{0}", fileName);
            string newFileName      = appendedFileName;

            if (BaseSystem.IO.File.Exists(string.Format(SAVE_DESTINATION_FORMAT, animSaveDestination, newFileName)))
            {
                newFileName = CinemaMocapHelper.GetNewFilename(animSaveDestination, appendedFileName, "dae");
                UnityEngine.Debug.LogWarning(string.Format(NAME_DUPLICATE_ERROR_MSG, appendedFileName, newFileName));
            }

            // Save
            if (transformationType == TransformationType.Matrix)
            {
                ColladaUtility.SaveAnimationData(data, SOURCE_FILE_MATRIX_PATH, string.Format(SAVE_DESTINATION_FORMAT, animSaveDestination, newFileName), true);
            }
            else
            {
                ColladaUtility.SaveAnimationData(data, SOURCE_FILE_PATH, string.Format(SAVE_DESTINATION_FORMAT, animSaveDestination, newFileName), false);
            }
        }
        /// <summary>
        /// Create instances of all Mocap Filters in the assembly and return the collection.
        /// </summary>
        /// <returns>The collection of filters</returns>
        public static List <MocapFilter> loadAvailableFilters()
        {
            List <MocapFilter> filters = new List <MocapFilter>();

            List <Type> types = CinemaMocapHelper.GetFilters();

            foreach (Type t in types)
            {
                MocapFilter filter = Activator.CreateInstance(t) as MocapFilter;
                if (filter != null)
                {
                    filters.Add(filter);

                    foreach (NameAttribute attribute in t.GetCustomAttributes(typeof(NameAttribute), true))
                    {
                        filter.Name = attribute.Name;
                    }

                    foreach (MocapFilterAttribute attribute in t.GetCustomAttributes(typeof(MocapFilterAttribute), true))
                    {
                        filter.PreMapping = attribute.PreMapping;
                    }
                    foreach (OrdinalAttribute attribute in t.GetCustomAttributes(typeof(OrdinalAttribute), true))
                    {
                        filter.Ordinal = attribute.Ordinal;
                    }
                }
            }

            return(filters);
        }
Exemple #3
0
        private void DrawBones(ZigInputJoint[] userSkeleton)
        {
            for (int t = 0; t < userSkeleton.Length; t++)
            {
                ZigJointId    parentId    = CinemaMocapHelper.ParentBoneJoint(userSkeleton[t].Id);
                ZigInputJoint parentJoint = null;

                for (int s = 0; s < userSkeleton.Length; s++)
                {
                    if (userSkeleton[s].Id == parentId)// find parent and leave loop.
                    {
                        parentJoint = userSkeleton[s];
                        break;
                    }
                }

                if (parentJoint != null && parentJoint.Id != ZigJointId.None && userSkeleton[t].GoodPosition && parentJoint.GoodPosition)
                {
                    // parent and child joint coordinates
                    int childX  = textureSize.Width / 2 - (int)(userSkeleton[t].Position.x * 300 / userSkeleton[t].Position.z);
                    int childY  = textureSize.Height / 2 - (int)(userSkeleton[t].Position.y * 300 / userSkeleton[t].Position.z);
                    int parentX = textureSize.Width / 2 - (int)(parentJoint.Position.x * 300 / parentJoint.Position.z);
                    int parentY = textureSize.Height / 2 - (int)(parentJoint.Position.y * 300 / parentJoint.Position.z);

                    // draw lines between joints
                    Color color = (!userSkeleton[t].Inferred) ? Color.cyan : Color.red;
                    CinemaMocapHelper.drawFastLine(outputPixels, textureSize.Width, textureSize.Height, childX, childY, parentX, parentY, color);
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// Load all of the mocap profiles found in the project.
        /// </summary>
        private void loadMocapProfiles()
        {
            inputProfiles.Clear();

            List <Type> types = CinemaMocapHelper.GetInputProfiles();

            foreach (Type t in types)
            {
                foreach (InputProfileAttribute attribute in t.GetCustomAttributes(typeof(InputProfileAttribute), true))
                {
                    inputProfiles.Add(new TypeLabelContextData(t, attribute.ProfileName));
                }
            }
        }
        /// <summary>
        /// Load all output profiles context data found in the assembly.
        /// </summary>
        public static List <TypeLabelContextData> LoadMetaData()
        {
            List <TypeLabelContextData> outputProfiles = new List <TypeLabelContextData>();

            List <Type> types = CinemaMocapHelper.GetOutputProfiles();

            foreach (Type t in types)
            {
                foreach (OutputProfileAttribute attribute in t.GetCustomAttributes(typeof(OutputProfileAttribute), true))
                {
                    outputProfiles.Add(new TypeLabelContextData(t, attribute.Name));
                }
            }

            return(outputProfiles);
        }
Exemple #6
0
        internal static List <Type> GetSensorEditorViewers(params SupportedDevice[] devices)
        {
            List <Type> viewers = new List <Type>();

            foreach (Type type in CinemaMocapHelper.GetAllSubTypes(typeof(SensorEditorViewer)))
            {
                foreach (SensorEditorViewerAttribute attribute in type.GetCustomAttributes(typeof(SensorEditorViewerAttribute), true))
                {
                    if (attribute != null && ArrayUtility.Contains <SupportedDevice>(devices, attribute.Device))
                    {
                        viewers.Add(type);
                    }
                }
            }
            return(viewers);
        }
Exemple #7
0
        private void DrawJoints(ZigInputJoint[] userSkeleton)
        {
            int xMid = textureSize.Width / 2;
            int yMid = textureSize.Height / 2;

            for (int t = 0; t < userSkeleton.Length; t++)
            {
                if (userSkeleton[t].GoodPosition)
                {
                    int x = xMid - (int)(userSkeleton[t].Position.x * 300 / userSkeleton[t].Position.z);
                    int y = yMid - (int)(userSkeleton[t].Position.y * 300 / userSkeleton[t].Position.z);

                    Color color = (!userSkeleton[t].Inferred) ? Color.cyan : Color.red;
                    CinemaMocapHelper.drawFastBox(outputPixels, textureSize.Width, textureSize.Height, x - 2, y - 2, x + 2, y + 2, color);
                }
            }
        }
Exemple #8
0
        /// <summary>
        /// Load all input profiles context data found in the assembly.
        /// </summary>
        public static List <InputProfileMetaData> LoadMetaData(params MocapWorkflow[] filter)
        {
            List <InputProfileMetaData> metaData = new List <InputProfileMetaData>();

            List <Type> types = CinemaMocapHelper.GetInputProfiles();

            foreach (Type t in types)
            {
                foreach (InputProfileAttribute attribute in t.GetCustomAttributes(typeof(InputProfileAttribute), true))
                {
                    if (Array.Exists <MocapWorkflow>(filter, item => item == attribute.MocapPhase))
                    {
                        metaData.Add(new InputProfileMetaData(t, attribute));
                    }
                }
            }

            return(metaData);
        }
        public static List <MappingProfile> LoadMappingProfiles(InputSkeletonType inputSkeleton)
        {
            List <MappingProfile> mappingProfiles = new List <MappingProfile>();

            List <Type> types = CinemaMocapHelper.GetMappingProfiles();

            foreach (Type t in types)
            {
                foreach (MappingProfileAttribute attribute in t.GetCustomAttributes(typeof(MappingProfileAttribute), true))
                {
                    if (attribute.InputSkeleton == inputSkeleton)
                    {
                        mappingProfiles.Add(Activator.CreateInstance(t) as MappingProfile);
                    }
                }
            }

            return(mappingProfiles);
        }
Exemple #10
0
        /// <summary>
        /// Load all of the layout profiles found in the project.
        /// </summary>
        private void loadLayoutProfiles()
        {
            layoutProfiles.Clear();

            List <Type> types = CinemaMocapHelper.GetLayoutProfiles();

            foreach (Type t in types)
            {
                foreach (CinemaMocapLayoutAttribute attribute in t.GetCustomAttributes(typeof(CinemaMocapLayoutAttribute), true))
                {
                    layoutProfiles.Add(new TypeLabelContextData(t, attribute.Name, attribute.Ordinal));
                }
            }

            layoutProfiles.Sort(delegate(TypeLabelContextData x, TypeLabelContextData y)
            {
                return(x.Ordinal - y.Ordinal);
            });
        }
        public static List <MappingProfileMetaData> LoadMetaData(InputSkeletonType inputSkeleton)
        {
            var metaData = new List <MappingProfileMetaData>();

            List <Type> types = CinemaMocapHelper.GetMappingProfiles();

            foreach (Type t in types)
            {
                foreach (MappingProfileAttribute attribute in t.GetCustomAttributes(typeof(MappingProfileAttribute), true))
                {
                    if (attribute.InputSkeleton == inputSkeleton)
                    {
                        metaData.Add(new MappingProfileMetaData(t, attribute));
                    }
                }
            }

            return(metaData);
        }
        /// <summary>
        /// Load all of the layout profiles found in the project.
        /// </summary>
        public static List <TypeLabelContextData> LoadMetaData()
        {
            List <TypeLabelContextData> layoutProfiles = new List <TypeLabelContextData>();

            List <Type> types = CinemaMocapHelper.GetLayoutProfiles();

            foreach (Type t in types)
            {
                foreach (CinemaMocapLayoutAttribute attribute in t.GetCustomAttributes(typeof(CinemaMocapLayoutAttribute), true))
                {
                    layoutProfiles.Add(new TypeLabelContextData(t, attribute.Name, attribute.Ordinal));
                }
            }

            layoutProfiles.Sort(delegate(TypeLabelContextData x, TypeLabelContextData y)
            {
                return(x.Ordinal - y.Ordinal);
            });

            return(layoutProfiles);
        }
        private void DrawBones(Rect areaContent)
        {
            GUILayout.BeginArea(areaContent);
            Color origHandles = Handles.color;

            foreach (Dictionary <JointType, Windows.Kinect.Joint> jointDictionary in trackedBodyJoints)
            {
                foreach (Windows.Kinect.Joint joint in jointDictionary.Values)
                {
                    // find parent joint
                    JointType            parentJointType = CinemaMocapHelper.ParentBoneJoint(joint.JointType);
                    Windows.Kinect.Joint parentJoint;

                    jointDictionary.TryGetValue(parentJointType, out parentJoint);

                    // get position of each joint
                    ColorSpacePoint childPos  = coordinateMapper.MapCameraPointToColorSpace(joint.Position);
                    ColorSpacePoint parentPos = coordinateMapper.MapCameraPointToColorSpace(parentJoint.Position);

                    // set color depending on child joint tracking state
                    if (joint.TrackingState == Windows.Kinect.TrackingState.Tracked)
                    {
                        Handles.color = Color.green;
                    }
                    else if (joint.TrackingState == Windows.Kinect.TrackingState.Inferred)
                    {
                        Handles.color = Color.red;
                    }

                    // draw bone/line between joints using CinemaMocapHelper
                    Handles.DrawLine(new Vector3((childPos.X / ColorWidth) * areaContent.width, (childPos.Y / ColorHeight) * areaContent.height, 0), new Vector3((parentPos.X / ColorWidth) * areaContent.width, (parentPos.Y / ColorHeight) * areaContent.height, 0));
                }
            }

            Handles.color = origHandles;
            GUILayout.EndArea();
        }
Exemple #14
0
        /// <summary>
        /// Draw the Window's contents
        /// </summary>
        protected void OnGUI()
        {
            // Show Defaults options
            EditorGUILayout.Foldout(true, "Defaults");
            EditorGUI.indentLevel++;

            GUIContent[] mocapProfileContent = new GUIContent[inputProfiles.Count];
            for (int i = 0; i < inputProfiles.Count; i++)
            {
                mocapProfileContent[i] = new GUIContent(inputProfiles[i].Label);
            }
            int tempProfileSelection = EditorGUILayout.Popup(new GUIContent("Device", "Profile"), mocapProfileSelection, mocapProfileContent);

            if (mocapProfileSelection != tempProfileSelection)
            {
                mocapProfileSelection = tempProfileSelection;
                EditorPrefs.SetString(InputProfileKey, inputProfiles[mocapProfileSelection].Label);
            }

            GUIContent[] layoutContent = new GUIContent[layoutProfiles.Count];
            for (int i = 0; i < layoutProfiles.Count; i++)
            {
                layoutContent[i] = new GUIContent(layoutProfiles[i].Label);
            }
            int tempSelection = EditorGUILayout.Popup(new GUIContent("Layout", "Layout"), layoutProfileSelection, layoutContent);

            if (tempSelection != layoutProfileSelection)
            {
                layoutProfileSelection = tempSelection;
                EditorPrefs.SetString(LayoutKey, layoutProfiles[layoutProfileSelection].Label);
            }

            // Check if save locations have changed from mocap window
            if (anim20JointSaveDestination != EditorPrefs.GetString(Anim20JointSaveDestKey))
            {
                anim20JointSaveDestination = EditorPrefs.GetString(Anim20JointSaveDestKey);
                anim20AbsPath = (Application.dataPath).Replace("Assets", anim20JointSaveDestination);
            }
            if (anim25JointSaveDestination != EditorPrefs.GetString(Anim25JointSaveDestKey))
            {
                anim25JointSaveDestination = EditorPrefs.GetString(Anim25JointSaveDestKey);
                anim25AbsPath = (Application.dataPath).Replace("Assets", anim25JointSaveDestination);
            }
            if (sessionSaveDestination != EditorPrefs.GetString(Anim20JointSaveDestKey))
            {
                sessionSaveDestination = EditorPrefs.GetString(SessionSaveDestKey);
                sessionAbsPath         = (Application.dataPath).Replace("Assets", sessionSaveDestination);
            }

            // 20 Joint Save Path Field & Button

            EditorGUILayout.PrefixLabel("Kinect 1 Anim Save:");

            EditorGUILayout.BeginHorizontal();

            EditorGUI.indentLevel++;
            EditorGUILayout.SelectableLabel(anim20JointSaveDestination, EditorStyles.textField, GUILayout.Height(16f));
            EditorGUI.indentLevel--;


            if (GUILayout.Button(new GUIContent("..."), EditorStyles.miniButton, GUILayout.Width(24f)))
            {
                // Ensure the path text field does not have focus, or else we cannot change the contents.
                GUI.SetNextControlName("");
                GUI.FocusControl("");

                string temp = EditorUtility.SaveFolderPanel("Select a folder within your project", anim20JointSaveDestination, "");

                // Pressing cancel returns an empty string, don't clear the previous text on cancel.
                if (temp != string.Empty)
                {
                    anim20AbsPath = temp;
                }
            }

            EditorGUILayout.EndHorizontal();

            // Display error if path not within project folder
            if (!anim20AbsPath.StartsWith(Application.dataPath))
            {
                EditorGUILayout.HelpBox("Invalid selection!\nYou must select a location within your project's \"Assets\" folder.", MessageType.Warning);
                anim20JointSaveDestination = CinemaMocapHelper.GetRelativeProjectPath(Application.dataPath);
                EditorPrefs.SetString(Anim20JointSaveDestKey, anim20JointSaveDestination);
            }
            else
            {
                anim20JointSaveDestination = CinemaMocapHelper.GetRelativeProjectPath(anim20AbsPath);
                EditorPrefs.SetString(Anim20JointSaveDestKey, anim20JointSaveDestination);
            }

            // 25 Joint Save Path Field & Button

            EditorGUILayout.PrefixLabel("Kinect 2 Anim Save:");

            EditorGUILayout.BeginHorizontal();

            EditorGUI.indentLevel++;
            EditorGUILayout.SelectableLabel(anim25JointSaveDestination, EditorStyles.textField, GUILayout.Height(16f));
            EditorGUI.indentLevel--;


            if (GUILayout.Button(new GUIContent("..."), EditorStyles.miniButton, GUILayout.Width(24f)))
            {
                // Ensure the path text field does not have focus, or else we cannot change the contents.
                GUI.SetNextControlName("");
                GUI.FocusControl("");

                string temp = EditorUtility.SaveFolderPanel("Select a folder within your project", anim25JointSaveDestination, "");

                // Pressing cancel returns an empty string, don't clear the previous text on cancel.
                if (temp != string.Empty)
                {
                    anim25AbsPath = temp;
                }
            }

            EditorGUILayout.EndHorizontal();

            // Display error if path not within project folder
            if (!anim25AbsPath.StartsWith(Application.dataPath))
            {
                EditorGUILayout.HelpBox("Invalid selection!\nYou must select a location within your project's \"Assets\" folder.", MessageType.Warning);
                anim25JointSaveDestination = CinemaMocapHelper.GetRelativeProjectPath(Application.dataPath);
                EditorPrefs.SetString(Anim25JointSaveDestKey, anim25JointSaveDestination);
            }
            else
            {
                anim25JointSaveDestination = CinemaMocapHelper.GetRelativeProjectPath(anim25AbsPath);
                EditorPrefs.SetString(Anim25JointSaveDestKey, anim25JointSaveDestination);
            }

            // Session Save Path Field & Button

            EditorGUILayout.PrefixLabel("Session Save:");

            EditorGUILayout.BeginHorizontal();

            EditorGUI.indentLevel++;
            EditorGUILayout.SelectableLabel(sessionSaveDestination, EditorStyles.textField, GUILayout.Height(16f));
            EditorGUI.indentLevel--;


            if (GUILayout.Button(new GUIContent("..."), EditorStyles.miniButton, GUILayout.Width(24f)))
            {
                // Ensure the path text field does not have focus, or else we cannot change the contents.
                GUI.SetNextControlName("");
                GUI.FocusControl("");

                string temp = EditorUtility.SaveFolderPanel("Select a folder within your project", sessionSaveDestination, "");

                // Pressing cancel returns an empty string, don't clear the previous text on cancel.
                if (temp != string.Empty)
                {
                    sessionAbsPath = temp;
                }
            }

            EditorGUILayout.EndHorizontal();

            // Display error if path not within project folder
            if (!sessionAbsPath.StartsWith(Application.dataPath))
            {
                EditorGUILayout.HelpBox("Invalid selection!\nYou must select a location within your project's \"Assets\" folder.", MessageType.Warning);
                sessionSaveDestination = CinemaMocapHelper.GetRelativeProjectPath(Application.dataPath);
                EditorPrefs.SetString(SessionSaveDestKey, sessionSaveDestination);
            }
            else
            {
                sessionSaveDestination = CinemaMocapHelper.GetRelativeProjectPath(sessionAbsPath);
                EditorPrefs.SetString(SessionSaveDestKey, sessionSaveDestination);
            }

            EditorGUI.indentLevel--;

            //EditorGUILayout.Foldout(true, "Developers");

            //EditorGUI.indentLevel++;
            //bool tempDevMode = EditorGUILayout.Toggle(new GUIContent("Developer Mode"), developerMode);
            //if (tempDevMode != developerMode)
            //{
            //    developerMode = tempDevMode;
            //    EditorPrefs.SetBool(DeveloperModeKey, tempDevMode);
            //}
            //EditorGUI.indentLevel--;
        }
Exemple #15
0
        public override void DrawPipelineSettings()
        {
            int tempDelaySelection = EditorGUILayout.Popup(new GUIContent("Start Delay", "The delay in seconds before recording begins after pressing the record button."), delaySelection, delays);

            if (tempDelaySelection != delaySelection)
            {
                delaySelection = tempDelaySelection;
                EditorPrefs.SetInt(RECORD_START_DELAY_KEY, delaySelection);
            }

            bool isDeveloperModeEnabled = true;

            if (isDeveloperModeEnabled)
            {
                bool tempSaveSession = EditorGUILayout.Toggle(new GUIContent("Save Session", "Saves the raw data of the session in the project folder for later use."), saveSession);

                if (tempSaveSession != saveSession)
                {
                    saveSession = tempSaveSession;
                    EditorPrefs.SetBool(PIPELINE_SAVE_SESSION_KEY, saveSession);
                }

                if (saveSession)
                {
                    // Check if save location has changed from settings window
                    if (sessionSaveDestination != EditorPrefs.GetString(PIPELINE_SAVE_DESTINATION_KEY))
                    {
                        sessionSaveDestination = EditorPrefs.GetString(PIPELINE_SAVE_DESTINATION_KEY);
                        absPath = (Application.dataPath).Replace("Assets", sessionSaveDestination);
                    }

                    string tempFileName = EditorGUILayout.TextField(new GUIContent("Session Filename"), fileName);

                    if (tempFileName != fileName)
                    {
                        fileName = tempFileName;
                        EditorPrefs.SetString(PIPELINE_SAVE_FILENAME_KEY, fileName);
                    }

                    EditorGUILayout.PrefixLabel("Save Location:");

                    EditorGUILayout.BeginHorizontal();

                    EditorGUI.indentLevel++;
                    EditorGUILayout.SelectableLabel(sessionSaveDestination, EditorStyles.textField, GUILayout.Height(16f));
                    EditorGUI.indentLevel--;


                    bool saveDestChanged = false;
                    if (GUILayout.Button(new GUIContent("..."), EditorStyles.miniButton, GUILayout.Width(24f)))
                    {
                        // Ensure the path text field does not have focus, or else we cannot change the contents.
                        GUI.SetNextControlName("");
                        GUI.FocusControl("");

                        string temp = EditorUtility.SaveFolderPanel("Select a folder within your project", sessionSaveDestination, "");

                        // Pressing cancel returns an empty string, don't clear the previous text on cancel.
                        if (temp != string.Empty)
                        {
                            absPath = temp;
                        }

                        saveDestChanged = true;
                    }

                    EditorGUILayout.EndHorizontal();

                    // Display error if path not within project folder
                    if (!absPath.StartsWith(Application.dataPath))
                    {
                        EditorGUILayout.HelpBox("Invalid selection!\nYou must select a location within your project's \"Assets\" folder.", MessageType.Warning);
                        sessionSaveDestination = CinemaMocapHelper.GetRelativeProjectPath(Application.dataPath);
                    }
                    else
                    {
                        sessionSaveDestination = CinemaMocapHelper.GetRelativeProjectPath(absPath);
                    }

                    if (saveDestChanged)
                    {
                        EditorPrefs.SetString(PIPELINE_SAVE_DESTINATION_KEY, sessionSaveDestination);
                    }
                }
            }

            EditorGUI.BeginDisabledGroup(!InputProfile.IsDeviceOn);

            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.PrefixLabel(" ");
            if (GUILayout.Button(captureState == RecordingState.NotRecording ? new GUIContent("Record") : new GUIContent("Stop"), EditorStyles.miniButton))
            {
                if (captureState == RecordingState.NotRecording)
                {
                    int delaySeconds = int.Parse(delays[delaySelection].text.Split(' ')[0]);
                    StartRecording(delaySeconds);
                }
                else
                {
                    MocapSession session = StopRecording();
                    saveAnimation(session);
                }
            }
            EditorGUILayout.EndHorizontal();
            EditorGUI.EndDisabledGroup();
        }
Exemple #16
0
        public override void DrawOutputSettings()
        {
            // Check if save location has changed from settings window
            if (animSaveDestination != EditorPrefs.GetString(SAVE_DESTINATION_KEY))
            {
                animSaveDestination = EditorPrefs.GetString(SAVE_DESTINATION_KEY);
                absPath             = (Application.dataPath).Replace("Assets", animSaveDestination);
            }

            TransformationType tempTransformationType = (TransformationType)EditorGUILayout.EnumPopup(new GUIContent("Transformation Type"), transformationType);

            if (tempTransformationType != transformationType)
            {
                transformationType = tempTransformationType;
                EditorPrefs.SetInt(TRANSFORMATION_TYPE_KEY, (int)transformationType);
            }

            //int tempFrameRate = EditorGUILayout.IntField(new GUIContent("Frame Rate", "The amount of frames to create per second in the output animation."), frameRate);

            //if (tempFrameRate != frameRate)
            //{
            //    frameRate = tempFrameRate;
            //    EditorPrefs.SetInt(FRAME_RATE_KEY, frameRate);
            //}



            int tempFrameRateIndex = EditorGUILayout.Popup("Frame Rate", selectedFrameRateIndex, new string[2] {
                "30 FPS", "60 FPS"
            });

            if (tempFrameRateIndex != selectedFrameRateIndex)
            {
                selectedFrameRateIndex = tempFrameRateIndex;
                EditorPrefs.SetInt(FRAME_RATE_INDEX_KEY, selectedFrameRateIndex);
            }

            string tempFileName = EditorGUILayout.TextField(new GUIContent("Animation Name", "The name of the animation when saved to .dae format."), fileName);

            if (tempFileName != fileName)
            {
                fileName = tempFileName;
                EditorPrefs.SetString(FILENAME_KEY, fileName);
            }

            // Save Path Field & Button

            EditorGUILayout.PrefixLabel("Save Location:");

            EditorGUILayout.BeginHorizontal();

            EditorGUI.indentLevel++;
            EditorGUILayout.SelectableLabel(animSaveDestination, EditorStyles.textField, GUILayout.Height(16f));
            EditorGUI.indentLevel--;

            bool saveDestChanged = false;

            if (GUILayout.Button(new GUIContent("..."), EditorStyles.miniButton, GUILayout.Width(24f)))
            {
                // Ensure the path text field does not have focus, or else we cannot change the contents.
                GUI.SetNextControlName("");
                GUI.FocusControl("");

                string temp = EditorUtility.SaveFolderPanel("Select a folder within your project", animSaveDestination, "");

                // Pressing cancel returns an empty string, don't clear the previous text on cancel.
                if (temp != string.Empty)
                {
                    absPath = temp;
                }

                saveDestChanged = true;
            }

            EditorGUILayout.EndHorizontal();

            // Display error if path not within project folder
            if (!absPath.StartsWith(Application.dataPath))
            {
                EditorGUILayout.HelpBox("Invalid selection!\nYou must select a location within your project's \"Assets\" folder.", MessageType.Warning);
                animSaveDestination = CinemaMocapHelper.GetRelativeProjectPath(Application.dataPath);
            }
            else
            {
                animSaveDestination = CinemaMocapHelper.GetRelativeProjectPath(absPath);
            }

            if (saveDestChanged)
            {
                EditorPrefs.SetString(SAVE_DESTINATION_KEY, animSaveDestination);
            }
        }
        /// <summary>
        /// Once capture is complete, request the OutputProfile to save the animation.
        /// </summary>
        protected void saveAnimation(MocapSession session)
        {
            if (OutputProfile == null)
            {
                Debug.LogWarning("No Output method was found. Animation was not saved");
                return;
            }
            if (MappingProfile == null)
            {
                Debug.LogWarning("No Mapping method was found. Animation was not saved");
                return;
            }
            if (session == null)
            {
                return;
            }

            var animation = new NUIHumanoidAnimation();
            var cache     = new CaptureCache();

            foreach (MocapSessionKeyframe keyframe in session.CaptureData)
            {
                var elapsedTime = keyframe.ElapsedMilliseconds;
                var skeleton    = NUICaptureHelper.GetNUISkeleton(keyframe.Skeleton);

                cache.AddNewFrame(skeleton, elapsedTime);

                // Filter the raw input with enabled filters.
                NUISkeleton filtered = skeleton;
                foreach (MocapFilter filter in preMapFilters)
                {
                    if (filter.Enabled)
                    {
                        filtered = filter.Filter(cache);
                        cache.AddFiltered(filter.Name, filtered);
                    }
                }

                // Convert the input skeleton to the normalized skeleton (Unity)
                NUISkeleton mapped = MappingProfile.MapSkeleton(filtered);
                cache.AddMapped(mapped);

                // Apply any post-mapped filters selected by the user.
                filtered = mapped;
                foreach (MocapFilter filter in postMapFilters)
                {
                    if (filter.Enabled)
                    {
                        filtered = filter.Filter(cache);
                        cache.AddFiltered(filter.Name, filtered);
                    }
                }
                cache.AddResult(filtered);

                filtered.Joints[NUIJointType.SpineBase].Position = skeleton.Joints[NUIJointType.SpineBase].Position;
                animation.AddKeyframe(filtered, keyframe.ElapsedMilliseconds);
            }

            // Save the session
            if (saveSession)
            {
                string newFileName = fileName;
                if (BaseSystem.IO.File.Exists(string.Format(SAVE_DESTINATION_FORMAT, sessionSaveDestination, newFileName)))
                {
                    newFileName = CinemaMocapHelper.GetNewFilename(sessionSaveDestination, fileName, "asset");
                    UnityEngine.Debug.LogWarning(string.Format(NAME_DUPLICATE_ERROR_MSG, fileName, newFileName));
                }

                AssetDatabase.CreateAsset(session, string.Format(SAVE_DESTINATION_FORMAT, sessionSaveDestination, newFileName));
                AssetDatabase.SaveAssets();
            }

            // Save the animation
            OutputProfile.SaveAnimation(animation);
            AssetDatabase.Refresh();
        }