Example #1
0
        void BufferTest(int init, params int[] size)
        {
            var initBytes = init == 0 ? null : new byte[init];
            var storage   = new ArrayByteBuffer(initBytes);
            var buffer    = new glTFBuffer(storage);

            var values = new List <byte>();
            int offset = 0;

            foreach (var x in size)
            {
                var nums = Enumerable.Range(offset, x).Select(y => (Byte)y).ToArray();
                values.AddRange(nums);
                var bytes = new ArraySegment <Byte>(nums);
                offset += x;
                buffer.Append(bytes, glBufferTarget.NONE);
            }

            Assert.AreEqual(values.Count, buffer.byteLength);
            Assert.True(Enumerable.SequenceEqual(values, buffer.GetBytes().ToArray()));
        }
Example #2
0
        void FromGameObject(glTF gltf, GameObject go, bool useSparseAccessorForMorphTarget = false)
        {
            var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]);
            var bufferIndex = gltf.AddBuffer(bytesBuffer);

            GameObject tmpParent = null;

            if (go.transform.childCount == 0)
            {
                tmpParent = new GameObject("tmpParent");
                go.transform.SetParent(tmpParent.transform, true);
                go = tmpParent;
            }

            try
            {
                Nodes = go.transform.Traverse()
                        .Skip(1) // exclude root object for the symmetry with the importer
                        .ToList();

                #region Materials and Textures
                Materials = Nodes
                            .Where(x => !x.HasTextMeshProComponent())
                            .SelectMany(x => x.GetSharedMaterials()).Where(x => x != null).Distinct().ToList();
                var unityTextures = Materials.SelectMany(x => TextureExporter.GetTextures(x)).Where(x => x.texture != null).Distinct().ToList();

                TextureManager = new TextureExportManager(unityTextures.Select(x => x.texture));

                var materialExporter = CreateMaterialExporter();
                gltf.materials = Materials.Select(x => materialExporter.ExportMaterial(x, TextureManager)).ToList();

                for (int i = 0; i < unityTextures.Count; ++i)
                {
                    var unityTexture = unityTextures[i];
                    TextureExporter.ExportTexture(gltf, bufferIndex, TextureManager.GetExportTexture(i), unityTexture.textureType);
                }
                #endregion


                #region Meshes
                var unityMeshes = Nodes
                                  .Select(x => new MeshWithRenderer
                {
                    Mesh     = x.GetSharedMesh(),
                    Renderer = x.GetComponent <Renderer>(),
                })
                                  .Where(x =>
                {
                    if (x.Mesh == null)
                    {
                        return(false);
                    }
                    if (x.Renderer.sharedMaterials == null ||
                        x.Renderer.sharedMaterials.Length == 0)
                    {
                        return(false);
                    }

                    return(true);
                })
                                  .ToList();

                var uniqueMeshes = new List <MeshWithRenderer>();
                foreach (var um in unityMeshes)
                {
                    if (!uniqueMeshes.Any(x => x.IsSameMeshAndMaterials(um)))
                    {
                        uniqueMeshes.Add(um);
                    }
                }

                MeshExporter.ExportMeshes(glTF, bufferIndex, uniqueMeshes, Materials, useSparseAccessorForMorphTarget, ExportOnlyBlendShapePosition);

                Meshes = unityMeshes.Select(x => x.Mesh).ToList();
                #endregion

                #region Nodes and Skins
                var unitySkins = Nodes
                                 .Select(x => x.GetComponent <SkinnedMeshRenderer>()).Where(x =>
                                                                                            x != null &&
                                                                                            x.bones != null &&
                                                                                            x.bones.Length > 0)
                                 .ToList();
                gltf.nodes  = Nodes.Select(x => ExportNode(x, Nodes, uniqueMeshes, unitySkins)).ToList();
                gltf.scenes = new List <gltfScene>
                {
                    new gltfScene
                    {
                        nodes = go.transform.GetChildren().Select(x => Nodes.IndexOf(x)).ToArray(),
                    }
                };

                foreach (var x in unitySkins)
                {
                    var matrices = x.sharedMesh.bindposes.Select(y => y.ReverseZ()).ToArray();
                    var accessor = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, matrices, glBufferTarget.NONE);

                    var skin = new glTFSkin
                    {
                        inverseBindMatrices = accessor,
                        joints   = x.bones.Select(y => Nodes.IndexOf(y)).ToArray(),
                        skeleton = Nodes.IndexOf(x.rootBone),
                    };
                    var skinIndex = gltf.skins.Count;
                    gltf.skins.Add(skin);

                    foreach (var z in Nodes.Where(y => y.Has(x)))
                    {
                        var nodeIndex = Nodes.IndexOf(z);
                        var node      = gltf.nodes[nodeIndex];
                        node.skin = skinIndex;
                    }
                }
                #endregion

