public void MaterialImporterTest() { var parser = new GltfParser(); parser.ParsePath(AliciaPath); var vrmImporter = new VRMImporterContext(parser, null); var materialParam = new VRMMaterialImporter(vrmImporter.VRM).GetMaterialParam(parser, 0); Assert.AreEqual("VRM/MToon", materialParam.ShaderName); Assert.AreEqual("Alicia_body", materialParam.TextureSlots["_MainTex"].UnityObjectName); var(key, value) = materialParam.EnumerateSubAssetKeyValue().First(); Assert.AreEqual(new SubAssetKey(typeof(Texture2D), "Alicia_body"), key); }
private static void LoadHumanoidObsolete(VRMImporterContext context) { var parsed = UniJSON.JsonParser.Parse(context.Json)["extensions"]["VRM"]; var skeleton = context.Root.transform.Traverse().Select(x => ToSkeletonBone(x)).ToArray(); var description = new HumanDescription { human = parsed[HUMANOID_KEY]["bones"] .ObjectItems .Select(x => new { x.Key, Index = x.Value.Value.GetInt32() }) .Where(x => x.Index != -1) .Select(x => { var humanBone = EnumUtil.TryParseOrDefault <HumanBodyBones>(x.Key); var hb = new HumanBone { boneName = context.Nodes[x.Index].name, humanName = ToHumanBoneName(humanBone) }; hb.limit.useDefaultValues = true; return(hb); }).ToArray(), skeleton = skeleton, lowerArmTwist = 0.5f, upperArmTwist = 0.5f, upperLegTwist = 0.5f, lowerLegTwist = 0.5f, armStretch = 0.05f, legStretch = 0.05f, feetSpacing = 0.0f, }; context.HumanoidAvatar = AvatarBuilder.BuildHumanAvatar(context.Root, description); context.HumanoidAvatar.name = "VrmAvatar"; context.AvatarDescription = UniHumanoid.AvatarDescription.CreateFrom(description); context.AvatarDescription.name = "AvatarDescription"; var humanoid = context.Root.AddComponent <VRMHumanoidDescription>(); humanoid.Avatar = context.HumanoidAvatar; humanoid.Description = context.AvatarDescription; var animator = context.Root.GetComponent <Animator>(); if (animator == null) { animator = context.Root.AddComponent <Animator>(); } animator.avatar = context.HumanoidAvatar; }
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.extra.name) ? string.Format("buffer#{0:00}", i) : image.extra.name; 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, ArraySegment <byte> dataChunk) { #if true var now = Time.time; VRMImporter.LoadVrmAsync(context, dataChunk, go => { var delta = Time.time - now; Debug.LogFormat("LoadVrmAsync {0:0.0} seconds", delta); OnLoaded(go); }); #else // ローカルファイルシステムからロードします VRMImporter.LoadVrmAsync(path, OnLoaded); #endif }
public static async Task <RuntimeGltfInstance> LoadAsync(string path, IAwaitCaller awaitCaller = null, MaterialGeneratorCallback materialGeneratorCallback = null, MetaCallback metaCallback = null ) { if (!File.Exists(path)) { throw new FileNotFoundException(path); } if (awaitCaller == null) { Debug.LogWarning("VrmUtility.LoadAsync: awaitCaller argument is null. ImmediateCaller is used as the default fallback. When playing, we recommend RuntimeOnlyAwaitCaller."); awaitCaller = new ImmediateCaller(); } using (GltfData data = new AutoGltfFileParser(path).Parse()) { try { var vrm = new VRMData(data); IMaterialDescriptorGenerator materialGen = default; if (materialGeneratorCallback != null) { materialGen = materialGeneratorCallback(vrm.VrmExtension); } using (var loader = new VRMImporterContext(vrm, materialGenerator: materialGen)) { if (metaCallback != null) { var meta = await loader.ReadMetaAsync(awaitCaller, true); metaCallback(meta); } return(await loader.LoadAsync(awaitCaller)); } } catch (NotVrm0Exception) { // retry Debug.LogWarning("file extension is vrm. but not vrm ?"); using (var loader = new UniGLTF.ImporterContext(data)) { return(await loader.LoadAsync(awaitCaller)); } } } }
public void TraverseRenderers(VRMImporterContext context = null) { var rendererComponents = transform.GetComponentsInChildren <Renderer>(); foreach (var renderer in rendererComponents) { Renderers.Add(new RendererFirstPersonFlags { Renderer = renderer, FirstPersonFlag = context == null ? FirstPersonFlag.Auto : GetFirstPersonFlag(context, renderer) }); } }
static IEnumerator LoadMeshes(VRMImporterContext context) { for (int i = 0; i < context.GLTF.meshes.Count; ++i) { var meshWithMaterials = gltfImporter.ImportMesh(context, i); var mesh = meshWithMaterials.Mesh; if (string.IsNullOrEmpty(mesh.name)) { mesh.name = string.Format("UniGLTF import#{0}", i); } context.Meshes.Add(meshWithMaterials); yield return(null); } }
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); } }
public void MaterialImporterTest() { var path = AliciaPath; using (var data = new GlbFileParser(path).Parse()) { var vrmImporter = new VRMImporterContext(new VRMData(data), null); var materialParam = new VRMMaterialDescriptorGenerator(vrmImporter.VRM).Get(data, 0); Assert.AreEqual("VRM/MToon", materialParam.ShaderName); Assert.AreEqual("Alicia_body", materialParam.TextureSlots["_MainTex"].UnityObjectName); var(key, value) = materialParam.EnumerateSubAssetKeyValue().First(); Assert.AreEqual(new SubAssetKey(typeof(Texture), "Alicia_body"), key); } }
static void ImportRuntime(string path) { // load into scene var data = new GlbFileParser(path).Parse(); // VRM extension を parse します var vrm = new VRMData(data); using (var context = new VRMImporterContext(vrm)) { var loaded = context.Load(); loaded.EnableUpdateWhenOffscreen(); loaded.ShowMeshes(); Selection.activeGameObject = loaded.gameObject; } }
static IEnumerator LoadMaterials(VRMImporterContext context) { if (context.GLTF.materials == null || !context.GLTF.materials.Any()) { context.Materials.Add(context.CreateMaterial(context, 0)); } else { for (int i = 0; i < context.GLTF.materials.Count; ++i) { context.Materials.Add(context.CreateMaterial(context, i)); yield return(null); } } }
public void MToonMaterialParamTest() { if (!VRMTestAssets.TryGetPath("Models/VRoid/VictoriaRubin/VictoriaRubin.vrm", out string path)) { return; } var data = new GlbFileParser(path).Parse(); var vrm = new VRMData(data); var importer = new VRMImporterContext(vrm, null); Assert.AreEqual(73, vrm.Data.GLTF.materials.Count); Assert.True(VRMMToonMaterialImporter.TryCreateParam(vrm.Data, importer.VRM, 0, out MaterialDescriptor matDesc)); }
void LoadAsync(VRMImporterContext context) { #if true var now = Time.time; context.LoadAsync(_ => { var delta = Time.time - now; Debug.LogFormat("LoadAsync {0:0.0} seconds", delta); OnLoaded(context); }); #else // ローカルファイルシステムからロードします VRMImporter.LoadVrmAsync(path, OnLoaded); #endif }
public void TraverseRenderers(VRMImporterContext context = null) { Renderers = Traverse(transform) .Select(x => x.GetComponent <Renderer>()) .Where(x => x != null) .Select(x => new RendererFirstPersonFlags { Renderer = x, FirstPersonFlag = context == null ? FirstPersonFlag.Auto : GetFirstPersonFlag(context, x) }) .ToList() ; }
static void ImportRuntime(string path) { // load into scene var parser = new GltfParser(); parser.ParsePath(path); using (var context = new VRMImporterContext(parser)) { context.Load(); context.EnableUpdateWhenOffscreen(); context.ShowMeshes(); context.DisposeOnGameObjectDestroyed(); Selection.activeGameObject = context.Root; } }
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); }; }
static void ImportVrm(UnityPath path) { if (!path.IsUnderAssetsFolder) { throw new Exception(); } var parser = new GltfParser(); try { parser.ParseGlb(File.ReadAllBytes(path.FullPath)); } catch (KeyNotFoundException) { // invalid VRM-0.X. // maybe VRM-1.0.do nothing return; } var prefabPath = path.Parent.Child(path.FileNameWithoutExtension + ".prefab"); // save texture assets ! LoadTextureAsyncFunc textureLoader = async(caller, textureIndex, used) => { var gltfTexture = parser.GLTF.textures[textureIndex]; var gltfImage = parser.GLTF.images[gltfTexture.source]; var assetPath = prefabPath.Parent.Child(gltfImage.uri); var texture = await UniGLTF.AssetTextureLoader.LoadTaskAsync(assetPath, parser.GLTF, textureIndex); return(new TextureLoadInfo(texture, used, false)); }; var context = new VRMImporterContext(parser, textureLoader); var editor = new VRMEditorImporterContext(context); editor.ExtractImages(prefabPath); EditorApplication.delayCall += () => { // // after textures imported // context.Load(); editor.SaveAsAsset(prefabPath); editor.Dispose(); }; }
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; } }
public void OnImported(VRMImporterContext context) { var animator = GetComponent <Animator>(); if (animator != null) { LeftEye = OffsetOnTransform.Create(animator.GetBoneTransform(HumanBodyBones.LeftEye)); RightEye = OffsetOnTransform.Create(animator.GetBoneTransform(HumanBodyBones.RightEye)); } var gltfFirstPerson = context.VRM.firstPerson; HorizontalInner.Apply(gltfFirstPerson.lookAtHorizontalInner); HorizontalOuter.Apply(gltfFirstPerson.lookAtHorizontalOuter); VerticalDown.Apply(gltfFirstPerson.lookAtVerticalDown); VerticalUp.Apply(gltfFirstPerson.lookAtVerticalUp); }
/// <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 }
public void MToonMaterialParamTest() { if (!VRMTestAssets.TryGetPath("Models/VRoid/VictoriaRubin/VictoriaRubin.vrm", out string path)) { return; } var parser = new GltfParser(); parser.ParsePath(path); var importer = new VRMImporterContext(parser, null); var materialImporter = new VRMMaterialImporter(importer.VRM); Assert.AreEqual(73, parser.GLTF.materials.Count); Assert.True(materialImporter.TryCreateParam(parser, 0, out MaterialImportParam param)); }
public static void LoadVrmAsync(Byte[] bytes, Action <GameObject> onLoaded, Action <Exception> onError = null, bool show = true) { var context = new VRMImporterContext(); using (context.MeasureTime("ParseGlb")) { context.ParseGlb(bytes); } context.LoadAsync(_ => { if (show) { context.ShowMeshes(); } onLoaded(context.Root); }, onError); }
public static void ImportVrmAndCreatePrefab(string vrmPath, UnityPath prefabPath) { if (!prefabPath.IsUnderAssetsFolder) { Debug.LogWarningFormat("out of asset path: {0}", prefabPath); return; } /// <summary> /// これは EditorApplication.delayCall により呼び出される。 /// /// * delayCall には UnityEngine.Object 持ち越すことができない /// * vrmPath のみを持ち越す /// /// </summary> /// <value></value> Action <IEnumerable <UnityPath> > onCompleted = texturePaths => { var map = texturePaths .Select(x => x.LoadAsset <Texture>()) .ToDictionary(x => new SubAssetKey(x), x => x as UnityEngine.Object); // 確実に Dispose するために敢えて再パースしている using (var data = new GlbFileParser(vrmPath).Parse()) using (var context = new VRMImporterContext(new VRMData(data), externalObjectMap: map)) { var editor = new VRMEditorImporterContext(context, prefabPath); foreach (var textureInfo in context.TextureDescriptorGenerator.Get().GetEnumerable()) { VRMShaders.TextureImporterConfigurator.Configure(textureInfo, context.TextureFactory.ExternalTextures); } var loaded = context.Load(); editor.SaveAsAsset(loaded); } }; using (var data = new GlbFileParser(vrmPath).Parse()) using (var context = new VRMImporterContext(new VRMData(data))) { var editor = new VRMEditorImporterContext(context, prefabPath); // extract texture images editor.ConvertAndExtractImages(onCompleted); } }
static void LoadFirstPerson(VRMImporterContext context) { var firstPerson = context.Root.AddComponent <VRMFirstPerson>(); var gltfFirstPerson = context.VRM.extensions.VRM.firstPerson; if (gltfFirstPerson.firstPersonBone != -1) { firstPerson.FirstPersonBone = context.Nodes[gltfFirstPerson.firstPersonBone]; firstPerson.FirstPersonOffset = gltfFirstPerson.firstPersonBoneOffset; } else { // fallback firstPerson.SetDefault(); } firstPerson.TraverseRenderers(context); // LookAt /*var lookAtHead =*/ context.Root.AddComponent <VRMLookAtHead>(); switch (gltfFirstPerson.lookAtType) { case LookAtType.Bone: { var applyer = context.Root.AddComponent <VRMLookAtBoneApplyer>(); applyer.HorizontalInner.Apply(gltfFirstPerson.lookAtHorizontalInner); applyer.HorizontalOuter.Apply(gltfFirstPerson.lookAtHorizontalOuter); applyer.VerticalDown.Apply(gltfFirstPerson.lookAtVerticalDown); applyer.VerticalUp.Apply(gltfFirstPerson.lookAtVerticalUp); } break; case LookAtType.BlendShape: { var applyer = context.Root.AddComponent <VRMLookAtBlendShapeApplyer>(); applyer.Horizontal.Apply(gltfFirstPerson.lookAtHorizontalOuter); applyer.VerticalDown.Apply(gltfFirstPerson.lookAtVerticalDown); applyer.VerticalUp.Apply(gltfFirstPerson.lookAtVerticalUp); } break; } }
void OnLoaded(VRMImporterContext context) { var root = context.Root; root.transform.SetParent(transform, false); //メッシュを表示します context.ShowMeshes(); // add motion var humanPoseTransfer = root.AddComponent <UniHumanoid.HumanPoseTransfer>(); if (m_target != null) { GameObject.Destroy(m_target.gameObject); } m_target = humanPoseTransfer; SetupTarget(); }
private static void LoadHumanoid(VRMImporterContext context) { context.AvatarDescription = context.VRM.extensions.VRM.humanoid.ToDescription(context.Nodes); context.AvatarDescription.name = "AvatarDescription"; context.HumanoidAvatar = context.AvatarDescription.CreateAvatar(context.Root.transform); context.HumanoidAvatar.name = Path.GetFileNameWithoutExtension(context.Path); var humanoid = context.Root.AddComponent <VRMHumanoidDescription>(); humanoid.Avatar = context.HumanoidAvatar; humanoid.Description = context.AvatarDescription; var animator = context.Root.GetComponent <Animator>(); if (animator == null) { animator = context.Root.AddComponent <Animator>(); } animator.avatar = context.HumanoidAvatar; }
static void LoadBlendShapeMaster(VRMImporterContext context) { context.BlendShapeAvatar = ScriptableObject.CreateInstance <BlendShapeAvatar>(); context.BlendShapeAvatar.name = "BlendShape"; var blendShapeList = context.VRM.extensions.VRM.blendShapeMaster.blendShapeGroups; if (blendShapeList != null && blendShapeList.Count > 0) { foreach (var x in blendShapeList) { context.BlendShapeAvatar.Clips.Add(LoadBlendShapeBind(context, x)); } } var proxy = context.Root.AddComponent <VRMBlendShapeProxy>(); context.BlendShapeAvatar.CreateDefaultPreset(); proxy.BlendShapeAvatar = context.BlendShapeAvatar; }
static void LoadMeta(VRMImporterContext context) { var meta = context.ReadMeta(); if (meta.Thumbnail == null) { /* * // 作る * var lookAt = context.Root.GetComponent<VRMLookAtHead>(); * var thumbnail = lookAt.CreateThumbnail(); * thumbnail.name = "thumbnail"; * meta.Thumbnail = thumbnail; * context.Textures.Add(new TextureItem(thumbnail)); */ } var _meta = context.Root.AddComponent <VRMMeta>(); _meta.Meta = meta; context.Meta = meta; }
public static Unit OnLoadModel(VRMImporterContext context) { LoadMeta(context); try { LoadHumanoidObsolete(context); Debug.LogWarning("LoadHumanoidObsolete"); } catch (Exception) { LoadHumanoid(context); } LoadBlendShapeMaster(context); LoadSecondaryMotions(context); LoadFirstPerson(context); return(Unit.Default); }
public static Unit OnLoadModel(VRMImporterContext context) { LoadMeta(context); try { LoadHumanoidObsolete(context); Debug.LogWarning("LoadHumanoidObsolete"); } catch (Exception) { LoadHumanoid(context); } LoadBlendShapeMaster(context); VRMSpringUtility.LoadSecondary(context.Root.transform, context.Nodes, context.VRM.extensions.VRM.secondaryAnimation); LoadFirstPerson(context); return(Unit.Default); }