// ----------------------------------------- // DumpAnims // ----------------------------------------- void DumpAnims(GameObject _animPrefab, GLTF _gltf, BufferInfo _bufInfo) { // get animations GameObject prefabInst = PrefabUtility.InstantiatePrefab(_animPrefab) as GameObject; List <AnimationClip> clips = Utils.GetAnimationClips(prefabInst); // get joints List <GameObject> joints = new List <GameObject>(); Utils.RecurseNode(prefabInst, _go => { // this is not a joint if (_go.GetComponent <SkinnedMeshRenderer>() != null) { return(false); } joints.Add(_go); return(true); }); // if (clips != null) { // process AnimationClip(s) foreach (AnimationClip clip in clips) { int accOffset = _bufInfo.GetAccessorCount(); AnimData animData = DumpAnimData(prefabInst, clip); DumpBufferInfoFromAnimData(animData, _bufInfo); GLTF_AnimationEx gltfAnim = DumpGltfAnimationEx(animData, joints, accOffset); _gltf.animations.Add(gltfAnim); } } Object.DestroyImmediate(prefabInst); }
Dictionary <string, JSON_Asset> saveAssets( string dest, List <Object> prefabs, List <Object> modelPrefabs, List <Mesh> meshes, List <Texture> textures, List <Texture> spriteTextures, List <Material> materials, List <Font> fonts ) { Dictionary <string, JSON_Asset> assetsJson = new Dictionary <string, JSON_Asset>(); // DELME { // // save meshes // var destMeshes = Path.Combine(dest, "meshes"); // foreach (Mesh mesh in meshes) { // string id = Utils.AssetID(mesh); // GLTF gltf = new GLTF(); // gltf.asset = new GLTF_Asset // { // version = "1.0.0", // generator = "u3d-exporter" // }; // BufferInfo bufInfo = new BufferInfo // { // id = id, // name = mesh.name // }; // DumpMesh(mesh, gltf, bufInfo, 0); // DumpBuffer(bufInfo, gltf); // Save( // destMeshes, // id, // gltf, // new List<BufferInfo> { bufInfo } // ); // // add asset to table // assetsJson.Add(id, new JSON_Asset { // type = "mesh", // urls = new Dictionary<string, string> { // { "gltf", "meshes/" + id + ".gltf" }, // { "bin", "meshes/" + id + ".bin" } // } // }); // } // } DELME // ======================================== // save animations // ======================================== var destAnims = Path.Combine(dest, "anims"); foreach (GameObject prefab in prefabs) { // skip ModelPrefab if (PrefabUtility.GetPrefabType(prefab) == PrefabType.ModelPrefab) { Debug.LogWarning("Can not export model prefab " + prefab.name + " in the scene"); continue; } // skip non-animation prefab bool isAnimPrefab = Utils.IsAnimPrefab(prefab); if (isAnimPrefab == false) { continue; } // get animations GameObject prefabInst = PrefabUtility.InstantiatePrefab(prefab) as GameObject; List <AnimationClip> clips = Utils.GetAnimationClips(prefabInst); // get joints List <GameObject> joints = new List <GameObject>(); Utils.RecurseNode(prefabInst, _go => { // this is not a joint if (_go.GetComponent <SkinnedMeshRenderer>() != null) { return(false); } joints.Add(_go); return(true); }); // dump animation clips if (clips != null) { // process AnimationClip(s) foreach (AnimationClip clip in clips) { string id = Utils.AssetID(clip); GLTF gltf = new GLTF(); gltf.asset = new GLTF_Asset { version = "1.0.0", generator = "u3d-exporter" }; BufferInfo bufInfo = new BufferInfo { id = id, name = prefab.name }; AnimData animData = DumpAnimData(prefabInst, clip); DumpBufferInfoFromAnimData(animData, bufInfo); GLTF_AnimationEx gltfAnim = DumpGltfAnimationEx(animData, joints, 0); gltf.animations.Add(gltfAnim); DumpBuffer(bufInfo, gltf); Save( destAnims, id + ".anim", gltf, new List <BufferInfo> { bufInfo } ); // add asset to table try { if (!assetsJson.ContainsKey(id)) { assetsJson.Add(id, new JSON_Asset { type = "animation", urls = new Dictionary <string, string> { { "anim", "anims/" + id + ".anim" }, { "bin", "anims/" + id + ".bin" } } }); } } catch (System.SystemException e) { Debug.LogError("Failed to add " + id + " to assets: " + e); } } } Object.DestroyImmediate(prefabInst); } // ======================================== // save prefabs // ======================================== var destMeshes = Path.Combine(dest, "meshes"); var destPrefabs = Path.Combine(dest, "prefabs"); // create dest directory if (!Directory.Exists(destMeshes)) { Directory.CreateDirectory(destMeshes); } if (!Directory.Exists(destPrefabs)) { Directory.CreateDirectory(destPrefabs); } foreach (GameObject prefab in prefabs) { string id = Utils.AssetID(prefab); // save prefabs if (PrefabUtility.GetPrefabType(prefab) == PrefabType.ModelPrefab) { Debug.LogWarning("Can not export model prefab " + prefab.name + " in the scene"); continue; } var prefabJson = DumpPrefab(prefab); string path; string json = JsonConvert.SerializeObject(prefabJson, Formatting.Indented); path = Path.Combine(destPrefabs, id + ".json"); StreamWriter writer = new StreamWriter(path); writer.Write(json); writer.Close(); // Debug.Log(Path.GetFileName(path) + " saved."); // add asset to table if (!assetsJson.ContainsKey(id)) { assetsJson.Add(id, new JSON_Asset { type = "prefab", urls = new Dictionary <string, string> { { "json", "prefabs/" + id + ".json" }, } }); } } // save model prefab (as gltf) foreach (GameObject modelPrefab in modelPrefabs) { string id = Utils.AssetID(modelPrefab); // save model prefabs GLTF gltf = new GLTF(); gltf.asset = new GLTF_Asset { version = "1.0.0", generator = "u3d-exporter" }; BufferInfo bufInfo = new BufferInfo { id = id, name = modelPrefab.name }; bool isAnimPrefab = Utils.IsAnimPrefab(modelPrefab); if (isAnimPrefab) { DumpSkinningModel(modelPrefab, gltf, bufInfo); DumpBuffer(bufInfo, gltf); } else { DumpModel(modelPrefab, gltf, bufInfo); DumpBuffer(bufInfo, gltf); } Save( destMeshes, id + ".gltf", gltf, new List <BufferInfo> { bufInfo } ); // add asset to table if (!assetsJson.ContainsKey(id)) { assetsJson.Add(id, new JSON_Asset { type = "gltf", urls = new Dictionary <string, string> { { "gltf", "meshes/" + id + ".gltf" }, { "bin", "meshes/" + id + ".bin" } } }); } } // save meshes (as gltf) foreach (Mesh mesh in meshes) { string id = Utils.AssetID(mesh); // save model prefabs GLTF gltf = new GLTF(); gltf.asset = new GLTF_Asset { version = "1.0.0", generator = "u3d-exporter" }; BufferInfo bufInfo = new BufferInfo { id = id, name = mesh.name }; DumpMesh(mesh, gltf, bufInfo, 0); DumpBuffer(bufInfo, gltf); Save( destMeshes, id + ".mesh", gltf, new List <BufferInfo> { bufInfo } ); // add asset to table if (!assetsJson.ContainsKey(id)) { assetsJson.Add(id, new JSON_Asset { type = "mesh", urls = new Dictionary <string, string> { { "mesh", "meshes/" + id + ".mesh" }, { "bin", "meshes/" + id + ".bin" } } }); } } // ======================================== // save textures // ======================================== var destTextures = Path.Combine(dest, "textures"); // create dest directory if (!Directory.Exists(destTextures)) { Directory.CreateDirectory(destTextures); } foreach (Texture tex in textures) { var textureJson = DumpTexture(tex); string path; string json = JsonConvert.SerializeObject(textureJson, Formatting.Indented); string id = Utils.AssetID(tex); // json path = Path.Combine(destTextures, id + ".json"); StreamWriter writer = new StreamWriter(path); writer.Write(json); writer.Close(); // image string assetPath = AssetDatabase.GetAssetPath(tex); path = Path.Combine(destTextures, id + Utils.AssetExt(tex)); File.Copy(assetPath, path, true); // Debug.Log(Path.GetFileName(path) + " saved."); // add asset to table if (!assetsJson.ContainsKey(id)) { assetsJson.Add(id, new JSON_Asset { type = "texture", urls = new Dictionary <string, string> { { "json", "textures/" + id + ".json" }, { "image", "textures/" + id + Utils.AssetExt(tex) }, } }); } } // ======================================== // save sprite textures // ======================================== var destSprites = Path.Combine(dest, "sprites"); // create dest directory if (!Directory.Exists(destSprites)) { Directory.CreateDirectory(destSprites); } foreach (Texture spriteTex in spriteTextures) { var spriteTextureJson = DumpSpriteTexture(spriteTex); string path; string json = JsonConvert.SerializeObject(spriteTextureJson, Formatting.Indented); string id = Utils.AssetID(spriteTex); // json path = Path.Combine(destSprites, id + ".json"); StreamWriter writer = new StreamWriter(path); writer.Write(json); writer.Close(); // image string assetPath = AssetDatabase.GetAssetPath(spriteTex); path = Path.Combine(destSprites, id + Utils.AssetExt(spriteTex)); File.Copy(assetPath, path); // add asset to table if (!assetsJson.ContainsKey(id)) { assetsJson.Add(id, new JSON_Asset { type = "texture", urls = new Dictionary <string, string> { { "json", "sprites/" + id + ".json" }, { "image", "sprites/" + id + Utils.AssetExt(spriteTex) }, } }); } } // ======================================== // save fonts // ======================================== var destFonts = Path.Combine(dest, "fonts"); if (!Directory.Exists(destFonts)) { Directory.CreateDirectory(destFonts); } foreach (Font font in fonts) { if (font.dynamic) { if (font.fontNames.Length > 1) // system font // do nothing { } else // opentype font { JSON_OpenTypeFont fontJson = DumpOpenTypeFont(font); // save font json string path; string json = JsonConvert.SerializeObject(fontJson, Formatting.Indented); string id = Utils.AssetID(font); path = Path.Combine(destFonts, id + ".json"); StreamWriter writer = new StreamWriter(path); writer.Write(json); writer.Close(); // save font file (ttf) Texture tex = font.material.mainTexture; string assetPath = AssetDatabase.GetAssetPath(font); path = Path.Combine(destFonts, id + Utils.AssetExt(font)); File.Copy(assetPath, path, true); if (!assetsJson.ContainsKey(id)) { assetsJson.Add(id, new JSON_Asset { type = "otfont", urls = new Dictionary <string, string> { { "json", "fonts/" + id + ".json" }, { "bin", "fonts/" + id + Utils.AssetExt(font) }, } }); } } } else // bitmapFont { JSON_BitmapFont fontJson = DumpBitmapFont(font); string path; string json = JsonConvert.SerializeObject(fontJson, Formatting.Indented); string id = Utils.AssetID(font); path = Path.Combine(destFonts, id + ".json"); StreamWriter writer = new StreamWriter(path); writer.Write(json); writer.Close(); if (!assetsJson.ContainsKey(id)) { assetsJson.Add(id, new JSON_Asset { type = "bmfont", urls = new Dictionary <string, string> { { "json", "fonts/" + id + ".json" }, } }); } } } // ======================================== // save materials // ======================================== var destMaterials = Path.Combine(dest, "materials"); // create dest directory if (!Directory.Exists(destMaterials)) { Directory.CreateDirectory(destMaterials); } foreach (Material mat in materials) { var materialJson = DumpMaterial(mat); if (materialJson == null) { continue; } string path; string json = JsonConvert.SerializeObject(materialJson, Formatting.Indented); string id = Utils.AssetID(mat); // json path = Path.Combine(destMaterials, id + ".json"); StreamWriter writer = new StreamWriter(path); writer.Write(json); writer.Close(); // Debug.Log(Path.GetFileName(path) + " saved."); // add asset to table if (!assetsJson.ContainsKey(id)) { assetsJson.Add(id, new JSON_Asset { type = "material", urls = new Dictionary <string, string> { { "json", "materials/" + id + ".json" }, } }); } } // ======================================== // save assets // ======================================== { string path = Path.Combine(dest, "assets.json"); string json = JsonConvert.SerializeObject(assetsJson, Formatting.Indented); StreamWriter writer = new StreamWriter(path); writer.Write(json); writer.Close(); } return(assetsJson); }
// ----------------------------------------- // DumpGltfAnimationEx // ----------------------------------------- GLTF_AnimationEx DumpGltfAnimationEx(AnimData _animData, List <GameObject> _joints, int _accOffset) { GLTF_AnimationEx result = new GLTF_AnimationEx(); result.name = _animData.name; List <GLTF_AnimChannelEx> channels = new List <GLTF_AnimChannelEx>(); int offset = 2; // acc offset start from 2 (0 is time0, 1 is times) foreach (var entry in _animData.nameToFrames) { NodeFrames frames = entry.Value; // T if (frames.tlist.Count > 0) { // NOTE: index 0 = "time0", index 1 = "time1" GLTF_AnimChannelEx channel = new GLTF_AnimChannelEx { input = (frames.tlist.Count == 1 ? 0 : 1) + _accOffset, output = offset + _accOffset, node = _joints.IndexOf(frames.node), path = "translation", }; channels.Add(channel); offset += 1; } // S if (frames.slist.Count > 0) { // NOTE: index 0 = "time0", index 1 = "time1" GLTF_AnimChannelEx channel = new GLTF_AnimChannelEx { input = (frames.slist.Count == 1 ? 0 : 1) + _accOffset, output = offset + _accOffset, node = _joints.IndexOf(frames.node), path = "scale", }; channels.Add(channel); offset += 1; } // R if (frames.rlist.Count > 0) { // NOTE: index 0 = "time0", index 1 = "time1" GLTF_AnimChannelEx channel = new GLTF_AnimChannelEx { input = (frames.rlist.Count == 1 ? 0 : 1) + _accOffset, output = offset + _accOffset, node = _joints.IndexOf(frames.node), path = "rotation", }; channels.Add(channel); offset += 1; } } result.channels = channels; return(result); }