コード例 #1
0
    public async void Setup(SyncObject obj)
    {
        // TODO: dynamic model change handling
        if (!obj.HasField("model") || !(obj.GetField("model") is BlobHandle))
        {
            // TODO:
            obj.WriteErrorLog("Model", $"This object has no model field or not a blob handle. Ignoring.");
            return;
        }

        BlobHandle handle = (BlobHandle)obj.GetField("model");

        Blob blob = await obj.Node.ReadBlob(handle);

        obj.WriteDebugLog("Model", $"Blob {handle} loaded");

        // Because UniGLTF.ImporterContext is the parent class of VRMImporterContext,
        //  ( https://github.com/vrm-c/UniVRM/blob/3b68eb7f99bfe78ea9c83ea75511282ef1782f1a/Assets/VRM/UniVRM/Scripts/Format/VRMImporterContext.cs#L11 )
        // loading procedure is probably almost same (See PlyayerAvatar.cs for VRM loading).
        //  https://github.com/vrm-c/UniVRM/blob/3b68eb7f99bfe78ea9c83ea75511282ef1782f1a/Assets/VRM/UniGLTF/Editor/Tests/UniGLTFTests.cs#L46
        ctx = new UniGLTF.ImporterContext();
        // ParseGlb parses GLB file.
        //  https://github.com/vrm-c/UniVRM/blob/3b68eb7f99bfe78ea9c83ea75511282ef1782f1a/Assets/VRM/UniGLTF/Scripts/IO/ImporterContext.cs#L239
        // Currently, only GLB (glTF binary format) is supported because it is self-contained
        ctx.ParseGlb(blob.Data);
        ctx.Root = gameObject;
        await ctx.LoadAsyncTask();

        // UniGLTF also has ShowMeshes https://github.com/ousttrue/UniGLTF/wiki/Rutime-API#import
        ctx.ShowMeshes();

        obj.WriteDebugLog("Model", "Model load completed");

        LoadComplete?.Invoke(this);
    }
コード例 #2
0
        async void LoadModelAsync(string path, bool isVrm)
        {
            if (!File.Exists(path))
            {
                return;
            }

            Debug.LogFormat("{0}", path);

            GltfData data;

            try
            {
                data = new AutoGltfFileParser(path).Parse();
            }
            catch (Exception ex)
            {
                Debug.LogWarningFormat("parse error: {0}", ex);
                return;
            }

            if (isVrm)
            {
                try
                {
                    var vrm = new VRMData(data);
                    using (var loader = new VRMImporterContext(vrm, materialGenerator: GetVrmMaterialGenerator(m_useUrpMaterial.isOn, vrm.VrmExtension)))
                    {
                        await m_texts.UpdateMetaAsync(loader);

                        var instance = await loader.LoadAsync(GetIAwaitCaller(m_useAsync.isOn));

                        SetModel(instance);
                    }
                }
                catch (NotVrm0Exception)
                {
                    // retry
                    Debug.LogWarning("file extension is vrm. but not vrm ?");
                    using (var loader = new UniGLTF.ImporterContext(data, materialGenerator: GetGltfMaterialGenerator(m_useUrpMaterial.isOn)))
                    {
                        var instance = await loader.LoadAsync(GetIAwaitCaller(m_useAsync.isOn));

                        SetModel(instance);
                    }
                }
            }
            else
            {
                using (var loader = new UniGLTF.ImporterContext(data, materialGenerator: GetGltfMaterialGenerator(m_useUrpMaterial.isOn)))
                {
                    var instance = await loader.LoadAsync(GetIAwaitCaller(m_useAsync.isOn));

                    SetModel(instance);
                }
            }
        }
コード例 #3
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));
                    }
                }
            }
        }
コード例 #4
0
        public static void ImportAsset(string src, string ext, UnityPath prefabPath)
        {
            if (!prefabPath.IsUnderAssetsFolder)
            {
                Debug.LogWarningFormat("out of asset path: {0}", prefabPath);
                return;
            }

            var context = new ImporterContext();

            context.Parse(src);

            // Extract textures to assets folder
            context.ExtranctImages(prefabPath);

            ImportDelayed(src, prefabPath, context);
        }
