Beispiel #1
0
        public override void OnEnable()
        {
            base.OnEnable();

            var importer = target as VrmScriptedImporter;

            m_importer = importer;
            using (var data = new GlbFileParser(m_importer.assetPath).Parse())
            {
                m_result = Vrm10Data.Parse(data);
                if (m_result != null)
                {
                    OnData();
                }
                else
                {
                    using (var migrated = Vrm10Data.Migrate(data, out m_result, out m_migration))
                    {
                        if (m_result != null)
                        {
                            OnData();
                        }
                    }
                }
            }
        }
Beispiel #2
0
        static void Process(Vrm10Data result, ScriptedImporter scriptedImporter, AssetImportContext context, RenderPipelineTypes renderPipeline, bool doNormalize)
        {
            //
            // Import(create unity objects)
            //
            var extractedObjects = scriptedImporter.GetExternalObjectMap()
                                   .Where(kv => kv.Value != null)
                                   .ToDictionary(kv => new SubAssetKey(kv.Value.GetType(), kv.Key.name), kv => kv.Value);

            var materialGenerator = GetMaterialDescriptorGenerator(renderPipeline);

            using (var loader = new Vrm10Importer(result, extractedObjects,
                                                  materialGenerator: materialGenerator,
                                                  doNormalize: doNormalize))
            {
                // settings TextureImporters
                foreach (var textureInfo in loader.TextureDescriptorGenerator.Get().GetEnumerable())
                {
                    VRMShaders.TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalTextures);
                }

                var loaded = loader.Load();
                loaded.ShowMeshes();

                loaded.TransferOwnership((key, o) =>
                {
                    context.AddObjectToAsset(key.Name, o);
                });
                var root = loaded.Root;
                GameObject.DestroyImmediate(loaded);

                context.AddObjectToAsset(root.name, root);
                context.SetMainObject(root);
            }
        }
Beispiel #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);
Beispiel #4
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));
        }
        public override void OnEnable()
        {
            base.OnEnable();

            var importer = target as VrmScriptedImporter;

            m_importer = importer;
            using (Vrm10Data.ParseOrMigrate(m_importer.assetPath, importer.MigrateToVrm1, out m_result, out m_migration))
            {
                if (m_result == null)
                {
                    // error
                    return;
                }
                m_model = ModelReader.Read(m_result.Data);

                var tmp = m_importer.GetExternalObjectMap();

                var generator    = new Vrm10MaterialDescriptorGenerator();
                var materialKeys = m_result.Data.GLTF.materials.Select((x, i) => generator.Get(m_result.Data, i).SubAssetKey);
                var textureKeys  = new Vrm10TextureDescriptorGenerator(m_result.Data).Get().GetEnumerable().Select(x => x.SubAssetKey);
                m_materialEditor = new RemapEditorMaterial(materialKeys.Concat(textureKeys), GetEditorMap, SetEditorMap);
                m_vrmEditor      = new RemapEditorVrm(new[] { VRM10Object.SubAssetKey }.Concat(EnumerateExpressinKeys(m_result.VrmExtension.Expressions)), GetEditorMap, SetEditorMap);
            }
        }
Beispiel #6
0
        public static Vrm10Instance LoadAlicia()
        {
            using (var data = Vrm10Data.ParseOrMigrate(AliciaPath, true, out Vrm10Data vrm, out MigrationData migration))
                using (var loader = new Vrm10Importer(vrm))
                {
                    var task = loader.LoadAsync(new VRMShaders.ImmediateCaller());
                    task.Wait();

                    var instance = task.Result;

                    return(instance.GetComponent <Vrm10Instance>());
                }
        }
Beispiel #7
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);
        /// <summary>
        ///
        /// </summary>
        /// <param name="scriptedImporter"></param>
        /// <param name="context"></param>
        /// <param name="migrateToVrm1">vrm0 だった場合に vrm1 化する</param>
        /// <param name="renderPipeline"></param>
        /// <param name="doNormalize">normalize する</param>
        public static void Import(ScriptedImporter scriptedImporter, AssetImportContext context, bool migrateToVrm1, RenderPipelineTypes renderPipeline, bool doNormalize)
        {
#if VRM_DEVELOP
            Debug.Log("OnImportAsset to " + scriptedImporter.assetPath);
#endif

            using (var data = Vrm10Data.ParseOrMigrate(scriptedImporter.assetPath, migrateToVrm1, out Vrm10Data result, out MigrationData migration))
            {
                if (result == null)
                {
                    // fail to parse vrm1
                    return;
                }

                //
                // Import(create unity objects)
                //
                var extractedObjects = scriptedImporter.GetExternalObjectMap()
                                       .Where(kv => kv.Value != null)
                                       .ToDictionary(kv => new SubAssetKey(kv.Value.GetType(), kv.Key.name), kv => kv.Value);

                var materialGenerator = GetMaterialDescriptorGenerator(renderPipeline);

                using (var loader = new Vrm10Importer(result, extractedObjects,
                                                      materialGenerator: materialGenerator,
                                                      doNormalize: doNormalize))
                {
                    // settings TextureImporters
                    foreach (var textureInfo in loader.TextureDescriptorGenerator.Get().GetEnumerable())
                    {
                        VRMShaders.TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalTextures);
                    }

                    var loaded = loader.Load();
                    loaded.ShowMeshes();

                    loaded.TransferOwnership((key, o) =>
                    {
                        context.AddObjectToAsset(key.Name, o);
                    });
                    var root = loaded.Root;
                    GameObject.DestroyImmediate(loaded);

                    context.AddObjectToAsset(root.name, root);
                    context.SetMainObject(root);
                }
            }
        }
