Beispiel #1
0
        public void TextureExtractTest()
        {
            var path = GetGltfTestModelPath("BoomBox.glb");

            if (path == null)
            {
                return;
            }

            // parse
            var data = new GlbFileParser(path.FullName).Parse();

            // load
            using (var context = new ImporterContext(data))
            {
                var instance   = context.Load();
                var textureMap = instance.RuntimeResources
                                 .Select(kv => (kv.Item1, kv.Item2 as Texture))
                                 .Where(kv => kv.Item2 != null)
                                 .ToDictionary(kv => kv.Item1, kv => kv.Item2)
                ;

                // extractor
                var extractor = new TextureExtractor(data, UnityPath.FromUnityPath(""), textureMap);
                var m         = context.TextureDescriptorGenerator.Get().GetEnumerable()
                                .FirstOrDefault(x => x.SubAssetKey.Name == "texture_1.standard");

                Assert.Catch <NotImplementedException>(() => extractor.Extract(m.SubAssetKey, m));
            }
        }
Beispiel #2
0
        static void ExtractMaterialsAndTextures(ScriptedImporter self, GltfParser parser)
        {
            if (string.IsNullOrEmpty(self.assetPath))
            {
                return;
            }

            Action <Texture2D> addRemap = externalObject =>
            {
                self.AddRemap(new AssetImporter.SourceAssetIdentifier(typeof(UnityEngine.Texture2D), externalObject.name), externalObject);
            };
            Action <IEnumerable <UnityPath> > onCompleted = _ =>
            {
                AssetDatabase.ImportAsset(self.assetPath, ImportAssetOptions.ForceUpdate);
                self.ExtractMaterials();
                AssetDatabase.ImportAsset(self.assetPath, ImportAssetOptions.ForceUpdate);
            };

            var assetPath = UnityPath.FromFullpath(parser.TargetPath);
            var dirName   = $"{assetPath.FileNameWithoutExtension}.Textures";

            TextureExtractor.ExtractTextures(parser, assetPath.Parent.Child(dirName),
                                             GltfTextureEnumerator.Enumerate,
                                             self.GetSubAssets <UnityEngine.Texture2D>(self.assetPath).ToArray(),
                                             addRemap,
                                             onCompleted
                                             );
        }
Beispiel #3
0
        static void ExtractMaterialsAndTextures(ScriptedImporter self)
        {
            if (string.IsNullOrEmpty(self.assetPath))
            {
                return;
            }

            Action <Texture2D> addRemap = externalObject =>
            {
                self.AddRemap(new AssetImporter.SourceAssetIdentifier(typeof(UnityEngine.Texture2D), externalObject.name), externalObject);
            };
            Action <IEnumerable <string> > onCompleted = _ =>
            {
                AssetDatabase.ImportAsset(self.assetPath, ImportAssetOptions.ForceUpdate);
                self.ExtractMaterials();
                AssetDatabase.ImportAsset(self.assetPath, ImportAssetOptions.ForceUpdate);
            };

            TextureExtractor.ExtractTextures(self.assetPath,
                                             GltfTextureEnumerator.Enumerate,
                                             self.GetSubAssets <UnityEngine.Texture2D>(self.assetPath).ToArray(),
                                             addRemap,
                                             onCompleted
                                             );
        }
Beispiel #4
0
        /// <summary>
        ///
        /// * Texture(.png etc...)をディスクに書き出す
        /// * EditorApplication.delayCall で処理を進めて 書き出した画像が Asset として成立するのを待つ
        /// * 書き出した Asset から TextureImporter を取得して設定する
        ///
        /// </summary>
        /// <param name="importer"></param>
        /// <param name="dirName"></param>
        /// <param name="onCompleted"></param>
        public static void ExtractTextures(GltfParser parser, UnityPath textureDirectory,
                                           TextureEnumerator textureEnumerator, Texture2D[] subAssets, Action <Texture2D> addRemap,
                                           Action <IEnumerable <UnityPath> > onCompleted = null)
        {
            var extractor = new TextureExtractor(parser, textureDirectory, subAssets);

            foreach (var x in textureEnumerator(parser))
            {
                extractor.Extract(x);
            }

            EditorApplication.delayCall += () =>
            {
                // Wait for the texture assets to be imported

                foreach (var kv in extractor.Textures)
                {
                    var targetPath = kv.Key;
                    var param      = kv.Value;

                    // remap
                    var externalObject = targetPath.LoadAsset <Texture2D>();
                    if (externalObject != null)
                    {
                        addRemap(externalObject);
                    }
                }

                if (onCompleted != null)
                {
                    onCompleted(extractor.Textures.Keys);
                }
            };
        }