コード例 #5
0
 public static void ImportAnimation(ImporterContext ctx)
 {
     // animation
     if (ctx.GLTF.animations != null && ctx.GLTF.animations.Any())
     {
         var animation = ctx.Root.AddComponent <Animation>();
         ctx.AnimationClips = ImportAnimationClip(ctx);
         foreach (var clip in ctx.AnimationClips)
         {
             animation.AddClip(clip, clip.name);
         }
         if (ctx.AnimationClips.Count > 0)
         {
             animation.clip = ctx.AnimationClips.First();
         }
     }
 }
コード例 #6
0
        /// <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);
            }
        }
コード例 #7
0
        /// <summary>
        /// Build unity objects from parsed gltf
        /// </summary>
        public static void Load(this ImporterContext self)
        {
            var meassureTime = new ImporterContextSpeedLog();
            var task         = self.LoadAsync(default(ImmediateCaller), meassureTime.MeasureTime);

            if (!task.IsCompleted)
            {
                throw new Exception();
            }
            if (task.IsFaulted)
            {
                throw new AggregateException(task.Exception);
            }

#if VRM_DEVELOP
            Debug.Log($"{self.Parser.TargetPath}: {meassureTime.GetSpeedLog()}");
#endif
        }
コード例 #8
0
        public void Import(ImporterContext context)
        {
            // animation
            if (context.GLTF.animations != null && context.GLTF.animations.Any())
            {
                var animation = context.Root.AddComponent <Animation>();
                context.AnimationClips = ImportAnimationClips(context.GLTF, context.InvertAxis);

                foreach (var clip in context.AnimationClips)
                {
                    animation.AddClip(clip, clip.name);
                }
                if (context.AnimationClips.Count > 0)
                {
                    animation.clip = context.AnimationClips.First();
                }
            }
        }
コード例 #9
0
ファイル: gltfImporter.cs プロジェクト: akihikodaki/UniGLTF
        static void ImportAnimation(ImporterContext ctx)
        {
            // animation
            if (ctx.GLTF.animations != null && ctx.GLTF.animations.Any())
            {
                ctx.Animation      = new AnimationClip();
                ctx.Animation.name = ANIMATION_NAME;
                ctx.Animation.ClearCurves();

                ImportAnimation(ctx, ctx.Animation);

                ctx.Animation.legacy   = true;
                ctx.Animation.name     = "legacy";
                ctx.Animation.wrapMode = WrapMode.Loop;
                var animation = ctx.Root.AddComponent <Animation>();
                animation.clip = ctx.Animation;
            }
        }
コード例 #10
0
        /// <summary>
        /// glb をパースして、UnityObject化、さらにAsset化する
        /// </summary>
        /// <param name="scriptedImporter"></param>
        /// <param name="context"></param>
        /// <param name="reverseAxis"></param>
        public static void Import(ScriptedImporter scriptedImporter, AssetImportContext context, Axises reverseAxis)
        {
#if VRM_DEVELOP
            Debug.Log("OnImportAsset to " + scriptedImporter.assetPath);
#endif

            //
            // Parse(parse glb, parser gltf json)
            //
            var parser = new GltfParser();
            parser.ParsePath(scriptedImporter.assetPath);

            //
            // Import(create unity objects)
            //
            var externalObjectMap = scriptedImporter.GetExternalObjectMap().Select(kv => (kv.Value.name, kv.Value)).ToArray();

            var externalTextures = EnumerateTexturesFromUri(externalObjectMap, parser, UnityPath.FromUnityPath(scriptedImporter.assetPath).Parent).ToArray();

            using (var loader = new ImporterContext(parser, externalObjectMap.Concat(externalTextures)))
            {
                // settings TextureImporters
                foreach (var(key, textureInfo) in GltfTextureEnumerator.EnumerateAllTexturesDistinct(parser))
                {
                    TextureImporterConfigurator.Configure(textureInfo, loader.TextureFactory.ExternalMap);
                }

                loader.InvertAxis = reverseAxis;
                loader.Load();
                loader.ShowMeshes();

                loader.TransferOwnership(o =>
                {
                    context.AddObjectToAsset(o.name, o);
                    if (o is GameObject)
                    {
                        // Root GameObject is main object
                        context.SetMainObject(loader.Root);
                    }

                    return(true);
                });
            }
        }