Beispiel #9
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);
            }
        }
Beispiel #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="scriptedImporter"></param>
        /// <param name="context"></param>
        /// <param name="doMigrate">vrm0 だった場合に vrm1 化する</param>
        /// <param name="renderPipeline"></param>
        /// <param name="doNormalize">normalize する</param>
        public static void Import(ScriptedImporter scriptedImporter, AssetImportContext context, bool doMigrate, RenderPipelineTypes renderPipeline, bool doNormalize)
        {
#if VRM_DEVELOP
            Debug.Log("OnImportAsset to " + scriptedImporter.assetPath);
#endif

            // 1st parse as vrm1
            using (var data = new GlbFileParser(scriptedImporter.assetPath).Parse())
            {
                var vrm1Data = Vrm10Data.Parse(data);
                if (vrm1Data != null)
                {
                    // successfully parsed vrm-1.0
                    Process(vrm1Data, scriptedImporter, context, renderPipeline, doNormalize);
                }

                if (!doMigrate)
                {
                    return;
                }

                // try migration...
                MigrationData migration;
                using (var migrated = Vrm10Data.Migrate(data, out vrm1Data, out migration))
                {
                    if (vrm1Data != null)
                    {
                        Process(vrm1Data, scriptedImporter, context, renderPipeline, doNormalize);
                    }
                }

                // fail to migrate...
                if (migration != null)
                {
                    Debug.LogWarning(migration.Message);
                }
                return;
            }
        }
Beispiel #11
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>();
            }
        }
Beispiel #12
0
        /// <summary>
        /// vrm1 をパースする。vrm0 からのマイグレートもできる。
        /// </summary>
        /// <param name="path"></param>
        /// <param name="bytes"></param>
        /// <param name="doMigrate"></param>
        /// <param name="vrm1Data">成功した場合非 null</param>
        /// <param name="migration">doMigrate==true の場合、関連情報が入る</param>
        /// <returns>GltfDataを作成できたときは Return するのでDisposeすること</returns>
        public static GltfData ParseOrMigrate(string path, byte[] bytes, bool doMigrate, out Vrm10Data vrm1Data, out MigrationData migration)
        {
            var data = new GlbLowLevelParser(path, bytes).Parse();

            byte[]             migrated      = default;
            byte[]             migratedBytes = null;
            Migration.Vrm0Meta oldMeta       = default;
            try
            {
                if (UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(data.GLTF.extensions, out UniGLTF.Extensions.VRMC_vrm.VRMC_vrm vrm))
                {
                    // success
                    vrm1Data  = new Vrm10Data(data, vrm);
                    migration = default;
                    return(data);
                }

                if (!doMigrate)
                {
                    vrm1Data  = default;
                    migration = new MigrationData("Not vrm1 and no migration");
                    return(data);
                }

                // try migrateion
                // Migration.Vrm0Meta oldMeta = default;
                JsonNode json = data.Json.ParseAsJson();
                if (!json.TryGet("extensions", out JsonNode extensions))
                {
                    vrm1Data  = default;
                    migration = new MigrationData("gltf: no extensions");
                    return(data);
                }

                if (!extensions.TryGet("VRM", out JsonNode vrm0))
                {
                    vrm1Data  = default;
                    migration = new MigrationData("gltf: no vrm0");
                    return(data);
                }

                // found vrm0
                oldMeta = Migration.Vrm0Meta.FromJsonBytes(json);
                if (oldMeta == null)
                {
                    throw new NullReferenceException("oldMeta");
                }

                // try migrate...
                migrated = MigrationVrm.Migrate(data);
                if (migrated == null)
                {
                    vrm1Data  = default;
                    migration = new MigrationData("Found vrm0. But fail to migrate", oldMeta);
                    return(data);
                }

                if (VRMShaders.Symbols.VRM_DEVELOP)
                {
                    // load 時の右手左手座標変換でバッファが破壊的変更されるので、コピーを作っている
                    migratedBytes = migrated.Select(x => x).ToArray();
                }
            }
            catch (Exception ex)
            {
                // 何か起きた。Dispose は頼む
                vrm1Data  = default;
                migration = new MigrationData(ex.Message);
                return(data);
            }

            // マイグレーション前を破棄
            data.Dispose();
            // マイグレーション結果をパースする
            var migratedData = new GlbLowLevelParser(data.TargetPath, migrated).Parse();

            try
            {
                if (!UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(migratedData.GLTF.extensions, out VRMC_vrm vrm))
                {
                    // migration した結果のパースに失敗した !
                    vrm1Data  = default;
                    migration = new MigrationData("vrm0: migrate but error ?", oldMeta, migrated);
                    return(migratedData);
                }

                {
                    // success
                    vrm1Data  = new Vrm10Data(migratedData, vrm);
                    migration = new MigrationData("vrm0: migrated", oldMeta, migratedBytes);
                    return(migratedData);
                }
            }
            catch (Exception ex)
            {
                // 何か起きた。Dispose は頼む
                vrm1Data  = default;
                migration = new MigrationData(ex.Message);
                return(migratedData);
            }
        }
