/// <summary> /// Load the VRM file from the binary. /// /// You should call this on Unity main thread. /// This will throw Exceptions (include OperationCanceledException). /// </summary> /// <param name="bytes">vrm file data</param> /// <param name="canLoadVrm0X">if true, this loader can load the vrm-0.x model as vrm-1.0 model with migration.</param> /// <param name="normalizeTransform">if true, vrm-1.0 models' transforms are normalized. (e.g. rotation, scaling)</param> /// <param name="showMeshes">if true, show meshes when loaded.</param> /// <param name="awaitCaller">this loader use specified await strategy.</param> /// <param name="materialGenerator">this loader use specified material generation strategy.</param> /// <param name="vrmMetaInformationCallback">return callback that notify meta information before loading.</param> /// <param name="ct">CancellationToken</param> /// <returns>vrm-1.0 instance. Maybe return null if unexpected error was raised.</returns> public static async Task <Vrm10Instance> LoadBytesAsync( byte[] bytes, bool canLoadVrm0X = true, bool normalizeTransform = true, bool showMeshes = true, IAwaitCaller awaitCaller = null, IMaterialDescriptorGenerator materialGenerator = null, VrmMetaInformationCallback vrmMetaInformationCallback = null, CancellationToken ct = default) { if (awaitCaller == null) { awaitCaller = Application.isPlaying ? (IAwaitCaller) new RuntimeOnlyAwaitCaller() : (IAwaitCaller) new ImmediateCaller(); } return(await LoadAsync( string.Empty, bytes, canLoadVrm0X, normalizeTransform, showMeshes, awaitCaller, materialGenerator, vrmMetaInformationCallback, ct)); }
private static async Task <Vrm10Instance> TryLoadingAsVrm10Async( GltfData gltfData, bool normalizeTransform, bool showMeshes, IAwaitCaller awaitCaller, IMaterialDescriptorGenerator materialGenerator, VrmMetaInformationCallback vrmMetaInformationCallback, CancellationToken ct) { ct.ThrowIfCancellationRequested(); if (awaitCaller == null) { throw new ArgumentNullException(); } var vrm10Data = await awaitCaller.Run(() => Vrm10Data.Parse(gltfData)); ct.ThrowIfCancellationRequested(); if (vrm10Data == null) { // NOTE: Failed to parse as VRM 1.0. return(null); } return(await LoadVrm10DataAsync( vrm10Data, null, normalizeTransform, showMeshes, awaitCaller, materialGenerator, vrmMetaInformationCallback, ct)); }
private static async Task <Vrm10Instance> LoadVrm10DataAsync( Vrm10Data vrm10Data, MigrationData migrationData, bool normalizeTransform, bool showMeshes, IAwaitCaller awaitCaller, IMaterialDescriptorGenerator materialGenerator, VrmMetaInformationCallback vrmMetaInformationCallback, CancellationToken ct) { ct.ThrowIfCancellationRequested(); if (awaitCaller == null) { throw new ArgumentNullException(); } if (vrm10Data == null) { throw new ArgumentNullException(nameof(vrm10Data)); } using (var loader = new Vrm10Importer(vrm10Data, materialGenerator: materialGenerator, doNormalize: normalizeTransform)) { // 1. Load meta information if callback was available. if (vrmMetaInformationCallback != null) { var thumbnail = await loader.LoadVrmThumbnailAsync(); if (migrationData != null) { vrmMetaInformationCallback(thumbnail, default, migrationData.OriginalMetaBeforeMigration);
public VRMImporterContext( VRMData data, IReadOnlyDictionary <SubAssetKey, Object> externalObjectMap = null, ITextureDeserializer textureDeserializer = null, IMaterialDescriptorGenerator materialGenerator = null) : base(data.Data, externalObjectMap, textureDeserializer, materialGenerator ?? new VRMMaterialDescriptorGenerator(data.VrmExtension)) { _data = data; TextureDescriptorGenerator = new VrmTextureDescriptorGenerator(Data, VRM); }
public static async Task <RuntimeGltfInstance> LoadAsync(string path, bool doMigrate, bool doNormalize, IAwaitCaller awaitCaller = null, IMaterialDescriptorGenerator materialGenerator = null, MetaCallback metaCallback = null ) { using (var data = Vrm10Data.ParseOrMigrate(path, doMigrate, out Vrm10Data vrm1Data, out MigrationData migration)) { if (vrm1Data == null) { return(default);
public static async Task <RuntimeGltfInstance> LoadAsync(string path, IAwaitCaller awaitCaller = null, MaterialGeneratorCallback materialGeneratorCallback = null, MetaCallback metaCallback = null, bool loadAnimation = false ) { 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, loadAnimation: loadAnimation)) { 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)); } } } }
/// <summary> /// glb をパースして、UnityObject化、さらにAsset化する /// </summary> /// <param name="scriptedImporter"></param> /// <param name="context"></param> /// <param name="reverseAxis"></param> protected static void Import(ScriptedImporter scriptedImporter, AssetImportContext context, Axes reverseAxis, RenderPipelineTypes renderPipeline) { #if VRM_DEVELOP Debug.Log("OnImportAsset to " + scriptedImporter.assetPath); #endif // // Parse(parse glb, parser gltf json) // var data = new AutoGltfFileParser(scriptedImporter.assetPath).Parse(); // // Import(create unity objects) // // 2 回目以降の Asset Import において、 Importer の設定で Extract した UnityEngine.Object が入る var extractedObjects = scriptedImporter.GetExternalObjectMap() .Where(x => x.Value != null) .ToDictionary(kv => new SubAssetKey(kv.Value.GetType(), kv.Key.name), kv => kv.Value); IMaterialDescriptorGenerator materialGenerator = GetMaterialGenerator(renderPipeline); using (var loader = new ImporterContext(data, extractedObjects, materialGenerator: materialGenerator)) { // Configure TextureImporter to Extracted Textures. foreach (var textureInfo in loader.TextureDescriptorGenerator.Get().GetEnumerable()) { TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalTextures); } loader.InvertAxis = reverseAxis; var loaded = loader.Load(); loaded.ShowMeshes(); loaded.TransferOwnership((k, o) => { context.AddObjectToAsset(k.Name, o); }); var root = loaded.Root; GameObject.DestroyImmediate(loaded); context.AddObjectToAsset(root.name, root); context.SetMainObject(root); } }
private static async Task <Vrm10Instance> TryMigratingFromVrm0XAsync( GltfData gltfData, bool normalizeTransform, bool showMeshes, IAwaitCaller awaitCaller, IMaterialDescriptorGenerator materialGenerator, VrmMetaInformationCallback vrmMetaInformationCallback, CancellationToken ct) { ct.ThrowIfCancellationRequested(); if (awaitCaller == null) { throw new ArgumentNullException(); } Vrm10Data migratedVrm10Data = default; MigrationData migrationData = default; using (var migratedGltfData = await awaitCaller.Run(() => Vrm10Data.Migrate(gltfData, out migratedVrm10Data, out migrationData))) { ct.ThrowIfCancellationRequested(); if (migratedVrm10Data == null) { throw new Exception(migrationData?.Message ?? "Failed to migrate."); } var migratedVrm10Instance = await LoadVrm10DataAsync( migratedVrm10Data, migrationData, normalizeTransform, showMeshes, awaitCaller, materialGenerator, vrmMetaInformationCallback, ct); if (migratedVrm10Instance == null) { throw new Exception(migrationData?.Message ?? "Failed to load migrated."); } return(migratedVrm10Instance); } }
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); } 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(new ImmediateCaller(), 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 Vrm10Importer( Vrm10Data vrm, IReadOnlyDictionary <SubAssetKey, UnityEngine.Object> externalObjectMap = null, ITextureDeserializer textureDeserializer = null, IMaterialDescriptorGenerator materialGenerator = null, bool doNormalize = false) : base(vrm.Data, externalObjectMap, textureDeserializer) { if (vrm == null) { throw new ArgumentNullException("vrm"); } m_vrm = vrm; m_doNormalize = doNormalize; TextureDescriptorGenerator = new Vrm10TextureDescriptorGenerator(Data); MaterialDescriptorGenerator = materialGenerator ?? new Vrm10MaterialDescriptorGenerator(); m_externalMap = externalObjectMap; if (m_externalMap == null) { m_externalMap = new Dictionary <SubAssetKey, UnityEngine.Object>(); } }
/// <summary> /// UnityObject の 生成(LoadAsync) と 破棄(Dispose) を行う。 /// LoadAsync が成功した場合、返り値(RuntimeGltfInstance) に破棄する責務を移動させる。 /// </summary> /// <param name="data">Jsonからデシリアライズされた GLTF 情報など</param> /// <param name="externalObjectMap">外部オブジェクトのリスト(主にScriptedImporterのRemapで使う)</param> /// <param name="textureDeserializer">Textureロードをカスタマイズする</param> /// <param name="materialGenerator">Materialロードをカスタマイズする(URP向け)</param> public ImporterContext( GltfData data, IReadOnlyDictionary <SubAssetKey, UnityEngine.Object> externalObjectMap = null, ITextureDeserializer textureDeserializer = null, IMaterialDescriptorGenerator materialGenerator = null) { Data = data; TextureDescriptorGenerator = new GltfTextureDescriptorGenerator(Data); MaterialDescriptorGenerator = materialGenerator ?? new GltfMaterialDescriptorGenerator(); ExternalObjectMap = externalObjectMap ?? new Dictionary <SubAssetKey, UnityEngine.Object>(); textureDeserializer = textureDeserializer ?? new UnityTextureDeserializer(); TextureFactory = new TextureFactory(textureDeserializer, ExternalObjectMap .Where(x => x.Value is Texture) .ToDictionary(x => x.Key, x => (Texture)x.Value), Data.MigrationFlags.IsRoughnessTextureValueSquared); MaterialFactory = new MaterialFactory(ExternalObjectMap .Where(x => x.Value is Material) .ToDictionary(x => x.Key, x => (Material)x.Value), MaterialFallback.FallbackShaders); AnimationClipFactory = new AnimationClipFactory(ExternalObjectMap .Where(x => x.Value is AnimationClip) .ToDictionary(x => x.Key, x => (AnimationClip)x.Value)); }
public static async Task <RuntimeGltfInstance> LoadAsync(string path, IAwaitCaller awaitCaller = null, IMaterialDescriptorGenerator materialGenerator = null) { if (!File.Exists(path)) { throw new FileNotFoundException(path); } Debug.LogFormat("{0}", path); using (GltfData data = new AutoGltfFileParser(path).Parse()) using (var loader = new UniGLTF.ImporterContext(data, materialGenerator: materialGenerator)) { return(await loader.LoadAsync(awaitCaller)); } }
private static async Task <Vrm10Instance> LoadAsync( string name, byte[] bytes, bool canLoadVrm0X, bool normalizeTransform, bool showMeshes, IAwaitCaller awaitCaller, IMaterialDescriptorGenerator materialGenerator, VrmMetaInformationCallback vrmMetaInformationCallback, CancellationToken ct) { ct.ThrowIfCancellationRequested(); if (awaitCaller == null) { throw new ArgumentNullException(); } using (var gltfData = new GlbLowLevelParser(name, bytes).Parse()) { // 1. Try loading as vrm-1.0 var instance = await TryLoadingAsVrm10Async( gltfData, normalizeTransform, showMeshes, awaitCaller, materialGenerator, vrmMetaInformationCallback, ct); if (instance != null) { if (ct.IsCancellationRequested) { UnityObjectDestoyer.DestroyRuntimeOrEditor(instance.gameObject); ct.ThrowIfCancellationRequested(); } return(instance); } // 2. Stop loading if not allowed migration. if (!canLoadVrm0X) { throw new Exception($"Failed to load as VRM 1.0: {name}"); } // 3. Try migration from vrm-0.x into vrm-1.0 var migratedInstance = await TryMigratingFromVrm0XAsync( gltfData, normalizeTransform, showMeshes, awaitCaller, materialGenerator, vrmMetaInformationCallback, ct); if (migratedInstance != null) { if (ct.IsCancellationRequested) { UnityObjectDestoyer.DestroyRuntimeOrEditor(migratedInstance.gameObject); ct.ThrowIfCancellationRequested(); } return(migratedInstance); } // 4. Failed loading. throw new Exception($"Failed to load: {name}"); } }