コード例 #11
0
ファイル: gltfImporter.cs プロジェクト: Phantom100/UniGLTF
        public static void SetupSkinning(ImporterContext context, List<TransformWithSkin> nodes, int i)
        {
            var x = nodes[i];
            var skinnedMeshRenderer = x.Transform.GetComponent<SkinnedMeshRenderer>();
            if (skinnedMeshRenderer != null)
            {
                var mesh = skinnedMeshRenderer.sharedMesh;
                if (x.SkinIndex.HasValue)
                {
                    if (mesh == null) throw new Exception();
                    if (skinnedMeshRenderer == null) throw new Exception();

                    if (x.SkinIndex.Value < context.GLTF.skins.Count)
                    {
                        var skin = context.GLTF.skins[x.SkinIndex.Value];

                        skinnedMeshRenderer.sharedMesh = null;

                        var joints = skin.joints.Select(y => nodes[y].Transform).ToArray();
                        skinnedMeshRenderer.bones = joints;
                        //skinnedMeshRenderer.rootBone = nodes[skin.skeleton].Transform;

                        if (skin.inverseBindMatrices != -1)
                        {
                            // BlendShape only ?
#if false
                            // https://docs.unity3d.com/ScriptReference/Mesh-bindposes.html
                            var hipsParent = nodes[0].Transform;
                            var calculatedBindPoses = joints.Select(y => y.worldToLocalMatrix * hipsParent.localToWorldMatrix).ToArray();
                            mesh.bindposes = calculatedBindPoses;
#else
                            var bindPoses = context.GLTF.GetArrayFromAccessor<Matrix4x4>(skin.inverseBindMatrices)
                                .Select(y => y.ReverseZ())
                                .ToArray()
                                ;
                            mesh.bindposes = bindPoses;
#endif
                        }

                        skinnedMeshRenderer.sharedMesh = mesh;
                    }
                }
            }
        }
コード例 #12
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));
                    }
                }
            }
        }
コード例 #13
0
        static ImporterContext ImportGltf(string srcPath, bool isGlb)
        {
            Debug.LogFormat("ImportGltf: {0}", srcPath);
            var context = new ImporterContext
            {
                Path = srcPath,
            };

            if (isGlb)
            {
                glbImporter.Import <glTF>(context, File.ReadAllBytes(srcPath));
            }
            else
            {
                context.Json = File.ReadAllText(srcPath, System.Text.Encoding.UTF8);
                gltfImporter.Import <glTF>(context, new ArraySegment <byte>());
            }
            return(context);
        }
コード例 #14
0
        GameObject Load(string path)
        {
            var bytes = File.ReadAllBytes(path);

            Debug.LogFormat("[OnClick] {0}", path);
            var context = new ImporterContext();

            var ext = Path.GetExtension(path).ToLower();

            switch (ext)
            {
            case ".gltf":
                context.ParseJson(Encoding.UTF8.GetString(bytes), new FileSystemStorage(Path.GetDirectoryName(path)));
                break;

            case ".zip":
            {
                var zipArchive = Zip.ZipArchiveStorage.Parse(bytes);
                var gltf       = zipArchive.Entries.FirstOrDefault(x => x.FileName.ToLower().EndsWith(".gltf"));
                if (gltf == null)
                {
                    throw new Exception("no gltf in archive");
                }
                var jsonBytes = zipArchive.Extract(gltf);
                var json      = Encoding.UTF8.GetString(jsonBytes);
                context.ParseJson(json, zipArchive);
            }
            break;

            case ".glb":
                context.ParseGlb(bytes);
                break;

            default:
                throw new NotImplementedException();
            }

            context.Load();
            context.Root.name = Path.GetFileNameWithoutExtension(path);
            context.ShowMeshes();

            return(context.Root);
        }
コード例 #15
0
ファイル: UniGLTFTests.cs プロジェクト: coiai/UniVRM
        public void UniGLTFSimpleSceneTest()
        {
            var             go      = CreateSimpleScene();
            ImporterContext context = default;

            try
            {
                // export
                var gltf = new glTF();

                string json = null;
                using (var exporter = new gltfExporter(gltf))
                {
                    exporter.Prepare(go);
                    exporter.Export(MeshExportSettings.Default);

                    // remove empty buffer
                    gltf.buffers.Clear();

                    json = gltf.ToJson();
                }

                // parse
                var parser = new GltfParser();
                parser.ParseJson(json, new SimpleStorage(new ArraySegment <byte>()));

                // import
                context = new ImporterContext(parser);
                context.Load();

                AssertAreEqual(go.transform, context.Root.transform);
            }
            finally
            {
                //Debug.LogFormat("Destroy, {0}", go.name);
                GameObject.DestroyImmediate(go);
                if (context != null)
                {
                    var editor = new EditorImporterContext(context);
                    editor.EditorDestroyRootAndAssets();
                }
            }
        }