Beispiel #13
0
 public static GltfData ParseOrMigrate(string path, bool doMigrate, out Vrm10Data vrm1Data, out MigrationData migration)
 {
     return(ParseOrMigrate(path, File.ReadAllBytes(path), doMigrate, out vrm1Data, out migration));
 }
Beispiel #14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="data"></param>
        /// <param name="vrm1Data"></param>
        /// <param name="migration"></param>
        /// <returns>Migrated GltfData if succeeded. Must Dispose</returns>
        public static GltfData Migrate(GltfData data, out Vrm10Data vrm1Data, out MigrationData migration)
        {
            var json = data.Json.ParseAsJson();

            if (!json.TryGet("extensions", out JsonNode extensions))
            {
                vrm1Data  = default;
                migration = new MigrationData("gltf: no extensions");
                return(null);
            }

            if (!extensions.TryGet("VRM", out JsonNode vrm0))
            {
                vrm1Data  = default;
                migration = new MigrationData("gltf: no vrm0");
                return(null);
            }

            // found vrm0
            var oldMeta = Migration.Vrm0Meta.FromJsonBytes(json);

            if (oldMeta == null)
            {
                throw new NullReferenceException("oldMeta");
            }

            // try migrate...
            byte[] migrated = null;
            try
            {
                migrated = MigrationVrm.Migrate(data);
                if (migrated == null)
                {
                    vrm1Data  = default;
                    migration = new MigrationData("Found vrm0. But fail to migrate", oldMeta);
                    return(null);
                }
            }
            catch (MigrationException ex)
            {
                // migration 失敗
                vrm1Data  = default;
                migration = new MigrationData(ex.ToString(), oldMeta);
                return(null);
            }
            catch (Exception ex)
            {
                // その他のエラー
                vrm1Data  = default;
                migration = new MigrationData(ex.ToString(), oldMeta);
                return(null);
            }

            byte[] debugCopy = null;
            if (VRMShaders.Symbols.VRM_DEVELOP)
            {
                // load 時の右手左手座標変換でバッファが破壊的変更されるので、コピーを作っている
                debugCopy = migrated.Select(x => x).ToArray();
            }

            // マイグレーション結果をパースする
            var migratedData = new GlbLowLevelParser(data.TargetPath, migrated).Parse();

            try
            {
                if (!UniGLTF.Extensions.VRMC_vrm.GltfDeserializer.TryGet(migratedData.GLTF.extensions, out VRMC_vrm vrm))
                {
                    // migration した結果のパースに失敗した !
                    vrm1Data  = default;
                    migration = new MigrationData("vrm0: migrate but error ?", oldMeta, migrated);
                    // 破棄
                    migratedData.Dispose();
                    return(null);
                }

                {
                    // success. 非null値が返るのはここだけ。
                    vrm1Data  = new Vrm10Data(migratedData, vrm);
                    migration = new MigrationData("vrm0: migrated", oldMeta, debugCopy);
                    return(migratedData);
                }
            }
            catch (Exception ex)
            {
                Debug.LogWarning(ex);
                vrm1Data  = default;
                migration = new MigrationData(ex.Message);
                // 破棄
                migratedData.Dispose();
                return(null);
            }
        }