public static void ConvertToComposeData(UnityEngine.Object targetObject) { var targetMesh = Utils.GetMesh(targetObject); if (targetMesh == null) { return; } var materials = Utils.GetMaterials(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 <UTJ.BlendShapeBuilder.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(); }
public Mesh(AssetInfo assetInfo) : base(assetInfo) { CompressedMesh = new CompressedMesh(AssetsFile); if (IsReadBlendShapes) { Shapes = new BlendShapeData(AssetsFile); } if (IsReadLocalAABB) { LocalAABB = new AABB(); } if (IsReadCollision) { CollisionData = new CollisionMeshData(); } }
public static BlendShapeData CreateFromMesh(Mesh sharedMesh) { var blendShapeData = new BlendShapeData { blendShapeCount = sharedMesh.blendShapeCount, blendShapes = new BlendShapeShape[sharedMesh.blendShapeCount] }; for (int i = 0; i < blendShapeData.blendShapeCount; i++) { var blendShapeFrameCount = sharedMesh.GetBlendShapeFrameCount(i); blendShapeData.blendShapes[i] = new BlendShapeShape { frameCount = blendShapeFrameCount, name = sharedMesh.GetBlendShapeName(i), frames = new BlendShapeFrame[blendShapeFrameCount] }; for (int j = 0; j < blendShapeFrameCount; j++) { var blendShapeFrame = new BlendShapeFrame { weight = sharedMesh.GetBlendShapeFrameWeight(i, j), shapeIndex = i, frameIndex = j, deltaNormals = new Vector3[sharedMesh.vertexCount], deltaTangents = new Vector3[sharedMesh.vertexCount], deltaVertices = new Vector3[sharedMesh.vertexCount], newDeltaNormals = new List <Vector3>(), newDeltaTangents = new List <Vector3>(), newDeltaVertices = new List <Vector3>() }; sharedMesh.GetBlendShapeFrameVertices(i, j, blendShapeFrame.deltaVertices, blendShapeFrame.deltaNormals, blendShapeFrame.deltaTangents); blendShapeData.blendShapes[i].frames[j] = blendShapeFrame; } } return(blendShapeData); }
public IEnumerator UpdateData(GameObject obj, BlendShapeContainter data) { //blend shapes at a keyframe BlendShapeData m_data = data.blendShapeData[viewHandler.frame]; for (int i = 0; i < m_data.blendShapes.Count; i++) { int mappedBlendShapeIndex = GetBlendShapeReference(m_data.blendShapes[i].shapeKey); if (mappedBlendShapeIndex != -1) { // mapping specific blendshape float blendShapeValue = m_data.blendShapes[i].value * 100; skinnedMeshRenderer.SetBlendShapeWeight(mappedBlendShapeIndex, blendShapeValue); } } yield return(new WaitForEndOfFrame()); StartCoroutine(UpdateData(obj, data)); }
void OnAddFrame(BlendShapeData bsd) { Undo.RecordObject(this, "BlendShapeBuilder"); var frame = new BlendShapeFrameData(); bsd.frames.Add(frame); bsd.NormalizeWeights(); var meshBase = Utils.GetMesh(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"); }
private static BlendShapeData GetShapes(IExportContainer container, Mesh origin) { if (Mesh.HasBlendShapes(container.Version)) { if (Mesh.HasBlendChannels(container.Version)) { return(origin.Shapes.Convert()); } else { BlendShapeData instance = new BlendShapeData(); instance.Vertices = origin.ShapeVertices.ToArray(); instance.Shapes = origin.BlendShapes.ToArray(); instance.Channels = BlendShapeConverter.GenerateBlendChannels(origin.BlendShapes); instance.FullWeights = BlendShapeConverter.GenerateFullWeights(origin.BlendShapes); return(instance); } } else { return(new BlendShapeData(container.ExportVersion)); } }
public void Add(PoseTemplate srcPoseTemplate) { var blendShape = new BlendShapeData(); blendShape.name = srcPoseTemplate.name; { blendShape.blendShapePaths = new string[srcPoseTemplate.blendShapePaths.Length]; srcPoseTemplate.blendShapePaths.CopyTo(blendShape.blendShapePaths, 0); blendShape.blendShapeValues = new PoseTemplate.BlendShapeData[srcPoseTemplate.blendShapeValues.Length]; for (int i = 0; i < srcPoseTemplate.blendShapeValues.Length; i++) { blendShape.blendShapeValues[i].names = new string[srcPoseTemplate.blendShapeValues[i].names.Length]; srcPoseTemplate.blendShapeValues[i].names.CopyTo(blendShape.blendShapeValues[i].names, 0); blendShape.blendShapeValues[i].weights = new float[srcPoseTemplate.blendShapeValues[i].weights.Length]; srcPoseTemplate.blendShapeValues[i].weights.CopyTo(blendShape.blendShapeValues[i].weights, 0); } } if (list == null) { list = new List <BlendShapeData>(); } list.Add(blendShape); }
bool CaptureSkinnedMeshRenderer(ref MeshData dst, SkinnedMeshRenderer smr, GetMessage mes, ref Mesh mesh) { mesh = smr.sharedMesh; if (mesh == null) { return(false); } if (!mes.bakeSkin && !mesh.isReadable) { Debug.LogWarning("Mesh " + smr.name + " is not readable and be ignored"); return(false); } Cloth cloth = smr.GetComponent <Cloth>(); if (cloth != null && mes.bakeCloth) { CaptureMesh(ref dst, mesh, cloth, mes.flags, smr.sharedMaterials); } if (mes.bakeSkin) { Mesh tmp = new Mesh(); smr.BakeMesh(tmp); CaptureMesh(ref dst, tmp, null, mes.flags, smr.sharedMaterials); } else { CaptureMesh(ref dst, mesh, null, mes.flags, smr.sharedMaterials); // bones if (mes.flags.getBones) { dst.SetBonePaths(this, smr.bones); dst.bindposes = mesh.bindposes; NativeArray <byte> bonesPerVertex = mesh.GetBonesPerVertex(); NativeArray <BoneWeight1> weights = mesh.GetAllBoneWeights(); dst.WriteBoneWeightsV(ref bonesPerVertex, ref weights); } // blendshapes if (mes.flags.getBlendShapes && mesh.blendShapeCount > 0) { Vector3[] v = new Vector3[mesh.vertexCount]; Vector3[] n = new Vector3[mesh.vertexCount]; Vector3[] t = new Vector3[mesh.vertexCount]; for (int bi = 0; bi < mesh.blendShapeCount; ++bi) { BlendShapeData bd = dst.AddBlendShape(mesh.GetBlendShapeName(bi)); bd.weight = smr.GetBlendShapeWeight(bi); int frameCount = mesh.GetBlendShapeFrameCount(bi); for (int fi = 0; fi < frameCount; ++fi) { mesh.GetBlendShapeFrameVertices(bi, fi, v, n, t); float w = mesh.GetBlendShapeFrameWeight(bi, fi); bd.AddFrame(w, v, n, t); } } } } return(true); }
private void ProcessMesh(Mesh sharedMesh, Renderer renderer, HashSet <string> meshHashSet) { if (sharedMesh.vertexCount == 0) { return; } var colors = new List <Color>(); var vertices = new List <Vector3>(); var normals = new List <Vector3>(); var tangents = new List <Vector4>(); var indices = new List <List <int> >(); var uvs = new List <Vector2>(); var blendShapeData = BlendShapeData.CreateFromMesh(sharedMesh); for (int i = 0; i < sharedMesh.subMeshCount; i++) { indices.Add(new List <int>()); Dictionary <int, int> triangleMap = new Dictionary <int, int>(); var subMesh = sharedMesh.GetSubMesh(i); Color color = _colors[sharedMesh.GetInstanceID()][i]; for (int j = subMesh.indexStart; j < subMesh.indexStart + subMesh.indexCount; j++) { int index = sharedMesh.triangles[j]; if (!triangleMap.ContainsKey(index)) { triangleMap.Add(index, vertices.Count); vertices.Add(sharedMesh.vertices[index]); colors.Add(color); normals.Add(sharedMesh.normals[index]); tangents.Add(sharedMesh.tangents[index]); uvs.Add(sharedMesh.uv[index]); blendShapeData.AddIndex(index); } indices[i].Add(triangleMap[index]); } } sharedMesh.SetVertices(vertices); sharedMesh.SetNormals(normals); sharedMesh.SetUVs(0, uvs); sharedMesh.SetTangents(tangents); // Apply blend shape data blendShapeData.ApplyToMesh(sharedMesh); if (_importMaterialColours || meshHashSet.Contains(sharedMesh.name)) { sharedMesh.SetColors(colors); } for (int i = 0; i < indices.Count; i++) { sharedMesh.SetTriangles(indices[i], i, true); } // meshFilter.sharedMesh.subMeshCount = 1; // meshFilter.sharedMesh.SetSubMesh(0, new UnityEngine.Rendering.SubMeshDescriptor(0, mesh.vertexCount)); // renderer.sharedMaterials = new Material[1] { _defaultMaterial }; if (ModelColourEditorSettings.Instance.defaultMaterial != null) { renderer.sharedMaterials = Enumerable.Repeat(ModelColourEditorSettings.Instance.defaultMaterial, sharedMesh.subMeshCount).ToArray(); } }
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))) { BuildMesh(true); } if (GUILayout.Button("Generate New Asset", GUILayout.Width(150))) { var result = BuildMesh(); string path = EditorUtility.SaveFilePanel("Generate New Asset", "Assets", Utils.SanitizeFileName(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(); } }