コード例 #16
0
        public static void ImportMenu()
        {
            var path = EditorUtility.OpenFilePanel("open gltf", "", "gltf,glb");

            if (string.IsNullOrEmpty(path))
            {
                return;
            }

            if (Application.isPlaying)
            {
                //
                // load into scene
                //
                var parser = new GltfParser();
                parser.ParsePath(path);
                var context = new ImporterContext(parser);
                context.Load();
                context.ShowMeshes();
                Selection.activeGameObject = context.Root;
            }
            else
            {
                //
                // save as asset
                //
                if (path.StartsWithUnityAssetPath())
                {
                    Debug.LogWarningFormat("disallow import from folder under the Assets");
                    return;
                }

                var assetPath = EditorUtility.SaveFilePanel("save prefab", "Assets", Path.GetFileNameWithoutExtension(path), "prefab");
                if (string.IsNullOrEmpty(path))
                {
                    return;
                }

                // import as asset
                gltfAssetPostprocessor.ImportAsset(path, Path.GetExtension(path).ToLower(), UnityPath.FromFullpath(assetPath));
            }
        }
コード例 #17
0
        /// <summary>
        /// Build unity objects from parsed gltf
        /// </summary>
        public static RuntimeGltfInstance Load(this ImporterContext self)
        {
            var meassureTime = new ImporterContextSpeedLog();
            var task         = self.LoadAsync(new ImmediateCaller(), meassureTime.MeasureTime);

            if (!task.IsCompleted)
            {
                throw new Exception();
            }
            if (task.IsFaulted)
            {
                throw new AggregateException(task.Exception);
            }

#if VRM_DEVELOP
            Debug.Log($"{self.Data.TargetPath}: {meassureTime.GetSpeedLog()}");
#endif

            return(task.Result);
        }
