Beispiel #1
0
        public static void ConvertToComposeData(UnityEngine.Object targetObject)
        {
            var targetMesh = Utils.ExtractMesh(targetObject);

            if (targetMesh == null)
            {
                return;
            }
            var materials = Utils.ExtractMaterials(targetObject);

            int numBS = targetMesh.blendShapeCount;

            if (numBS == 0)
            {
                Debug.Log("BlendShapeInspector: This mesh has no BlendShape.");
                return;
            }

            var baseMesh = Instantiate(targetMesh);

            baseMesh.name = targetMesh.name;
            baseMesh.ClearBlendShapes();
            var baseGO = Utils.MeshToGameObject(baseMesh, Vector3.zero, materials);

            var builder = baseGO.AddComponent <BlendShapeBuilder>();
            var data    = builder.data.blendShapeData;

            data.Clear();

            for (int bi = 0; bi < numBS; ++bi)
            {
                var name      = targetMesh.GetBlendShapeName(bi);
                int numFrames = targetMesh.GetBlendShapeFrameCount(bi);
                var gos       = ExtractBlendShapeFrames(targetMesh, bi, -1, materials);

                float step   = 100.0f / numFrames;
                float weight = step;
                var   bsd    = new BlendShapeData();
                data.Add(bsd);
                bsd.name = name;
                foreach (var go in gos)
                {
                    var fd = new BlendShapeFrameData();
                    bsd.frames.Add(fd);
                    fd.mesh   = go;
                    fd.weight = weight;
                    weight   += step;
                }
            }
            Undo.RegisterCreatedObjectUndo(baseGO, "BlendShapeBuilder");

            Selection.activeObject = baseGO;
            BlendShapeBuilderWindow.Open();
        }
Beispiel #2
0
        void OnAddFrame(BlendShapeData bsd)
        {
            Undo.RecordObject(this, "BlendShapeBuilder");
            var frame = new BlendShapeFrameData();

            bsd.frames.Add(frame);
            bsd.NormalizeWeights();

            var meshBase = Utils.ExtractMesh(m_target.gameObject);

            if (meshBase == null)
            {
                return;
            }

            var meshNew = Instantiate(meshBase);

            meshNew.name = meshNew.name.Replace("(Clone)", ":" + bsd.name + "[" + (bsd.frames.Count - 1) + "]");
            frame.mesh   = Utils.MeshToGameObject(meshNew, m_target.gameObject);

            Undo.RegisterCreatedObjectUndo(frame.mesh, "BlendShapeBuilder");
        }