Beispiel #5
0
        /// <summary>
        ///
        /// * Texture(.png etc...)をディスクに書き出す
        /// * EditorApplication.delayCall で処理を進めて 書き出した画像が Asset として成立するのを待つ
        /// * 書き出した Asset から TextureImporter を取得して設定する
        ///
        /// </summary>
        /// <param name="importer"></param>
        /// <param name="dirName"></param>
        /// <param name="onCompleted"></param>
        public static void ExtractTextures(GltfData data, UnityPath textureDirectory,
                                           ITextureDescriptorGenerator textureDescriptorGenerator, IReadOnlyDictionary <SubAssetKey, Texture> subAssets,
                                           Action <SubAssetKey, Texture2D> addRemap,
                                           Action <IEnumerable <UnityPath> > onCompleted = null)
        {
            var extractor = new TextureExtractor(data, textureDirectory, subAssets);

            foreach (var param in textureDescriptorGenerator.Get().GetEnumerable())
            {
                extractor.Extract(param.SubAssetKey, param);
            }

            EditorApplication.delayCall += () =>
            {
                // Wait for the texture assets to be imported

                foreach (var(key, targetPath) in extractor.Textures)
                {
                    // remap
                    var externalObject = targetPath.LoadAsset <Texture2D>();
#if VRM_DEVELOP
                    // Debug.Log($"remap: {targetPath} => {externalObject}");
#endif
                    if (externalObject != null)
                    {
                        addRemap(key, externalObject);
                    }
                }

                if (onCompleted != null)
                {
                    onCompleted(extractor.Textures.Values);
                }
            };
        }
Beispiel #6
0
        static void ExtractMaterialsAndTextures(ScriptedImporter self, GltfParser parser, EnumerateAllTexturesDistinctFunc enumTextures, Func <string, string> textureDir, Func <string, string> materialDir)
        {
            if (string.IsNullOrEmpty(self.assetPath))
            {
                return;
            }

            Action <SubAssetKey, Texture2D> addRemap = (key, externalObject) =>
            {
                self.AddRemap(new AssetImporter.SourceAssetIdentifier(key.Type, key.Name), externalObject);
            };
            Action <IEnumerable <UnityPath> > onCompleted = _ =>
            {
                AssetDatabase.ImportAsset(self.assetPath, ImportAssetOptions.ForceUpdate);
                self.ExtractMaterials(materialDir);
                AssetDatabase.ImportAsset(self.assetPath, ImportAssetOptions.ForceUpdate);
            };

            var assetPath = UnityPath.FromFullpath(parser.TargetPath);
            var dirName   = textureDir(assetPath.Value); // $"{assetPath.FileNameWithoutExtension}.Textures";

            TextureExtractor.ExtractTextures(parser, assetPath.Parent.Child(dirName),
                                             enumTextures,
                                             self.GetSubAssets <UnityEngine.Texture2D>(self.assetPath).ToArray(),
                                             addRemap,
                                             onCompleted
                                             );
        }