コード例 #18
0
        /// <summary>
        /// Build unity objects from parsed gltf
        /// </summary>
        public static void Load(this ImporterContext self)
        {
            var meassureTime = new ImporterContextSpeedLog();
            var task         = self.LoadAsync(default(ImmediateCaller), meassureTime.MeasureTime);

            if (!task.IsCompleted)
            {
                throw new Exception();
            }
            if (task.IsFaulted)
            {
                if (task.Exception is AggregateException ae && ae.InnerExceptions.Count == 1)
                {
                    throw ae.InnerException;
                }
                else
                {
                    throw task.Exception;
                }
            }
コード例 #19
0
        /// <summary>
        /// Build unity objects from parsed gltf
        /// </summary>
        public static void Load(this ImporterContext self)
        {
            var meassureTime = new ImporterContextSpeedLog();

            using (var queue = TaskQueue.Create())
            {
                var task = self.LoadAsync(meassureTime.MeasureTime);

                // 中断された await を消化する
                while (!task.IsCompleted)
                {
                    // execute synchronous
                    queue.ExecuteOneCallback();
                }
            }

#if VRM_DEVELOP
            Debug.Log(meassureTime.GetSpeedLog());
#endif
        }
コード例 #20
0
        static void RuntimeLoadExport(FileInfo gltf, int subStrStart)
        {
            var parser = new GltfParser();

            try
            {
                parser.ParsePath(gltf.FullName);
            }
            catch (Exception ex)
            {
                Debug.LogError($"ParseError: {gltf}");
                Debug.LogException(ex);
            }

            using (var loader = new ImporterContext(parser))
            {
                try
                {
                    loader.Load();
                }
                catch (Exception ex)
                {
                    Message(gltf.FullName.Substring(subStrStart), ex);
                }

                if (Skip.Contains(gltf.Directory.Parent.Name))
                {
                    // Export issue:
                    // skip
                    return;
                }

                if (loader.Root == null)
                {
                    Debug.LogWarning($"root is null: ${gltf}");
                    return;
                }

                Export(loader.Root);
            }
        }
コード例 #21
0
        public static void ImportMenu()
        {
            var path = UnityEditor.EditorUtility.OpenFilePanel("open gltf", "", "gltf,glb");

            if (!string.IsNullOrEmpty(path))
            {
                Debug.Log(path);
                var context = new ImporterContext
                {
                    Path = path,
                };
                var bytes = File.ReadAllBytes(path);
                var ext   = Path.GetExtension(path).ToLower();
                switch (ext)
                {
                case ".gltf":
                {
                    context.ParseJson <glTF>(Encoding.UTF8.GetString(bytes), new FileSystemStorage(Path.GetDirectoryName(path)));
                    gltfImporter.Import <glTF>(context);
                    context.Root.name = Path.GetFileNameWithoutExtension(path);
                    context.ShowMeshes();
                    Selection.activeGameObject = context.Root;
                }
                break;

                case ".glb":
                {
                    context.ParseGlb <glTF>(bytes);
                    gltfImporter.Import <glTF>(context);
                    context.Root.name = Path.GetFileNameWithoutExtension(path);
                    context.ShowMeshes();
                    Selection.activeGameObject = context.Root;
                }
                break;

                default:
                    Debug.LogWarningFormat("unknown ext: {0}", path);
                    break;
                }
            }
        }
コード例 #22
0
        static void RuntimeLoadExport(FileInfo gltf, int subStrStart)
        {
            GltfData data = null;

            try
            {
                data = new AutoGltfFileParser(gltf.FullName).Parse();
            }
            catch (Exception ex)
            {
                Debug.LogError($"ParseError: {gltf}");
                Debug.LogException(ex);
            }

            using (data)
                using (var loader = new ImporterContext(data))
                {
                    try
                    {
                        var loaded = loader.Load();
                        if (loaded == null)
                        {
                            Debug.LogWarning($"root is null: ${gltf}");
                            return;
                        }

                        if (Skip.Contains(gltf.Directory.Parent.Name))
                        {
                            // Export issue:
                            // skip
                            return;
                        }

                        Export(loaded.gameObject);
                    }
                    catch (Exception ex)
                    {
                        Message(gltf.FullName.Substring(subStrStart), ex);
                    }
                }
        }
コード例 #23
0
ファイル: MeshImporter.cs プロジェクト: frank40089/UniVRM
        public MeshContext ReadMesh(ImporterContext ctx, int meshIndex)
        {
            var gltfMesh = ctx.GLTF.meshes[meshIndex];

            var meshContext = new MeshContext(gltfMesh.name, meshIndex);

            if (HasSharedVertexBuffer(gltfMesh))
            {
                meshContext.ImportMeshSharingVertexBuffer(ctx, gltfMesh);
            }
            else
            {
                meshContext.ImportMeshIndependentVertexBuffer(ctx, gltfMesh);
            }

            meshContext.RenameBlendShape(gltfMesh);

            meshContext.DropUnusedVertices();

            return(meshContext);
        }
コード例 #24
0
 static void OnPostprocessAllAssets(string[] importedAssets,
                                    string[] deletedAssets,
                                    string[] movedAssets,
                                    string[] movedFromAssetPaths)
 {
     foreach (string path in importedAssets)
     {
         ImporterContext context = null;
         var             ext     = Path.GetExtension(path).ToLower();
         try
         {
             if (ext == ".gltf")
             {
                 context = ImportGltf(path, false);
             }
             else if (ext == ".glb")
             {
                 context = ImportGltf(path, true);
             }
             if (context != null)
             {
                 context.SaveAsAsset();
             }
             if (context != null)
             {
                 context.Destroy(false);
             }
         }
         catch (Exception ex)
         {
             Debug.LogErrorFormat("import error: {0}", path);
             Debug.LogErrorFormat("{0}", ex);
             if (context != null)
             {
                 context.Destroy(true);
             }
         }
     }
 }
コード例 #25
0
        public MeshContext ReadMesh(ImporterContext ctx, int meshIndex)
        {
            var gltfMesh = ctx.GLTF.meshes[meshIndex];

            bool        sharedMorphTarget = gltfMesh.extras != null && gltfMesh.extras.targetNames.Count > 0;
            MeshContext meshContext;

            if (sharedMorphTarget)
            {
                meshContext = _ImportMeshSharingMorphTarget(ctx, gltfMesh);
            }
            else
            {
                glTFAttributes lastAttributes   = null;
                var            sharedAttributes = true;
                foreach (var prim in gltfMesh.primitives)
                {
                    if (lastAttributes != null && !prim.attributes.Equals(lastAttributes))
                    {
                        sharedAttributes = false;
                        break;
                    }

                    lastAttributes = prim.attributes;
                }

                meshContext = sharedAttributes
                    ? _ImportMeshSharingVertexBuffer(ctx, gltfMesh)
                    : _ImportMeshIndependentVertexBuffer(ctx, gltfMesh);
            }

            meshContext.name = gltfMesh.name;
            if (string.IsNullOrEmpty(meshContext.name))
            {
                meshContext.name = string.Format("UniGLTF import#{0}", meshIndex);
            }

            return(meshContext);
        }
コード例 #26
0
ファイル: gltfImporter.cs プロジェクト: Phantom100/UniGLTF
        //
        // fix node's coordinate. z-back to z-forward
        //
        public static void FixCoordinate(ImporterContext context, List<TransformWithSkin> nodes)
        {
            var globalTransformMap = nodes.ToDictionary(x => x.Transform, x => new PosRot
            {
                Position = x.Transform.position,
                Rotation = x.Transform.rotation,
            });
            foreach (var x in context.GLTF.rootnodes)
            {
                // fix nodes coordinate
                // reverse Z in global
                var t = nodes[x].Transform;
                //t.SetParent(root.transform, false);

                foreach (var transform in t.Traverse())
                {
                    var g = globalTransformMap[transform];
                    transform.position = g.Position.ReverseZ();
                    transform.rotation = g.Rotation.ReverseZ();
                }
            }
        }
コード例 #27
0
        public void ImportExportTest()
        {
            var path       = Path.GetFullPath(Application.dataPath + "/../glTF-Sample-Models/2.0/Box/glTF/Box.gltf");
            var context    = new ImporterContext();
            var bytes      = File.ReadAllBytes(path);
            var importJson = Encoding.UTF8.GetString(bytes);

            context.ParseJson(importJson, new FileSystemStorage(Path.GetDirectoryName(path)));
            context.Load();

            var gltf       = gltfExporter.Export(context.Root);
            var exportJson = gltf.ToJson();

            var l = UniJSON.JsonParser.Parse(importJson);
            var r = UniJSON.JsonParser.Parse(exportJson);

            foreach (var diff in l.Diff(r))
            {
                Debug.Log(diff);
            }

            //Assert.AreEqual();
        }
コード例 #28
0
        public static List <AnimationClip> ImportAnimationClip(ImporterContext ctx)
        {
            List <AnimationClip> animationClips = new List <AnimationClip>();

            for (int i = 0; i < ctx.GLTF.animations.Count; ++i)
            {
                var clip = new AnimationClip();
                clip.ClearCurves();
                clip.legacy = true;
                clip.name   = ctx.GLTF.animations[i].name;
                if (string.IsNullOrEmpty(clip.name))
                {
                    clip.name = "legacy_" + i;
                }
                clip.wrapMode = WrapMode.Loop;

                var animation = ctx.GLTF.animations[i];
                if (string.IsNullOrEmpty(animation.name))
                {
                    animation.name = string.Format("animation:{0}", i);
                }

                foreach (var channel in animation.channels)
                {
                    var targetTransform = ctx.Nodes[channel.target.node];
                    var relativePath    = targetTransform.RelativePathFrom(ctx.Root.transform);
                    switch (channel.target.path)
                    {
                    case glTFAnimationTarget.PATH_TRANSLATION:
                    {
                        var sampler = animation.samplers[channel.sampler];
                        var input   = ctx.GLTF.GetArrayFromAccessor <float>(sampler.input);
                        var output  = ctx.GLTF.GetArrayFromAccessorAsFloat(sampler.output);

                        AnimationImporter.SetAnimationCurve(
                            clip,
                            relativePath,
                            new string[] { "localPosition.x", "localPosition.y", "localPosition.z" },
                            input,
                            output,
                            sampler.interpolation,
                            typeof(Transform),
                            (values, last) =>
                            {
                                Vector3 temp = new Vector3(values[0], values[1], values[2]);
                                return(temp.ReverseZ().ToArray());
                            }
                            );
                    }
                    break;

                    case glTFAnimationTarget.PATH_ROTATION:
                    {
                        var sampler = animation.samplers[channel.sampler];
                        var input   = ctx.GLTF.GetArrayFromAccessor <float>(sampler.input);
                        var output  = ctx.GLTF.GetArrayFromAccessorAsFloat(sampler.output);

                        AnimationImporter.SetAnimationCurve(
                            clip,
                            relativePath,
                            new string[] { "localRotation.x", "localRotation.y", "localRotation.z", "localRotation.w" },
                            input,
                            output,
                            sampler.interpolation,
                            typeof(Transform),
                            (values, last) =>
                            {
                                Quaternion currentQuaternion = new Quaternion(values[0], values[1], values[2], values[3]);
                                Quaternion lastQuaternion    = new Quaternion(last[0], last[1], last[2], last[3]);
                                return(AnimationImporter.GetShortest(lastQuaternion, currentQuaternion.ReverseZ()).ToArray());
                            }
                            );

                        clip.EnsureQuaternionContinuity();
                    }
                    break;

                    case glTFAnimationTarget.PATH_SCALE:
                    {
                        var sampler = animation.samplers[channel.sampler];
                        var input   = ctx.GLTF.GetArrayFromAccessor <float>(sampler.input);
                        var output  = ctx.GLTF.GetArrayFromAccessorAsFloat(sampler.output);

                        AnimationImporter.SetAnimationCurve(
                            clip,
                            relativePath,
                            new string[] { "localScale.x", "localScale.y", "localScale.z" },
                            input,
                            output,
                            sampler.interpolation,
                            typeof(Transform),
                            (values, last) => values);
                    }
                    break;

                    case glTFAnimationTarget.PATH_WEIGHT:
                    {
                        var node = ctx.GLTF.nodes[channel.target.node];
                        var mesh = ctx.GLTF.meshes[node.mesh];
                        //var primitive = mesh.primitives.FirstOrDefault();
                        //var targets = primitive.targets;

                        List <string> blendShapeNames     = new List <string>();
                        var           transform           = ctx.Nodes[channel.target.node];
                        var           skinnedMeshRenderer = transform.GetComponent <SkinnedMeshRenderer>();
                        if (skinnedMeshRenderer == null)
                        {
                            continue;
                        }

                        for (int j = 0; j < skinnedMeshRenderer.sharedMesh.blendShapeCount; j++)
                        {
                            blendShapeNames.Add(skinnedMeshRenderer.sharedMesh.GetBlendShapeName(j));
                        }

                        var keyNames = blendShapeNames
                                       .Where(x => !string.IsNullOrEmpty(x))
                                       .Select(x => "blendShape." + x)
                                       .ToArray();

                        var sampler = animation.samplers[channel.sampler];
                        var input   = ctx.GLTF.GetArrayFromAccessor <float>(sampler.input);
                        var output  = ctx.GLTF.GetArrayFromAccessor <float>(sampler.output);
                        AnimationImporter.SetAnimationCurve(
                            clip,
                            relativePath,
                            keyNames,
                            input,
                            output,
                            sampler.interpolation,
                            typeof(SkinnedMeshRenderer),
                            (values, last) =>
                            {
                                for (int j = 0; j < values.Length; j++)
                                {
                                    values[j] *= 100.0f;
                                }
                                return(values);
                            });
                    }
                    break;

                    default:
                        Debug.LogWarningFormat("unknown path: {0}", channel.target.path);
                        break;
                    }
                }
                animationClips.Add(clip);
            }

            return(animationClips);
        }
コード例 #29
0
        public void SameMeshButDifferentMaterialExport()
        {
            var go = new GameObject("same_mesh");

            try
            {
                var shader = Shader.Find("Unlit/Color");

                var cubeA = GameObject.CreatePrimitive(PrimitiveType.Cube);
                {
                    cubeA.transform.SetParent(go.transform);
                    var material = new Material(shader);
                    material.name  = "red";
                    material.color = Color.red;
                    cubeA.GetComponent <Renderer>().sharedMaterial = material;
                }

                {
                    var cubeB = GameObject.Instantiate(cubeA);
                    cubeB.transform.SetParent(go.transform);
                    var material = new Material(shader);
                    material.color = Color.blue;
                    material.name  = "blue";
                    cubeB.GetComponent <Renderer>().sharedMaterial = material;

                    Assert.AreEqual(cubeB.GetComponent <MeshFilter>().sharedMesh, cubeA.GetComponent <MeshFilter>().sharedMesh);
                }

                // export
                var gltf = new glTF();
                var json = default(string);
                using (var exporter = new gltfExporter(gltf))
                {
                    exporter.Prepare(go);
                    exporter.Export();

                    json = gltf.ToJson();
                }

                Assert.AreEqual(2, gltf.meshes.Count);

                var red = gltf.materials[gltf.meshes[0].primitives[0].material];
                Assert.AreEqual(new float[] { 1, 0, 0, 1 }, red.pbrMetallicRoughness.baseColorFactor);

                var blue = gltf.materials[gltf.meshes[1].primitives[0].material];
                Assert.AreEqual(new float[] { 0, 0, 1, 1 }, blue.pbrMetallicRoughness.baseColorFactor);

                Assert.AreEqual(2, gltf.nodes.Count);

                Assert.AreNotEqual(gltf.nodes[0].mesh, gltf.nodes[1].mesh);

                // import
                {
                    var context = new ImporterContext();
                    context.ParseJson(json, new SimpleStorage(new ArraySegment <byte>(new byte[1024 * 1024])));
                    //Debug.LogFormat("{0}", context.Json);
                    context.Load();

                    var importedRed         = context.Root.transform.GetChild(0);
                    var importedRedMaterial = importedRed.GetComponent <Renderer>().sharedMaterial;
                    Assert.AreEqual("red", importedRedMaterial.name);
                    Assert.AreEqual(Color.red, importedRedMaterial.color);

                    var importedBlue         = context.Root.transform.GetChild(1);
                    var importedBlueMaterial = importedBlue.GetComponent <Renderer>().sharedMaterial;
                    Assert.AreEqual("blue", importedBlueMaterial.name);
                    Assert.AreEqual(Color.blue, importedBlueMaterial.color);
                }

                // import new version
                {
                    var context = new ImporterContext
                    {
                        UseUniJSONParser = true
                    };
                    context.ParseJson(json, new SimpleStorage(new ArraySegment <byte>(new byte[1024 * 1024])));
                    //Debug.LogFormat("{0}", context.Json);
                    context.Load();

                    var importedRed         = context.Root.transform.GetChild(0);
                    var importedRedMaterial = importedRed.GetComponent <Renderer>().sharedMaterial;
                    Assert.AreEqual("red", importedRedMaterial.name);
                    Assert.AreEqual(Color.red, importedRedMaterial.color);

                    var importedBlue         = context.Root.transform.GetChild(1);
                    var importedBlueMaterial = importedBlue.GetComponent <Renderer>().sharedMaterial;
                    Assert.AreEqual("blue", importedBlueMaterial.name);
                    Assert.AreEqual(Color.blue, importedBlueMaterial.color);
                }
            }
            finally
            {
                GameObject.DestroyImmediate(go);
            }
        }
コード例 #30
0
ファイル: ViewerUI.cs プロジェクト: PoChang007/UniVRM
        async void LoadModelAsync(string path)
        {
            if (!File.Exists(path))
            {
                return;
            }

            Debug.LogFormat("{0}", path);
            var ext = Path.GetExtension(path).ToLower();

            switch (ext)
            {
            case ".vrm":
            {
                var data = new GlbFileParser(path).Parse();

                using (var context = new VRMImporterContext(data))
                {
                    await m_texts.UpdateMetaAsync(context);

                    var loaded = await context.LoadAsync();

                    loaded.EnableUpdateWhenOffscreen();
                    loaded.ShowMeshes();
                    SetModel(loaded.gameObject);
                }
                break;
            }

            case ".glb":
            {
                var data = new GlbFileParser(path).Parse();

                var context = new UniGLTF.ImporterContext(data);
                var loaded  = context.Load();
                loaded.EnableUpdateWhenOffscreen();
                loaded.ShowMeshes();
                SetModel(loaded.gameObject);
                break;
            }

            case ".gltf":
            {
                var data = new GltfFileWithResourceFilesParser(path).Parse();

                var context = new UniGLTF.ImporterContext(data);
                var loaded  = context.Load();
                loaded.EnableUpdateWhenOffscreen();
                loaded.ShowMeshes();
                SetModel(loaded.gameObject);
                break;
            }

            case ".zip":
            {
                var data = new ZipArchivedGltfFileParser(path).Parse();

                var context = new UniGLTF.ImporterContext(data);
                var loaded  = context.Load();
                loaded.EnableUpdateWhenOffscreen();
                loaded.ShowMeshes();
                SetModel(loaded.gameObject);
                break;
            }

            default:
                Debug.LogWarningFormat("unknown file type: {0}", path);
                break;
            }
        }