static void ImportDelayed(GLTFImporter context, UnityPath prefabPath) { EditorApplication.delayCall += () => { // // After textures imported(To ensure TextureImporter be accessible). // // try // { var t = Save(context, prefabPath); // } // catch (UniGLTFNotSupportedException ex) // { // Debug.LogWarningFormat($"{src}: {ex.Message}"); // context.EditorDestroyRootAndAssets(); // } // catch (Exception ex) // { // Debug.LogErrorFormat("import error: {0}", src); // Debug.LogErrorFormat("{0}", ex); // context.EditorDestroyRootAndAssets(); // } }; }
private static async Task Save(GLTFImporter context, UnityPath path) { await context.Load(context.storage, p => Debug.Log(p)); context.ShowMeshes(); await SaveAsAsset(context, path); context.EditorDestroyRoot(); }
public void VersionChecker() { Assert.False(GLTFImporter.IsGeneratedGLTFumaAndOlderThan("hoge", 1, 16)); Assert.False(GLTFImporter.IsGeneratedGLTFumaAndOlderThan("UniGLTF-1.16", 1, 16)); Assert.True(GLTFImporter.IsGeneratedGLTFumaAndOlderThan("UniGLTF-1.15", 1, 16)); Assert.False(GLTFImporter.IsGeneratedGLTFumaAndOlderThan("UniGLTF-11.16", 1, 16)); Assert.True(GLTFImporter.IsGeneratedGLTFumaAndOlderThan("UniGLTF-0.16", 1, 16)); Assert.True(GLTFImporter.IsGeneratedGLTFumaAndOlderThan("UniGLTF", 1, 16)); }
public void Unload() { _unloaded = true; if (_loader != null) { _loader.Dispose(); _loader = null; } if (_storage != null) { _storage.Dispose(); _storage = null; } }
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 GLTFImporter(); context.Parse(src); // Extract textures to assets folder ExtranctImages(context, prefabPath); ImportDelayed(context, prefabPath); }
/// <summary> /// Extract images from glb or gltf out of Assets folder. /// </summary> /// <param name="prefabPath"></param> public static void ExtranctImages(GLTFImporter context, UnityPath prefabPath) { var prefabParentDir = prefabPath.parent; // glb buffer var folder = prefabPath.GetAssetFolder(".Textures"); // // https://answers.unity.com/questions/647615/how-to-update-import-settings-for-newly-created-as.html // int created = 0; //for (int i = 0; i < GLTF.textures.Count; ++i) for (int i = 0; i < context.gltf.images.Count; ++i) { folder.EnsureFolder(); //var x = GLTF.textures[i]; var image = context.gltf.images[i]; var src = context.storage.GetPath(image.uri); if (UnityPath.FromFullpath(src).isUnderAssetsFolder) { // asset is exists. } else { string textureName; var byteSegment = context.gltf.GetImageBytes(context.storage, i, out textureName, out var url); // path var dst = folder.Child(textureName + image.GetExt()); File.WriteAllBytes(dst.fullPath, byteSegment.ToArray()); dst.ImportAsset(); // make relative path from PrefabParentDir image.uri = dst.value.Substring(prefabParentDir.value.Length + 1); ++created; } } if (created > 0) { AssetDatabase.Refresh(); } context.CreateTextureItems(prefabParentDir); }
public void ImportAnimation(GLTFImporter importer) { //Debug.Log("import animations " + importer.gltf.animations?.Count); // animation if (importer.gltf.animations != null && importer.gltf.animations.Any()) { var animation = importer.root.AddComponent <Animation>(); importer.animationClips = ImportAnimationClip(importer); foreach (var clip in importer.animationClips) { animation.AddClip(clip, clip.name); } if (importer.animationClips.Count > 0) { animation.clip = importer.animationClips.First(); } } }
public static void ImportMenu() { var path = EditorUtility.OpenFilePanel("open gltf", "", "gltf,glb,zip"); if (string.IsNullOrEmpty(path)) { return; } if (Application.isPlaying) { // // load into scene // var context = new GLTFImporter(); //context.Load(path); 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)); } }
public void UniGLTFSimpleSceneTest() { var go = CreateSimpelScene(); var context = new GLTFImporter(); try { // export var gltf = new GLTFRoot(); string json = null; using (var exporter = new GLTFExporter(gltf)) { exporter.Prepare(go); exporter.Export(); // remove empty buffer gltf.buffers.Clear(); json = gltf.ToJson(); } // import context.ParseJson(json, new SimpleStorage(new ArraySegment <byte>())); //Debug.LogFormat("{0}", context.Json); //context.Load(); AssertAreEqual(go.transform, context.root.transform); } finally { //Debug.LogFormat("Destory, {0}", go.name); GameObject.DestroyImmediate(go); context.EditorDestroyRootAndAssets(); } }
public MaterialImporter(IShaderStore shaderStore, GLTFImporter context) { m_shaderStore = shaderStore; m_context = context; }
public static async Task SaveAsAsset(GLTFImporter context, UnityPath prefabPath) { //var prefabPath = PrefabPath; if (prefabPath.isFileExists) { // clear SubAssets foreach (var x in prefabPath.GetSubAssets().Where(x => !(x is GameObject) && !(x is Component))) { GameObject.DestroyImmediate(x, true); } } // // save sub assets // var paths = new List <UnityPath>() { prefabPath }; foreach (var o in context.ObjectsForSubAsset()) { if (o == null) { continue; } var assetPath = GetAssetPath(prefabPath, o); if (!assetPath.isNull) { if (assetPath.isFileExists) { if (!IsOverwrite(o)) { // 上書きしない Debug.LogWarningFormat("already exists. skip {0}", assetPath); continue; } } assetPath.parent.EnsureFolder(); assetPath.CreateAsset(o); paths.Add(assetPath); } else { // save as subasset prefabPath.AddObjectToAsset(o); } } await Task.Yield(); // Create or upate Main Asset // if (prefabPath.isFileExists) // { // Debug.LogFormat("replace prefab: {0}", prefabPath); // //var prefab = prefabPath.LoadAsset<GameObject>(); // } // else // { // Debug.LogFormat("create prefab: {0}", prefabPath); // PrefabUtility.SaveAsPrefabAsset(context.root, prefabPath.value);//.CreatePrefab(prefabPath.Value, context.root); // } PrefabUtility.SaveAsPrefabAssetAndConnect(context.root, prefabPath.value, InteractionMode.AutomatedAction); //.ReplacePrefab(context.root, prefab, ReplacePrefabOptions.ReplaceNameBased); await Task.Yield(); AssetDatabase.Refresh(); // foreach (var x in paths) // { // x.ImportAsset(); // } await Task.Yield(); }
public TransformWithSkin BuildHierarchy(GLTFImporter context, int i) { var go = context.nodes[i].gameObject; if (string.IsNullOrEmpty(go.name)) { go.name = $"node{i:000}"; } var nodeWithSkin = new TransformWithSkin { transform = go.transform, }; // // build hierachy // var node = context.gltf.nodes[i]; if (node.children != null) { foreach (var child in node.children) { // node has local transform context.nodes[child].transform.SetParent(context.nodes[i].transform, false); } } // // attach mesh // //Debug.Log("node mesh ... "+node.name+" == "+node.mesh); if (node.mesh != -1) { var mesh = context.meshes[node.mesh]; if (mesh.mesh.blendShapeCount == 0 && node.skin == -1) { // without blendshape and bone skinning var filter = go.AddComponent <MeshFilter>(); filter.sharedMesh = mesh.mesh; var renderer = go.AddComponent <MeshRenderer>(); renderer.sharedMaterials = mesh.materials; // invisible in loading renderer.enabled = false; mesh.renderers.Add(renderer); } else { var renderer = go.AddComponent <SkinnedMeshRenderer>(); if (node.skin != -1) { nodeWithSkin.skinIndex = node.skin; } renderer.sharedMesh = mesh.mesh; renderer.sharedMaterials = mesh.materials; // invisible in loading renderer.enabled = false; mesh.renderers.Add(renderer); } } return(nodeWithSkin); }
public List <AnimationClip> ImportAnimationClip(GLTFImporter importer) { List <AnimationClip> animasionClips = new List <AnimationClip>(); for (int i = 0; i < importer.gltf.animations.Count; ++i) { var clip = new AnimationClip(); clip.ClearCurves(); clip.legacy = true; clip.name = importer.gltf.animations[i].name; if (string.IsNullOrEmpty(clip.name)) { clip.name = "legacy_" + i; } clip.wrapMode = WrapMode.Loop; var animation = importer.gltf.animations[i]; if (string.IsNullOrEmpty(animation.name)) { animation.name = string.Format("animation:{0}", i); } foreach (var channel in animation.channels) { var targetTransform = importer.nodes[channel.target.node]; var relativePath = targetTransform.RelativePathFrom(importer.root.transform); switch (channel.target.path) { case GLTFAnimationTarget.PATH_TRANSLATION: { var sampler = animation.samplers[channel.sampler]; var input = importer.gltf.GetArrayFromAccessor <float>(sampler.input); var output = importer.gltf.GetArrayFromAccessorAsFloat(sampler.output); 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 = importer.gltf.GetArrayFromAccessor <float>(sampler.input); var output = importer.gltf.GetArrayFromAccessorAsFloat(sampler.output); 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(lastQuaternion.GetShortest(currentQuaternion.ReverseZ()).ToArray()); } ); clip.EnsureQuaternionContinuity(); } break; case GLTFAnimationTarget.PATH_SCALE: { var sampler = animation.samplers[channel.sampler]; var input = importer.gltf.GetArrayFromAccessor <float>(sampler.input); var output = importer.gltf.GetArrayFromAccessorAsFloat(sampler.output); 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 = importer.gltf.nodes[channel.target.node]; var mesh = importer.gltf.meshes[node.mesh]; //var primitive = mesh.primitives.FirstOrDefault(); //var targets = primitive.targets; List <string> blendShapeNames = new List <string>(); var transform = importer.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 = importer.gltf.GetArrayFromAccessor <float>(sampler.input); var output = importer.gltf.GetArrayFromAccessor <float>(sampler.output); 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; case GLTFAnimationTarget.PATH_ACTIVE: { var sampler = animation.samplers[channel.sampler]; var input = importer.gltf.GetArrayFromAccessor <float>(sampler.input); var output = importer.gltf.GetArrayFromAccessorAsFloat(sampler.output); SetAnimationCurve( clip, relativePath, new string[] { "m_IsActive" }, input, output, sampler.interpolation, typeof(GameObject), (values, last) => values); } break; default: Debug.LogWarningFormat("unknown path: {0}", channel.target.path); break; } } animasionClips.Add(clip); } return(animasionClips); }
private async Task <GameObject> Load(Action <float> progress) { await Task.Yield(); _unloaded = false; var name = url.Substring(url.LastIndexOf("/") + 1); //加载.gltf文件 await _storage.LoadString(name, p => progress?.Invoke(p * 0.1f)); if (_unloaded) { return(null); } _loader = new GLTFImporter(this, null, null, null, null); //用JsonUtility解析到gltf数据 _loader.ParseJson(_storage.GetString(name)); //加载buffers里面的.bin数据 int total = _loader.gltf.buffers.Count; int current = 0; var stepPrecent = showWithTexture ? 0.4f : 0.8f; foreach (var buffer in _loader.gltf.buffers) { Debug.Log(buffer.uri); await _storage.LoadBinary(buffer.uri, p => progress?.Invoke(0.1f + stepPrecent * (current + p) / total)); if (_unloaded) { return(null); } //Debug.Log(buffer.uri + " loaded"); buffer.OpenStorage(_storage); current++; } //跳过图片的加载 if (showWithTexture) { current = 0; total = _loader.gltf.images.Count; foreach (var image in _loader.gltf.images) { await _storage.LoadTexture(image.uri, p => progress?.Invoke(0.5f + 0.4f * (current + p) / total)); current++; if (_unloaded) { return(null); } } } //解析mesh、material、animation等数据 await _loader.Load(_storage, p => progress?.Invoke(0.9f + p * 0.1f)); if (_unloaded) { return(null); } //loader.Parse(url,www.downloadHandler.data); _loader.ShowMeshes(); _loader.root.SetActive(false); _loader.root.transform.SetParent(transform); _loader.root.SetActive(true); return(_loader.root); }
//ImporterContext m_context; public ShaderStore(GLTFImporter _) { //m_context = context; }