private void CreateNormalBuffer(BrgMesh mesh, GltfFormatter formatter, Stream bufferStream) { long bufferViewOffset; Vector3 max = new Vector3(float.MinValue); Vector3 min = new Vector3(float.MaxValue); using (BinaryWriter writer = new BinaryWriter(bufferStream, Encoding.UTF8, true)) { // padding writer.Write(new byte[(-bufferStream.Length) & (PaddingBytes(Accessor.ComponentTypeEnum.FLOAT) - 1)]); bufferViewOffset = bufferStream.Length; foreach (int index in Indices) { Vector3 vec = mesh.Normals[index]; vec = vec / vec.Length(); 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); } } BufferView posBufferView = new BufferView(); posBufferView.Buffer = 0; posBufferView.ByteLength = Indices.Count * 12; posBufferView.ByteOffset = (int)bufferViewOffset; posBufferView.ByteStride = 12; posBufferView.Name = "normalBufferView"; posBufferView.Target = BufferView.TargetEnum.ARRAY_BUFFER; Accessor posAccessor = new Accessor(); posAccessor.BufferView = formatter.bufferViews.Count; posAccessor.ByteOffset = 0; posAccessor.ComponentType = Accessor.ComponentTypeEnum.FLOAT; posAccessor.Count = Indices.Count; posAccessor.Max = new[] { max.X, max.Y, max.Z }; posAccessor.Min = new[] { min.X, min.Y, min.Z }; posAccessor.Name = "normalBufferViewAccessor"; posAccessor.Type = Accessor.TypeEnum.VEC3; formatter.bufferViews.Add(posBufferView); formatter.accessors.Add(posAccessor); }
private void CreateIndexBuffer(BrgMesh mesh, GltfFormatter formatter, Stream bufferStream) { long bufferViewOffset; short faceMin = short.MaxValue; short faceMax = short.MinValue; using (BinaryWriter writer = new BinaryWriter(bufferStream, Encoding.UTF8, true)) { // padding writer.Write(new byte[(-bufferStream.Length) & (PaddingBytes(Accessor.ComponentTypeEnum.UNSIGNED_SHORT) - 1)]); bufferViewOffset = bufferStream.Length; foreach (var face in 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]); } } BufferView indexBufferView = new BufferView(); indexBufferView.Buffer = 0; indexBufferView.ByteLength = Faces.Count * 6; indexBufferView.ByteOffset = (int)bufferViewOffset; indexBufferView.Name = "indexBufferView"; indexBufferView.Target = BufferView.TargetEnum.ELEMENT_ARRAY_BUFFER; Accessor indexAccessor = new Accessor(); indexAccessor.BufferView = formatter.bufferViews.Count; indexAccessor.ByteOffset = 0; indexAccessor.ComponentType = Accessor.ComponentTypeEnum.UNSIGNED_SHORT; indexAccessor.Count = Faces.Count * 3; indexAccessor.Max = new[] { (float)faceMax }; indexAccessor.Min = new[] { (float)faceMin }; indexAccessor.Name = "indexBufferViewAccessor"; indexAccessor.Type = Accessor.TypeEnum.SCALAR; formatter.bufferViews.Add(indexBufferView); formatter.accessors.Add(indexAccessor); }
public void Serialize(MeshPrimitive primitive, BrgMesh mesh, GltfFormatter formatter, Stream bufferStream) { if (!mesh.Header.Flags.HasFlag(BrgMeshFlag.SECONDARYMESH)) { primitive.Mode = MeshPrimitive.ModeEnum.TRIANGLES; CreateIndexBuffer(mesh, formatter, bufferStream); primitive.Indices = formatter.accessors.Count - 1; primitive.Attributes = CreateAttributes(mesh, formatter, bufferStream); } else { Targets.Add(CreateAttributes(mesh, formatter, bufferStream)); } }
private Dictionary <string, int> CreateAttributes(BrgMesh mesh, GltfFormatter formatter, Stream bufferStream) { var attributes = new Dictionary <string, int>(); CreatePositionBuffer(mesh, formatter, bufferStream); int posAccessor = formatter.accessors.Count - 1; attributes.Add("POSITION", posAccessor); CreateNormalBuffer(mesh, formatter, bufferStream); int normAccessor = formatter.accessors.Count - 1; attributes.Add("NORMAL", normAccessor); return(attributes); }
public MainWindow() { InitializeComponent(); string[] args = Environment.GetCommandLineArgs(); BrgFile file; if (args.Length > 1 && false) { file = new BrgFile(File.Open(args[1], FileMode.Open, FileAccess.Read, FileShare.Read)); file.WriteJson(File.Open(args[1] + ".json", FileMode.Create, FileAccess.Write, FileShare.Read)); if (args.Length > 2 && args[2] == "-s") { Application.Current.Shutdown(); } } else { //archer e slinger_attacka.brg file = new BrgFile(File.Open(@"C:\Games\Steam\steamapps\common\Age of Mythology\models\version2.0\infantry g hoplite head standard.brg", FileMode.Open, FileAccess.Read, FileShare.Write)); file.WriteJson(File.Open("infantry g hoplite head standard.brg.json.brg", FileMode.Create, FileAccess.Write, FileShare.Read)); var grnFile = new AoMEngineLibrary.Graphics.Grn.GrnFile(); grnFile.Read(File.Open(@"C:\Games\Steam\steamapps\common\Age of Mythology\models\version2.0\ajax.grn", FileMode.Open, FileAccess.Read, FileShare.Write)); } //BrgFile t = new BrgFile(); //t.ReadJson(File.Open("hi.brg", FileMode.Open, FileAccess.Read, FileShare.Read)); //t.WriteJson(File.Open("hi2.brg", FileMode.Create, FileAccess.Write, FileShare.Read)); List <Point3D> positions = new List <Point3D>(file.Meshes[0].Vertices.Count); List <int> triangleIndices = new List <int>(file.Meshes[0].Faces.Count * 3); for (int i = 0; i < file.Meshes[0].Vertices.Count; ++i) { positions.Add(new Point3D( file.Meshes[0].Vertices[i].X, file.Meshes[0].Vertices[i].Y, file.Meshes[0].Vertices[i].Z)); } for (int i = 0; i < file.Meshes[0].Faces.Count; ++i) { triangleIndices.Add(file.Meshes[0].Faces[i].Indices[0]); triangleIndices.Add(file.Meshes[0].Faces[i].Indices[1]); triangleIndices.Add(file.Meshes[0].Faces[i].Indices[2]); } Mesh3D mesh = new Mesh3D(positions, triangleIndices); MeshVisual3D meshVis = new MeshVisual3D(); meshVis.Mesh = mesh; ModelVisual3D modVis = new ModelVisual3D(); GeometryModel3D geomod = new GeometryModel3D(); MeshGeometry3D meshgeo = new MeshGeometry3D(); //modVis.Transform = new MatrixTransform3D(new Matrix3D(-1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1)); //modVis.Transform = new MatrixTransform3D(new Matrix3D(-0, -0, -1, 0, -1, -0, -0, 0, 0, 1, 0, 0, 0, 0, 0, 1)); modVis.Transform = new MatrixTransform3D(new Matrix3D(0, -1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1)); meshgeo.Positions = new Point3DCollection(positions); meshgeo.TriangleIndices = new Int32Collection(triangleIndices); geomod.Geometry = meshgeo; modVis.Content = geomod; MaterialGroup matGroup = new MaterialGroup(); matGroup.Children.Add(new DiffuseMaterial(new SolidColorBrush(Color.FromArgb(255, 0xFF, 0x00, 0xFF)))); geomod.Material = matGroup; //viewport3d.Children.Add(meshVis); viewport3d.Children.Add(modVis); file = new BrgFile(File.Open(@"C:\Games\Steam\steamapps\common\Age of Mythology\models\version2.0\animal aurochs_attacka.brg", FileMode.Open, FileAccess.Read)); glTFLoader.Schema.Gltf gltf; using (var stream = File.Open("dataBuffer.bin", FileMode.Create, FileAccess.Write, FileShare.Read)) { GltfFormatter frmt = new GltfFormatter(); gltf = frmt.FromBrg(file, stream); } glTFLoader.Interface.SaveModel(gltf, "brgGltf.gltf"); }