Пример #1
0
        /// <summary>
        /// Merges the right root into the left root
        /// This function combines all of the lists of objects on each glTF root together and updates the relative indicies
        /// All properties all merged except Asset and Default, which will stay "mergeToRoot"'s value
        /// </summary>
        /// <param name="mergeToRoot">The node to merge into</param>
        /// <param name="mergeFromRoot">The node to merge from</param>
        public static void MergeGLTF(GLTFRoot mergeToRoot, GLTFRoot mergeFromRoot)
        {
            PreviousGLTFSizes previousGLTFSize = new PreviousGLTFSizes()
            {
                PreviousAccessorCount   = mergeToRoot.Accessors?.Count ?? 0,
                PreviousBufferCount     = mergeToRoot.Buffers?.Count ?? 0,
                PreviousAnimationCount  = mergeToRoot.Animations?.Count ?? 0,
                PreviousBufferViewCount = mergeToRoot.BufferViews?.Count ?? 0,
                PreviousCameraCount     = mergeToRoot.Cameras?.Count ?? 0,
                PreviousImageCount      = mergeToRoot.Images?.Count ?? 0,
                PreviousMaterialCount   = mergeToRoot.Materials?.Count ?? 0,
                PreviousMeshCount       = mergeToRoot.Meshes?.Count ?? 0,
                PreviousNodeCount       = mergeToRoot.Nodes?.Count ?? 0,
                PreviousSamplerCount    = mergeToRoot.Samplers?.Count ?? 0,
                PreviousSceneCount      = mergeToRoot.Scenes?.Count ?? 0,
                PreviousSkinCount       = mergeToRoot.Skins?.Count ?? 0,
                PreviousTextureCount    = mergeToRoot.Textures?.Count ?? 0
            };

            GLTFRoot mergeFromRootCopy = new GLTFRoot(mergeFromRoot);

            // for each type:
            // 1) add the right hand range to the left hand object
            // 2) update all ids to be based off of the appended size

            // merge extensions
            MergeExtensions(mergeToRoot, mergeFromRootCopy);

            // merge accessors, buffers, and bufferviews
            MergeAccessorsBufferViewsAndBuffers(mergeToRoot, mergeFromRootCopy, previousGLTFSize);

            // merge materials, samplers, images, and textures
            MergeMaterialsImagesTexturesAndSamplers(mergeToRoot, mergeFromRootCopy, previousGLTFSize);

            // merge meshes
            MergeMeshes(mergeToRoot, mergeFromRootCopy, previousGLTFSize);

            // merge cameras
            MergeCameras(mergeToRoot, mergeFromRootCopy);

            // merge nodes
            MergeNodes(mergeToRoot, mergeFromRootCopy, previousGLTFSize);

            // merge animation, and skin
            MergeAnimationsAndSkins(mergeToRoot, mergeFromRootCopy, previousGLTFSize);

            // merge scenes
            MergeScenes(mergeToRoot, mergeFromRootCopy, previousGLTFSize);
        }
Пример #2
0
        private static void MergeNodes(GLTFRoot mergeToRoot, GLTFRoot mergeFromRoot, PreviousGLTFSizes previousGLTFSizes)
        {
            if (mergeFromRoot.Nodes == null)
            {
                return;
            }

            if (mergeToRoot.Nodes == null)
            {
                mergeToRoot.Nodes = new List <Node>(mergeFromRoot.Nodes.Count);
            }

            mergeToRoot.Nodes.AddRange(mergeFromRoot.Nodes);

            for (int i = previousGLTFSizes.PreviousNodeCount; i < mergeToRoot.Nodes.Count; ++i)
            {
                Node node = mergeToRoot.Nodes[i];
                if (node.Mesh != null)
                {
                    MeshId meshId = node.Mesh;
                    meshId.Id     += previousGLTFSizes.PreviousMeshCount;
                    node.Mesh.Root = mergeToRoot;
                }

                if (node.Camera != null)
                {
                    CameraId cameraId = node.Camera;
                    cameraId.Id  += previousGLTFSizes.PreviousCameraCount;
                    cameraId.Root = mergeToRoot;
                }

                if (node.Children != null)
                {
                    foreach (NodeId child in node.Children)
                    {
                        child.Id  += previousGLTFSizes.PreviousNodeCount;
                        child.Root = mergeToRoot;
                    }
                }

                if (node.Skin != null)
                {
                    SkinId skinId = node.Skin;
                    skinId.Id  += previousGLTFSizes.PreviousSkinCount;
                    skinId.Root = mergeToRoot;
                }
            }
        }
