示例#1
0
        private glTFLoader.Schema.Image GetImageFromBitmapText(Bitmap bitmap)
        {
            byte[] imageBytes = GetImageBytes(bitmap);

            var textureBuffer = new glTFLoader.Schema.Buffer();

            textureBuffer.Uri        = Constants.TextBufferHeader + Convert.ToBase64String(imageBytes);
            textureBuffer.ByteLength = imageBytes.Length;

            int textureBufferIdx = dummy.Buffers.AddAndReturnIndex(textureBuffer);

            // Create bufferviews
            var textureBufferView = new BufferView()
            {
                Buffer     = textureBufferIdx,
                ByteOffset = 0,
                ByteLength = textureBuffer.ByteLength,
            };
            int textureBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(textureBufferView);

            return(new glTFLoader.Schema.Image()
            {
                BufferView = textureBufferViewIdx,
                MimeType = glTFLoader.Schema.Image.MimeTypeEnum.image_png,
            });
        }
示例#2
0
        private glTFLoader.Schema.Image GetImageFromFileText(string fileName)
        {
            byte[] imageBytes = GetImageBytesFromFile(fileName);

            var textureBuffer = new glTFLoader.Schema.Buffer()
            {
                Uri        = Constants.TextBufferHeader + Convert.ToBase64String(imageBytes),
                ByteLength = imageBytes.Length,
            };

            int textureBufferIdx = dummy.Buffers.AddAndReturnIndex(textureBuffer);

            var textureBufferView = new glTFLoader.Schema.BufferView()
            {
                Buffer     = textureBufferIdx,
                ByteOffset = 0,
                ByteLength = textureBuffer.ByteLength,
            };
            int textureBufferViewIdx = dummy.BufferViews.AddAndReturnIndex(textureBufferView);

            return(new glTFLoader.Schema.Image()
            {
                BufferView = textureBufferViewIdx,
                MimeType = glTFLoader.Schema.Image.MimeTypeEnum.image_png,
            });
        }
示例#3
0
        private Gltf InitializeGlTF()
        {
            var gltf  = new Gltf();
            var asset = new Asset();

            asset.Version   = "2.0";
            asset.Generator = "hypar-gltf";

            gltf.Asset = asset;

            var root = new Node();

            root.Translation = new[] { 0.0f, 0.0f, 0.0f };
            root.Scale       = new[] { 1.0f, 1.0f, 1.0f };

            // Set Z up by rotating -90d around the X Axis
            var q = new Quaternion(new Vector3(1, 0, 0), -Math.PI / 2);

            root.Rotation = new[] {
                (float)q.X, (float)q.Y, (float)q.Z, (float)q.W
            };

            gltf.Nodes = new[] { root };

            gltf.Scene = 0;
            var scene = new Scene();

            scene.Nodes = new[] { 0 };
            gltf.Scenes = new[] { scene };

            gltf.ExtensionsUsed = new[] { "KHR_materials_pbrSpecularGlossiness" };

            var materialsToAdd = this._materials.Values.ToList();

            materialsToAdd.Add(BuiltInMaterials.XAxis);
            materialsToAdd.Add(BuiltInMaterials.YAxis);
            materialsToAdd.Add(BuiltInMaterials.ZAxis);
            materialsToAdd.Add(BuiltInMaterials.Edges);
            materialsToAdd.Add(BuiltInMaterials.EdgesHighlighted);

            var materials = gltf.AddMaterials(materialsToAdd);

            var lines = new List <Vector3>();

            foreach (var kvp in this._elements)
            {
                var e = kvp.Value;
                GetRenderDataForElement(e, gltf, materials, lines);
            }

            AddLines(100000, lines.ToArray(), gltf, materials[BuiltInMaterials.Edges.Name], null);

            var buff = new glTFLoader.Schema.Buffer();

            buff.ByteLength = _buffer.Count();
            gltf.Buffers    = new[] { buff };

            return(gltf);
        }
示例#4
0
文件: Model.cs 项目: vdubya/elements
        private Gltf InitializeGlTF()
        {
            var gltf  = new Gltf();
            var asset = new Asset();

            asset.Version   = "2.0";
            asset.Generator = "hypar-gltf";

            gltf.Asset = asset;

            var root = new Node();

            // root.Matrix = new float[]{1.0f,0.0f,0.0f,0.0f,
            //                 0.0f,0.0f,-1.0f,0.0f,
            //                 0.0f,1.0f,0.0f,0.0f,
            //                 0.0f,0.0f,0.0f,1.0f};

            root.Translation = new[] { 0.0f, 0.0f, 0.0f };
            root.Scale       = new[] { 1.0f, 1.0f, 1.0f };

            // Set Z up by rotating -90d around the X Axis
            var q = new Quaternion(new Vector3(1, 0, 0), -Math.PI / 2);

            root.Rotation = new[] {
                (float)q.X, (float)q.Y, (float)q.Z, (float)q.W
            };

            gltf.Nodes = new[] { root };

            gltf.Scene = 0;
            var scene = new Scene();

            scene.Nodes = new[] { 0 };
            gltf.Scenes = new[] { scene };

            gltf.ExtensionsUsed = new[] { "KHR_materials_pbrSpecularGlossiness" };

            var materials = new Dictionary <string, int>();

            foreach (var kvp in this._materials)
            {
                var m   = kvp.Value;
                var mId = gltf.AddMaterial(m.Name, m.Color.Red, m.Color.Green, m.Color.Blue, m.Color.Alpha, m.SpecularFactor, m.GlossinessFactor);
                materials.Add(m.Name, mId);
            }

            foreach (var kvp in this._elements)
            {
                var e = kvp.Value;
                GetRenderDataForElement(e, gltf, materials);
            }

            var buff = new glTFLoader.Schema.Buffer();

            buff.ByteLength = _buffer.Count();
            gltf.Buffers    = new[] { buff };

            return(gltf);
        }