Beispiel #3
0
        public void DrawBlendShapeBuilder()
        {
            if (m_target == null)
            {
                return;
            }
            var m_data = m_target.data;

            bool repaint = false;

            GUILayout.BeginHorizontal();
            {
                GUILayout.Label("Base Mesh", GUILayout.Width(70));
                var rect  = EditorGUILayout.GetControlRect();
                var width = rect.width;
                var pos   = rect.position;

                EditorGUI.ObjectField(new Rect(pos, new Vector2(width, 16)), m_data.baseMesh, typeof(UnityEngine.Object), true);
            }
            if (GUILayout.Button("Find Targets", GUILayout.Width(80)))
            {
                FindValidTargets();
            }
            GUILayout.EndHorizontal();


            m_foldBlendShapes = EditorGUILayout.Foldout(m_foldBlendShapes, "BlendShapes");
            if (m_foldBlendShapes)
            {
                var bsData = m_data.blendShapeData;
                var evt    = Event.current;

                // handle drag & drop
                if (evt.type == EventType.DragUpdated || evt.type == EventType.DragPerform)
                {
                    var dropArea = GUILayoutUtility.GetLastRect();
                    if (dropArea.Contains(evt.mousePosition))
                    {
                        DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                        if (evt.type == EventType.DragPerform)
                        {
                            DragAndDrop.AcceptDrag();
                            Undo.RecordObject(m_target, "BlendShapeBuilder");
                            foreach (var obj in DragAndDrop.objectReferences)
                            {
                                if (IsValidTarget(obj))
                                {
                                    var bsd = new BlendShapeData();
                                    bsd.name = obj.name;
                                    bsd.frames.Add(new BlendShapeFrameData {
                                        mesh = obj
                                    });
                                    m_data.blendShapeData.Add(bsd);
                                }
                            }
                        }
                        evt.Use();
                    }
                }

                BlendShapeData delBS = null;

                foreach (var data in bsData)
                {
                    GUILayout.BeginHorizontal();
                    GUILayout.Space(indentSize);
                    GUILayout.BeginVertical("Box");
                    GUILayout.BeginHorizontal();
                    data.fold = EditorGUILayout.Foldout(data.fold, data.name);
                    if (GUILayout.Button("-", GUILayout.Width(20)))
                    {
                        Undo.RecordObject(m_target, "BlendShapeBuilder");
                        delBS = data;
                    }

                    GUILayout.EndHorizontal();
                    if (data.fold)
                    {
                        // handle drag & drop
                        if (evt.type == EventType.DragUpdated || evt.type == EventType.DragPerform)
                        {
                            var dropArea = GUILayoutUtility.GetLastRect();
                            if (dropArea.Contains(evt.mousePosition))
                            {
                                DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

                                if (evt.type == EventType.DragPerform)
                                {
                                    DragAndDrop.AcceptDrag();
                                    Undo.RecordObject(m_target, "BlendShapeBuilder");
                                    data.ClearInvalidFrames();
                                    foreach (var obj in DragAndDrop.objectReferences)
                                    {
                                        if (IsValidTarget(obj))
                                        {
                                            data.frames.Add(new BlendShapeFrameData {
                                                mesh = obj
                                            });
                                        }
                                    }
                                    data.NormalizeWeights();
                                }
                                evt.Use();
                            }
                        }

                        GUILayout.BeginHorizontal();
                        GUILayout.Space(indentSize);
                        GUILayout.BeginVertical();

                        {
                            var rect  = EditorGUILayout.GetControlRect();
                            var width = rect.width;
                            var pos   = rect.position;

                            EditorGUI.BeginChangeCheck();
                            EditorGUI.LabelField(new Rect(pos, new Vector2(width, 16)), "Name");
                            pos.x += 50; width -= 50;
                            var name = EditorGUI.TextField(new Rect(pos, new Vector2(width, 16)), data.name);
                            if (EditorGUI.EndChangeCheck())
                            {
                                Undo.RecordObject(m_target, "BlendShapeBuilder");
                                data.name = name;
                            }
                        }

                        EditorGUILayout.LabelField(new GUIContent("Frames", "Weight Mesh    Vertex Normal Tangent"));

                        GUILayout.BeginHorizontal();
                        GUILayout.Space(indentSize);
                        GUILayout.BeginVertical();

                        BlendShapeFrameData delFrame = null;
                        int numFrames = data.frames.Count;
                        int numV = 0, numN = 0, numT = 0;
                        foreach (var frame in data.frames)
                        {
                            if (frame.vertex)
                            {
                                ++numV;
                            }
                            if (frame.normal)
                            {
                                ++numN;
                            }
                            if (frame.tangent)
                            {
                                ++numT;
                            }

                            GUILayout.BeginHorizontal();

                            var rect  = EditorGUILayout.GetControlRect();
                            var width = rect.width;
                            var pos   = rect.position;

                            EditorGUI.BeginChangeCheck();
                            var w = EditorGUI.FloatField(new Rect(pos, new Vector2(36, 16)), frame.weight);
                            if (EditorGUI.EndChangeCheck())
                            {
                                Undo.RecordObject(m_target, "BlendShapeBuilder");
                                frame.weight = w;
                            }

                            pos.x += 40;

                            EditorGUI.BeginChangeCheck();
                            var m = EditorGUI.ObjectField(new Rect(pos, new Vector2(width - 40, 16)), frame.mesh, typeof(UnityEngine.Object), true);
                            if (EditorGUI.EndChangeCheck())
                            {
                                if (IsValidTarget(m))
                                {
                                    Undo.RecordObject(m_target, "BlendShapeBuilder");
                                    frame.mesh = m;
                                }
                            }

                            if (GUILayout.Button("Edit", GUILayout.Width(50)))
                            {
                                OnEditFrame(frame);
                            }

                            EditorGUI.BeginChangeCheck();
                            var v = GUILayout.Toggle(frame.vertex, "V", GUILayout.Width(25));
                            if (EditorGUI.EndChangeCheck())
                            {
                                Undo.RecordObject(m_target, "BlendShapeBuilder");
                                frame.vertex = v;
                            }

                            EditorGUI.BeginChangeCheck();
                            var n = GUILayout.Toggle(frame.normal, "N", GUILayout.Width(25));
                            if (EditorGUI.EndChangeCheck())
                            {
                                Undo.RecordObject(m_target, "BlendShapeBuilder");
                                frame.normal = n;
                            }

                            EditorGUI.BeginChangeCheck();
                            var t = GUILayout.Toggle(frame.tangent, "T", GUILayout.Width(25));
                            if (EditorGUI.EndChangeCheck())
                            {
                                Undo.RecordObject(m_target, "BlendShapeBuilder");
                                frame.tangent = t;
                            }

                            if (GUILayout.Button("-", GUILayout.Width(20)))
                            {
                                delFrame = frame;
                            }

                            GUILayout.EndHorizontal();
                        }
                        if (delFrame != null)
                        {
                            Undo.RecordObject(m_target, "BlendShapeBuilder");
                            data.frames.Remove(delFrame);
                            data.NormalizeWeights();
                        }

                        GUILayout.BeginHorizontal();
                        GUILayout.FlexibleSpace();
                        if (numFrames > 0)
                        {
                            bool v = false;
                            EditorGUI.BeginChangeCheck();
                            if (numV == numFrames || numV == 0)
                            {
                                v = GUILayout.Toggle(numV == numFrames, "V", GUILayout.Width(25));
                            }
                            else
                            {
                                v = GUILayout.Toggle(numV == numFrames, "V", "ToggleMixed", GUILayout.Width(25));
                            }
                            if (EditorGUI.EndChangeCheck())
                            {
                                Undo.RecordObject(m_target, "BlendShapeBuilder");
                                foreach (var frame in data.frames)
                                {
                                    frame.vertex = v;
                                }
                            }

                            EditorGUI.BeginChangeCheck();
                            if (numN == numFrames || numN == 0)
                            {
                                v = GUILayout.Toggle(numN == numFrames, "N", GUILayout.Width(25));
                            }
                            else
                            {
                                v = GUILayout.Toggle(numN == numFrames, "N", "ToggleMixed", GUILayout.Width(25));
                            }
                            if (EditorGUI.EndChangeCheck())
                            {
                                Undo.RecordObject(m_target, "BlendShapeBuilder");
                                foreach (var frame in data.frames)
                                {
                                    frame.normal = v;
                                }
                            }

                            EditorGUI.BeginChangeCheck();
                            if (numT == numFrames || numT == 0)
                            {
                                v = GUILayout.Toggle(numT == numFrames, "T", GUILayout.Width(25));
                            }
                            else
                            {
                                v = GUILayout.Toggle(numT == numFrames, "T", "ToggleMixed", GUILayout.Width(25));
                            }
                            if (EditorGUI.EndChangeCheck())
                            {
                                Undo.RecordObject(m_target, "BlendShapeBuilder");
                                foreach (var frame in data.frames)
                                {
                                    frame.tangent = v;
                                }
                            }
                        }
                        if (GUILayout.Button("+", GUILayout.Width(20)))
                        {
                            OnAddFrame(data);
                        }
                        GUILayout.EndHorizontal();

                        GUILayout.BeginHorizontal();
                        if (GUILayout.Button("Normalize Weights", GUILayout.Width(120)))
                        {
                            Undo.RecordObject(m_target, "BlendShapeBuilder");
                            data.NormalizeWeights();
                        }
                        if (GUILayout.Button("Sort By Weights", GUILayout.Width(110)))
                        {
                            Undo.RecordObject(m_target, "BlendShapeBuilder");
                            data.SortByWeights();
                        }
                        if (GUILayout.Button("Clear", GUILayout.Width(60)))
                        {
                            Undo.RecordObject(m_target, "BlendShapeBuilder");
                            data.frames.Clear();
                        }
                        GUILayout.EndHorizontal();

                        GUILayout.EndVertical();
                        GUILayout.EndHorizontal();

                        GUILayout.EndVertical();
                        GUILayout.Space(10);
                        GUILayout.EndHorizontal();
                    }

                    GUILayout.EndVertical();
                    GUILayout.EndHorizontal();
                }

                if (delBS != null)
                {
                    bsData.Remove(delBS);
                }

                GUILayout.BeginHorizontal();
                GUILayout.Space(indentSize);
                GUILayout.BeginHorizontal("Box");
                GUILayout.FlexibleSpace();
                if (GUILayout.Button("+", GUILayout.Width(20)))
                {
                    Undo.RecordObject(m_target, "BlendShapeBuilder");
                    var tmp = new BlendShapeData();
                    tmp.name = "NewBlendShape" + bsData.Count;
                    bsData.Add(tmp);
                }
                GUILayout.EndHorizontal();
                GUILayout.EndHorizontal();
            }

            GUILayout.Space(8);
            m_data.preserveExistingBlendShapes = GUILayout.Toggle(m_data.preserveExistingBlendShapes, "Preserve Existing BlendShapes");

            GUILayout.BeginHorizontal();
            if (GUILayout.Button("Update Mesh", GUILayout.Width(150)))
            {
                Build(true);
            }
            if (GUILayout.Button("Generate New Asset", GUILayout.Width(150)))
            {
                var    result = Build();
                string path   = EditorUtility.SaveFilePanel("Generate New Asset", "Assets", Utils.SanitizeForFileName(m_data.baseMesh.name), "asset");
                if (path.Length > 0)
                {
                    var dataPath = Application.dataPath;
                    if (!path.StartsWith(dataPath))
                    {
                        Debug.LogError("Invalid path: Path must be under " + dataPath);
                    }
                    else
                    {
                        path = path.Replace(dataPath, "Assets");
                        AssetDatabase.CreateAsset(result, path);
                        Debug.Log("Asset exported: " + path);
                    }
                }
            }
            GUILayout.EndHorizontal();

            GUILayout.Space(6);

            if (repaint)
            {
                RepaintAllViews();
            }
        }