/// <summary> /// Draw editor window interface. /// </summary> void OnGUI() { InitUI(); if (!AvatarMakerInitializer.IsPlatformSupported()) { GUILayout.Space(20); EditorGUILayout.HelpBox("Avatar Maker plugin supports only Windows platform and works in the Editor mode.", MessageType.Error); return; } if (EditorApplication.isPlaying) { GUILayout.Space(20); EditorGUILayout.HelpBox("Avatar Maker plugin doesn't work in the Play mode.", MessageType.Error); return; } if (AvatarMakerInitializer.IsInitializationInProgress) { GUILayout.Space(20); EditorGUILayout.HelpBox("Loading...", MessageType.Info); return; } GUILayout.BeginVertical(); { scrollWindow = GUILayout.BeginScrollView(scrollWindow); { OnGUIAvatarGenerationSection(); GUILayout.Space(20); OnGUISelectedAvatarSection(); GUILayout.Space(20); OnGUIAvatarsListSection(); } GUILayout.EndScrollView(); } GUILayout.EndVertical(); if (!string.IsNullOrEmpty(ProgressText)) { GUILayout.TextArea("Progress: " + ProgressText, GUILayout.MinHeight(40), GUILayout.MaxHeight(40)); } else { GUILayout.Space(40); } }
private void OnEnable() { if (!AvatarMakerInitializer.IsPlatformSupported()) { Debug.LogError("Avatar plugin supports only Windows platform and works in the Editor mode."); return; } if (!AvatarMakerInitializer.IsInitialized) { AvatarMakerInitializer.StartInitialization(); } avatarProvider = AvatarMakerInitializer.AvatarProvider; UpdateAvatarList(); }
private void OnEnable() { if (!AvatarMakerInitializer.IsPlatformSupported()) { Debug.LogError("Avatar plugin supports only Windows platform and works in the Editor mode."); return; } if (!AvatarMakerInitializer.IsInitialized) { AvatarMakerInitializer.StartInitialization(); } #if UNITY_2018_1_OR_NEWER EditorApplication.hierarchyChanged += OnHierarchyChanged; #else EditorApplication.hierarchyWindowChanged += OnHierarchyChanged; #endif OnHierarchyChanged(); }
void OnGUI() { InitUI(); GUILayout.Label("Facial Motion Capture", titleStyle); GUILayout.Space(20); if (!AvatarMakerInitializer.IsPlatformSupported()) { EditorGUILayout.HelpBox("Avatar Maker plugin supports only Windows platform and works in the Editor mode.", MessageType.Error); return; } if (EditorApplication.isPlaying) { GUILayout.Space(20); EditorGUILayout.HelpBox("Avatar Maker plugin doesn't work in the Play mode.", MessageType.Error); return; } if (AvatarMakerInitializer.IsInitializationInProgress) { EditorGUILayout.HelpBox("Loading...", MessageType.Info); return; } if (!AvatarMakerInitializer.IsMotionCaptureSupported) { EditorGUILayout.HelpBox("Your CPU doesn't have AVX extension required for Motion Tracking.", MessageType.Error); return; } if (isEditAnimationMode) { if (animationModifier != null && animationModifier.IsValidAvatarAnimation) { OnGuiEditAnimation(); return; } else { isEditAnimationMode = false; } } if (avatarInfo == null) { if (isCapturing) { avatarAnimator.StopCapturing(); avatarAnimator = null; isCapturing = false; } if (AnimationMode.InAnimationMode()) { ToggleAnimationMode(); } EditorGUILayout.HelpBox(avatarErrorLabel, MessageType.Info); return; } scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition); WebCamDevice[] cameraDevices = WebCamTexture.devices; if (cameraDevices != null && cameraDevices.Length > 0) { if (!isCapturing) { if (cameraDevices.Length > 1) { string[] cameraNames = cameraDevices.Select(d => { return(d.name); }).ToArray(); cameraId = GUILayout.SelectionGrid(cameraId, cameraNames, 1, "toggle"); } else { cameraId = 0; } } EditorGUI.BeginDisabledGroup(avatarInfo == null); capturingButtonLabel = isCapturing ? "Stop capturing" : "Start capturing"; isCapturing = GUILayout.Toggle(isCapturing, capturingButtonLabel, "Button"); EditorGUI.EndDisabledGroup(); } else { EditorGUILayout.HelpBox("There is no available web camera.", MessageType.Info); } if (isCapturing) { capturingErrorLabel = string.Empty; if (avatarAnimator == null) { avatarAnimator = new AvatarAnimator(avatarInfo.transform, avatarInfo.headMeshRenderer, cameraOffset); isCapturing = avatarAnimator.StartCapturing(WebCamTexture.devices[cameraId].name, avatarInfo.code); if (!isCapturing) { capturingErrorLabel = "Unable to start motion capture."; Debug.LogError(capturingErrorLabel); avatarAnimator = null; return; } ApplyBlendshapesImpact(); if (AvatarAnimator.RecordAtStart) { StartRecording(); } if (AnimationMode.InAnimationMode()) { ToggleAnimationMode(); } } Texture2D tex = avatarAnimator.HandleCapturedFrame(); DisplayFrameTexture(tex); } else { if (avatarAnimator != null) { avatarAnimator.StopCapturing(); avatarAnimator = null; } } if (!string.IsNullOrEmpty(capturingErrorLabel)) { EditorGUILayout.HelpBox(capturingErrorLabel, MessageType.Error); } GUILayout.Space(20); EditorGUILayout.BeginVertical("Box"); { EditorGUILayout.LabelField("Recording options", titleStyle); GUILayout.Space(5); if (isCapturing) { recordingButtonLabel = avatarAnimator.IsRecording ? "Stop recording" : "Start recording"; if (avatarAnimator.IsRecording != GUILayout.Toggle(avatarAnimator.IsRecording, recordingButtonLabel, "Button")) { if (avatarAnimator.IsRecording) { StopRecording(); } else { StartRecording(); } } GUILayout.Space(5); } AvatarAnimator.RecordAtStart = GUILayout.Toggle(AvatarAnimator.RecordAtStart, "Record at start"); recordedAnimationClip = (AnimationClip)EditorGUILayout.ObjectField("Animation file: ", recordedAnimationClip, typeof(AnimationClip), false); AvatarAnimator.ApplyTranslation = GUILayout.Toggle(AvatarAnimator.ApplyTranslation, "Capture translation"); AvatarAnimator.ApplyRotation = GUILayout.Toggle(AvatarAnimator.ApplyRotation, "Capture rotation"); } EditorGUILayout.EndVertical(); GUILayout.Space(10); OnGuiPlayingAnimation(); if (!string.IsNullOrEmpty(exportErrorLabel)) { EditorGUILayout.HelpBox(exportErrorLabel, MessageType.Error); ShowAvatarMakerProLink(); } GUILayout.Space(10); showBlendshapeCoefficients = EditorGUILayout.Foldout(showBlendshapeCoefficients, "Blendshapes Impact"); if (showBlendshapeCoefficients) { if (blendshapesImpactControls.Count == 0) { List <string> blendshapeNames = AvatarAnimator.GetBlendshapesNames(); for (int i = 0; i < blendshapeNames.Count; i++) { blendshapesImpactControls.Add(blendshapeNames[i], new SliderWithTextValues(1.0f)); blendshapesImpactValues.Add(blendshapeNames[i], 1f); } } blendshapesScrollPosition = GUILayout.BeginScrollView(blendshapesScrollPosition, GUILayout.Height(Mathf.Max(200f, position.height - 200f))); var blendshapesNames = blendshapesImpactControls.Keys.ToList <string>(); for (int i = 0; i < blendshapesNames.Count; i++) { SliderWithTextValues controlsValues = blendshapesImpactControls[blendshapesNames[i]]; GUILayout.BeginHorizontal(); GUILayout.Label(blendshapesNames[i] + ":", GUILayout.MaxWidth(100)); float blendshapeImpactVal = GUILayout.HorizontalSlider(controlsValues.sliderValue, 0, maxImpactValue); if (blendshapeImpactVal != controlsValues.sliderValue) { controlsValues.SetValue(blendshapeImpactVal); blendshapesImpactValues[blendshapesNames[i]] = blendshapeImpactVal; ApplyBlendshapesImpact(); } string modifiedValueStr = GUILayout.TextField(controlsValues.textValue, GUILayout.Width(100)); if (modifiedValueStr != blendshapeImpactVal.ToString()) { controlsValues.textValue = modifiedValueStr; if (float.TryParse(modifiedValueStr, out blendshapeImpactVal) && blendshapeImpactVal >= 0 && blendshapeImpactVal <= maxImpactValue) { controlsValues.sliderValue = blendshapeImpactVal; blendshapesImpactValues[blendshapesNames[i]] = blendshapeImpactVal; ApplyBlendshapesImpact(); } } GUILayout.EndHorizontal(); } GUILayout.Space(10); GUILayout.BeginHorizontal(); if (GUILayout.Button("Save", buttonSkin)) { SaveBlendshapesImpactValues(); } if (GUILayout.Button("Load", buttonSkin)) { LoadBlendshapesImpactValues(); } GUILayout.EndHorizontal(); GUILayout.Space(10); GUILayout.EndScrollView(); } EditorGUILayout.EndScrollView(); if (isCapturing) { Repaint(); } }
/// <summary> /// Draw editor window interface. /// </summary> void OnGUI() { InitUI(); GUILayout.Label("Avatar Maker", titleStyle); if (!AvatarMakerInitializer.IsPlatformSupported()) { GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label("Avatar plugin supports only Windows platform and works in the Editor mode."); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); return; } if (AvatarMakerInitializer.IsInitializationInProgress) { GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label(EditorApplication.isPlaying?"Exit play mode to load SDK":"Loading..."); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); return; } float windowSizeX = position.size.x; GUILayout.Space(20); GUILayout.Label("Generate Avatar: ", titleStyle); if (!AvatarMakerPlugin.IsProVersion()) { int countAvailableAvatars = AvatarMakerPlugin.CountAvailableAvatars(); if (countAvailableAvatars > 0) { EditorGUILayout.HelpBox(string.Format("You have {0} avatar(s) to generate in the Free-version.", countAvailableAvatars), MessageType.Info); } else { EditorGUILayout.HelpBox("You exceeded the number of generated avatars available in the Free-version!", MessageType.Error); } cameraPreviewYOffset = 135f; } GUILayout.BeginHorizontal(); if (GUILayout.Button("Select Photo")) { string path = EditorUtility.OpenFilePanel("Select image", "", "jpg,png"); if (path.Length != 0) { var fileContent = File.ReadAllBytes(path); Debug.Log(fileContent.Length + " bytes file selected"); EditorRunner.instance.Run(GenerateAndDisplayHeadRoutine(fileContent, pipelineType)); } } isCameraCapturing = GUILayout.Toggle(isCameraCapturing, "Web Camera", "Button"); GUILayout.EndHorizontal(); if (isCameraCapturing) { WebCamDevice[] devices = webCameraController.Devices; if (devices.Length > 0) { scrollWebCams = GUILayout.BeginScrollView(scrollWebCams, GUILayout.Width(150), GUILayout.Height(200)); for (int i = 0; i < devices.Length; i++) { WebCamDevice device = devices[i]; if (GUILayout.Button(device.name)) { selectedWebCamIndex = i; StartCapturing(devices[i]); } } GUILayout.EndScrollView(); if (!webCameraController.IsCapturing) { if (selectedWebCamIndex < devices.Length) { StartCapturing(devices[selectedWebCamIndex]); } } else { var texture = webCameraController.Texture; if (photoPreview != null) { OnGUIPhotoPreview(photoPreview); GUILayout.BeginHorizontal(); if (GUILayout.Button("Reset")) { DestroyImmediate(photoPreview); photoPreview = null; } if (GUILayout.Button("Generate avatar!")) { byte[] bytes = photoPreview.EncodeToPNG(); EditorRunner.instance.Run(GenerateAndDisplayHeadRoutine(bytes, pipelineType, asyncResult => { DestroyImmediate(photoPreview); photoPreview = null; })); isCameraCapturing = false; } GUILayout.EndHorizontal(); } else { OnGUIPhotoPreview(texture); GUILayout.BeginHorizontal(); GUILayout.Label("WebCam: " + selectedWebCam.name, GUILayout.Width(180)); GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label("Resolution: ", GUILayout.Width(80)); webcamWidthString = GUILayout.TextField(webcamWidthString, "Label", GUILayout.Width(40)); webcamHeightString = GUILayout.TextField(webcamHeightString, "Label", GUILayout.Width(40)); int parsedWidth = 640; int parsedHeight = 480; GUILayout.FlexibleSpace(); if (int.TryParse(webcamWidthString, out parsedWidth)) { //webcamWidth = parsedWidth; } else { webcamWidthString = texture.width.ToString(); } if (int.TryParse(webcamHeightString, out parsedHeight)) { //webcamHeight = parsedHeight; } else { webcamHeightString = texture.height.ToString(); } if (parsedWidth != texture.width || parsedHeight != texture.height) { if (GUILayout.Button("Apply", GUILayout.Width(60))) { webCameraController.StartCapturing(selectedWebCam.name, parsedWidth, parsedHeight); webcamWidthString = webcamHeightString = ""; } } else { GUILayout.Space(60); } GUILayout.EndHorizontal(); GUILayout.EndHorizontal(); if (GUILayout.Button("Capture Photo")) { photoPreview = webCameraController.CapturePhoto(); if (photoPreview != null) { byte[] photoBytes = photoPreview.EncodeToPNG(); string filePath = Path.Combine(Application.persistentDataPath, "Photo.png"); Debug.Log("SAVE TO " + filePath); File.WriteAllBytes(filePath, photoBytes); Debug.Log(photoBytes.Length + " bytes saved"); } else { Debug.LogError("Unable to capture photo!"); } } Repaint(); } } } else { GUILayout.Label("No webcam available"); } } else { if (webCameraController.IsCapturing) { webCameraController.StopCapturing(); } } GUILayout.FlexibleSpace(); if (Selection.activeGameObject != null && Selection.activeGameObject.scene.name != null) { var selectedAvatarInfoPrev = selectedAvatarInfo; selectedAvatarInfo = Selection.activeGameObject.GetComponent <AvatarInfo>(); if (selectedAvatarInfo != null) { GUILayout.Label("Selected Avatar: ", titleStyle); if (selectedAvatarInfoPrev != selectedAvatarInfo) { selectedAvatarName = selectedAvatarInfo.name; } //GUILayout.Label(selectedAvatarInfo.code); GUILayout.BeginHorizontal(); selectedAvatarName = EditorGUILayout.TextField(selectedAvatarName, GUILayout.Height(18)); if (!string.IsNullOrEmpty(selectedAvatarName) && selectedAvatarName != selectedAvatarInfo.name) { if (GUILayout.Button("Rename", buttonSkin, GUILayout.Width(60), GUILayout.Height(18))) { selectedAvatarInfo.name = selectedAvatarName; WriteAvatarNameByCode(selectedAvatarInfo.code, selectedAvatarName); UpdateAvatarList(); } } else { GUILayout.Button("Rename", buttonSkin, GUILayout.Width(60), GUILayout.Height(18)); } GUILayout.EndHorizontal(); if (showBlendshapes) { scrollPosBlendshapes = GUILayout.BeginScrollView(scrollPosBlendshapes, GUILayout.Width(Mathf.Max(450f, windowSizeX)), GUILayout.Height(Mathf.Max(200f, position.height - 400f))); if (showHairstyles) { GUILayout.Label("Hairstyles:", titleStyle); GUILayout.BeginHorizontal(); GUILayout.Label("Haircut Color:", GUILayout.MaxWidth(100f)); selectedAvatarInfo.HaircutColor = EditorGUILayout.ColorField(selectedAvatarInfo.HaircutColor); if (GUILayout.Button("Default", buttonSkin, GUILayout.Width(100), GUILayout.Height(16))) { selectedAvatarInfo.HaircutColor = selectedAvatarInfo.avgHaircutColor; } GUILayout.EndHorizontal(); bool selected = (selectedAvatarInfo.selectedHairstyle == -1); if (GUILayout.Toggle(selected, "None") != selected) { selectedAvatarInfo.selectedHairstyle = -1; EditorRunner.instance.Run(ChangeHairRoutine(selectedAvatarInfo, -1)); } for (int i = 0; i < selectedAvatarInfo.haircuts.Length; i++) { var haircut = selectedAvatarInfo.haircuts[i]; selected = (selectedAvatarInfo.selectedHairstyle == i); if (GUILayout.Toggle(selected, haircut) != selected) { selectedAvatarInfo.selectedHairstyle = i; EditorRunner.instance.Run(ChangeHairRoutine(selectedAvatarInfo, i)); } } } if (showBlendshapes) { GUILayout.Label("Blendshapes:", titleStyle); var blendShapeCount = selectedAvatarInfo.headMeshRenderer.sharedMesh.blendShapeCount; for (int i = 1; i < blendShapeCount; i++) { GUILayout.BeginHorizontal(); GUILayout.Label(selectedAvatarInfo.headMeshRenderer.sharedMesh.GetBlendShapeName(i) + ":", GUILayout.MaxWidth(100)); var blendWeight = GUILayout.HorizontalSlider(selectedAvatarInfo.headMeshRenderer.GetBlendShapeWeight(i), 0, 100); GUILayout.EndHorizontal(); selectedAvatarInfo.headMeshRenderer.SetBlendShapeWeight(i, blendWeight); } } GUILayout.EndScrollView(); } GUILayout.Space(20); GUILayout.BeginHorizontal(); if (GUILayout.Button("Create Prefab")) { if (AvatarMakerInitializer.IsExportEnabled) { AvatarPrefabBuilder.CreateAvatarUnifiedMeshPrefab(selectedAvatarInfo.gameObject, HEAD_OBJECT_NAME, HAIRCUT_OBJECT_NAME, selectedAvatarInfo.code, selectedAvatarInfo.SelectedHairstyleName, selectedAvatarInfo.HaircutColor, selectedAvatarInfo.HaircutColorTint, new List <Type> { typeof(AvatarInfo) }); } else { Debug.LogError("Unable to create prefab in the Free-version!"); showExportError = true; } } if (GUILayout.Button("Export to FBX")) { if (AvatarMakerInitializer.IsExportEnabled) { ExportAvatarAsFbx(); } else { Debug.LogError("Export to FBX is unaccessible in the Free-version!"); showExportError = true; } } if (GUILayout.Button("Export to FBX with blendshapes")) { if (AvatarMakerInitializer.IsExportEnabled) { ExportAvatarWithBlendshapesWeightsAsFbx(); } else { Debug.LogError("Export to FBX is unaccessible in the Free-version!"); showExportError = true; } } if (GUILayout.Button("Export to OBJ")) { if (AvatarMakerInitializer.IsExportEnabled) { ExportAvatarAsObj(); } else { Debug.LogError("Export to OBJ is unaccessible in the Free-version!"); showExportError = true; } } GUILayout.EndHorizontal(); if (showExportError) { EditorGUILayout.HelpBox("Export feature is available only in the Avatar Maker Pro version!", MessageType.Error); ShowAvatarMakerProLink(); } } } else if (selectedAvatarInfo != null) { selectedAvatarInfo = null; } GUILayout.FlexibleSpace(); if (loadedAvatars.Count > 0) { GUILayout.Label("Avatars: ", titleStyle); if (showAvatarList) { scrollPosAvatars = GUILayout.BeginScrollView(scrollPosAvatars, GUILayout.Width(Mathf.Max(450, windowSizeX)), GUILayout.Height(Mathf.Min(170f, GUI.skin.button.fixedHeight + GUI.skin.button.fixedHeight * loadedAvatars.Count))); foreach (var avatar in loadedAvatars) { if (avatar != null) { string avatarName = avatar.name; //(avatar.code.Split('_')[2]); //avatarName = avatarName.Substring(0, 4) + "." + avatarName.Substring(4, 2) + "." + avatarName.Substring(6, 2) + " " + avatarName.Substring(8, 2) + "h "+ avatarName.Substring(10,2)+"m "+ avatarName.Substring(12,2)+"s"; GUIStyle buttonStyle = (GUI.skin.button); if (avatar.state != GalleryAvatarState.COMPLETED) { avatarName = "Failed " + avatarName; buttonStyle = redButtonStyle; } else if (selectedAvatarInfo != null && selectedAvatarInfo.code == avatar.code) { buttonStyle = greenBoldButtonStyle; } GUILayout.BeginHorizontal(); if (GUILayout.Button(avatarName, buttonStyle, GUILayout.Width(position.width - 150))) { EditorRunner.instance.Run(ShowAvatarByCode(avatar.code)); } if (GUILayout.Button("Delete")) { if (EditorUtility.DisplayDialog("Delete avatar?", "Are you sure you want to delete " + avatar.code + "?", "Yes", "No")) { EditorRunner.instance.Run(DeleteAvatarRoutine(avatar.code)); GameObject sceneAvatar = GameObject.Find(avatar.name); if (sceneAvatar != null && sceneAvatar.GetComponent <AvatarInfo>() != null) { DestroyImmediate(sceneAvatar); } } } GUILayout.EndHorizontal(); } } if (loadedAvatars.Count > 2 && GUILayout.Button("Delete All")) { if (EditorUtility.DisplayDialog("Delete all saved avatars?", "Are you sure you want to delete all saved avatars? ", "Yes", "No")) { foreach (var avatar in loadedAvatars) { EditorRunner.instance.Run(DeleteAvatarRoutine(avatar.code)); } } } GUILayout.EndScrollView(); } } //GUILayout.EndScrollView(); if (!string.IsNullOrEmpty(ProgressText)) { GUILayout.TextArea("Progress: " + ProgressText, GUILayout.MinHeight(40), GUILayout.MaxHeight(40)); } else { GUILayout.Space(40); } }