private void UpdateBlendShapeSetIcon() { if (!blendShapeSetIconUpdate) { return; } blendShapeSetIconUpdate = false; if (va.blendShapeSetList == null || va.blendShapeSetList.Count <= 0) { return; } TransformPoseSave beforePose = new TransformPoseSave(va.editGameObject); BlendShapeWeightSave beforeBlendShape = new BlendShapeWeightSave(va.editGameObject); va.transformPoseSave.ResetDefaultTransform(); va.blendShapeWeightSave.ResetDefaultWeight(); var gameObject = GameObject.Instantiate <GameObject>(va.editGameObject); gameObject.hideFlags |= HideFlags.HideAndDontSave; gameObject.transform.rotation = Quaternion.identity; Action ForceObjectUpdate = () => { gameObject.SetActive(false); gameObject.SetActive(true); }; int blankLayer; { for (blankLayer = 31; blankLayer > 0; blankLayer--) { if (string.IsNullOrEmpty(LayerMask.LayerToName(blankLayer))) { break; } } if (blankLayer < 0) { blankLayer = 31; } } foreach (var renderer in gameObject.GetComponentsInChildren <Renderer>()) { renderer.gameObject.layer = blankLayer; } var renderers = gameObject.GetComponentsInChildren <SkinnedMeshRenderer>().Where(renderer => renderer.sharedMesh != null && renderer.sharedMesh.blendShapeCount > 0).ToArray(); foreach (var renderer in renderers) { renderer.updateWhenOffscreen = true; } { RenderTexture iconTexture = new RenderTexture(IconTextureSize, IconTextureSize, 16, RenderTextureFormat.ARGB32); iconTexture.hideFlags |= HideFlags.HideAndDontSave; iconTexture.Create(); var cameraObject = new GameObject(); cameraObject.hideFlags |= HideFlags.HideAndDontSave; var camera = cameraObject.AddComponent <Camera>(); camera.targetTexture = iconTexture; camera.clearFlags = CameraClearFlags.Color; camera.backgroundColor = Color.clear; camera.cullingMask = 1 << blankLayer; { Bounds bounds = new Bounds(); foreach (var renderer in renderers) { if (Mathf.Approximately(bounds.size.sqrMagnitude, 0f)) { bounds = renderer.bounds; } else { bounds.Encapsulate(renderer.bounds); } } var transform = camera.transform; var sizeMax = Mathf.Max(bounds.size.x, Mathf.Max(bounds.size.y, bounds.size.z)); switch (blendShapeSetIconCameraMode) { case IconCameraMode.forward: { var rot = Quaternion.AngleAxis(180f, Vector3.up); transform.localRotation = rot; sizeMax = Mathf.Max(bounds.size.x, bounds.size.y); transform.localPosition = new Vector3(bounds.center.x, bounds.center.y, bounds.max.z) - transform.forward; } break; case IconCameraMode.back: { transform.localRotation = Quaternion.identity; sizeMax = Mathf.Max(bounds.size.x, bounds.size.y); transform.localPosition = new Vector3(bounds.center.x, bounds.center.y, bounds.min.z) - transform.forward; } break; case IconCameraMode.up: { var rot = Quaternion.AngleAxis(90f, Vector3.right); transform.localRotation = rot; sizeMax = Mathf.Max(bounds.size.x, bounds.size.z); transform.localPosition = new Vector3(bounds.center.x, bounds.max.y, bounds.center.z) - transform.forward; } break; case IconCameraMode.down: { var rot = Quaternion.AngleAxis(-90f, Vector3.right); transform.localRotation = rot; sizeMax = Mathf.Max(bounds.size.x, bounds.size.z); transform.localPosition = new Vector3(bounds.center.x, bounds.min.y, bounds.center.z) - transform.forward; } break; case IconCameraMode.right: { var rot = Quaternion.AngleAxis(-90f, Vector3.up); transform.localRotation = rot; sizeMax = Mathf.Max(bounds.size.y, bounds.size.z); transform.localPosition = new Vector3(bounds.max.x, bounds.center.y, bounds.center.z) - transform.forward; } break; case IconCameraMode.left: { var rot = Quaternion.AngleAxis(90f, Vector3.up); transform.localRotation = rot; sizeMax = Mathf.Max(bounds.size.y, bounds.size.z); transform.localPosition = new Vector3(bounds.min.x, bounds.center.y, bounds.center.z) - transform.forward; } break; } camera.orthographic = true; camera.orthographicSize = sizeMax * 0.6f; camera.farClipPlane = 1f + sizeMax * 5f; } cameraObject.transform.SetParent(gameObject.transform); gameObject.transform.rotation = va.editGameObject.transform.rotation; foreach (var set in va.blendShapeSetList) { va.blendShapeWeightSave.ResetDefaultWeight(); if (set.poseTemplate.blendShapePaths != null && set.poseTemplate.blendShapeValues != null) { foreach (var renderer in renderers) { var path = AnimationUtility.CalculateTransformPath(renderer.transform, gameObject.transform); var index = EditorCommon.ArrayIndexOf(set.poseTemplate.blendShapePaths, path); if (index < 0) { continue; } for (int i = 0; i < set.poseTemplate.blendShapeValues[index].names.Length; i++) { var sindex = renderer.sharedMesh.GetBlendShapeIndex(set.poseTemplate.blendShapeValues[index].names[i]); if (sindex < 0 || sindex >= renderer.sharedMesh.blendShapeCount) { continue; } renderer.SetBlendShapeWeight(sindex, set.poseTemplate.blendShapeValues[index].weights[i]); } } } ForceObjectUpdate(); camera.Render(); { RenderTexture save = RenderTexture.active; RenderTexture.active = iconTexture; if (set.icon == null) { set.icon = new Texture2D(iconTexture.width, iconTexture.height, TextureFormat.ARGB32, iconTexture.useMipMap); set.icon.hideFlags |= HideFlags.HideAndDontSave; } set.icon.ReadPixels(new Rect(0, 0, iconTexture.width, iconTexture.height), 0, 0); set.icon.Apply(); RenderTexture.active = save; } } GameObject.DestroyImmediate(cameraObject); iconTexture.Release(); RenderTexture.DestroyImmediate(iconTexture); } GameObject.DestroyImmediate(gameObject); beforePose.ResetDefaultTransform(); beforeBlendShape.ResetDefaultWeight(); { va.editGameObject.SetActive(false); va.editGameObject.SetActive(true); } va.SetUpdateResampleAnimation(); }
private void ToolsTemplatePose() { var transforms = EditorCommon.GetHierarchyTransform(activeRootObject.transform); Undo.RecordObjects(transforms.ToArray(), "Template Pose"); var animator = activeRootObject.GetComponent <Animator>(); if (animator != null && !animator.isInitialized) { animator.Rebind(); } var save = new TransformPoseSave.SaveData(activeRootObject.transform); string[] paths = new string[transforms.Count]; for (int i = 0; i < transforms.Count; i++) { paths[i] = AnimationUtility.CalculateTransformPath(transforms[i], activeRootObject.transform); } #region Human if (animator != null && animator.isHuman) { var uAnimator = new UAnimator(); var humanPoseHandler = new HumanPoseHandler(animator.avatar, uAnimator.GetAvatarRoot(animator)); var humanPose = new HumanPose(); humanPoseHandler.GetHumanPose(ref humanPose); { var musclePropertyName = new MusclePropertyName(); if (toolPoseTemplate.haveRootT) { humanPose.bodyPosition = toolPoseTemplate.rootT; } if (toolPoseTemplate.haveRootQ) { humanPose.bodyRotation = toolPoseTemplate.rootQ; } if (toolPoseTemplate.musclePropertyNames != null && toolPoseTemplate.muscleValues != null) { Assert.IsTrue(toolPoseTemplate.musclePropertyNames.Length == toolPoseTemplate.muscleValues.Length); for (int i = 0; i < toolPoseTemplate.musclePropertyNames.Length; i++) { var muscleIndex = EditorCommon.ArrayIndexOf(musclePropertyName.PropertyNames, toolPoseTemplate.musclePropertyNames[i]); if (muscleIndex < 0) { continue; } humanPose.muscles[muscleIndex] = toolPoseTemplate.muscleValues[i]; } } if (toolPoseTemplate.tdofIndices != null && toolPoseTemplate.tdofValues != null) { //not support } } humanPoseHandler.SetHumanPose(ref humanPose); } #endregion #region Generic if (toolPoseTemplate.transformPaths != null && toolPoseTemplate.transformPaths != null) { Assert.IsTrue(toolPoseTemplate.transformPaths.Length == toolPoseTemplate.transformValues.Length); for (int i = 0; i < toolPoseTemplate.transformPaths.Length; i++) { var index = EditorCommon.ArrayIndexOf(paths, toolPoseTemplate.transformPaths[i]); if (index < 0) { continue; } transforms[index].localPosition = toolPoseTemplate.transformValues[i].position; transforms[index].localRotation = toolPoseTemplate.transformValues[i].rotation; transforms[index].localScale = toolPoseTemplate.transformValues[i].scale; } } #endregion #region BlendShape if (toolPoseTemplate.blendShapePaths != null && toolPoseTemplate.blendShapeValues != null) { foreach (var renderer in activeRootObject.GetComponentsInChildren <SkinnedMeshRenderer>(true)) { if (renderer == null || renderer.sharedMesh == null || renderer.sharedMesh.blendShapeCount <= 0) { continue; } Undo.RecordObject(renderer, "Template Pose"); var path = AnimationUtility.CalculateTransformPath(renderer.transform, activeRootObject.transform); var index = EditorCommon.ArrayIndexOf(toolPoseTemplate.blendShapePaths, path); if (index < 0) { continue; } var names = new string[renderer.sharedMesh.blendShapeCount]; for (int i = 0; i < renderer.sharedMesh.blendShapeCount; i++) { names[i] = renderer.sharedMesh.GetBlendShapeName(i); } for (int i = 0; i < toolPoseTemplate.blendShapeValues[index].names.Length; i++) { var nameindex = EditorCommon.ArrayIndexOf(names, toolPoseTemplate.blendShapeValues[index].names[i]); if (nameindex < 0) { continue; } renderer.SetBlendShapeWeight(nameindex, toolPoseTemplate.blendShapeValues[index].weights[i]); } } } #endregion save.LoadLocal(activeRootObject.transform); }
public void BlendShapeTreeGUI() { var e = Event.current; GUIStyleReady(); EditorGUILayout.BeginVertical(GUI.skin.box); if (blendShapeMode == BlendShapeMode.Slider) { #region Slider const int IndentWidth = 15; #region GetBlendShapeLevel Func <BlendShapeNode, int, int> GetBlendShapeLevel = null; GetBlendShapeLevel = (mg, level) => { if (mg.foldout) { if (mg.infoList != null && mg.infoList.Length > 0) { level++; } } return(level); }; #endregion #region SetBlendShapeFoldout Action <BlendShapeNode, bool> SetBlendShapeFoldout = null; SetBlendShapeFoldout = (mg, foldout) => { mg.foldout = foldout; }; #endregion var mgRoot = blendShapeNodes; #region Reset All { EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Select All", GUILayout.Width(100))) { if (va.IsKeyControl(e) || e.shift) { var combineGoList = new List <GameObject>(va.selectionGameObjects); var combineBindings = new List <EditorCurveBinding>(va.uAw.GetCurveSelection()); foreach (var root in mgRoot) { if (root.renderer != null && root.renderer.gameObject != null) { combineGoList.Add(root.renderer.gameObject); } if (root.infoList != null && root.infoList.Length > 0) { foreach (var info in root.infoList) { combineBindings.Add(va.AnimationCurveBindingBlendShape(root.renderer, info.blendShapeName)); } } } va.SelectGameObjects(combineGoList.ToArray()); va.SetAnimationWindowSynchroSelection(combineBindings.ToArray()); } else { var combineGoList = new List <GameObject>(); var combineBindings = new List <EditorCurveBinding>(); foreach (var root in mgRoot) { if (root.renderer != null && root.renderer.gameObject != null) { combineGoList.Add(root.renderer.gameObject); } if (root.infoList != null && root.infoList.Length > 0) { foreach (var info in root.infoList) { combineBindings.Add(va.AnimationCurveBindingBlendShape(root.renderer, info.blendShapeName)); } } } va.SelectGameObjects(combineGoList.ToArray()); va.SetAnimationWindowSynchroSelection(combineBindings.ToArray()); } } EditorGUILayout.Space(); if (GUILayout.Button("Reset All", GUILayout.Width(100))) { Undo.RecordObject(vae, "Reset All BlendShape Group"); for (int i = 0; i < blendShapeGroupValues.Length; i++) { blendShapeGroupValues[i] = 0f; } foreach (var root in mgRoot) { if (root.infoList != null && root.infoList.Length > 0) { foreach (var info in root.infoList) { va.SetAnimationValueBlendShapeIfNotOriginal(root.renderer, info.blendShapeName, va.blendShapeWeightSave.GetDefaultWeight(root.renderer, info.blendShapeName)); } } } } EditorGUILayout.EndHorizontal(); } #endregion EditorGUILayout.Space(); #region BlendShape BlendShapeRootNode rootNode = null; int RowCount = 0; Action <BlendShapeNode> BlendShapeTreeGUI = null; BlendShapeTreeGUI = (mg) => { const int FoldoutWidth = 22; const int FoldoutSpace = 17; EditorGUILayout.BeginHorizontal(RowCount++ % 2 == 0 ? vaw.guiStyleAnimationRowEvenStyle : vaw.guiStyleAnimationRowOddStyle); { var rect = EditorGUILayout.GetControlRect(); { var r = rect; r.width = FoldoutWidth; EditorGUI.BeginChangeCheck(); mg.foldout = EditorGUI.Foldout(r, mg.foldout, "", true); if (EditorGUI.EndChangeCheck()) { if (e.alt) { SetBlendShapeFoldout(mg, mg.foldout); } } } { var r = rect; r.x += FoldoutWidth; r.y += 1; r.width -= FoldoutWidth; r.height += 1; if (GUI.Button(r, new GUIContent(mg.name, blendShapeGroupValues[blendShapeGroupTreeTable[mg]].ToString()))) { if (va.IsKeyControl(e) || e.shift) { var combineGoList = new List <GameObject>(va.selectionGameObjects); var combineBindings = new List <EditorCurveBinding>(va.uAw.GetCurveSelection()); if (rootNode.renderer != null && rootNode.renderer.gameObject != null) { combineGoList.Add(rootNode.renderer.gameObject); } if (rootNode.infoList != null && rootNode.infoList.Length > 0) { foreach (var info in rootNode.infoList) { combineBindings.Add(va.AnimationCurveBindingBlendShape(rootNode.renderer, info.blendShapeName)); } } va.SelectGameObjects(combineGoList.ToArray()); va.SetAnimationWindowSynchroSelection(combineBindings.ToArray()); } else { var combineGoList = new List <GameObject>(); var combineBindings = new List <EditorCurveBinding>(); if (rootNode.renderer != null && rootNode.renderer.gameObject != null) { combineGoList.Add(rootNode.renderer.gameObject); } if (rootNode.infoList != null && rootNode.infoList.Length > 0) { foreach (var info in rootNode.infoList) { combineBindings.Add(va.AnimationCurveBindingBlendShape(rootNode.renderer, info.blendShapeName)); } } va.SelectGameObjects(combineGoList.ToArray()); va.SetAnimationWindowSynchroSelection(combineBindings.ToArray()); } } } } GUILayout.Space(FoldoutSpace); { EditorGUI.BeginChangeCheck(); var value = GUILayout.HorizontalSlider(blendShapeGroupValues[blendShapeGroupTreeTable[mg]], 0f, 100f, GUILayout.Width(vaw.editorSettings.settingEditorSliderSize)); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(vae, "Change BlendShape Group"); blendShapeGroupValues[blendShapeGroupTreeTable[mg]] = value; if (mg.infoList != null && mg.infoList.Length > 0) { foreach (var info in mg.infoList) { va.SetAnimationValueBlendShape(rootNode.renderer, info.blendShapeName, value); } } } } GUILayout.Space(IndentWidth * GetBlendShapeLevel(mg, 0)); if (GUILayout.Button("Reset", GUILayout.Width(44))) { Undo.RecordObject(vae, "Reset BlendShape Group"); blendShapeGroupValues[blendShapeGroupTreeTable[mg]] = 0f; if (mg.infoList != null && mg.infoList.Length > 0) { foreach (var info in mg.infoList) { va.SetAnimationValueBlendShapeIfNotOriginal(rootNode.renderer, info.blendShapeName, va.blendShapeWeightSave.GetDefaultWeight(rootNode.renderer, info.blendShapeName)); } } } EditorGUILayout.EndHorizontal(); if (mg.foldout) { EditorGUI.indentLevel++; if (mg.infoList != null && mg.infoList.Length > 0) { #region BlendShape foreach (var info in mg.infoList) { var blendShapeValue = va.GetAnimationValueBlendShape(rootNode.renderer, info.blendShapeName); EditorGUILayout.BeginHorizontal(RowCount++ % 2 == 0 ? vaw.guiStyleAnimationRowEvenStyle : vaw.guiStyleAnimationRowOddStyle); EditorGUI.indentLevel++; { var rect = EditorGUILayout.GetControlRect(); { var offset = IndentWidth * EditorGUI.indentLevel + FoldoutWidth - IndentWidth; rect.x += offset; rect.width -= offset; rect.y += 1; rect.height += 1; } if (GUI.Button(rect, new GUIContent(info.blendShapeName))) { if (va.IsKeyControl(e) || e.shift) { var combineGoList = new List <GameObject>(va.selectionGameObjects); var combineBindings = new List <EditorCurveBinding>(va.uAw.GetCurveSelection()); if (rootNode.renderer != null && rootNode.renderer.gameObject != null) { combineGoList.Add(rootNode.renderer.gameObject); } combineBindings.Add(va.AnimationCurveBindingBlendShape(rootNode.renderer, info.blendShapeName)); va.SelectGameObjects(combineGoList.ToArray()); va.SetAnimationWindowSynchroSelection(combineBindings.ToArray()); } else { if (rootNode.renderer != null && rootNode.renderer.gameObject != null) { va.SelectGameObject(rootNode.renderer.gameObject); } va.SetAnimationWindowSynchroSelection(new EditorCurveBinding[] { va.AnimationCurveBindingBlendShape(rootNode.renderer, info.blendShapeName) }); } } } { var mirrorName = va.GetMirrorBlendShape(rootNode.renderer, info.blendShapeName); if (blendShapeMirrorName) { var rect = EditorGUILayout.GetControlRect(); rect.y += 2; { var mirrorIndex = EditorCommon.ArrayIndexOf(rootNode.blendShapeNames, mirrorName); EditorGUI.BeginChangeCheck(); mirrorIndex = EditorGUI.Popup(rect, mirrorIndex, rootNode.blendShapeNames); if (EditorGUI.EndChangeCheck()) { string newMirrorName = mirrorIndex > 0 ? rootNode.blendShapeNames[mirrorIndex] : null; if (info.blendShapeName == newMirrorName) { newMirrorName = null; } va.ChangeBlendShapeMirror(rootNode.renderer, info.blendShapeName, newMirrorName); if (!string.IsNullOrEmpty(newMirrorName)) { va.ChangeBlendShapeMirror(rootNode.renderer, newMirrorName, info.blendShapeName); } } } if (!string.IsNullOrEmpty(mirrorName)) { var mirrorTex = vaw.mirrorTex; rect.width = mirrorTex.width; rect.height = mirrorTex.height; rect.x += 15f; if (GUI.Button(rect, new GUIContent("", string.Format("Mirror: '{0}'", mirrorName)), vaw.guiStyleMirrorButton)) { if (rootNode.renderer != null && rootNode.renderer.gameObject != null) { va.SelectGameObject(rootNode.renderer.gameObject); } va.SetAnimationWindowSynchroSelection(new EditorCurveBinding[] { va.AnimationCurveBindingBlendShape(rootNode.renderer, mirrorName) }); } } } else { if (!string.IsNullOrEmpty(mirrorName)) { var mirrorTex = vaw.guiStyleMirrorButton.normal.background; if (GUILayout.Button(new GUIContent("", string.Format("Mirror: '{0}'", mirrorName)), vaw.guiStyleMirrorButton, GUILayout.Width(mirrorTex.width), GUILayout.Height(mirrorTex.height))) { if (rootNode.renderer != null && rootNode.renderer.gameObject != null) { va.SelectGameObject(rootNode.renderer.gameObject); } va.SetAnimationWindowSynchroSelection(new EditorCurveBinding[] { va.AnimationCurveBindingBlendShape(rootNode.renderer, mirrorName) }); } } else { GUILayout.Space(FoldoutSpace); } } } { EditorGUI.BeginChangeCheck(); var value2 = GUILayout.HorizontalSlider(blendShapeValue, 0f, 100f, GUILayout.Width(vaw.editorSettings.settingEditorSliderSize)); if (EditorGUI.EndChangeCheck()) { va.SetAnimationValueBlendShape(rootNode.renderer, info.blendShapeName, value2); } } if (GUILayout.Button("Reset", GUILayout.Width(44))) { va.SetAnimationValueBlendShapeIfNotOriginal(rootNode.renderer, info.blendShapeName, va.blendShapeWeightSave.GetDefaultWeight(rootNode.renderer, info.blendShapeName)); } EditorGUI.indentLevel--; EditorGUILayout.EndHorizontal(); } #endregion } EditorGUI.indentLevel--; } }; foreach (var root in mgRoot) { if (root.renderer != null && root.mesh != null && root.renderer.sharedMesh == root.mesh) { rootNode = root; BlendShapeTreeGUI(root); } } #endregion #endregion } else if (blendShapeMode == BlendShapeMode.List) { #region List if (e.type == EventType.Layout) { UpdateBlendShapeSetListReorderableList(); } if (blendShapeSetListReorderableList != null) { blendShapeSetListReorderableList.DoLayoutList(); } #endregion } else if (blendShapeMode == BlendShapeMode.Icon) { #region Icon if (e.type == EventType.Layout) { UpdateBlendShapeSetIcon(); } { EditorGUILayout.BeginHorizontal(EditorStyles.toolbar); { EditorGUI.BeginChangeCheck(); blendShapeSetIconCameraMode = (IconCameraMode)EditorGUILayout.EnumPopup(blendShapeSetIconCameraMode, EditorStyles.toolbarDropDown, GUILayout.Width(80f)); if (EditorGUI.EndChangeCheck()) { blendShapeSetIconUpdate = true; } } EditorGUILayout.Space(); blendShapeSetIconShowName = GUILayout.Toggle(blendShapeSetIconShowName, "Show Name", EditorStyles.toolbarButton); EditorGUILayout.Space(); blendShapeSetIconSize = EditorGUILayout.Slider(blendShapeSetIconSize, 32f, IconTextureSize); EditorGUILayout.EndHorizontal(); } EditorGUILayout.Space(); if (va.blendShapeSetList.Count > 0) { float areaWidth = vae.position.width - 16f; int countX = Math.Max(1, Mathf.FloorToInt(areaWidth / blendShapeSetIconSize)); int countY = Mathf.CeilToInt(va.blendShapeSetList.Count / (float)countX); for (int i = 0; i < countY; i++) { EditorGUILayout.BeginHorizontal(); for (int j = 0; j < countX; j++) { var index = i * countX + j; if (index >= va.blendShapeSetList.Count) { break; } var rect = EditorGUILayout.GetControlRect(false, blendShapeSetIconSize, guiStyleIconButton, GUILayout.Width(blendShapeSetIconSize), GUILayout.Height(blendShapeSetIconSize)); if (GUI.Button(rect, va.blendShapeSetList[index].icon, guiStyleIconButton)) { var poseTemplate = va.blendShapeSetList[index].poseTemplate; va.LoadPoseTemplate(poseTemplate, false, false, VeryAnimation.PoseTemplateFlags.BlendShape); } if (blendShapeSetIconShowName) { GUI.Label(rect, va.blendShapeSetList[index].poseTemplate.name, guiStyleNameLabel); } } EditorGUILayout.EndHorizontal(); } } else { EditorGUILayout.LabelField("List is Empty", EditorStyles.centeredGreyMiniLabel); } #endregion } EditorGUILayout.EndVertical(); }