Beispiel #7
0
        /// <summary>
        ///
        /// * Texture(.png etc...)をディスクに書き出す
        /// * EditorApplication.delayCall で処理を進めて 書き出した画像が Asset として成立するのを待つ
        /// * 書き出した Asset から TextureImporter を取得して設定する
        ///
        /// </summary>
        /// <param name="importer"></param>
        /// <param name="dirName"></param>
        /// <param name="onCompleted"></param>
        public static void ExtractTextures(string assetPath, TextureEnumerator textureEnumerator, Texture2D[] subAssets, Action <Texture2D> addRemap, Action <IEnumerable <string> > onCompleted = null)
        {
            var extractor  = new TextureExtractor(assetPath, subAssets);
            var normalMaps = new List <string>();

            foreach (var x in textureEnumerator(extractor.GLTF))
            {
                var gltfTexture = extractor.GLTF.textures[x.Index0.Value];
                var gltfImage   = extractor.GLTF.images[gltfTexture.source];
                extractor.Extract(x, !string.IsNullOrEmpty(gltfImage.uri));
            }

            EditorApplication.delayCall += () =>
            {
                // Wait for the texture assets to be imported

                foreach (var kv in extractor.Textures)
                {
                    var targetPath = kv.Key;
                    var param      = kv.Value;

                    // remap
                    var externalObject = AssetDatabase.LoadAssetAtPath <UnityEngine.Texture2D>(targetPath);
                    if (externalObject != null)
                    {
                        addRemap(externalObject);
                    }
                }

                if (onCompleted != null)
                {
                    onCompleted(extractor.Textures.Keys);
                }
            };
        }
        public static void ExtractTextures(this ScriptedImporter importer, string dirName, Action onCompleted = null)
        {
            if (string.IsNullOrEmpty(importer.assetPath))
            {
                return;
            }

            var path = string.Format("{0}/{1}.{2}",
                                     Path.GetDirectoryName(importer.assetPath),
                                     Path.GetFileNameWithoutExtension(importer.assetPath),
                                     dirName
                                     );

            importer.SafeCreateDirectory(path);

            // Reload Model
            var extractor = new TextureExtractor(importer);

            foreach (var material in extractor.GLTF.materials)
            {
                foreach (var x in extractor.Parser.EnumerateTextures(material))
                {
                    extractor.Extract(x);
                }
            }

            EditorApplication.delayCall += () =>
            {
                foreach (var extracted in extractor.Textures)
                {
                    // TextureImporter
                    var targetTextureImporter = AssetImporter.GetAtPath(extracted.Path) as TextureImporter;
                    targetTextureImporter.sRGBTexture = extracted.sRGB;
                    if (extracted.IsNormalMap)
                    {
                        targetTextureImporter.textureType = TextureImporterType.NormalMap;
                    }
                    targetTextureImporter.SaveAndReimport();

                    // remap
                    var externalObject = AssetDatabase.LoadAssetAtPath <UnityEngine.Texture2D>(extracted.Path);
                    importer.AddRemap(new AssetImporter.SourceAssetIdentifier(typeof(UnityEngine.Texture2D), externalObject.name), externalObject);
                }

                AssetDatabase.ImportAsset(importer.assetPath, ImportAssetOptions.ForceUpdate);

                if (onCompleted != null)
                {
                    onCompleted();
                }
            };
        }
Beispiel #9
0
        public static void ExtractMaterials(this ScriptedImporter importer)
        {
            if (string.IsNullOrEmpty(importer.assetPath))
            {
                return;
            }
            var path = $"{Path.GetDirectoryName(importer.assetPath)}/{Path.GetFileNameWithoutExtension(importer.assetPath)}.Materials";
            var info = TextureExtractor.SafeCreateDirectory(path);

            foreach (var asset in importer.GetSubAssets <Material>(importer.assetPath))
            {
                ExtractSubAsset(asset, $"{path}/{asset.name}.mat", false);
            }
        }
Beispiel #10
0
        void ExtractMaterialsAndTextures(ScriptedImporter self, GltfData data, ITextureDescriptorGenerator textureDescriptorGenerator, Func <string, string> textureDir, Func <string, string> materialDir)
        {
            if (string.IsNullOrEmpty(self.assetPath))
            {
                return;
            }

            Action <SubAssetKey, Texture2D> addRemap = (key, externalObject) =>
            {
                self.AddRemap(new AssetImporter.SourceAssetIdentifier(key.Type, key.Name), externalObject);
            };
            Action <IEnumerable <UnityPath> > onCompleted = _ =>
            {
                // texture extract 後に importer 発動
                AssetDatabase.ImportAsset(self.assetPath, ImportAssetOptions.ForceUpdate);

                ExtractMaterials(self, materialDir);
            };

            // subAsset を ExternalObject として投入する
            var subAssets = AssetDatabase.LoadAllAssetsAtPath(self.assetPath)
                            .Select(x => x as Texture)
                            .Where(x => x != null)
                            .Select(x => (new SubAssetKey(x), x))
                            .ToDictionary(kv => kv.Item1, kv => kv.Item2)
            ;

            var assetPath = UnityPath.FromUnityPath(self.assetPath);
            var dirName   = textureDir(assetPath.Value); // $"{assetPath.FileNameWithoutExtension}.Textures";

            TextureExtractor.ExtractTextures(
                data,
                assetPath.Parent.Child(dirName),
                textureDescriptorGenerator,
                subAssets,
                addRemap,
                onCompleted
                );
        }
