public virtual void Export(ITextureSerializer textureSerializer) { Nodes = Copy.transform.Traverse() .Skip(1) // exclude root object for the symmetry with the importer .ToList(); var uniqueUnityMeshes = new MeshExportList(); uniqueUnityMeshes.GetInfo(Nodes, m_settings); #region Materials and Textures ReportProgress("Materials and Textures", 0.2f); Materials = uniqueUnityMeshes.GetUniqueMaterials().ToList(); _textureExporter = new TextureExporter(textureSerializer); var materialExporter = CreateMaterialExporter(); _gltf.materials = Materials.Select(x => materialExporter.ExportMaterial(x, TextureExporter, m_settings)).ToList(); #endregion #region Meshes ReportProgress("Meshes", 0.4f); MeshBlendShapeIndexMap = new Dictionary <Mesh, Dictionary <int, int> >(); foreach (var unityMesh in uniqueUnityMeshes) { if (!unityMesh.CanExport) { continue; } var(gltfMesh, blendShapeIndexMap) = m_settings.DivideVertexBuffer ? MeshExporter_DividedVertexBuffer.Export(_data, unityMesh, Materials, m_settings.InverseAxis.Create(), m_settings) : MeshExporter_SharedVertexBuffer.Export(_data, unityMesh, Materials, m_settings.InverseAxis.Create(), m_settings) ; _gltf.meshes.Add(gltfMesh); Meshes.Add(unityMesh.Mesh); if (!MeshBlendShapeIndexMap.ContainsKey(unityMesh.Mesh)) { // 重複防止 MeshBlendShapeIndexMap.Add(unityMesh.Mesh, blendShapeIndexMap); } } #endregion #region Nodes and Skins ReportProgress("Nodes and Skins", 0.8f); var skins = uniqueUnityMeshes .SelectMany(x => x.Renderers) .Where(x => x.Item1 is SkinnedMeshRenderer && x.UniqueBones != null) .Select(x => x.Item1 as SkinnedMeshRenderer) .ToList() ; foreach (var node in Nodes) { var gltfNode = ExportNode(node, Nodes, uniqueUnityMeshes, skins); _gltf.nodes.Add(gltfNode); } _gltf.scenes = new List <gltfScene> { new gltfScene { nodes = Copy.transform.GetChildren().Select(x => Nodes.IndexOf(x)).ToArray(), } }; foreach (var x in uniqueUnityMeshes) { foreach (var(renderer, uniqueBones) in x.Renderers) { if (uniqueBones != null && renderer is SkinnedMeshRenderer smr) { var matrices = x.GetBindPoses().Select(m_settings.InverseAxis.Create().InvertMat4).ToArray(); var accessor = _data.ExtendBufferAndGetAccessorIndex(matrices, glBufferTarget.NONE); var skin = new glTFSkin { inverseBindMatrices = accessor, joints = uniqueBones.Select(y => Nodes.IndexOf(y)).ToArray(), skeleton = Nodes.IndexOf(smr.rootBone), }; var skinIndex = _gltf.skins.Count; _gltf.skins.Add(skin); foreach (var z in Nodes.Where(y => y.Has(renderer))) { var nodeIndex = Nodes.IndexOf(z); var node = _gltf.nodes[nodeIndex]; node.skin = skinIndex; } } } } #endregion #if UNITY_EDITOR #region Animations ReportProgress("Animations", 0.9f); var clips = new List <AnimationClip>(); var animator = Copy.GetComponent <Animator>(); var animation = Copy.GetComponent <Animation>(); if (animator != null) { clips = AnimationExporter.GetAnimationClips(animator); } else if (animation != null) { clips = AnimationExporter.GetAnimationClips(animation); } if (clips.Any()) { foreach (AnimationClip clip in clips) { var animationWithCurve = AnimationExporter.Export(clip, Copy.transform, Nodes); foreach (var kv in animationWithCurve.SamplerMap) { var sampler = animationWithCurve.Animation.samplers[kv.Key]; var inputAccessorIndex = _data.ExtendBufferAndGetAccessorIndex(kv.Value.Input); sampler.input = inputAccessorIndex; var outputAccessorIndex = _data.ExtendBufferAndGetAccessorIndex(kv.Value.Output); sampler.output = outputAccessorIndex; // modify accessors var outputAccessor = _gltf.accessors[outputAccessorIndex]; var channel = animationWithCurve.Animation.channels.First(x => x.sampler == kv.Key); switch (glTFAnimationTarget.GetElementCount(channel.target.path)) { case 1: outputAccessor.type = "SCALAR"; //outputAccessor.count = ; break; case 3: outputAccessor.type = "VEC3"; outputAccessor.count /= 3; break; case 4: outputAccessor.type = "VEC4"; outputAccessor.count /= 4; break; default: throw new NotImplementedException(); } } animationWithCurve.Animation.name = clip.name; _gltf.animations.Add(animationWithCurve.Animation); } } #endregion #endif ExportExtensions(textureSerializer); // Extension で Texture が増える場合があるので最後に呼ぶ var exported = _textureExporter.Export(); for (var exportedTextureIdx = 0; exportedTextureIdx < exported.Count; ++exportedTextureIdx) { var(unityTexture, colorSpace) = exported[exportedTextureIdx]; GltfTextureExporter.PushGltfTexture(_data, unityTexture, colorSpace, textureSerializer); } FixName(_gltf); }
public virtual void Export(ITextureSerializer textureSerializer) { Nodes = Copy.transform.Traverse() .Skip(1) // exclude root object for the symmetry with the importer .ToList(); var uniqueUnityMeshes = new MeshExportList(); uniqueUnityMeshes.GetInfo(Nodes, m_settings); #region Materials and Textures ReportProgress("Materials and Textures", 0.2f); Materials = uniqueUnityMeshes.GetUniqueMaterials().ToList(); _textureExporter = new TextureExporter(textureSerializer); var materialExporter = CreateMaterialExporter(); _gltf.materials = Materials.Select(x => materialExporter.ExportMaterial(x, TextureExporter, m_settings)).ToList(); #endregion #region Meshes ReportProgress("Meshes", 0.4f); MeshBlendShapeIndexMap = new Dictionary <Mesh, Dictionary <int, int> >(); foreach (var unityMesh in uniqueUnityMeshes) { if (!unityMesh.CanExport) { continue; } var(gltfMesh, blendShapeIndexMap) = m_settings.DivideVertexBuffer ? MeshExporter_DividedVertexBuffer.Export(_data, unityMesh, Materials, m_settings.InverseAxis.Create(), m_settings) : MeshExporter_SharedVertexBuffer.Export(_data, unityMesh, Materials, m_settings.InverseAxis.Create(), m_settings) ; _gltf.meshes.Add(gltfMesh); Meshes.Add(unityMesh.Mesh); if (!MeshBlendShapeIndexMap.ContainsKey(unityMesh.Mesh)) { // 重複防止 MeshBlendShapeIndexMap.Add(unityMesh.Mesh, blendShapeIndexMap); } } #endregion #region Nodes and Skins ReportProgress("Nodes and Skins", 0.8f); var skins = uniqueUnityMeshes .SelectMany(x => x.Renderers) .Where(x => x.Item1 is SkinnedMeshRenderer && x.UniqueBones != null) .Select(x => x.Item1 as SkinnedMeshRenderer) .ToList() ; foreach (var node in Nodes) { var gltfNode = ExportNode(node, Nodes, uniqueUnityMeshes, skins); _gltf.nodes.Add(gltfNode); } _gltf.scenes = new List <gltfScene> { new gltfScene { nodes = Copy.transform.GetChildren().Select(x => Nodes.IndexOf(x)).ToArray(), } }; foreach (var x in uniqueUnityMeshes) { foreach (var(renderer, uniqueBones) in x.Renderers) { if (uniqueBones != null && renderer is SkinnedMeshRenderer smr) { var matrices = x.GetBindPoses().Select(m_settings.InverseAxis.Create().InvertMat4).ToArray(); var accessor = _data.ExtendBufferAndGetAccessorIndex(matrices, glBufferTarget.NONE); var skin = new glTFSkin { inverseBindMatrices = accessor, joints = uniqueBones.Select(y => Nodes.IndexOf(y)).ToArray(), skeleton = Nodes.IndexOf(smr.rootBone), }; var skinIndex = _gltf.skins.Count; _gltf.skins.Add(skin); foreach (var z in Nodes.Where(y => y.Has(renderer))) { var nodeIndex = Nodes.IndexOf(z); var node = _gltf.nodes[nodeIndex]; node.skin = skinIndex; } } } } #endregion if (m_animationExporter != null) { ReportProgress("Animations", 0.9f); m_animationExporter.Export(_data, Copy, Nodes); } ExportExtensions(textureSerializer); // Extension で Texture が増える場合があるので最後に呼ぶ var exported = _textureExporter.Export(); for (var exportedTextureIdx = 0; exportedTextureIdx < exported.Count; ++exportedTextureIdx) { var(unityTexture, colorSpace) = exported[exportedTextureIdx]; GltfTextureExporter.PushGltfTexture(_data, unityTexture, colorSpace, textureSerializer); } FixName(_gltf); }