#if UNITY_EDITOR
                #region Animations

                var clips     = new List <AnimationClip>();
                var animator  = go.GetComponent <Animator>();
                var animation = go.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, go.transform, Nodes);

                        foreach (var kv in animationWithCurve.SamplerMap)
                        {
                            var sampler = animationWithCurve.Animation.samplers[kv.Key];

                            var inputAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Input);
                            sampler.input = inputAccessorIndex;

                            var outputAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, 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
            }
            finally
            {
                if (tmpParent != null)
                {
                    tmpParent.transform.GetChild(0).SetParent(null);
                    if (Application.isPlaying)
                    {
                        GameObject.Destroy(tmpParent);
                    }
                    else
                    {
                        GameObject.DestroyImmediate(tmpParent);
                    }
                }
            }
        }
        /// <summary>
        /// Prepareで作ったCopyから、glTFにデータを変換する
        /// </summary>
        public virtual void Export()
        {
            var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]);
            var bufferIndex = glTF.AddBuffer(bytesBuffer);

            #region Materials and Textures

            var unityTextures = Materials.SelectMany(x => TextureIO.GetTextures(x)).Where(x => x.Texture != null)
                                .Distinct().ToList();

            TextureManager = new TextureExportManager(unityTextures.Select(x => x.Texture));

            var materialExporter = CreateMaterialExporter();
            glTF.materials = Materials.Select(x => materialExporter.ExportMaterial(x, TextureManager)).ToList();

            for (var i = 0; i < unityTextures.Count; ++i)
            {
                var unityTexture = unityTextures[i];
                TextureIO.ExportTexture(glTF, bufferIndex, TextureManager.GetExportTexture(i),
                                        unityTexture.TextureType);
            }

            #endregion

            if (Copy != null)
            {
                #region Meshes

                var unityMeshes = Nodes
                                  .Select(x => new MeshWithRenderer
                {
                    Mesh       = x.GetSharedMesh(),
                    Rendererer = x.GetComponent <Renderer>(),
                })
                                  .Where(x =>
                {
                    if (x.Mesh == null)
                    {
                        return(false);
                    }
                    if (x.Rendererer.sharedMaterials == null ||
                        x.Rendererer.sharedMaterials.Length == 0)
                    {
                        return(false);
                    }

                    return(true);
                })
                                  .ToList();
                MeshExporter.ExportMeshes(glTF, bufferIndex, unityMeshes, Materials, UseSparseAccessorForBlendShape);
                Meshes = unityMeshes.Select(x => x.Mesh).ToList();

                #endregion

                #region Nodes and Skins

                var unitySkins = Nodes
                                 .Select(x => x.GetComponent <SkinnedMeshRenderer>()).Where(x =>
                                                                                            x != null &&
                                                                                            x.bones != null &&
                                                                                            x.bones.Length > 0)
                                 .ToList();
                glTF.nodes = Nodes.Select(x =>
                                          ExportNode(x, Nodes, unityMeshes.Select(y => y.Rendererer).ToList(), unitySkins)).ToList();
                glTF.scenes = new List <gltfScene>
                {
                    new gltfScene
                    {
                        nodes = Copy.transform.GetChildren().Select(x => Nodes.IndexOf(x)).ToArray(),
                    }
                };

                foreach (var x in unitySkins)
                {
                    var matrices = x.sharedMesh.bindposes.Select(y => y.ReverseZ()).ToArray();
                    var accessor = glTF.ExtendBufferAndGetAccessorIndex(bufferIndex, matrices, glBufferTarget.NONE);

                    var skin = new glTFSkin
                    {
                        inverseBindMatrices = accessor,
                        joints   = x.bones.Select(y => Nodes.IndexOf(y)).ToArray(),
                        skeleton = Nodes.IndexOf(x.rootBone),
                    };
                    var skinIndex = glTF.skins.Count;
                    glTF.skins.Add(skin);

                    foreach (var z in Nodes.Where(y => y.Has(x)))
                    {
                        var nodeIndex = Nodes.IndexOf(z);
                        var node      = glTF.nodes[nodeIndex];
                        node.skin = skinIndex;
                    }
                }

                #endregion

#if UNITY_EDITOR
                #region Animations

                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 (var clip in clips)
                    {
                        var animationWithCurve = AnimationExporter.Export(clip, Copy.transform, Nodes);
                        AnimationExporter.WriteAnimationWithSampleCurves(glTF, animationWithCurve, clip.name, bufferIndex);
                    }
                }
                #endregion
