/// <summary>
    /// vrm読み込み
    /// </summary>
    void Load()
    {
        if (VRM != null)
        {
            Destroy(VRM);
        }

        Context.Load();
        Context.ShowMeshes();

        VRM = Context.Root;

        // 3Dビューの初期表示位置を頭に設定
        var anim = VRM.GetComponent <Animator>();
        var head = anim.GetBoneTransform(HumanBodyBones.Head);

        Camera.position = new Vector3(0, head.position.y, 0);

        // メタ情報とブレンドシェイプの取得
        Meta.Get();
        BlendShape.Get();

        Export.Path = Path;

        Text.gameObject.SetActive(false);
    }
    /// <summary>
    /// 表情プリセットにcsvから設定を読み込み
    /// </summary>
    public void Load(string path)
    {
        if (Vrm.VRM == null)
        {
            return;
        }

        // csv読み込み
        var list   = new List <List <string> >();
        var reader = new StreamReader(path);

        while (reader.Peek() >= 0)
        {
            list.Add(new List <string>());
            string[] cols = reader.ReadLine().Split(',');
            for (int n = 0; n < cols.Length; n++)
            {
                list[list.Count - 1].Add(cols[n]);
            }
        }
        reader.Close();

        // ブレンドシェイプの一致性確認
        var index  = 2;
        var meshes = Vrm.VRM.GetComponentsInChildren <SkinnedMeshRenderer>();

        foreach (SkinnedMeshRenderer mesh in meshes)
        {
            var meshPath = mesh.transform.RelativePathFrom(Vrm.VRM.transform);
            for (int i = 0; i < mesh.sharedMesh.blendShapeCount; i++)
            {
                var meshName = mesh.sharedMesh.GetBlendShapeName(i);
                if (list[index][CSV_COL_PATH] != meshPath ||
                    list[index][CSV_COL_INDEX] != i.ToString() ||
                    list[index][CSV_COL_NAME] != meshName)
                {
                    Text.text = "メッシュのパス\nブレンドシェイプ名\nが不一致";
                    CsvErrorCheckPlane.SetActive(true);
                    return;
                }
                index++;
            }
        }
        if (list.Count != index)
        {
            Text.text  = "ブレンドシェイプ数が不一致\n";
            Text.text += "CSV = " + (list.Count - 2) + "\n";
            Text.text += "VRM = " + (index - 2) + "\n";
            CsvErrorCheckPlane.SetActive(true);
            return;
        }

        // 表情プリセット設定
        var proxy = Vrm.VRM.GetComponent <VRMBlendShapeProxy>();

        proxy.BlendShapeAvatar.Clips.Clear();
        for (int col = CSV_COL_WEIGHT; col < list[CSV_ROW_LABEL].Count; col++)
        {
            var clip = ScriptableObject.CreateInstance <BlendShapeClip>();
            clip.BlendShapeName = list[CSV_ROW_LABEL][col];
            clip.IsBinary       = bool.Parse(list[CSV_ROW_ISBINARY][col]);

            var values = new List <BlendShapeBinding>();
            for (int row = CSV_ROW_WEIGHT; row < list.Count; row++)
            {
                if (list[row][col] != "0")
                {
                    // 0でない値が設定されていた場合だけ表情プリセットに追加
                    var shape = new BlendShapeBinding();
                    shape.RelativePath = list[row][CSV_COL_PATH];
                    shape.Index        = int.Parse(list[row][CSV_COL_INDEX]);
                    shape.Weight       = float.Parse(list[row][col]);
                    values.Add(shape);
                }
            }

            clip.Values = values.ToArray();
            proxy.BlendShapeAvatar.Clips.Add(clip);
        }

        BlendShape.Get();
    }
    /// <summary>
    /// 表情プリセットにcsvから設定を読み込み
    /// </summary>
    public void Load(string path)
    {
        if (Vrm.VRM == null)
        {
            return;
        }

        // csv読み込み
        var list   = new List <List <string> >();
        var reader = new StreamReader(path);

        while (reader.Peek() >= 0)
        {
            list.Add(new List <string>());
            string[] cols = reader.ReadLine().Split(',');
            for (int n = 0; n < cols.Length; n++)
            {
                list[list.Count - 1].Add(cols[n]);
            }
        }
        reader.Close();

        var index  = CSV_ROW_WEIGHT;
        var meshes = Vrm.VRM.GetComponentsInChildren <SkinnedMeshRenderer>();

        foreach (SkinnedMeshRenderer mesh in meshes)
        {
            var meshPath = mesh.transform.RelativePathFrom(Vrm.VRM.transform);
            for (int i = 0; i < mesh.sharedMesh.blendShapeCount; i++)
            {
                var meshName = mesh.sharedMesh.GetBlendShapeName(i);
                if (list[index][CSV_COL_PATH] != meshPath ||
                    list[index][CSV_COL_INDEX] != i.ToString() ||
                    list[index][CSV_COL_NAME] != meshName)
                {
                    // オブジェクトのパス、インデックス、ブレンドシェイプ名が一致しなければ中断
                    return;
                }
                index++;
            }
        }

        var proxy = Vrm.VRM.GetComponent <VRMBlendShapeProxy>();
        var clips = proxy.BlendShapeAvatar.Clips;

        if (clips.Count != list[CSV_ROW_LABEL].Count - CSV_COL_WEIGHT)
        {
            // 表情プリセットの数が一致しなければ中断
            return;
        }

        // 表情プリセット設定
        for (int col = CSV_COL_WEIGHT; col < list[CSV_ROW_LABEL].Count; col++)
        {
            var clip = clips[col - CSV_COL_WEIGHT];
            clip.IsBinary = bool.Parse(list[CSV_ROW_ISBINARY][col]);

            var values = new List <BlendShapeBinding>();
            for (int row = CSV_ROW_WEIGHT; row < list.Count; row++)
            {
                if (list[row][col] != "0")
                {
                    // 0でない値が設定されていた場合だけ表情プリセットに追加
                    var shape = new BlendShapeBinding();
                    shape.RelativePath = list[row][CSV_COL_PATH];
                    shape.Index        = int.Parse(list[row][CSV_COL_INDEX]);
                    shape.Weight       = float.Parse(list[row][col]);
                    values.Add(shape);
                }
            }

            clip.Values = values.ToArray();
            proxy.BlendShapeAvatar.Clips[col - CSV_COL_WEIGHT] = clip;
        }

        BlendShape.Get();
    }