Пример #3
0
        private static void MergeScenes(GLTFRoot mergeToRoot, GLTFRoot mergeFromRoot, PreviousGLTFSizes previousGLTFSizes)
        {
            if (mergeFromRoot.Scenes == null)
            {
                return;
            }

            if (mergeToRoot.Scenes == null)
            {
                mergeToRoot.Scenes = new List <Scene>(mergeFromRoot.Scenes.Count);
            }

            mergeToRoot.Scenes.AddRange(mergeFromRoot.Scenes);
            for (int i = previousGLTFSizes.PreviousSceneCount; i < mergeToRoot.Scenes.Count; ++i)
            {
                Scene scene = mergeToRoot.Scenes[i];
                foreach (NodeId nodeId in scene.Nodes)
                {
                    nodeId.Id  += previousGLTFSizes.PreviousNodeCount;
                    nodeId.Root = mergeToRoot;
                }
            }
        }
Пример #4
0
        private static void MergeAnimationsAndSkins(GLTFRoot mergeToRoot, GLTFRoot mergeFromRoot, PreviousGLTFSizes previousGLTFSizes)
        {
            if (mergeFromRoot.Skins != null)
            {
                if (mergeToRoot.Skins == null)
                {
                    mergeToRoot.Skins = new List <Skin>(mergeFromRoot.Skins.Count);
                }

                mergeToRoot.Skins.AddRange(mergeFromRoot.Skins);
                for (int i = previousGLTFSizes.PreviousSkinCount; i < mergeToRoot.Skins.Count; ++i)
                {
                    Skin skin = mergeToRoot.Skins[i];
                    if (skin.InverseBindMatrices != null)
                    {
                        skin.InverseBindMatrices.Id += previousGLTFSizes.PreviousAccessorCount;
                    }

                    if (skin.Skeleton != null)
                    {
                        skin.Skeleton.Id += previousGLTFSizes.PreviousNodeCount;
                    }

                    if (skin.Joints != null)
                    {
                        foreach (NodeId joint in skin.Joints)
                        {
                            joint.Id += previousGLTFSizes.PreviousNodeCount;
                        }
                    }
                }
            }

            if (mergeFromRoot.Animations != null)
            {
                if (mergeToRoot.Animations == null)
                {
                    mergeToRoot.Animations = new List <Animation>(mergeFromRoot.Animations.Count);
                }

                mergeToRoot.Animations.AddRange(mergeFromRoot.Animations);

                for (int i = previousGLTFSizes.PreviousAnimationCount; i < mergeToRoot.Animations.Count; ++i)
                {
                    Animation animation = mergeToRoot.Animations[i];
                    foreach (AnimationSampler sampler in animation.Samplers)
                    {
                        AccessorId inputId = sampler.Input;
                        inputId.Id  += previousGLTFSizes.PreviousAccessorCount;
                        inputId.Root = mergeToRoot;

                        AccessorId outputId = sampler.Output;
                        outputId.Id  += previousGLTFSizes.PreviousAccessorCount;
                        outputId.Root = mergeToRoot;
                    }

                    foreach (AnimationChannel channel in animation.Channels)
                    {
                        SamplerId samplerId = channel.Sampler;
                        samplerId.Id  += previousGLTFSizes.PreviousSamplerCount;
                        samplerId.Root = mergeToRoot;

                        NodeId nodeId = channel.Target.Node;
                        nodeId.Id  += previousGLTFSizes.PreviousNodeCount;
                        nodeId.Root = mergeToRoot;
                    }
                }
            }
        }