#endif
            }
        }
Example #4
0
        /// <summary>
        /// Prepareで作ったCopyから、glTFにデータを変換する
        /// </summary>
        public virtual void Export()
        {
            var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]);
            var bufferIndex = glTF.AddBuffer(bytesBuffer);

            #region Materials and Textures

            var unityTextures = Materials.SelectMany(x => TextureIO.GetTextures(x)).Where(x => x.Texture != null)
                                .Distinct().ToList();

            TextureManager = new TextureExportManager(unityTextures.Select(x => x.Texture));

            var materialExporter = CreateMaterialExporter();
            glTF.materials = Materials.Select(x => materialExporter.ExportMaterial(x, TextureManager)).ToList();

            for (var i = 0; i < unityTextures.Count; ++i)
            {
                var unityTexture = unityTextures[i];
                TextureIO.ExportTexture(glTF, bufferIndex, TextureManager.GetExportTexture(i),
                                        unityTexture.TextureType);
            }

            #endregion

            if (Copy != null)
            {
                #region Meshes

                var unityMeshes = Nodes
                                  .Select(x => new MeshWithRenderer
                {
                    Mesh       = x.GetSharedMesh(),
                    Rendererer = x.GetComponent <Renderer>(),
                })
                                  .Where(x =>
                {
                    if (x.Mesh == null)
                    {
                        return(false);
                    }
                    if (x.Rendererer.sharedMaterials == null ||
                        x.Rendererer.sharedMaterials.Length == 0)
                    {
                        return(false);
                    }

                    return(true);
                })
                                  .ToList();
                MeshExporter.ExportMeshes(glTF, bufferIndex, unityMeshes, Materials, UseSparseAccessorForBlendShape);
                Meshes = unityMeshes.Select(x => x.Mesh).ToList();

                #endregion

                #region Nodes and Skins

                var unitySkins = Nodes
                                 .Select(x => x.GetComponent <SkinnedMeshRenderer>()).Where(x =>
                                                                                            x != null &&
                                                                                            x.bones != null &&
                                                                                            x.bones.Length > 0)
                                 .ToList();
                glTF.nodes = Nodes.Select(x =>
                                          ExportNode(x, Nodes, unityMeshes.Select(y => y.Rendererer).ToList(), unitySkins)).ToList();
                glTF.scenes = new List <gltfScene>
                {
                    new gltfScene
                    {
                        nodes = Copy.transform.GetChildren().Select(x => Nodes.IndexOf(x)).ToArray(),
                    }
                };

                foreach (var x in unitySkins)
                {
                    var matrices = x.sharedMesh.bindposes.Select(y => y.ReverseZ()).ToArray();
                    var accessor = glTF.ExtendBufferAndGetAccessorIndex(bufferIndex, matrices, glBufferTarget.NONE);

                    var skin = new glTFSkin
                    {
                        inverseBindMatrices = accessor,
                        joints   = x.bones.Select(y => Nodes.IndexOf(y)).ToArray(),
                        skeleton = Nodes.IndexOf(x.rootBone),
                    };
                    var skinIndex = glTF.skins.Count;
                    glTF.skins.Add(skin);

                    foreach (var z in Nodes.Where(y => y.Has(x)))
                    {
                        var nodeIndex = Nodes.IndexOf(z);
                        var node      = glTF.nodes[nodeIndex];
                        node.skin = skinIndex;
                    }
                }

                #endregion

#if UNITY_EDITOR
                #region Animations

                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 (var 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 = glTF.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Input);
                            sampler.input = inputAccessorIndex;

                            var outputAccessorIndex =
                                glTF.ExtendBufferAndGetAccessorIndex(bufferIndex, 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
            }
        }