private void InitBlendShapes() { _blendshapeData = new Dictionary <string, BlendshapeData>(_blendshapeNames.Length + 1); BlendshapesListbox.AddNewListboxItem("BASIC", out _basicBlendshapeButton); _basicBlendshapeButton.onClick.AddListener(() => SelectBlendshape(WowVrcFileData.BlendshapeData.basicBlendshapeName)); _blendshapeData[WowVrcFileData.BlendshapeData.basicBlendshapeName] = new BlendshapeData() { Name = WowVrcFileData.BlendshapeData.basicBlendshapeName, Bones = new Dictionary <string, BoneData>(), ListboxButton = _basicBlendshapeButton }; foreach (var blendshapeName in _blendshapeNames) { Button button; BlendshapesListbox.AddNewListboxItem(blendshapeName, out button); _blendshapeData[blendshapeName] = new BlendshapeData() { Name = blendshapeName, Bones = new Dictionary <string, BoneData>(), ListboxButton = button }; button.onClick.AddListener(() => SelectBlendshape(blendshapeName)); } }
/// <summary> /// Rips out blendshapes from a skinned mesh renderer and figures out where to store it along with creating a manifest file /// </summary> /// <param name="smr"></param> /// <returns>A string path to the manifest file</returns> public static string ExtractBlendshapesFromMesh(SkinnedMeshRenderer smr, string dirPath, int totalProcessed = 0, int totalCount = 0, bool useProgressBar = true, bool generateManifest = true, NameScrubCallback smrScrub = null, NameScrubCallback morphScrub = null, List <string> nameWhitelist = null) { //Extracts all blendshapes out of the mesh, does not remove any of them from the mesh int blendshapeCount = smr.sharedMesh.blendShapeCount; string manifestPath = dirPath + "/manifest.json"; MorphManifest manifest = new MorphManifest(); manifest.name = smr.name; manifest.count = blendshapeCount; manifest.names = new string[blendshapeCount]; if (smrScrub != null) { manifest.name = smrScrub(manifest.name); } if (!Directory.Exists(dirPath)) { DirectoryInfo di = Directory.CreateDirectory(dirPath); } for (int i = 0; i < blendshapeCount; i++) { BlendshapeData bd = new BlendshapeData(); bd.name = smr.sharedMesh.GetBlendShapeName(i); if (morphScrub != null) { bd.name = morphScrub(bd.name); } bd.shapeIndex = i; int vertexCount = smr.sharedMesh.vertexCount; bd.deltaVertices = new Vector3[vertexCount]; bd.deltaNormals = new Vector3[vertexCount]; bd.deltaTangents = new Vector3[vertexCount]; //loads the blendshape data from the blendshape into our blendshapestate struct smr.sharedMesh.GetBlendShapeFrameVertices(bd.shapeIndex, bd.frameIndex, bd.deltaVertices, bd.deltaNormals, bd.deltaTangents); //convert a blendshape name from something like Genesis2Male__FBMHeavy to FBMHeavy int bdIndex = bd.name.LastIndexOf("__"); if (bdIndex > -1) { bd.name = bd.name.Substring(bdIndex + 2); } if (nameWhitelist != null && nameWhitelist.Count > 0) { if (!nameWhitelist.Contains(bd.name)) { continue; } else { UnityEngine.Debug.Log("Matched: " + bd.name); } } float percent = 0f; if (totalCount > 0) { percent = (float)totalProcessed / (float)totalCount; } if (useProgressBar) { //TODO: we need to move this back into editor land, as this function is ONLY used if you're using the production tool suite //EditorUtility.DisplayProgressBar("Extracting Blends", "Blend: " + bd.name, percent); } string relativePath = bd.name + "." + extension; string filePath = dirPath + "/" + relativePath; MCS_Utilities.Morph.MorphData morphData = new MCS_Utilities.Morph.MorphData(); morphData.name = bd.name; morphData.blendshapeData = bd; WriteMorphDataToFile(morphData, filePath, true, false); manifest.names[i] = bd.name; totalProcessed += 1; } if (generateManifest) { Stream fs = File.Create(manifestPath); string json = JsonUtility.ToJson(manifest); byte[] bytes = System.Text.Encoding.UTF8.GetBytes(json); fs.Write(bytes, 0, bytes.Length); fs.Close(); } return(manifestPath); }