示例#5
0
        private static void AddMesh(gltf.Gltf gltf, XbimMesher mesh)
        {
            gltf.Buffers = new glTFLoader.Schema.Buffer[1];
            var buf = new glTFLoader.Schema.Buffer();

            gltf.Buffers[0]  = buf;
            gltf.BufferViews = new gltf.BufferView[2];
        }
示例#6
0
        private static Byte[] TryLoadBase64BinaryBufferUnchecked(Schema.Buffer buffer, string prefix)
        {
            if (buffer.Uri == null || !buffer.Uri.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
            {
                return(null);
            }

            var content = buffer.Uri.Substring(prefix.Length);

            return(Convert.FromBase64String(content));
        }
示例#7
0
        private static Byte[] LoadBinaryBufferUnchecked(Schema.Buffer buffer, Func <string, Byte[]> externalReferenceSolver)
        {
            if (buffer.Uri == null)
            {
                return(externalReferenceSolver(null));
            }

            if (buffer.Uri.StartsWith(EMBEDDEDOCTETSTREAM))
            {
                var content = buffer.Uri.Substring(EMBEDDEDOCTETSTREAM.Length);
                return(Convert.FromBase64String(content));
            }

            return(externalReferenceSolver(buffer.Uri));
        }
        private static byte[] ReadBuffer(glTFLoader.Schema.Buffer buffer)
        {
            var match = Regex.Match(buffer.Uri, @"data:application/octet-stream;base64,(?<data>.+)");

            if (match.Success)
            {
                var base64Data = match.Groups["data"].Value;
                var binData    = Convert.FromBase64String(base64Data);
                if (binData.Length != buffer.ByteLength)
                {
                    throw new FormatException("Buffer has wrong length");
                }
                return(binData);
            }
            throw new FormatException("Only support inline encoded buffers, not external buffer files.");
        }
示例#9
0
 public void WriteDracoBytes(byte[] bytes, out int bufferIndex, out int byteOffset)
 {
     if (binary)
     {
         byteOffset = (int)binaryBuffer.Count;
         binaryBuffer.AddRange(bytes);
         bufferIndex = 0;
     }
     else
     {
         glTFLoader.Schema.Buffer buffer = new glTFLoader.Schema.Buffer()
         {
             Uri        = Constants.TextBufferHeader + Convert.ToBase64String(bytes),
             ByteLength = bytes.Length,
         };
         bufferIndex = dummy.Buffers.AddAndReturnIndex(buffer);
         byteOffset  = 0;
     }
 }
示例#10
0
        internal static void ToGlb(this Solid solid, string path)
        {
            var gltf  = new Gltf();
            var asset = new Asset();

            asset.Version   = "2.0";
            asset.Generator = "hypar-gltf";

            gltf.Asset = asset;

            var root = new Node();

            root.Translation = new[] { 0.0f, 0.0f, 0.0f };
            root.Scale       = new[] { 1.0f, 1.0f, 1.0f };

            // Set Z up by rotating -90d around the X Axis
            var q = new Quaternion(new Vector3(1, 0, 0), -Math.PI / 2);

            root.Rotation = new[] {
                (float)q.X, (float)q.Y, (float)q.Z, (float)q.W
            };

            gltf.Nodes = new[] { root };

            gltf.Scene = 0;
            var scene = new Scene();

            scene.Nodes = new[] { 0 };
            gltf.Scenes = new[] { scene };

            gltf.ExtensionsUsed = new[] { "KHR_materials_pbrSpecularGlossiness" };

            var materials = gltf.AddMaterials(new[] { BuiltInMaterials.Default, BuiltInMaterials.Edges, BuiltInMaterials.EdgesHighlighted });

            var buffer = new List <byte>();
            var mesh   = new Elements.Geometry.Mesh();

            solid.Tessellate(ref mesh);

            gltf.AddTriangleMesh("mesh", buffer, mesh.Vertices.ToArray(), mesh.Normals.ToArray(),
                                 mesh.Indices.ToArray(), mesh.VertexColors.ToArray(),
                                 mesh.VMin, mesh.VMax, mesh.NMin, mesh.NMax, mesh.CMin, mesh.CMax,
                                 mesh.IMin, mesh.IMax, materials[BuiltInMaterials.Default.Name], null, null);

            var edgeCount           = 0;
            var vertices            = new List <Vector3>();
            var verticesHighlighted = new List <Vector3>();

            foreach (var e in solid.Edges.Values)
            {
                if (e.Left.Loop == null || e.Right.Loop == null)
                {
                    verticesHighlighted.AddRange(new[] { e.Left.Vertex.Point, e.Right.Vertex.Point });
                }
                else
                {
                    vertices.AddRange(new[] { e.Left.Vertex.Point, e.Right.Vertex.Point });
                }

                edgeCount++;
            }

            if (vertices.Count > 0)
            {
                // Draw standard edges
                var vBuff  = vertices.ToArray().ToArray();
                var vCount = vertices.Count;
                // var indices = Enumerable.Range(0, vCount).Select(i => (ushort)i).ToArray();
                var indices = new List <ushort>();
                for (var i = 0; i < vertices.Count; i += 2)
                {
                    indices.Add((ushort)i);
                    indices.Add((ushort)(i + 1));
                }
                var bbox = new BBox3(vertices.ToArray());
                gltf.AddLineLoop($"edge_{edgeCount}", buffer, vBuff, indices.ToArray(), bbox.Min.ToArray(), bbox.Max.ToArray(), 0, (ushort)(vCount - 1), materials[BuiltInMaterials.Edges.Name], MeshPrimitive.ModeEnum.LINES, null);
            }

            if (verticesHighlighted.Count > 0)
            {
                // Draw highlighted edges
                var vBuff   = vertices.ToArray().ToArray();
                var vCount  = vertices.Count;
                var indices = new List <ushort>();
                for (var i = 0; i < vertices.Count; i += 2)
                {
                    indices.Add((ushort)i);
                    indices.Add((ushort)(i + 1));
                }
                var bbox = new BBox3(vertices.ToArray());
                gltf.AddLineLoop($"edge_{edgeCount}", buffer, vBuff, indices.ToArray(), bbox.Min.ToArray(), bbox.Max.ToArray(), 0, (ushort)(vCount - 1), materials[BuiltInMaterials.EdgesHighlighted.Name], MeshPrimitive.ModeEnum.LINES, null);
            }

            var buff = new glTFLoader.Schema.Buffer();

            buff.ByteLength = buffer.Count;
            gltf.Buffers    = new[] { buff };

            if (File.Exists(path))
            {
                File.Delete(path);
            }

            gltf.SaveBinaryModel(buffer.ToArray(), path);
        }
示例#11
0
        private static Gltf InitializeGlTF(Model model, List <byte> buffer)
        {
            var sw = new Stopwatch();

            sw.Start();

            var gltf  = new Gltf();
            var asset = new Asset();

            asset.Version   = "2.0";
            asset.Generator = "hypar-gltf";

            gltf.Asset = asset;

            var root = new Node();

            root.Translation = new[] { 0.0f, 0.0f, 0.0f };
            root.Scale       = new[] { 1.0f, 1.0f, 1.0f };

            // Set Z up by rotating -90d around the X Axis
            var q = new Quaternion(new Vector3(1, 0, 0), -Math.PI / 2);

            root.Rotation = new[] {
                (float)q.X, (float)q.Y, (float)q.Z, (float)q.W
            };

            gltf.Nodes = new[] { root };

            gltf.Scene = 0;
            var scene = new Scene();

            scene.Nodes = new[] { 0 };
            gltf.Scenes = new[] { scene };

            gltf.ExtensionsUsed = new[] { "KHR_materials_pbrSpecularGlossiness" };

            sw.Stop();
            Console.WriteLine($"glTF: {sw.Elapsed} elapsed for writing root node.");
            sw.Reset();

            sw.Start();
            var materialsToAdd = model.Materials.Values.ToList();

            materialsToAdd.Add(BuiltInMaterials.XAxis);
            materialsToAdd.Add(BuiltInMaterials.YAxis);
            materialsToAdd.Add(BuiltInMaterials.ZAxis);
            materialsToAdd.Add(BuiltInMaterials.Edges);
            materialsToAdd.Add(BuiltInMaterials.EdgesHighlighted);

            var materials = gltf.AddMaterials(materialsToAdd);

            sw.Stop();
            Console.WriteLine($"glTF: {sw.Elapsed} elapsed for writing materials.");
            sw.Reset();

            sw.Start();
            // Lines are stored in a list of lists
            // according to the max available index size of ushort.
            var lines = new List <List <Vector3> >()
            {
                new List <Vector3>()
            };

            var bufferViews = new List <BufferView>();
            var accessors   = new List <Accessor>();

            var elements = model.Elements.Values.ToArray();

            for (var i = 0; i < elements.Length; i++)
            {
                var e = elements[i];
                GetRenderDataForElement(e, gltf, materials, lines, buffer, bufferViews, accessors);
            }
            sw.Stop();
            Console.WriteLine($"glTF: {sw.Elapsed} elapsed for getting render data for nodes.");
            sw.Reset();

            sw.Start();
            if (lines.Count > 0)
            {
                foreach (var lineSet in lines)
                {
                    if (lineSet.Count > 0)
                    {
                        AddLines(100000, lineSet.ToArray(), gltf, materials[BuiltInMaterials.Edges.Name], buffer, bufferViews, accessors);
                    }
                }
            }
            sw.Stop();
            Console.WriteLine($"glTF: {sw.Elapsed} elapsed for writing edges.");
            sw.Reset();

            sw.Start();
            var buff = new glTFLoader.Schema.Buffer();

            buff.ByteLength = buffer.Count();
            gltf.Buffers    = new[] { buff };
            sw.Stop();
            Console.WriteLine($"glTF: {sw.Elapsed} elapsed for assigning buffer.");
            sw.Reset();

            gltf.BufferViews = bufferViews.ToArray();
            gltf.Accessors   = accessors.ToArray();

            return(gltf);
        }
示例#12
0
        internal static void ToGlb(this Solid solid, string path)
        {
            var gltf  = new Gltf();
            var asset = new Asset();

            asset.Version   = "2.0";
            asset.Generator = "hypar-gltf";

            gltf.Asset = asset;

            var root = new Node();

            root.Translation = new[] { 0.0f, 0.0f, 0.0f };
            root.Scale       = new[] { 1.0f, 1.0f, 1.0f };

            // Set Z up by rotating -90d around the X Axis
            var q = new Quaternion(new Vector3(1, 0, 0), -Math.PI / 2);

            root.Rotation = new[] {
                (float)q.X, (float)q.Y, (float)q.Z, (float)q.W
            };

            gltf.Nodes = new[] { root };

            gltf.Scene = 0;
            var scene = new Scene();

            scene.Nodes = new[] { 0 };
            gltf.Scenes = new[] { scene };

            gltf.ExtensionsUsed = new[] { "KHR_materials_pbrSpecularGlossiness" };

            var materials = gltf.AddMaterials(new[] { BuiltInMaterials.Default, BuiltInMaterials.Edges, BuiltInMaterials.EdgesHighlighted });

            var buffer = new List <byte>();
            var mesh   = new Elements.Geometry.Mesh();

            solid.Tessellate(ref mesh);

            byte[]   vertexBuffer;
            byte[]   normalBuffer;
            byte[]   indexBuffer;
            byte[]   colorBuffer;
            double[] vmin; double[] vmax;
            double[] nmin; double[] nmax;
            float[]  cmin; float[] cmax;
            ushort   imin; ushort imax;

            mesh.GetBuffers(out vertexBuffer, out indexBuffer, out normalBuffer, out colorBuffer,
                            out vmax, out vmin, out nmin, out nmax, out cmin,
                            out cmax, out imin, out imax);

            var bufferViews = new List <BufferView>();
            var accessors   = new List <Accessor>();

            gltf.AddTriangleMesh("mesh", buffer, bufferViews, accessors, vertexBuffer, normalBuffer,
                                 indexBuffer, colorBuffer, vmin, vmax, nmin, nmax,
                                 imin, imax, materials[BuiltInMaterials.Default.Name], cmin, cmax, null, null);

            var edgeCount           = 0;
            var vertices            = new List <Vector3>();
            var verticesHighlighted = new List <Vector3>();

            foreach (var e in solid.Edges.Values)
            {
                if (e.Left.Loop == null || e.Right.Loop == null)
                {
                    verticesHighlighted.AddRange(new[] { e.Left.Vertex.Point, e.Right.Vertex.Point });
                }
                else
                {
                    vertices.AddRange(new[] { e.Left.Vertex.Point, e.Right.Vertex.Point });
                }

                edgeCount++;
            }

            if (vertices.Count > 0)
            {
                // Draw standard edges
                AddLines(100000, vertices.ToArray(), gltf, materials[BuiltInMaterials.Edges.Name], buffer, bufferViews, accessors);
            }

            if (verticesHighlighted.Count > 0)
            {
                // Draw highlighted edges
                AddLines(100001, verticesHighlighted.ToArray(), gltf, materials[BuiltInMaterials.EdgesHighlighted.Name], buffer, bufferViews, accessors);
            }

            var buff = new glTFLoader.Schema.Buffer();

            buff.ByteLength = buffer.Count;
            gltf.Buffers    = new[] { buff };

            gltf.BufferViews = bufferViews.ToArray();
            gltf.Accessors   = accessors.ToArray();

            if (File.Exists(path))
            {
                File.Delete(path);
            }

            gltf.SaveBinaryModel(buffer.ToArray(), path);
        }
示例#13
0
		static byte[] loadDataUri (GL.Buffer buff) {
			int idxComa = buff.Uri.IndexOf (",", 5, StringComparison.Ordinal);
			return Convert.FromBase64String (buff.Uri.Substring (idxComa + 1));
		}
示例#14
0
        private static Gltf InitializeGlTF(Model model, List <byte> buffer, bool drawEdges = false)
        {
            var gltf  = new Gltf();
            var asset = new Asset();

            asset.Version   = "2.0";
            asset.Generator = "hypar-gltf";

            gltf.Asset = asset;

            var root = new Node();

            var rootTransform = new Transform(model.Transform);

            // Rotate the transform for +Z up.
            rootTransform.Rotate(new Vector3(1, 0, 0), -90.0);
            var m = rootTransform.Matrix;

            root.Matrix = new float[] {
                (float)m.m11, (float)m.m12, (float)m.m13, 0f,
                (float)m.m21, (float)m.m22, (float)m.m23, 0f,
                (float)m.m31, (float)m.m32, (float)m.m33, 0f,
                (float)m.tx, (float)m.ty, (float)m.tz, 1f
            };

            var nodes = new List <glTFLoader.Schema.Node> {
                root
            };
            var meshes = new List <glTFLoader.Schema.Mesh>();

            gltf.Scene = 0;
            var scene = new Scene();

            scene.Nodes = new[] { 0 };
            gltf.Scenes = new[] { scene };

            gltf.ExtensionsUsed = new[] {
                "KHR_materials_pbrSpecularGlossiness",
                "KHR_materials_unlit",
                "KHR_lights_punctual"
            };

            var bufferViews = new List <BufferView>();
            var accessors   = new List <Accessor>();

            var materialsToAdd = model.AllElementsOfType <Material>().ToList();

            if (drawEdges)
            {
                materialsToAdd.Add(BuiltInMaterials.Edges);
            }
            var materials = gltf.AddMaterials(materialsToAdd, buffer, bufferViews);

            var elements = model.Elements.Where(e =>
            {
                return(e.Value is GeometricElement || e.Value is ElementInstance);
            }).Select(e => e.Value).ToList();

            var lights = model.AllElementsOfType <DirectionalLight>().ToList();

            gltf.AddLights(lights, nodes);

            // Lines are stored in a list of lists
            // according to the max available index size.
            var lines     = new List <List <Vector3> >();
            var currLines = new List <Vector3>();

            lines.Add(currLines);

            var meshElementMap = new Dictionary <Guid, List <int> >();

            foreach (var e in elements)
            {
                // Check if we'll overrun the index size
                // for the current line array. If so,
                // create a new line array.
                if (currLines.Count * 2 > ushort.MaxValue)
                {
                    currLines = new List <Vector3>();
                    lines.Add(currLines);
                }

                GetRenderDataForElement(e,
                                        gltf,
                                        materials,
                                        buffer,
                                        bufferViews,
                                        accessors,
                                        meshes,
                                        nodes,
                                        meshElementMap,
                                        currLines,
                                        drawEdges);
            }
            if (buffer.Count == 0 && lights.Count == 0)
            {
                return(null);
            }

            if (drawEdges && lines.Count() > 0)
            {
                foreach (var lineSet in lines)
                {
                    if (lineSet.Count == 0)
                    {
                        continue;
                    }
                    AddLines(GetNextId(), lineSet, gltf, materials[BuiltInMaterials.Edges.Name], buffer, bufferViews, accessors, meshes, nodes, false);
                }
            }

            var buff = new glTFLoader.Schema.Buffer();

            buff.ByteLength  = buffer.Count;
            gltf.Buffers     = new[] { buff };
            gltf.BufferViews = bufferViews.ToArray();
            gltf.Accessors   = accessors.ToArray();
            gltf.Nodes       = nodes.ToArray();
            if (meshes.Count > 0)
            {
                gltf.Meshes = meshes.ToArray();
            }

            return(gltf);
        }
示例#15
0
        public Gltf FromBrg(BrgFile brg, Stream bufferStream)
        {
            // TODO clear class fields

            gltf.Asset         = new Asset();
            gltf.Asset.Version = "2.0";

            Scene scene = new Scene();

            scene.Nodes = new int[] { 0 };

            gltf.Scenes = new[] { scene };
            gltf.Scene  = 0;

            Node node = new Node();

            node.Mesh = 0;
            node.Name = "node";

            gltf.Nodes = new[] { node };

            //FromBrgMesh(brg.Meshes[0]);

            // Create materials / textures

            // Create primitives from first brg mesh
            // TODO: check if there is at least 1 mesh, and 1 face
            var primitives = (from face in brg.Meshes[0].Faces
                              group face by face.MaterialIndex into faceGroup
                              select new BrgMeshPrimitive(faceGroup.ToList())).ToList();

            // Load mesh data
            glTFLoader.Schema.Mesh mesh = new glTFLoader.Schema.Mesh();
            mesh.Primitives = new MeshPrimitive[primitives.Count];
            for (int i = 0; i < mesh.Primitives.Length; ++i)
            {
                mesh.Primitives[i] = new MeshPrimitive();
            }
            for (int j = 0; j < primitives.Count; ++j)
            {
                primitives[j].Serialize(mesh.Primitives[j], brg.Meshes[0], this, bufferStream);
            }
            for (int i = 0; i < brg.Meshes[0].MeshAnimations.Count; ++i)
            {
                for (int j = 0; j < primitives.Count; ++j)
                {
                    primitives[j].Serialize(mesh.Primitives[j], (BrgMesh)brg.Meshes[0].MeshAnimations[i], this, bufferStream);
                }
            }
            gltf.Meshes = new[] { mesh };

            // Create Animation
            if (brg.Meshes[0].MeshAnimations.Count > 0)
            {
                for (int i = 0; i < mesh.Primitives.Length; ++i)
                {
                    mesh.Primitives[i].Targets = primitives[i].Targets.ToArray();
                }

                mesh.Weights = new float[brg.Meshes[0].MeshAnimations.Count];

                gltf.Animations = new[] { CreateAnimation(brg.Animation, mesh.Weights.Length, bufferStream) };
            }

            // Create buffer stream
            gltf.BufferViews = bufferViews.ToArray();
            gltf.Accessors   = accessors.ToArray();
            var buffer = new glTFLoader.Schema.Buffer();

            gltf.Buffers      = new[] { buffer };
            buffer.ByteLength = (int)bufferStream.Length;
            buffer.Uri        = "dataBuffer.bin";

            return(gltf);
        }
示例#16
0
        /// <summary>
        /// Creates a single buffer and a minimum number of buffer-views to pack all the accessors.
        /// </summary>
        private void PackAccessors(GltfFile modelFile, Stream newBufferStream, string outputBufferUri)
        {
            var fileData = modelFile.Data;

            var buffers     = fileData.Buffers;
            var bufferViews = fileData.BufferViews;

            // TODO: Check sparse accessors
            // Group accessor by optional target, component-stride and component byte-length
            // For each group, we need to create a single buffer-view.
            var accessorGroups = fileData
                                 .Accessors
                                 .Where(a => a.BufferView.HasValue)
                                 .GroupBy(a => (target: bufferViews[a.BufferView.Value].Target, stride: a.GetByteStride(bufferViews) /*, componentByteLength: a.GetComponentByteLength()*/))
                                 .ToDictionary(g => g.Key, g => g.ToArray());

            // NOTE: The following select sequence has a side-effect
            var newBufferViews = accessorGroups
                                 .Select((pair, newBufferViewIndex) =>
            {
                //var ((target, stride, componentByteLength), accessors) = pair;
                var((target, stride), accessors) = pair;

                var newBufferViewOffset = (int)newBufferStream.Position;

                //Debug.Assert(newBufferStream.GetComponentPadding(componentByteLength) == 0);

                foreach (var accessor in accessors)
                {
                    var componentByteLength = accessor.GetComponentByteLength();

                    var accessorPadding = newBufferStream.GetComponentPadding(componentByteLength);
                    newBufferStream.WriteByte(0, accessorPadding);

                    var newAccessorByteOffset = (int)(newBufferStream.Position - newBufferViewOffset);

                    Debug.Assert(accessor.BufferView.HasValue);
                    var bufferView = bufferViews[accessor.BufferView.Value];
                    var buffer     = buffers[bufferView.Buffer];
                    var data       = _bufferFileData[buffer];

                    var bufferOffset = bufferView.ByteOffset + accessor.ByteOffset;

                    var rowLength = accessor.GetComponentDimension() * componentByteLength;

                    for (int i = 0; i < accessor.Count; ++i)
                    {
                        Debug.Assert(newBufferStream.GetComponentPadding(componentByteLength) == 0);
                        newBufferStream.Write(data, bufferOffset + i * stride, rowLength);
                        Debug.Assert(newBufferStream.GetComponentPadding(componentByteLength) == 0);
                    }

                    // Patch the accessor.
                    accessor.ByteOffset = newAccessorByteOffset;
                    accessor.BufferView = newBufferViewIndex;
                }

                var newBufferView = new BufferView
                {
                    Target     = target,
                    ByteOffset = newBufferViewOffset,
                    ByteStride = target == BufferView.TargetEnum.ARRAY_BUFFER ? stride : (int?)null,
                    ByteLength = (int)(newBufferStream.Position - newBufferViewOffset)
                };

                return(newBufferView);
            })
                                 .ToArray();

            var newBuffer = new Buffer
            {
                ByteLength = (int)newBufferStream.Length,
                Uri        = outputBufferUri
            };

            fileData.BufferViews = newBufferViews;
            fileData.Buffers     = new[] { newBuffer };
        }
示例#17
0
 private static Byte[] LoadBinaryBufferUnchecked(Schema.Buffer buffer, Func <string, Byte[]> externalReferenceSolver)
 {
     return(TryLoadBase64BinaryBufferUnchecked(buffer, EMBEDDEDGLTFBUFFER)
            ?? TryLoadBase64BinaryBufferUnchecked(buffer, EMBEDDEDOCTETSTREAM)
            ?? externalReferenceSolver(buffer?.Uri));
 }
示例#18
0
        /// <summary>
        /// Converts self contained GLB to glTF file and associated textures and data
        /// </summary>
        /// <param name="inputFilePath">glTF binary file (.glb) to unpack</param>
        /// <param name="outputDirectoryPath">Directory where the files will be extracted</param>
        public static void Unpack(string inputFilePath, string outputDirectoryPath)
        {
            if (!File.Exists(inputFilePath))
            {
                throw new ArgumentException("Input file does not exists");
            }
            if (!Directory.Exists(outputDirectoryPath))
            {
                throw new ArgumentException("Ouput directory does not exists");
            }

            string inputFileName      = Path.GetFileNameWithoutExtension(inputFilePath);
            string inputDirectoryPath = Path.GetDirectoryName(inputFilePath);

            var model = Interface.LoadModel(inputFilePath);

            glTFLoader.Schema.Buffer binBuffer = null;
            byte[] binBufferData = null;
            if (model.Buffers != null && string.IsNullOrEmpty(model.Buffers[0].Uri))
            {
                binBuffer     = model.Buffers[0];
                binBufferData = model.LoadBinaryBuffer(0, inputFilePath);
            }

            var imageBufferViewIndices = new List <int>();

            if (model.Images != null)
            {
                for (var index = 0; index < model.Images.Length; index++)
                {
                    var image = model.Images[index];

                    if (!string.IsNullOrEmpty(image.Uri))
                    {
                        if (!image.Uri.StartsWith("data:"))
                        {
                            var sourceFilePath = Path.Combine(inputDirectoryPath, image.Uri);
                            var fileName       = $"{inputFilePath}_image{index}.bin";

                            if (File.Exists(sourceFilePath))
                            {
                                var destinationFilePath = Path.Combine(outputDirectoryPath, fileName);
                                File.Copy(sourceFilePath, destinationFilePath, true);
                            }

                            image.Uri = fileName;
                        }
                    }
                    else if (image.BufferView.HasValue)
                    {
                        var bufferView = model.BufferViews[image.BufferView.Value];
                        if (bufferView.Buffer == 0)
                        {
                            imageBufferViewIndices.Add(image.BufferView.Value);

                            var fileExtension = image.MimeType == Image.MimeTypeEnum.image_jpeg ? "jpg" : "png";
                            var fileName      = $"{inputFileName}_image{index}.{fileExtension}";

                            using (var fileStream = File.Create(Path.Combine(outputDirectoryPath, fileName)))
                            {
                                fileStream.Write(binBufferData, bufferView.ByteOffset, bufferView.ByteLength);
                            }

                            image.BufferView = null;
                            image.MimeType   = null;
                            image.Uri        = fileName;
                        }
                    }
                }
            }

            if (model.BufferViews != null)
            {
                var binFileName   = $"{inputFileName}.bin";
                var binFilePath   = Path.Combine(outputDirectoryPath, binFileName);
                var binByteLength = 0;

                var indexMap    = new Dictionary <int, int>();
                var bufferViews = new List <BufferView>();
                using (var fileStream = File.Create(binFilePath))
                {
                    for (var index = 0; index < model.BufferViews.Length; index++)
                    {
                        if (!imageBufferViewIndices.Any(imageIndex => imageIndex == index))
                        {
                            var bufferView = model.BufferViews[index];
                            if (bufferView.Buffer == 0)
                            {
                                fileStream.Align(4);
                                var fileStreamPosition = fileStream.Position;
                                fileStream.Write(binBufferData, bufferView.ByteOffset, bufferView.ByteLength);
                                bufferView.ByteOffset = (int)fileStreamPosition;
                            }

                            var newIndex = bufferViews.Count;
                            if (index != newIndex)
                            {
                                indexMap.Add(index, newIndex);
                            }

                            bufferViews.Add(bufferView);
                        }
                    }

                    binByteLength = (int)fileStream.Length;
                }

                model.BufferViews = bufferViews.ToArray();

                if (binByteLength == 0)
                {
                    File.Delete(binFilePath);
                    if (binBuffer != null)
                    {
                        model.Buffers = model.Buffers.Skip(1).ToArray();
                        foreach (var bufferView in model.BufferViews)
                        {
                            bufferView.Buffer--;
                        }
                    }
                }
                else
                {
                    binBuffer.Uri        = binFileName;
                    binBuffer.ByteLength = binByteLength;
                }

                if (model.Accessors != null)
                {
                    foreach (var accessor in model.Accessors)
                    {
                        if (accessor.BufferView.HasValue)
                        {
                            if (indexMap.TryGetValue(accessor.BufferView.Value, out int newIndex))
                            {
                                accessor.BufferView = newIndex;
                            }
                        }
                    }
                }
            }

            if (model.Buffers != null)
            {
                for (var index = 1; index < model.Buffers.Length; index++)
                {
                    var buffer = model.Buffers[index];
                    if (!buffer.Uri.StartsWith("data:"))
                    {
                        var sourceFilePath = Path.Combine(inputDirectoryPath, buffer.Uri);
                        var fileName       = $"{inputFileName}{index}.bin";

                        if (File.Exists(sourceFilePath))
                        {
                            var destinationFilePath = Path.Combine(outputDirectoryPath, fileName);
                            File.Copy(sourceFilePath, destinationFilePath, true);
                        }

                        buffer.Uri = fileName;
                    }
                }
            }

            Interface.SaveModel(model, Path.Combine(outputDirectoryPath, $"{inputFileName}.gltf"));
        }
示例#19
0
        private void FromBrgMesh(BrgMesh brgMesh)
        {
            Vector3 max = new Vector3(float.MinValue);
            Vector3 min = new Vector3(float.MaxValue);

            using (FileStream fs = File.Open("posBuffer.bin", FileMode.Create, FileAccess.Write, FileShare.Read))
                using (BinaryWriter writer = new BinaryWriter(fs))
                {
                    foreach (Vector3 vec in brgMesh.Vertices)
                    {
                        max.X = Math.Max(max.X, vec.X);
                        max.Y = Math.Max(max.Y, vec.Y);
                        max.Z = Math.Max(max.Z, vec.Z);

                        min.X = Math.Min(min.X, vec.X);
                        min.Y = Math.Min(min.Y, vec.Y);
                        min.Z = Math.Min(min.Z, vec.Z);

                        writer.Write(vec.X);
                        writer.Write(vec.Y);
                        writer.Write(vec.Z);
                    }
                }

            glTFLoader.Schema.Buffer posBuffer = new glTFLoader.Schema.Buffer();
            posBuffer.ByteLength = brgMesh.Vertices.Count * 12;
            posBuffer.Uri        = "posBuffer.bin";

            BufferView posBufferView = new BufferView();

            posBufferView.Buffer     = 0;
            posBufferView.ByteLength = posBuffer.ByteLength;
            posBufferView.ByteOffset = 0;
            posBufferView.ByteStride = 12;
            posBufferView.Name       = "posBufferView";
            posBufferView.Target     = BufferView.TargetEnum.ARRAY_BUFFER;

            Accessor posAccessor = new Accessor();

            posAccessor.BufferView    = 0;
            posAccessor.ByteOffset    = 0;
            posAccessor.ComponentType = Accessor.ComponentTypeEnum.FLOAT;
            posAccessor.Count         = brgMesh.Vertices.Count;
            posAccessor.Max           = new[] { max.X, max.Y, max.Z };
            posAccessor.Min           = new[] { min.X, min.Y, min.Z };
            posAccessor.Name          = "posBufferViewAccessor";
            posAccessor.Type          = Accessor.TypeEnum.VEC3;

            short faceMin = short.MaxValue;
            short faceMax = short.MinValue;

            using (FileStream fs = File.Open("indexBuffer.bin", FileMode.Create, FileAccess.Write, FileShare.Read))
                using (BinaryWriter writer = new BinaryWriter(fs))
                {
                    foreach (var face in brgMesh.Faces)
                    {
                        faceMin = Math.Min(faceMin, face.Indices[0]);
                        faceMin = Math.Min(faceMin, face.Indices[1]);
                        faceMin = Math.Min(faceMin, face.Indices[2]);

                        faceMax = Math.Max(faceMax, face.Indices[0]);
                        faceMax = Math.Max(faceMax, face.Indices[1]);
                        faceMax = Math.Max(faceMax, face.Indices[2]);

                        writer.Write(face.Indices[0]);
                        writer.Write(face.Indices[1]);
                        writer.Write(face.Indices[2]);
                    }
                }

            glTFLoader.Schema.Buffer indexBuffer = new glTFLoader.Schema.Buffer();
            indexBuffer.ByteLength = brgMesh.Faces.Count * 6;
            indexBuffer.Uri        = "indexBuffer.bin";

            BufferView indexBufferView = new BufferView();

            indexBufferView.Buffer     = 1;
            indexBufferView.ByteLength = indexBuffer.ByteLength;
            indexBufferView.ByteOffset = 0;
            indexBufferView.Name       = "indexBufferView";
            indexBufferView.Target     = BufferView.TargetEnum.ELEMENT_ARRAY_BUFFER;

            Accessor indexAccessor = new Accessor();

            indexAccessor.BufferView    = 1;
            indexAccessor.ByteOffset    = 0;
            indexAccessor.ComponentType = Accessor.ComponentTypeEnum.UNSIGNED_SHORT;
            indexAccessor.Count         = brgMesh.Faces.Count * 3;
            indexAccessor.Max           = new[] { (float)faceMax };
            indexAccessor.Min           = new[] { (float)faceMin };
            indexAccessor.Name          = "indexBufferViewAccessor";
            indexAccessor.Type          = Accessor.TypeEnum.SCALAR;

            gltf.Buffers     = new[] { posBuffer, indexBuffer };
            gltf.BufferViews = new[] { posBufferView, indexBufferView };
            gltf.Accessors   = new[] { posAccessor, indexAccessor };

            MeshPrimitive meshPrimitive = new MeshPrimitive();

            meshPrimitive.Attributes = new Dictionary <string, int>();
            meshPrimitive.Attributes.Add("POSITION", 0);
            meshPrimitive.Indices = 1;
            meshPrimitive.Mode    = MeshPrimitive.ModeEnum.TRIANGLES;

            var mesh = new glTFLoader.Schema.Mesh();

            mesh.Name       = "mesh";
            mesh.Primitives = new[] { meshPrimitive };

            gltf.Meshes = new[] { mesh };

            Node node = new Node();

            node.Mesh = 0;
            node.Name = "node";

            gltf.Nodes = new[] { node };
        }