Esempio n. 1
0
        /// <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));
        }
Esempio n. 2
0
        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));
        }
Esempio n. 3
0
        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);
 }
Esempio n. 5
0
 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);
Esempio n. 6
0
        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);
            }
        }
Esempio n. 8
0
        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);
            }
        }
Esempio n. 9
0
        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));
                    }
                }
            }
        }
Esempio n. 10
0
        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>();
            }
        }
Esempio n. 11
0
        /// <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));
        }
Esempio n. 12
0
        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));
                }
        }
Esempio n. 13
0
        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}");
            }
        }