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); }
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); } } }
/// <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); }
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); }
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); } } }
/// <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); }
/// <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(); }
/// <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--; }
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(); }
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(); }