public static void LoadFromBytes(VRMImporterContext context) { context.CreateMaterial = VRMImporter.GetMaterialFunc(glTF_VRM_Material.Parse(context.Json)); gltfImporter.Import <glTF_VRM>(context); if (string.IsNullOrEmpty(context.Path)) { if (string.IsNullOrEmpty(context.VRM.extensions.VRM.meta.title)) { context.Root.name = "VRM_LOADED"; } else { context.Root.name = context.VRM.extensions.VRM.meta.title; } } else { context.Root.name = Path.GetFileNameWithoutExtension(context.Path); } OnLoadModel(context); context.ShowMeshes(); }
private static Schedulable <GameObject> LoadVrmAsyncInternal(VRMImporterContext ctx, bool show) { var schedulable = Schedulable.Create(); return(schedulable .AddTask(Scheduler.ThreadPool, () => { return glTF_VRM_Material.Parse(ctx.Json); }) .ContinueWith(Scheduler.MainThread, x => { // material function ctx.CreateMaterial = VRMImporter.GetMaterialFunc(x); }) .OnExecute(Scheduler.ThreadPool, parent => { // textures for (int i = 0; i < ctx.GLTF.textures.Count; ++i) { var index = i; parent.AddTask(Scheduler.MainThread, () => { var texture = new TextureItem(ctx.GLTF, index); texture.Process(ctx.GLTF, ctx.Storage); return texture; }) .ContinueWith(Scheduler.ThreadPool, x => ctx.Textures.Add(x)); } }) .ContinueWithCoroutine(Scheduler.MainThread, () => LoadMaterials(ctx)) .OnExecute(Scheduler.ThreadPool, parent => { // meshes for (int i = 0; i < ctx.GLTF.meshes.Count; ++i) { var index = i; parent.AddTask(Scheduler.ThreadPool, () => gltfImporter.ReadMesh(ctx, index)) .ContinueWith(Scheduler.MainThread, x => gltfImporter.BuildMesh(ctx, x)) .ContinueWith(Scheduler.ThreadPool, x => ctx.Meshes.Add(x)) ; } }) .ContinueWithCoroutine(Scheduler.MainThread, () => LoadNodes(ctx)) .ContinueWithCoroutine(Scheduler.MainThread, () => BuildHierarchy(ctx)) .ContinueWith(Scheduler.CurrentThread, _ => VRMImporter.OnLoadModel(ctx)) .ContinueWith(Scheduler.CurrentThread, _ => { ctx.Root.name = "VRM"; if (show) { ctx.ShowMeshes(); } return ctx.Root; })); }
/// <summary> /// Taskで非同期にロードする例 /// </summary> async void LoadVRMClicked() { #if UNITY_STANDALONE_WIN var path = FileDialogForWindows.FileDialog("open VRM", ".vrm"); #else var path = Application.dataPath + "/default.vrm"; #endif if (string.IsNullOrEmpty(path)) { return; } var context = new VRMImporterContext(path); var bytes = await ReadBytesAsync(path); // GLB形式でJSONを取得しParseします context.ParseVrm(bytes); // metaを取得(todo: thumbnailテクスチャのロード) var meta = context.ReadMeta(); Debug.LogFormat("meta: title:{0}", meta.Title); // ParseしたJSONをシーンオブジェクトに変換していく var now = Time.time; var go = await VRMImporter.LoadVrmAsync(context); var delta = Time.time - now; Debug.LogFormat("LoadVrmAsync {0:0.0} seconds", delta); OnLoaded(go); }
public void ImportExportTest() { var path = UniGLTF.UnityPath.FromUnityPath("Models/Alicia_vrm-0.40/AliciaSolid_vrm-0.40.vrm"); var context = new VRMImporterContext(path); context.ParseGlb(File.ReadAllBytes(path.FullPath)); VRMImporter.LoadFromBytes(context); using (new ActionDisposer(() => { GameObject.DestroyImmediate(context.Root); })) { var importJson = JsonParser.Parse(context.Json); importJson.SetValue("/extensions/VRM/exporterVersion", VRMVersion.VRM_VERSION); importJson.SetValue("/asset/generator", UniGLTF.UniGLTFVersion.UNIGLTF_VERSION); importJson.SetValue("/scene", 0); importJson.SetValue("/materials/*/doubleSided", false); //importJson.SetValue("/materials/*/pbrMetallicRoughness/roughnessFactor", 0); //importJson.SetValue("/materials/*/pbrMetallicRoughness/baseColorFactor", new float[] { 1, 1, 1, 1 }); importJson.SetValue("/accessors/*/normalized", false); importJson.RemoveValue("/nodes/*/extras"); importJson.SetValue("/bufferViews/12/byteStride", 4); importJson.SetValue("/bufferViews/13/byteStride", 4); importJson.SetValue("/bufferViews/14/byteStride", 4); importJson.SetValue("/bufferViews/15/byteStride", 4); importJson.SetValue("/bufferViews/22/byteStride", 4); importJson.SetValue("/bufferViews/29/byteStride", 4); importJson.SetValue("/bufferViews/45/byteStride", 4); importJson.SetValue("/bufferViews/46/byteStride", 4); importJson.SetValue("/bufferViews/47/byteStride", 4); importJson.SetValue("/bufferViews/201/byteStride", 4); importJson.SetValue("/bufferViews/202/byteStride", 4); importJson.SetValue("/bufferViews/203/byteStride", 4); importJson.SetValue("/bufferViews/204/byteStride", 4); importJson.SetValue("/bufferViews/211/byteStride", 4); importJson.SetValue("/bufferViews/212/byteStride", 4); importJson.SetValue("/bufferViews/213/byteStride", 4); importJson.SetValue("/bufferViews/214/byteStride", 4); importJson.SetValue("/bufferViews/215/byteStride", 4); importJson.SetValue("/bufferViews/243/byteStride", 4); importJson.SetValue("/bufferViews/247/byteStride", 64); importJson.SetValue("/bufferViews/248/byteStride", 64); importJson.SetValue("/bufferViews/249/byteStride", 64); importJson.SetValue("/bufferViews/250/byteStride", 64); importJson.SetValue("/bufferViews/251/byteStride", 64); importJson.SetValue("/bufferViews/252/byteStride", 64); importJson.SetValue("/bufferViews/253/byteStride", 64); var vrm = VRMExporter.Export(context.Root); var exportJson = JsonParser.Parse(vrm.ToJson()); foreach (var kv in importJson.Diff(exportJson)) { Debug.Log(kv); } Assert.AreEqual(importJson, exportJson); } }
public static void LoadFromBytes(VRMImporterContext context) { context.CreateMaterial = VRMImporter.GetMaterialFunc(glTF_VRM_Material.Parse(context.Json)); gltfImporter.Load(context); OnLoadModel(context); context.ShowMeshes(); }
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { foreach (string path in importedAssets) { var ext = Path.GetExtension(path).ToLower(); if (ext == ".vrm") { var context = new VRMImporterContext(path); context.ParseVrm(File.ReadAllBytes(context.Path)); // // https://answers.unity.com/questions/647615/how-to-update-import-settings-for-newly-created-as.html // for (int i = 0; i < context.GLTF.textures.Count; ++i) { var x = context.GLTF.textures[i]; var image = context.GLTF.images[x.source]; if (string.IsNullOrEmpty(image.uri)) { // glb buffer var folder = context.GetAssetFolder(".Textures").AssetPathToFullPath(); if (!Directory.Exists(folder)) { UnityEditor.AssetDatabase.CreateFolder(context.GLTF.baseDir, Path.GetFileNameWithoutExtension(context.Path) + ".Textures"); //Directory.CreateDirectory(folder); } var textureName = !string.IsNullOrEmpty(image.name) ? image.name: string.Format("buffer#{0:00}", i); var png = Path.Combine(folder, textureName + ".png"); var byteSegment = context.GLTF.GetViewBytes(image.bufferView); File.WriteAllBytes(png, byteSegment.ToArray()); var assetPath = png.ToUnityRelativePath(); //Debug.LogFormat("import asset {0}", assetPath); UnityEditor.AssetDatabase.ImportAsset(assetPath, UnityEditor.ImportAssetOptions.ForceUpdate); UnityEditor.AssetDatabase.Refresh(); image.uri = assetPath.Substring(context.GLTF.baseDir.Length + 1); } } EditorApplication.delayCall += () => { // delay and can import png texture VRMImporter.LoadFromBytes(context); context.SaveAsAsset(); context.Destroy(false); }; } } }
void LoadAsync(VRMImporterContext context) { #if true var now = Time.time; VRMImporter.LoadVrmAsync(context, go => { var delta = Time.time - now; Debug.LogFormat("LoadVrmAsync {0:0.0} seconds", delta); OnLoaded(go); }); #else // ローカルファイルシステムからロードします VRMImporter.LoadVrmAsync(path, OnLoaded); #endif }
public void MeshCoyTest() { var path = UniGLTF.UnityPath.FromUnityPath("Models/Alicia_vrm-0.40/AliciaSolid_vrm-0.40.vrm"); var context = new VRMImporterContext(); context.ParseGlb(File.ReadAllBytes(path.FullPath)); VRMImporter.LoadFromBytes(context); foreach (var mesh in context.Meshes) { var src = mesh.Mesh; var dst = src.Copy(true); MeshTests.MeshEquals(src, dst); } }
static void Import(string readPath, UnityPath prefabPath) { var bytes = File.ReadAllBytes(readPath); var context = new VRMImporterContext(UnityPath.FromFullpath(readPath)); context.ParseGlb(File.ReadAllBytes(readPath)); context.SaveTexturesAsPng(prefabPath); EditorApplication.delayCall += () => { // delay and can import png texture VRMImporter.LoadFromBytes(context); context.SaveAsAsset(prefabPath); context.Destroy(false); }; }
void LoadModel(string path) { if (!File.Exists(path)) { return; } Debug.LogFormat("{0}", path); var ext = Path.GetExtension(path).ToLower(); switch (ext) { case ".vrm": { var context = new VRMImporterContext(); var file = File.ReadAllBytes(path); context.ParseGlb(file); m_texts.UpdateMeta(context); //UniJSON.JsonParser.Parse(context.Json); VRMImporter.LoadVrmAsync(context, SetModel); break; } case ".glb": { var context = new UniGLTF.ImporterContext(); var file = File.ReadAllBytes(path); context.ParseGlb(file); UniGLTF.gltfImporter.Load(context); context.ShowMeshes(); SetModel(context.Root); break; } default: Debug.LogWarningFormat("unknown file type: {0}", path); break; } }
/// <summary> /// メタが不要な場合のローダー /// </summary> void LoadVRMClicked_without_meta() { #if UNITY_STANDALONE_WIN var path = FileDialogForWindows.FileDialog("open VRM", ".vrm"); #else var path = Application.dataPath + "/default.vrm"; #endif if (string.IsNullOrEmpty(path)) { return; } #if true var bytes = File.ReadAllBytes(path); // なんらかの方法でByte列を得た var context = new VRMImporterContext(); // GLB形式でJSONを取得しParseします context.ParseGlb(bytes); if (m_loadAsync) { // ローカルファイルシステムからロードします LoadAsync(context); } else { context.Load(); OnLoaded(context); } #else // ParseしたJSONをシーンオブジェクトに変換していく if (m_loadAsync) { // ローカルファイルシステムからロードします VRMImporter.LoadVrmAsync(path, OnLoaded); } else { var root = VRMImporter.LoadFromPath(path); OnLoaded(root); } #endif }
static void ImportMenu() { var path = EditorUtility.OpenFilePanel("open vrm", "", "vrm"); if (string.IsNullOrEmpty(path)) { return; } var ext = Path.GetExtension(path).ToLower(); if (ext != ".vrm") { return; } if (path.StartsWithUnityAssetPath()) { Debug.LogWarning("vrm in AssetFolder is imported automatically"); Selection.activeObject = AssetDatabase.LoadAssetAtPath <GameObject>(path.Replace(".vrm", ".prefab").ToUnityRelativePath()); return; } var root = VRMImporter.LoadFromPath(path); if (!EditorApplication.isPlaying) { // save root as Asset var prefabPath = EditorUtility.SaveFilePanel("save vrm prefab", "Assets", Path.GetFileNameWithoutExtension(path) + ".prefab", "prefab" ); if (!string.IsNullOrEmpty(prefabPath)) { VRMAssetWriter.SaveAsPrefab(root, prefabPath); var prefab = AssetDatabase.LoadAssetAtPath <GameObject>(prefabPath.ToUnityRelativePath()); Selection.activeObject = prefab; } } }
void OnOpenClicked() { var path = FileDialogForWindows.FileDialog("open vrm", "vrm"); if (string.IsNullOrEmpty(path)) { return; } Debug.LogFormat("{0}", path); var go = VRMImporter.LoadFromPath(path); if (go == null) { return; } SetModel(go); }
static void ImportVrm(UnityPath path) { if (!path.IsUnderAssetsFolder) { throw new Exception(); } var context = new VRMImporterContext(path); context.ParseGlb(File.ReadAllBytes(path.FullPath)); var prefabPath = path.Parent.Child(path.FileNameWithoutExtension + ".prefab"); context.SaveTexturesAsPng(prefabPath); EditorApplication.delayCall += () => { // delay and can import png texture VRMImporter.LoadFromBytes(context); context.SaveAsAsset(prefabPath); context.Destroy(false); }; }
static void ImportMenu() { var path = EditorUtility.OpenFilePanel("open vrm", "", "vrm"); if (string.IsNullOrEmpty(path)) { return; } if (Application.isPlaying) { // load into scene Selection.activeGameObject = VRMImporter.LoadFromPath(path); } else { if (path.StartsWithUnityAssetPath()) { Debug.LogWarningFormat("disallow import from folder under the Assets"); return; } var assetPath = EditorUtility.SaveFilePanel("save prefab", "Assets", Path.GetFileNameWithoutExtension(path), "prefab"); if (string.IsNullOrEmpty(path)) { return; } if (!assetPath.StartsWithUnityAssetPath()) { Debug.LogWarningFormat("out of asset path: {0}", assetPath); return; } // import as asset Import(path, UnityPath.FromUnityPath(assetPath)); } }
void LoadVRMClicked() { #if UNITY_STANDALONE_WIN var path = FileDialogForWindows.FileDialog("open VRM", ".vrm"); #else var path = Application.dataPath + "/default.vrm"; #endif if (string.IsNullOrEmpty(path)) { return; } var bytes = File.ReadAllBytes(path); // なんらかの方法でByte列を得た var context = new VRMImporterContext(path); // GLB形式でJSONを取得しParseします context.ParseVrm(bytes); // metaを取得(todo: thumbnailテクスチャのロード) var meta = context.ReadMeta(); Debug.LogFormat("meta: title:{0}", meta.Title); // ParseしたJSONをシーンオブジェクトに変換していく if (m_loadAsync) { LoadAsync(context); } else { VRMImporter.LoadFromBytes(context); OnLoaded(context.Root); } }
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { foreach (string path in importedAssets) { var ext = Path.GetExtension(path).ToLower(); if (ext == ".vrm") { var context = new VRMImporterContext(path); try { VRMImporter.LoadFromPath(context); /* * var prefabPath = String.Format("{0}/{1}.prefab", * Path.GetDirectoryName(path), * Path.GetFileNameWithoutExtension(path)); * * VRMAssetWriter.SaveAsPrefab(context.Root, prefabPath); * * var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath.ToUnityRelativePath()); * Selection.activeObject = prefab; */ context.SaveAsAsset(); context.Destroy(false); } catch (Exception ex) { Debug.LogError(ex); if (context != null) { context.Destroy(true); } } } } }
private static Schedulable <GameObject> LoadVrmAsyncInternal(VRMImporterContext ctx) { var schedulable = Schedulable.Create(); return(schedulable .AddTask(Scheduler.ThreadPool, () => { ctx.GLTF.baseDir = Path.GetDirectoryName(ctx.Path); return Unit.Default; }) .ContinueWith(Scheduler.ThreadPool, _ => { return glTF_VRM_Material.Parse(ctx.Json); }) .ContinueWith(Scheduler.MainThread, x => { // material function ctx.CreateMaterial = VRMImporter.GetMaterialFunc(x); }) .OnExecute(Scheduler.ThreadPool, parent => { // textures for (int i = 0; i < ctx.GLTF.textures.Count; ++i) { var index = i; parent.AddTask(Scheduler.MainThread, () => { var texture = new TextureItem(ctx.GLTF, index); texture.Process(); return texture; }) .ContinueWith(Scheduler.ThreadPool, x => ctx.Textures.Add(x)); } }) .ContinueWithCoroutine(Scheduler.MainThread, () => LoadMaterials(ctx)) .OnExecute(Scheduler.ThreadPool, parent => { // meshes for (int i = 0; i < ctx.GLTF.meshes.Count; ++i) { var index = i; parent.AddTask(Scheduler.ThreadPool, () => gltfImporter.ReadMesh(ctx, index)) .ContinueWith(Scheduler.MainThread, x => gltfImporter.BuildMesh(ctx, x)) .ContinueWith(Scheduler.ThreadPool, x => ctx.Meshes.Add(x)) ; } }) .ContinueWithCoroutine(Scheduler.MainThread, () => LoadNodes(ctx)) .ContinueWithCoroutine(Scheduler.MainThread, () => BuildHierarchy(ctx)) .ContinueWith(Scheduler.MainThread, _ => VRMImporter.OnLoadModel(ctx)) .ContinueWith(Scheduler.MainThread, _ => { /* * Debug.LogFormat("task end: {0}/{1}/{2}/{3}", * ctx.Textures.Count, * ctx.Materials.Count, * ctx.Meshes.Count, * ctx.Nodes.Count * ); */ ctx.Root.name = Path.GetFileNameWithoutExtension(ctx.Path); // 非表示のメッシュを表示する ctx.ShowMeshes(); return ctx.Root; })); }
private static Schedulable <GameObject> LoadVrmAsyncInternal(VRMImporterContext ctx, bool show) { return(Schedulable.Create() .AddTask(Scheduler.ThreadPool, () => { using (ctx.MeasureTime("glTF_VRM_Material.Parse")) { return glTF_VRM_Material.Parse(ctx.Json); } }) .ContinueWith(Scheduler.MainThread, gltfMaterials => { using (ctx.MeasureTime("new VRMMaterialImporter")) { ctx.MaterialImporter = new VRMMaterialImporter(ctx, gltfMaterials); } }) .OnExecute(Scheduler.ThreadPool, parent => { // textures for (int i = 0; i < ctx.GLTF.textures.Count; ++i) { var index = i; parent.AddTask(Scheduler.MainThread, () => { using (ctx.MeasureTime("texture.Process")) { var texture = new TextureItem(ctx.GLTF, index); texture.Process(ctx.GLTF, ctx.Storage); return texture; } }) .ContinueWith(Scheduler.ThreadPool, x => ctx.AddTexture(x)); } }) .ContinueWithCoroutine(Scheduler.MainThread, () => LoadMaterials(ctx)) .OnExecute(Scheduler.ThreadPool, parent => { // meshes for (int i = 0; i < ctx.GLTF.meshes.Count; ++i) { var index = i; parent.AddTask(Scheduler.ThreadPool, () => { using (ctx.MeasureTime("ReadMesh")) { return gltfImporter.ReadMesh(ctx, index); } }) .ContinueWith(Scheduler.MainThread, x => { using (ctx.MeasureTime("BuildMesh")) { return gltfImporter.BuildMesh(ctx, x); } }) .ContinueWith(Scheduler.ThreadPool, x => ctx.Meshes.Add(x)) ; } }) .ContinueWithCoroutine(Scheduler.MainThread, () => { using (ctx.MeasureTime("LoadNodes")) { return LoadNodes(ctx); } }) .ContinueWithCoroutine(Scheduler.MainThread, () => { using (ctx.MeasureTime("BuildHierarchy")) { return BuildHierarchy(ctx); } }) .ContinueWith(Scheduler.CurrentThread, _ => { //using (ctx.MeasureTime("OnLoadModel")) { return VRMImporter.OnLoadModel(ctx); } }) .ContinueWith(Scheduler.CurrentThread, _ => { ctx.Root.name = "VRM"; if (show) { ctx.ShowMeshes(); } Debug.Log(ctx.GetSpeedLog()); return ctx.Root; })); }
public static void LoadVrmAsync(VRMImporterContext ctx, ArraySegment <Byte> chunkData, Action <GameObject> onLoaded) { var schedulable = Schedulable.Create(); schedulable .AddTask(MainThreadDispatcher.Instance.ThreadScheduler, () => { ctx.GLTF.baseDir = Path.GetDirectoryName(ctx.Path); foreach (var buffer in ctx.GLTF.buffers) { buffer.OpenStorage(ctx.GLTF.baseDir, chunkData); } return(Unit.Default); }) .ContinueWith(MainThreadDispatcher.Instance.ThreadScheduler, _ => { return(glTF_VRM_Material.Parse(ctx.Json)); }) .ContinueWith(MainThreadDispatcher.Instance.UnityScheduler, x => { // material function ctx.CreateMaterial = VRMImporter.GetMaterialFunc(x); }) .OnExecute(MainThreadDispatcher.Instance.UnityScheduler, parent => { // textures for (int i = 0; i < ctx.GLTF.textures.Count; ++i) { var index = i; parent.AddTask(MainThreadDispatcher.Instance.UnityScheduler, () => gltfImporter.ImportTexture(ctx.GLTF, index)) .ContinueWith(MainThreadDispatcher.Instance.ThreadScheduler, x => ctx.Textures.Add(x)); } }) .ContinueWithCoroutine(MainThreadDispatcher.Instance.UnityScheduler, () => LoadMaterials(ctx)) .OnExecute(MainThreadDispatcher.Instance.UnityScheduler, parent => { // meshes for (int i = 0; i < ctx.GLTF.meshes.Count; ++i) { var index = i; parent.AddTask(MainThreadDispatcher.Instance.ThreadScheduler, () => gltfImporter.ReadMesh(ctx, index)) .ContinueWith(MainThreadDispatcher.Instance.UnityScheduler, x => gltfImporter.BuildMesh(ctx, x)) .ContinueWith(MainThreadDispatcher.Instance.ThreadScheduler, x => ctx.Meshes.Add(x)) ; } }) .ContinueWithCoroutine(MainThreadDispatcher.Instance.UnityScheduler, () => LoadNodes(ctx)) .ContinueWithCoroutine(MainThreadDispatcher.Instance.UnityScheduler, () => BuildHierarchy(ctx)) .ContinueWith(MainThreadDispatcher.Instance.UnityScheduler, _ => VRMImporter.OnLoadModel(ctx)) .Subscribe(MainThreadDispatcher.Instance.UnityScheduler, _ => { /* * Debug.LogFormat("task end: {0}/{1}/{2}/{3}", * ctx.Textures.Count, * ctx.Materials.Count, * ctx.Meshes.Count, * ctx.Nodes.Count * ); */ ctx.Root.name = Path.GetFileNameWithoutExtension(ctx.Path); // 非表示のメッシュを表示する ctx.ShowMeshes(); onLoaded(ctx.Root); }, ex => { Debug.LogError(ex); }) ; }