Пример #5
0
        private static void MergeMeshes(GLTFRoot mergeToRoot, GLTFRoot mergeFromRoot, PreviousGLTFSizes previousGLTFSizes)
        {
            if (mergeFromRoot.Meshes == null)
            {
                return;
            }

            if (mergeToRoot.Meshes == null)
            {
                mergeToRoot.Meshes = new List <Mesh>(mergeFromRoot.Meshes.Count);
            }

            mergeToRoot.Meshes.AddRange(mergeFromRoot.Meshes);
            for (int i = previousGLTFSizes.PreviousMeshCount; i < mergeToRoot.Meshes.Count; ++i)
            {
                Mesh mesh = mergeToRoot.Meshes[i];
                if (mesh.Primitives != null)
                {
                    foreach (MeshPrimitive primitive in mesh.Primitives)
                    {
                        foreach (var attributeAccessorPair in primitive.Attributes)
                        {
                            AccessorId accessorId = attributeAccessorPair.Value;
                            accessorId.Id  += previousGLTFSizes.PreviousAccessorCount;
                            accessorId.Root = mergeToRoot;
                        }

                        if (primitive.Indices != null)
                        {
                            AccessorId accessorId = primitive.Indices;
                            accessorId.Id  += previousGLTFSizes.PreviousAccessorCount;
                            accessorId.Root = mergeToRoot;
                        }

                        if (primitive.Material != null)
                        {
                            MaterialId materialId = primitive.Material;
                            materialId.Id  += previousGLTFSizes.PreviousMaterialCount;
                            materialId.Root = mergeToRoot;
                        }

                        if (primitive.Targets != null)
                        {
                            foreach (Dictionary <string, AccessorId> targetsDictionary in primitive.Targets)
                            {
                                foreach (var targetsPair in targetsDictionary)
                                {
                                    AccessorId accessorId = targetsPair.Value;
                                    accessorId.Id  += previousGLTFSizes.PreviousAccessorCount;
                                    accessorId.Root = mergeToRoot;
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #6
0
        private static void MergeMaterialsImagesTexturesAndSamplers(GLTFRoot mergeToRoot, GLTFRoot mergeFromRoot, PreviousGLTFSizes previousGLTFSizes)
        {
            if (mergeFromRoot.Samplers != null)
            {
                if (mergeToRoot.Samplers == null)
                {
                    mergeToRoot.Samplers = new List <Sampler>(mergeFromRoot.Samplers.Count);
                }

                mergeToRoot.Samplers.AddRange(mergeFromRoot.Samplers);
            }

            if (mergeFromRoot.Images != null)
            {
                if (mergeToRoot.Images == null)
                {
                    mergeToRoot.Images = new List <Image>(mergeFromRoot.Images.Count);
                }

                mergeToRoot.Images.AddRange(mergeFromRoot.Images);
                for (int i = previousGLTFSizes.PreviousImageCount; i < mergeToRoot.Images.Count; ++i)
                {
                    Image image = mergeToRoot.Images[i];
                    if (image.BufferView != null)
                    {
                        BufferViewId bufferViewId = image.BufferView;
                        bufferViewId.Id  += previousGLTFSizes.PreviousBufferViewCount;
                        bufferViewId.Root = mergeToRoot;
                    }
                }
            }

            if (mergeFromRoot.Textures != null)
            {
                if (mergeToRoot.Textures == null)
                {
                    mergeToRoot.Textures = new List <Texture>(mergeFromRoot.Textures.Count);
                }

                mergeToRoot.Textures.AddRange(mergeFromRoot.Textures);
                for (int i = previousGLTFSizes.PreviousTextureCount; i < mergeToRoot.Textures.Count; ++i)
                {
                    Texture texture = mergeToRoot.Textures[i];

                    if (texture.Sampler != null)
                    {
                        SamplerId samplerId = texture.Sampler;
                        samplerId.Id  += previousGLTFSizes.PreviousSamplerCount;
                        samplerId.Root = mergeToRoot;
                    }

                    if (texture.Source != null)
                    {
                        ImageId samplerId = texture.Source;
                        samplerId.Id  += previousGLTFSizes.PreviousImageCount;
                        samplerId.Root = mergeToRoot;
                    }
                }
            }

            if (mergeFromRoot.Materials != null)
            {
                if (mergeToRoot.Materials == null)
                {
                    mergeToRoot.Materials = new List <Material>(mergeFromRoot.Materials.Count);
                }

                mergeToRoot.Materials.AddRange(mergeFromRoot.Materials);
                for (int i = previousGLTFSizes.PreviousMaterialCount; i < mergeToRoot.Materials.Count; ++i)
                {
                    Material material = mergeToRoot.Materials[i];

                    PbrMetallicRoughness pbrMetallicRoughness = material.PbrMetallicRoughness;
                    if (pbrMetallicRoughness != null)
                    {
                        if (pbrMetallicRoughness.BaseColorTexture != null)
                        {
                            TextureId textureId = pbrMetallicRoughness.BaseColorTexture.Index;
                            textureId.Id  += previousGLTFSizes.PreviousTextureCount;
                            textureId.Root = mergeToRoot;
                        }
                        if (pbrMetallicRoughness.MetallicRoughnessTexture != null)
                        {
                            TextureId textureId = pbrMetallicRoughness.MetallicRoughnessTexture.Index;
                            textureId.Id  += previousGLTFSizes.PreviousTextureCount;
                            textureId.Root = mergeToRoot;
                        }
                    }

                    MaterialCommonConstant commonConstant = material.CommonConstant;
                    if (commonConstant?.LightmapTexture != null)
                    {
                        TextureId textureId = material.CommonConstant.LightmapTexture.Index;
                        textureId.Id  += previousGLTFSizes.PreviousTextureCount;
                        textureId.Root = mergeToRoot;
                    }

                    if (material.EmissiveTexture != null)
                    {
                        TextureId textureId = material.EmissiveTexture.Index;
                        material.EmissiveTexture.Index.Id += previousGLTFSizes.PreviousTextureCount;
                        textureId.Root = mergeToRoot;
                    }

                    if (material.NormalTexture != null)
                    {
                        TextureId textureId = material.NormalTexture.Index;
                        textureId.Id  += previousGLTFSizes.PreviousTextureCount;
                        textureId.Root = mergeToRoot;
                    }

                    if (material.OcclusionTexture != null)
                    {
                        TextureId textureId = material.OcclusionTexture.Index;
                        textureId.Id  += previousGLTFSizes.PreviousTextureCount;
                        textureId.Root = mergeToRoot;
                    }
                }
            }
        }
Пример #7
0
        private static void MergeAccessorsBufferViewsAndBuffers(GLTFRoot mergeToRoot, GLTFRoot mergeFromRoot, PreviousGLTFSizes previousGLTFSizes)
        {
            if (mergeFromRoot.Buffers != null)
            {
                if (mergeToRoot.Buffers == null)
                {
                    mergeToRoot.Buffers = new List <Buffer>(mergeFromRoot.Buffers.Count);
                }

                mergeToRoot.Buffers.AddRange(mergeFromRoot.Buffers);
            }

            if (mergeFromRoot.BufferViews != null)
            {
                if (mergeToRoot.BufferViews == null)
                {
                    mergeToRoot.BufferViews = new List <BufferView>(mergeFromRoot.BufferViews.Count);
                }

                mergeToRoot.BufferViews.AddRange(mergeFromRoot.BufferViews);
                for (int i = previousGLTFSizes.PreviousBufferViewCount; i < mergeToRoot.BufferViews.Count; ++i)
                {
                    GLTFId <Buffer> bufferId = mergeToRoot.BufferViews[i].Buffer;
                    bufferId.Id  += previousGLTFSizes.PreviousBufferCount;
                    bufferId.Root = mergeToRoot;
                }
            }

            if (mergeFromRoot.Accessors != null)
            {
                if (mergeToRoot.Accessors == null)
                {
                    mergeToRoot.Accessors = new List <Accessor>(mergeFromRoot.Accessors.Count);
                }

                mergeToRoot.Accessors.AddRange(mergeFromRoot.Accessors);
                for (int i = previousGLTFSizes.PreviousAccessorCount; i < mergeToRoot.Accessors.Count; ++i)
                {
                    Accessor accessor = mergeToRoot.Accessors[i];

                    if (accessor.BufferView != null)
                    {
                        BufferViewId bufferViewId = accessor.BufferView;
                        bufferViewId.Id  += previousGLTFSizes.PreviousBufferViewCount;
                        bufferViewId.Root = mergeToRoot;
                    }

                    AccessorSparse accessorSparse = accessor.Sparse;
                    if (accessorSparse != null)
                    {
                        BufferViewId indicesId = accessorSparse.Indices.BufferView;
                        indicesId.Id  += previousGLTFSizes.PreviousBufferViewCount;
                        indicesId.Root = mergeToRoot;

                        BufferViewId valuesId = accessorSparse.Values.BufferView;
                        valuesId.Id  += previousGLTFSizes.PreviousBufferViewCount;
                        valuesId.Root = mergeToRoot;
                    }
                }
            }
        }
Пример #8
0
        private static void MergeAccessorsBufferViewsAndBuffers(GLTFRoot mergeToRoot, GLTFRoot mergeFromRoot, PreviousGLTFSizes previousGLTFSizes)
        {
            bool isGLB = false;

            if (mergeFromRoot.Buffers != null)
            {
                if (mergeToRoot.Buffers == null)
                {
                    mergeToRoot.Buffers = new List <GLTFBuffer>(mergeFromRoot.Buffers.Count);
                }

                foreach (GLTFBuffer buffer in mergeFromRoot.Buffers)
                {
                    if (buffer.Uri != null)
                    {
                        mergeToRoot.Buffers.Add(buffer);
                    }
                    else
                    {
                        isGLB = true;                           // assume glb is a uri is null
                    }
                }
            }

            if (mergeFromRoot.BufferViews != null)
            {
                if (mergeToRoot.BufferViews == null)
                {
                    mergeToRoot.BufferViews = new List <BufferView>(mergeFromRoot.BufferViews.Count);
                }

                mergeToRoot.BufferViews.AddRange(mergeFromRoot.BufferViews);
                for (int i = previousGLTFSizes.PreviousBufferViewCount; i < mergeToRoot.BufferViews.Count; ++i)
                {
                    GLTFId <GLTFBuffer> bufferId = mergeToRoot.BufferViews[i].Buffer;
                    if (!(isGLB && bufferId.Id == 0))   // if it is pointing a the special glb buffer (index 0 of a glb) then we dont want to adjust the buffer view, otherwise we do
                    {
                        // adjusting bufferview id based on merge amount
                        bufferId.Id  += previousGLTFSizes.PreviousBufferCount;
                        bufferId.Root = mergeToRoot;
                    }
                }
            }

            if (mergeFromRoot.Accessors != null)
            {
                if (mergeToRoot.Accessors == null)
                {
                    mergeToRoot.Accessors = new List <Accessor>(mergeFromRoot.Accessors.Count);
                }

                mergeToRoot.Accessors.AddRange(mergeFromRoot.Accessors);
                for (int i = previousGLTFSizes.PreviousAccessorCount; i < mergeToRoot.Accessors.Count; ++i)
                {
                    Accessor accessor = mergeToRoot.Accessors[i];

                    if (accessor.BufferView != null)
                    {
                        BufferViewId bufferViewId = accessor.BufferView;
                        bufferViewId.Id  += previousGLTFSizes.PreviousBufferViewCount;
                        bufferViewId.Root = mergeToRoot;
                    }

                    AccessorSparse accessorSparse = accessor.Sparse;
                    if (accessorSparse != null)
                    {
                        BufferViewId indicesId = accessorSparse.Indices.BufferView;
                        indicesId.Id  += previousGLTFSizes.PreviousBufferViewCount;
                        indicesId.Root = mergeToRoot;

                        BufferViewId valuesId = accessorSparse.Values.BufferView;
                        valuesId.Id  += previousGLTFSizes.PreviousBufferViewCount;
                        valuesId.Root = mergeToRoot;
                    }
                }
            }
        }