Exemple #1
0
        private static int RecursivelyCopyNode(List <Node> nodes, ProtoNode nodeToCopy)
        {
            var newNode = new Node();

            newNode.Matrix = nodeToCopy.Matrix;
            if (nodeToCopy.Mesh != null)
            {
                newNode.Mesh = nodeToCopy.Mesh;
            }
            nodes.Add(newNode);
            var nodeIndex = nodes.Count - 1;

            var childIndices = new List <int>();

            foreach (var child in nodeToCopy.Children)
            {
                childIndices.Add(RecursivelyCopyNode(nodes, child));
            }
            if (childIndices.Count > 0)
            {
                newNode.Children = childIndices.ToArray();
            }

            return(nodeIndex);
        }
Exemple #2
0
        /// <summary>
        /// We construct a new, recursively-structured 'ProtoNode' from the flat gltf node, and mutate its mesh indices to
        /// point to the correct mesh in the merged gltf.
        /// </summary>
        private static ProtoNode RecursivelyModifyMeshIndices(glTFLoader.Schema.Node node, List <int> meshIndices, glTFLoader.Schema.Node[] loadedNodes)
        {
            var protoNode = new ProtoNode();

            protoNode.Matrix = node.Matrix;
            if (node.Mesh != null)
            {
                protoNode.Mesh = meshIndices[node.Mesh.Value];
            }
            if (node.Children != null && node.Children.Count() > 0)
            {
                foreach (var child in node.Children)
                {
                    protoNode.Children.Add(RecursivelyModifyMeshIndices(loadedNodes[child], meshIndices, loadedNodes));
                }
            }
            return(protoNode);
        }
Exemple #3
0
        internal static void AddInstanceAsCopyOfNode(
            List <glTFLoader.Schema.Node> nodes,
            ProtoNode nodeToCopy,
            Transform transform,
            System.Guid instanceElementId)
        {
            // Two new nodes are created: a top-level node, which has the
            // element's Transform, and one just below that, which handles
            // flipping the orientation of the glb to have Z up. That node has
            // the node to copy as its only child.
            // We use the node to copy exactly as is, with an unmodified
            // transform.
            // We need the outermost node to be "purely" the element's
            // transform, so that the transform can be modified in explore at
            // runtime (e.g. by a transform override) and have the expected effect.
            float[] elementTransform = TransformToMatrix(transform);
            var     newNode          = new glTFLoader.Schema.Node();

            newNode.Name   = $"{instanceElementId}";
            newNode.Matrix = elementTransform;
            nodes.Add(newNode);
            newNode.Children = new[] { nodes.Count };

            var rootTransform = new Transform();

            // glb has Y up. transform it to have Z up so we
            // can create instances of it in a Z up world. It will get switched
            // back to Y up further up in the node hierarchy.
            rootTransform.Rotate(new Vector3(1, 0, 0), 90.0);
            float[] glbOrientationTransform = TransformToMatrix(rootTransform);
            var     elementOrientationNode  = new glTFLoader.Schema.Node();

            elementOrientationNode.Matrix = glbOrientationTransform;
            nodes.Add(elementOrientationNode);
            elementOrientationNode.Children = new[] { nodes.Count };

            nodes[0].Children = (nodes[0].Children ?? Array.Empty <int>()).Concat(new[] { nodes.Count - 2 }).ToArray();

            RecursivelyCopyNode(nodes, nodeToCopy);
        }
Exemple #4
0
        public static List <int> AddAllMeshesFromFromGlb(Stream glbStream,
                                                         List <Buffer> buffers,
                                                         List <byte[]> bufferByteArrays,
                                                         List <BufferView> bufferViews,
                                                         List <Accessor> accessors,
                                                         List <glTFLoader.Schema.Mesh> meshes,
                                                         List <glTFLoader.Schema.Material> materials,
                                                         List <Texture> textures,
                                                         List <Image> images,
                                                         List <Sampler> samplers,
                                                         bool shouldAddMaterials,
                                                         System.Guid contentElementId,
                                                         out ProtoNode parentNode
                                                         )
        {
            var loadingStream = new MemoryStream();

            glbStream.Position = 0;
            glbStream.CopyTo(loadingStream);
            loadingStream.Position = 0;
            var loaded        = Interface.LoadModel(loadingStream);
            var newByteArrays = loaded.GetAllBufferByteArrays(glbStream);

            bufferByteArrays.AddRange(newByteArrays);

            var bufferIncrement = buffers.Count;

            foreach (var originBuffer in loaded.Buffers)
            {
                buffers.Add(originBuffer);
            }

            var buffViewIncrement = bufferViews.Count;

            foreach (var originBuffView in loaded.BufferViews)
            {
                originBuffView.Buffer = originBuffView.Buffer + bufferIncrement;
                bufferViews.Add(originBuffView);
            }

            var accessorIncrement = accessors.Count;

            foreach (var originAccessor in loaded.Accessors)
            {
                originAccessor.BufferView = originAccessor.BufferView + buffViewIncrement;
                accessors.Add(originAccessor);
            }

            var imageIncrement = images.Count;

            if (loaded.Images != null)
            {
                foreach (var originImage in loaded.Images)
                {
                    if (originImage.BufferView.HasValue)
                    {
                        originImage.BufferView = originImage.BufferView + buffViewIncrement;
                    }
                    images.Add(originImage);
                }
            }

            var samplerIncrement = samplers.Count;

            if (loaded.Samplers != null)
            {
                foreach (var originSampler in loaded.Samplers)
                {
                    samplers.Add(originSampler);
                }
            }

            var textureIncrement = textures.Count;

            if (loaded.Textures != null)
            {
                foreach (var originTexture in loaded.Textures)
                {
                    originTexture.Source = originTexture.Source + imageIncrement;
                    if (originTexture.Sampler.HasValue)
                    {
                        originTexture.Sampler = originTexture.Sampler + samplerIncrement;
                    }
                    textures.Add(originTexture);
                }
            }


            var materialIncrement = materials.Count;

            if (shouldAddMaterials)
            {
                AddMaterials(materials, loaded, textureIncrement);
            }

            var meshIndices = new List <int>();

            foreach (var originMesh in loaded.Meshes)
            {
                foreach (var prim in originMesh.Primitives)
                {
                    var attributes = new Dictionary <string, int>();
                    foreach (var kvp in prim.Attributes)
                    {
                        attributes[kvp.Key] = kvp.Value + accessorIncrement;
                    }
                    prim.Attributes = attributes;
                    prim.Indices    = prim.Indices + accessorIncrement;
                    if (shouldAddMaterials)
                    {
                        prim.Material = prim.Material + materialIncrement;
                    }
                    else
                    {
                        prim.Material = 0;  // This assumes that the default material is at index 0
                    }
                }
                originMesh.Name = $"{contentElementId}_mesh";
                meshes.Add(originMesh);
                meshIndices.Add(meshes.Count - 1);
            }

            var topNode = loaded.Nodes[loaded.Scenes[0].Nodes[0]];

            parentNode        = RecursivelyModifyMeshIndices(topNode, meshIndices, loaded.Nodes);
            parentNode.Matrix = topNode.Matrix;

            return(meshIndices);
        }