public void Read_File_Valid() { var temp = Path.GetTempFileName(); try { File.WriteAllText(temp, "shadow_obj a.a"); var obj = ObjFile.FromFile(temp); Assert.Equal("a.a", obj.ShadowObjectFileName); } finally { File.Delete(temp); } }
public GraphicalObject(string objFile, string mtlFile, GL Gl, Shader s) { obj = ObjFile.FromFile(objFile); mtl = ObjMaterialFile.FromFile(mtlFile); associatedShader = s; this.Gl = Gl; (vertices, indices) = CreateVertexInfo(); Ebo = new BufferObject <uint>(Gl, indices, BufferTargetARB.ElementArrayBuffer); Vbo = new BufferObject <float>(Gl, vertices, BufferTargetARB.ArrayBuffer); Vao = new VertexArrayObject <float, uint>(Gl, Vbo, Ebo); Vao.VertexAttributePointer(0, 3, VertexAttribPointerType.Float, 8, 0); Vao.VertexAttributePointer(1, 3, VertexAttribPointerType.Float, 8, 3); Vao.VertexAttributePointer(2, 2, VertexAttribPointerType.Float, 8, 6); }
public static Pm3DModel FromObjLods(params string[] filenames) { var lods = new List <Pm3DLod>(); foreach (var filename in filenames) { var obj = ObjFile.FromFile(filename); var objects = obj .Faces .GroupBy(face => face.ObjectName) .ToDictionary(grouping => grouping.Key ?? "", grouping => grouping.ToList()); lods.Add(new Pm3DLod(objects, obj.Vertices, obj.VertexNormals, obj.TextureVertices)); } return(new Pm3DModel(lods)); }
public static Model FromFile(string filename) { ExpectFile($"{filename}.json"); ExpectFile($"{filename}.obj"); var json = BlockbenchModel.FromFile($"{filename}.json"); var obj = ObjFile.FromFile($"{filename}.obj"); var objects = obj .Faces .GroupBy(face => new ModelObjectInfo(face.ObjectName, face.MaterialName)) .ToDictionary(grouping => grouping.Key, grouping => grouping.ToList()); var verts = obj.Vertices; var normals = obj.VertexNormals; var uvs = obj.TextureVertices; return(new Model(json, objects, verts, normals, uvs)); }
public static BakedModel BakeModel(Shader shader, string modelName) { var obj = ObjFile.FromFile($"assets/models/{modelName}.obj"); var mtl = ObjMaterialFile.FromFile($"assets/models/{modelName}.mtl"); var materials = new List <ObjMaterial>(mtl.Materials); var mat = materials.SingleOrDefault(m => m.DiffuseMap != null); List <float> vertexes = new List <float>(); List <float> uvs = new List <float>(); List <float> normals = new List <float>(); foreach (var face in obj.Faces) { foreach (var triple in face.Vertices) //for each vertice of the triangle { var vertexIndex = triple.Vertex - 1; var normalIndex = triple.Normal - 1; var uvIndex = triple.Texture - 1; var vertex = obj.Vertices[vertexIndex]; var normal = obj.VertexNormals[normalIndex]; var uv = obj.TextureVertices[uvIndex]; vertexes.Add(vertex.X); vertexes.Add(vertex.Y); vertexes.Add(vertex.Z); normals.Add(normal.X); normals.Add(normal.Y); normals.Add(normal.Z); uvs.Add(uv.X); uvs.Add(1 - uv.Y); //uvs.Add(uv.Y); } } return(BakeModel(shader, $"assets/models/{mat.DiffuseMap.FileName}", vertexes.ToArray(), normals.ToArray(), uvs.ToArray())); }
private void DrawModelWireframe() { var m = ObjFile.FromFile("Models/african_head.obj"); AddStage("Loading"); var bounds = m.Bounds(); var scale = _bitmap.Width / bounds.BiggestSize() - 8; var shift = Vector3.One * _bitmap.Width / 2; AddStage("Bounds"); foreach (var face in m.Faces) { var indicesCount = face.Vertices.Count; for (var i = 0; i < indicesCount; i++) { var vertex0 = face.Vertices[i].Vertex; var p0 = m.Vertices[vertex0 - 1].Position.ToVector3(); p0 *= scale; p0 += shift; var vertex1 = face.Vertices[(i + 1) % indicesCount].Vertex; var p1 = m.Vertices[vertex1 - 1].Position.ToVector3(); p1 *= scale; p1 += shift; _bitmap.DrawLine(new Vector2(p0.X, p0.Y), new Vector2(p1.X, p1.Y), Color.White); } } AddStage("Drawing"); }
public void Read_NullFile_Throws() { Assert.Throws <ArgumentNullException>("path", () => ObjFile.FromFile(null)); }
public static OptFile ObjToOpt(string objPath, bool scale) { string objDirectory = Path.GetDirectoryName(objPath); var obj = ObjFile.FromFile(objPath); var opt = new OptFile(); foreach (var mesh in obj.Meshes) { var optMesh = new Mesh(); opt.Meshes.Add(optMesh); if (scale) { foreach (var v in obj.Vertices) { optMesh.Vertices.Add(new Vector(v.X / OptFile.ScaleFactor, v.Z / OptFile.ScaleFactor, v.Y / OptFile.ScaleFactor)); } } else { foreach (var v in obj.Vertices) { optMesh.Vertices.Add(new Vector(v.X, v.Z, v.Y)); } } foreach (var v in obj.VertexTexCoords) { optMesh.TextureCoordinates.Add(new TextureCoordinates(v.U, -v.V)); } foreach (var v in obj.VertexNormals) { optMesh.VertexNormals.Add(new Vector(v.X, v.Z, v.Y)); } optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 0)); optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 0)); optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 1)); optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 1)); var optLod = new MeshLod(); optMesh.Lods.Add(optLod); foreach (var faceGroup in mesh.FaceGroups) { var optFaceGroup = new FaceGroup(); optLod.FaceGroups.Add(optFaceGroup); if (!string.IsNullOrEmpty(faceGroup.MaterialName)) { optFaceGroup.Textures.Add(faceGroup.MaterialName); } foreach (var face in faceGroup.Faces) { Index verticesIndex = new Index( face.VerticesIndex.A, face.VerticesIndex.B, face.VerticesIndex.C, face.VerticesIndex.D); if (verticesIndex.A >= optMesh.Vertices.Count) { verticesIndex.A = 0; } if (verticesIndex.B >= optMesh.Vertices.Count) { verticesIndex.B = 0; } if (verticesIndex.C >= optMesh.Vertices.Count) { verticesIndex.C = 0; } if (verticesIndex.D >= optMesh.Vertices.Count) { verticesIndex.D = 0; } Index textureCoordinatesIndex = new Index( face.VertexTexCoordsIndex.A, face.VertexTexCoordsIndex.B, face.VertexTexCoordsIndex.C, face.VertexTexCoordsIndex.D); if (textureCoordinatesIndex.A >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.A = 0; } if (textureCoordinatesIndex.B >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.B = 0; } if (textureCoordinatesIndex.C >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.C = 0; } if (textureCoordinatesIndex.D >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.D = 0; } Index vertexNormalsIndex = new Index( face.VertexNormalsIndex.A, face.VertexNormalsIndex.B, face.VertexNormalsIndex.C, face.VertexNormalsIndex.D); if (vertexNormalsIndex.A >= optMesh.VertexNormals.Count) { vertexNormalsIndex.A = 0; } if (vertexNormalsIndex.B >= optMesh.VertexNormals.Count) { vertexNormalsIndex.B = 0; } if (vertexNormalsIndex.C >= optMesh.VertexNormals.Count) { vertexNormalsIndex.C = 0; } if (vertexNormalsIndex.D >= optMesh.VertexNormals.Count) { vertexNormalsIndex.D = 0; } if (textureCoordinatesIndex.A < 0 || textureCoordinatesIndex.B < 0 || textureCoordinatesIndex.C < 0 || (verticesIndex.D >= 0 && textureCoordinatesIndex.D < 0)) { textureCoordinatesIndex.A = optMesh.TextureCoordinates.Count - 4; textureCoordinatesIndex.B = optMesh.TextureCoordinates.Count - 3; textureCoordinatesIndex.C = optMesh.TextureCoordinates.Count - 2; textureCoordinatesIndex.D = verticesIndex.D < 0 ? -1 : optMesh.TextureCoordinates.Count - 1; } Vector normal = Vector.Normal( optMesh.Vertices.ElementAtOrDefault(verticesIndex.A), optMesh.Vertices.ElementAtOrDefault(verticesIndex.B), optMesh.Vertices.ElementAtOrDefault(verticesIndex.C)); if (vertexNormalsIndex.A < 0 || vertexNormalsIndex.B < 0 || vertexNormalsIndex.C < 0 || (verticesIndex.D >= 0 && vertexNormalsIndex.D < 0)) { optMesh.VertexNormals.Add(normal); vertexNormalsIndex.A = optMesh.VertexNormals.Count - 1; vertexNormalsIndex.B = optMesh.VertexNormals.Count - 1; vertexNormalsIndex.C = optMesh.VertexNormals.Count - 1; vertexNormalsIndex.D = verticesIndex.D < 0 ? -1 : optMesh.VertexNormals.Count - 1; } var optFace = new Face() { VerticesIndex = verticesIndex, TextureCoordinatesIndex = textureCoordinatesIndex, VertexNormalsIndex = vertexNormalsIndex, Normal = normal }; optFaceGroup.Faces.Add(optFace); } } } opt.CompactBuffers(); opt.ComputeHitzones(); foreach (var material in obj.Materials.Values) { Texture texture; if (material.DiffuseMapFileName == null) { var color = material.DiffuseColor; byte r = (byte)(color.X * 255.0f); byte g = (byte)(color.Y * 255.0f); byte b = (byte)(color.Z * 255.0f); int width = 8; int height = 8; int length = width * height; byte[] data = new byte[length * 4]; for (int i = 0; i < length; i++) { data[i * 4 + 0] = b; data[i * 4 + 1] = g; data[i * 4 + 2] = r; data[i * 4 + 3] = 255; } texture = new Texture(); texture.Name = material.Name; texture.Width = width; texture.Height = height; texture.ImageData = data; } else { string colorFileName = Path.Combine(objDirectory, material.DiffuseMapFileName); texture = Texture.FromFile(colorFileName); texture.Name = material.Name; } if (material.AlphaMapFileName != null) { string alphaFileName = Path.Combine(objDirectory, material.AlphaMapFileName); texture.SetAlphaMap(alphaFileName); } else if (material.DissolveFactor > 0.0f && material.DissolveFactor < 1.0f) { byte alpha = (byte)(material.DissolveFactor * 255.0f); int length = texture.Width * texture.Height; byte[] alphaData = new byte[length]; var data = texture.ImageData; for (int i = 0; i < length; i++) { alphaData[i] = alpha; data[i * 4 + 3] = alpha; } texture.AlphaData = alphaData; } opt.Textures.Add(texture.Name, texture); } opt.GenerateTexturesMipmaps(); return(opt); }
public void CreateDeviceDependentResources(DeviceResources resources) { this.deviceResources = resources; var d3dDevice = this.deviceResources.D3DDevice; this.tessellator.CreateDeviceDependentResources(this.deviceResources); XMFloat4[] initData; // Parse the .obj file. Both triangle faces and quad faces are supported. // Only v and f tags are processed, other tags like vn, vt etc are ignored. { var initFile = ObjFile.FromFile("BaseMesh.obj"); var data = new List <XMFloat4>(); var v = new List <XMFloat4>(); for (int i = 0; i < initFile.Vertices.Count; i++) { ObjVector4 objPosition = initFile.Vertices[i].Position; XMFloat4 pos = new XMFloat4( objPosition.X, objPosition.Y, objPosition.Z, 1.0f); v.Add(pos); } foreach (ObjFace face in initFile.Faces) { if (face.Vertices.Count < 3) { continue; } data.Add(v[face.Vertices[0].Vertex - 1]); data.Add(v[face.Vertices[1].Vertex - 1]); data.Add(v[face.Vertices[2].Vertex - 1]); if (face.Vertices.Count >= 4) { data.Add(v[face.Vertices[2].Vertex - 1]); data.Add(v[face.Vertices[3].Vertex - 1]); data.Add(v[face.Vertices[0].Vertex - 1]); } } initData = data.ToArray(); } this.g_pBaseVB = d3dDevice.CreateBuffer( D3D11BufferDesc.From(initData, D3D11BindOptions.ShaderResource | D3D11BindOptions.VertexBuffer), initData, 0, 0); this.tessellator.SetBaseMesh((uint)initData.Length, this.g_pBaseVB); this.g_pVS = d3dDevice.CreateVertexShader(File.ReadAllBytes("RenderVertexShader.cso"), null); { byte[] shaderBytecode = File.ReadAllBytes("RenderBaseVertexShader.cso"); this.g_pBaseVS = d3dDevice.CreateVertexShader(shaderBytecode, null); D3D11InputElementDesc[] layoutDesc = new[] { new D3D11InputElementDesc( "POSITION", 0, DxgiFormat.R32G32B32A32Float, 0, 0, D3D11InputClassification.PerVertexData, 0) }; this.g_pBaseVBLayout = d3dDevice.CreateInputLayout(layoutDesc, shaderBytecode); } this.g_pPS = d3dDevice.CreatePixelShader(File.ReadAllBytes("RenderPixelShader.cso"), null); // Setup constant buffer this.g_pVSCB = d3dDevice.CreateBuffer(new D3D11BufferDesc { BindOptions = D3D11BindOptions.ConstantBuffer, ByteWidth = 4 * 16 }); // Rasterizer state this.g_pRasWireFrame = d3dDevice.CreateRasterizerState(new D3D11RasterizerDesc { CullMode = D3D11CullMode.None, FillMode = D3D11FillMode.WireFrame }); }