Esempio n. 1
0
        public void DividedVertexBufferTest()
        {
            var glTF        = new glTF();
            var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]);
            var bufferIndex = glTF.AddBuffer(bytesBuffer);

            var Materials = new List <Material> {
                new Material(Shader.Find("Standard")), // A
                new Material(Shader.Find("Standard")), // B
            };

            var(go, mesh) = CreateMesh(Materials.ToArray());
            var meshExportSettings = new GltfExportSettings
            {
                DivideVertexBuffer = true
            };
            var axisInverter = Axes.X.Create();

            var unityMesh = MeshExportList.Create(go);

            var(gltfMesh, blendShapeIndexMap) = meshExportSettings.DivideVertexBuffer
                ? MeshExporter_DividedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials, axisInverter, meshExportSettings)
                : MeshExporter_SharedVertexBuffer.Export(glTF, bufferIndex, unityMesh, Materials, axisInverter, meshExportSettings)
            ;

            {
                var indices = glTF.GetIndices(gltfMesh.primitives[0].indices);
                Assert.AreEqual(0, indices[0]);
                Assert.AreEqual(1, indices[1]);
                Assert.AreEqual(3, indices[2]);
                Assert.AreEqual(3, indices[3]);
                Assert.AreEqual(1, indices[4]);
                Assert.AreEqual(2, indices[5]);
            }
            {
                var positions = glTF.GetArrayFromAccessor <Vector3>(gltfMesh.primitives[0].attributes.POSITION);
                Assert.AreEqual(4, positions.Length);
            }

            {
                var indices = glTF.GetIndices(gltfMesh.primitives[1].indices);
                Assert.AreEqual(0, indices[0]);
                Assert.AreEqual(1, indices[1]);
                Assert.AreEqual(3, indices[2]);
                Assert.AreEqual(3, indices[3]);
                Assert.AreEqual(1, indices[4]);
                Assert.AreEqual(2, indices[5]);
            }
            {
                var positions = glTF.GetArrayFromAccessor <Vector3>(gltfMesh.primitives[1].attributes.POSITION);
                Assert.AreEqual(4, positions.Length);
            }
        }
Esempio n. 2
0
        public void DividedVertexBufferTest()
        {
            var data = new ExportingGltfData(50 * 1024 * 1024);

            var Materials = new List <Material> {
                new Material(Shader.Find("Standard")), // A
                new Material(Shader.Find("Standard")), // B
            };

            var(go, mesh) = CreateMesh(Materials.ToArray());
            var meshExportSettings = new GltfExportSettings
            {
                DivideVertexBuffer = true
            };
            var axisInverter = Axes.X.Create();

            var unityMesh = MeshExportList.Create(go);

            var(gltfMesh, blendShapeIndexMap) = meshExportSettings.DivideVertexBuffer
                ? MeshExporter_DividedVertexBuffer.Export(data, unityMesh, Materials, axisInverter, meshExportSettings)
                : MeshExporter_SharedVertexBuffer.Export(data, unityMesh, Materials, axisInverter, meshExportSettings)
            ;

            var parsed = GltfData.CreateFromGltfDataForTest(data.GLTF, data.BinBytes);
            {
                var indices = parsed.GetIndices(gltfMesh.primitives[0].indices);
                Assert.AreEqual(0, indices[0]);
                Assert.AreEqual(1, indices[1]);
                Assert.AreEqual(3, indices[2]);
                Assert.AreEqual(3, indices[3]);
                Assert.AreEqual(1, indices[4]);
                Assert.AreEqual(2, indices[5]);
            }
            {
                var positions = parsed.GetArrayFromAccessor <Vector3>(gltfMesh.primitives[0].attributes.POSITION);
                Assert.AreEqual(4, positions.Length);
            }

            {
                var indices = parsed.GetIndices(gltfMesh.primitives[1].indices);
                Assert.AreEqual(0, indices[0]);
                Assert.AreEqual(1, indices[1]);
                Assert.AreEqual(3, indices[2]);
                Assert.AreEqual(3, indices[3]);
                Assert.AreEqual(1, indices[4]);
                Assert.AreEqual(2, indices[5]);
            }
            {
                var positions = parsed.GetArrayFromAccessor <Vector3>(gltfMesh.primitives[1].attributes.POSITION);
                Assert.AreEqual(4, positions.Length);
            }
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
        }