public static (Mesh mesh, Vector3[] positions, Vector3[] normals) LoadObj(string path) { ObjLoaderFactory factory = new ObjLoaderFactory(); var objLoader = factory.Create(); using (var fStream = new FileStream(path, FileMode.Open)) { var result = objLoader.Load(fStream); Dictionary <FaceVertex, VertexObjData> vertexData = new Dictionary <FaceVertex, VertexObjData>(); var verts = result.Vertices; var norms = result.Normals; var tex = result.Textures; var faces = result.Groups[0].Faces; uint[] indices = new uint[faces.Count * 3]; for (int i = 0; i < faces.Count; i++) { for (int j = 0; j < 3; j++) { var vert = faces[i][j]; if (vertexData.ContainsKey(vert) == false) { var v = ConvertVert(verts[vert.VertexIndex - 1]); var n = ConvertNorm(norms[vert.NormalIndex - 1]); var t = ConvertTexCoord(tex[vert.TextureIndex - 1]); vertexData.Add(vert, new VertexObjData(v, n, t, vertexData.Count)); } } } List <VertexObjData> sortedVertexData = vertexData.Values.ToList(); //sortedVertexData.Sort((a, b) => a.index.CompareTo(b.index)); for (int i = 0; i < faces.Count; i++) { for (int j = 0; j < 3; j++) { indices[i * 3 + j] = (uint)vertexData[faces[i][j]].index; } } var positions = new Vector3[sortedVertexData.Count]; var normals = new Vector3[sortedVertexData.Count]; float[] vertices = new float[sortedVertexData.Count * VertexLayout.Stride(VertexLayout.Type.PositionNormal)]; for (int i = 0; i < sortedVertexData.Count; i++) { var vert = sortedVertexData[i]; positions[vert.index] = vert.position; normals[vert.index] = vert.normal; VBOUtility.SetVertex(vertices, vert.position, vert.normal, vert.index); } var mesh = new Mesh(VertexLayout.Type.PositionNormal); mesh.SetBufferData(vertices, indices, OpenTK.Graphics.OpenGL.BufferUsageHint.StaticDraw); return(mesh, positions, normals); } }
public static Mesh PlaneMesh(PrimitiveType type, float width, float height, int segmentsX = 1, int segmentsZ = 1) { var mesh = new Mesh(VertexLayout.Type.PositionNormalTexCoords); var vertexCount = 4 + 2 * (segmentsX - 1) + (1 + segmentsX) * (segmentsZ - 1); float deltaW = width / segmentsX; float deltaH = height / segmentsZ; float[] vertices = new float[vertexCount * VertexLayout.Stride(VertexLayout.Type.PositionNormalTexCoords)]; int vertexIndex = 0; for (int z = 0; z <= segmentsZ; z++) { for (int x = 0; x <= segmentsX; x++) { var pos = new Vector3(-width * 0.5f + deltaW * x, 0.0f, -height * 0.5f + deltaH * z); var norm = new Vector3(0.0f, 1.0f, 0.0f); var texCoords = new Vector2((float)x / segmentsX, (float)z / segmentsZ); VBOUtility.SetVertex(vertices, pos, norm, texCoords, vertexIndex++); } } if (type == PrimitiveType.Triangles) { mesh.SetBufferData(vertices, PlaneIndicesTriangles(segmentsX, segmentsZ), BufferUsageHint.StaticDraw); } else if (type == PrimitiveType.Patches) { mesh.SetBufferData(vertices, PlaneIndicesPatches(segmentsX, segmentsZ), BufferUsageHint.StaticDraw); } else { throw new InvalidOperationException("Only Triangles and Patches allowed"); } return(mesh); }
public static Mesh BezierPatch(float width, float height, int pointSet) { var mesh = new Mesh(VertexLayout.Type.PositionNormalTexCoords); var vertexCount = 16; float[] vertices = new float[vertexCount * VertexLayout.Stride(VertexLayout.Type.PositionNormalTexCoords)]; int vertexIndex = 0; var segmentsX = 3; var segmentsZ = 3; float deltaW = width / 3; float deltaH = height / 3; var cpSet = SelectCPSet(pointSet); for (int z = 0; z <= segmentsX; z++) { for (int x = 0; x <= segmentsZ; x++) { var pos = cpSet[x + z * (segmentsX + 1)]; var norm = new Vector3(0.0f, 1.0f, 0.0f); var texCoords = new Vector2((float)x / segmentsX, (float)z / segmentsZ); VBOUtility.SetVertex(vertices, pos, norm, texCoords, vertexIndex++); } } uint[] indices = new uint[16]; for (int i = 0; i < 16; i++) { indices[i] = (uint)i; } mesh.SetBufferData(vertices, indices, BufferUsageHint.StaticDraw); return(mesh); }
public JellyMesh(JellyData data, Vector3[] positions, Vector3[] normals) { _data = data; _UVWs = positions.Select((x) => GetVertexUVW(x)).ToArray(); _normals = normals; _vertices = new float[_UVWs.Length * VertexLayout.Stride(VertexLayout.Type.PositionNormal)]; }
public static Mesh BezierJoined(float width, float height, int segmentsX, int segmentsZ) { var mesh = new Mesh(VertexLayout.Type.PositionNormalTexCoords); var verticesX = 1 + 3 * segmentsX; var verticesZ = 1 + 3 * segmentsZ; var vertexCount = verticesX * verticesZ; float[] vertices = new float[vertexCount * VertexLayout.Stride(VertexLayout.Type.PositionNormalTexCoords)]; int vertexIndex = 0; float deltaW = width / (verticesX - 1); float deltaH = height / (verticesZ - 1); bool up = false; for (int z = 0; z < verticesX; z++) { up = false; for (int x = 0; x < verticesZ; x++) { if (x % 3 == 0) { up = !up; } var y = x % 3 == 1 || x % 3 == 2 ? width * 0.06f : 0.0f; if (up == false) { y = -y; } var pos = new Vector3(-width * 0.5f + deltaW * x, y, -height * 0.5f + deltaH * z); var norm = new Vector3(0.0f, 1.0f, 0.0f); var texCoords = new Vector2((float)x / (verticesX - 1), (float)z / (verticesZ - 1)); VBOUtility.SetVertex(vertices, pos, norm, texCoords, vertexIndex++); } } uint[] indices = new uint[segmentsX * segmentsZ * 16]; int indicesIdx = 0; for (int vPatch = 0; vPatch < segmentsZ; vPatch++) { for (int uPatch = 0; uPatch < segmentsX; uPatch++) { var uIdx = uPatch * 3; var vIdx = vPatch * 3; for (int j = vIdx; j < vIdx + 4; j++) { for (int i = uIdx; i < uIdx + 4; i++) { indices[indicesIdx] = (uint)(i + j * verticesX); indicesIdx++; } } } } mesh.SetBufferData(vertices, indices, BufferUsageHint.StaticDraw); return(mesh); }