Beispiel #11
0
        /// <summary>
        ///
        /// * Texture(.png etc...)をディスクに書き出す
        /// * EditorApplication.delayCall で処理を進めて 書き出した画像が Asset として成立するのを待つ
        /// * 書き出した Asset から TextureImporter を取得して設定する
        ///
        /// </summary>
        /// <param name="importer"></param>
        /// <param name="dirName"></param>
        /// <param name="onCompleted"></param>
        public static void ExtractTextures(GltfParser parser, UnityPath textureDirectory,
                                           TextureEnumerator textureEnumerator, Texture2D[] subAssets, Action <Texture2D> addRemap,
                                           Action <IEnumerable <UnityPath> > onCompleted = null)
        {
            var extractor = new TextureExtractor(parser, textureDirectory, subAssets);

            foreach (var x in textureEnumerator(extractor.GLTF))
            {
                var gltfTexture = extractor.GLTF.textures[x.Index0.Value];
                var gltfImage   = extractor.GLTF.images[gltfTexture.source];
                extractor.Extract(x, !string.IsNullOrEmpty(gltfImage.uri));
            }

            EditorApplication.delayCall += () =>
            {
                // Wait for the texture assets to be imported

                foreach (var kv in extractor.Textures)
                {
                    var targetPath = kv.Key;
                    var param      = kv.Value;

                    // remap
                    var externalObject = targetPath.LoadAsset <Texture2D>();
                    if (externalObject != null)
                    {
                        addRemap(externalObject);
                    }
                }

                if (onCompleted != null)
                {
                    onCompleted(extractor.Textures.Keys);
                }
            };
        }
Beispiel #12
0
        /// <summary>
        ///
        /// * Texture(.png etc...)をディスクに書き出す
        /// * EditorApplication.delayCall で処理を進めて 書き出した画像が Asset として成立するのを待つ
        /// * 書き出した Asset から TextureImporter を取得して設定する
        ///
        /// </summary>
        /// <param name="importer"></param>
        /// <param name="dirName"></param>
        /// <param name="onCompleted"></param>
        public static void ExtractTextures(string assetPath, TextureEnumerator textureEnumerator, Texture2D[] subAssets, Action <Texture2D> addRemap, Action <IEnumerable <string> > onCompleted = null)
        {
            var extractor  = new TextureExtractor(assetPath, subAssets);
            var normalMaps = new List <string>();

            foreach (var x in textureEnumerator(extractor.GLTF))
            {
                var gltfTexture = extractor.GLTF.textures[x.Index0.Value];
                var gltfImage   = extractor.GLTF.images[gltfTexture.source];
                extractor.Extract(x, !string.IsNullOrEmpty(gltfImage.uri));
            }

            EditorApplication.delayCall += () =>
            {
                foreach (var kv in extractor.Textures)
                {
                    var targetPath = kv.Key;
                    var param      = kv.Value;

                    // TextureImporter
                    var targetTextureImporter = AssetImporter.GetAtPath(targetPath) as TextureImporter;
                    if (targetTextureImporter != null)
                    {
                        switch (param.TextureType)
                        {
                        case GetTextureParam.OCCLUSION_PROP:
                        case GetTextureParam.METALLIC_GLOSS_PROP:
#if VRM_DEVELOP
                            Debug.Log($"{targetPath} => linear");
#endif
                            targetTextureImporter.sRGBTexture = false;
                            targetTextureImporter.SaveAndReimport();
                            break;

                        case GetTextureParam.NORMAL_PROP:
#if VRM_DEVELOP
                            Debug.Log($"{targetPath} => normalmap");
#endif
                            targetTextureImporter.textureType = TextureImporterType.NormalMap;
                            targetTextureImporter.SaveAndReimport();
                            break;
                        }
                    }
                    else
                    {
                        throw new FileNotFoundException(targetPath);
                    }

                    // remap
                    var externalObject = AssetDatabase.LoadAssetAtPath <UnityEngine.Texture2D>(targetPath);
                    if (externalObject != null)
                    {
                        addRemap(externalObject);
                    }
                }

                if (onCompleted != null)
                {
                    onCompleted(extractor.Textures.Keys);
                }
            };
        }