public void AddTempVertex( ref Vertex128 vertex128, ref Vector3 pos, ref Vector2 uv, ref Vector4 color, ref Vector3 normal) { TempVertexData vertex; Transform transform; if (null == geoModel) { transform = Transform.Identity; } else { geoModel.Parent.BuildTransform(out transform); geoModel.AddVertex(MaterialFallback, ref vertex128); } vertex.position = transform.TransformPosition(pos); vertex.texCoord = uv; vertex.color = color; vertex.normal = transform.TransformVectorNoScale(normal); TempVertex.Add(ref MaterialFallback.references.list, ref vertex); }
private void CalculateTangentBinormal(TempVertex vertex1, TempVertex vertex2, TempVertex vertex3, out Vector tangent, out Vector binormal) { // Calculate the two vectors for the this face. var vector1 = new[] { vertex2.x - vertex1.x, vertex2.y - vertex1.y, vertex2.z - vertex1.z }; var vector2 = new[] { vertex3.x - vertex1.x, vertex3.y - vertex1.y, vertex3.z - vertex1.z }; // Calculate the tu and tv texture space vectors. var tuVector = new[] { vertex2.tu - vertex1.tu, vertex3.tu - vertex1.tu }; var tvVector = new[] { vertex2.tv - vertex1.tv, vertex3.tv - vertex1.tv }; // Calculate the denominator of the tangent / binormal equation. var den = 1.0f / (tuVector[0] * tvVector[1] - tuVector[1] * tvVector[0]); // Calculate the cross products and multiply by the coefficient to get the tangent and binormal. tangent.x = (tvVector[1] * vector1[0] - tvVector[0] * vector2[0]) * den; tangent.y = (tvVector[1] * vector1[1] - tvVector[0] * vector2[1]) * den; tangent.z = (tvVector[1] * vector1[2] - tvVector[0] * vector2[2]) * den; binormal.x = (tuVector[0] * vector2[0] - tuVector[1] * vector1[0]) * den; binormal.y = (tuVector[0] * vector2[1] - tuVector[1] * vector1[1]) * den; binormal.z = (tuVector[0] * vector2[2] - tuVector[1] * vector1[2]) * den; // Calculate the length of this normal. var length = (float)Math.Sqrt(tangent.x * tangent.x + tangent.y * tangent.y + tangent.z * tangent.z); // Normalize the normal and the store it. tangent.x = tangent.x / length; tangent.y = tangent.y / length; tangent.z = tangent.z / length; // Calculate the length of this normal. length = (float)Math.Sqrt(binormal.x * binormal.x + binormal.y * binormal.y + binormal.z * binormal.z); // Normalize the normal and the store it. binormal.x = binormal.x / length; binormal.y = binormal.y / length; binormal.z = binormal.z / length; }
public static ObjVolume LoadFromString(string obj) { // Seperate lines from the file List <String> lines = new List <string>(obj.Split('\n')); // Lists to hold model data List <Vector3> verts = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Vector2> texs = new List <Vector2>(); List <Tuple <TempVertex, TempVertex, TempVertex> > faces = new List <Tuple <TempVertex, TempVertex, TempVertex> >(); // Base values verts.Add(new Vector3()); texs.Add(new Vector2()); normals.Add(new Vector3()); int currentindice = 0; // Read file line by line foreach (String line in lines) { if (line.StartsWith("v ")) // Vertex definition { // Cut off beginning of line String temp = line.Substring(2); Vector3 vec = new Vector3(); if (temp.Trim().Count((char c) => c == ' ') == 2) // Check if there's enough elements for a vertex { String[] vertparts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Attempt to parse each part of the vertice bool success = float.TryParse(vertparts[0], out vec.X); success |= float.TryParse(vertparts[1], out vec.Y); success |= float.TryParse(vertparts[2], out vec.Z); // If any of the parses failed, report the error if (!success) { Console.WriteLine("Error parsing vertex: {0}", line); } } else { Console.WriteLine("Error parsing vertex: {0}", line); } verts.Add(vec); } else if (line.StartsWith("vt ")) // Texture coordinate { // Cut off beginning of line String temp = line.Substring(2); Vector2 vec = new Vector2(); if (temp.Trim().Count((char c) => c == ' ') > 0) // Check if there's enough elements for a vertex { String[] texcoordparts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Attempt to parse each part of the vertice bool success = float.TryParse(texcoordparts[0], out vec.X); success |= float.TryParse(texcoordparts[1], out vec.Y); // If any of the parses failed, report the error if (!success) { Console.WriteLine("Error parsing texture coordinate: {0}", line); } } else { Console.WriteLine("Error parsing texture coordinate: {0}", line); } texs.Add(vec); } else if (line.StartsWith("vn ")) // Normal vector { // Cut off beginning of line String temp = line.Substring(2); Vector3 vec = new Vector3(); if (temp.Trim().Count((char c) => c == ' ') == 2) // Check if there's enough elements for a normal { String[] vertparts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Attempt to parse each part of the vertice bool success = float.TryParse(vertparts[0], out vec.X); success |= float.TryParse(vertparts[1], out vec.Y); success |= float.TryParse(vertparts[2], out vec.Z); // If any of the parses failed, report the error if (!success) { Console.WriteLine("Error parsing normal: {0}", line); } } else { Console.WriteLine("Error parsing normal: {0}", line); } normals.Add(vec); } else if (line.StartsWith("f ")) // Face definition { // Cut off beginning of line String temp = line.Substring(2); Tuple <TempVertex, TempVertex, TempVertex> face = new Tuple <TempVertex, TempVertex, TempVertex>(new TempVertex(), new TempVertex(), new TempVertex()); if (temp.Trim().Count((char c) => c == ' ') == 2) // Check if there's enough elements for a face { String[] faceparts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); int v1, v2, v3; int t1, t2, t3; int n1, n2, n3; // Attempt to parse each part of the face bool success = int.TryParse(faceparts[0].Split('/')[0], out v1); success |= int.TryParse(faceparts[1].Split('/')[0], out v2); success |= int.TryParse(faceparts[2].Split('/')[0], out v3); if (faceparts[0].Count((char c) => c == '/') >= 2) { success |= int.TryParse(faceparts[0].Split('/')[1], out t1); success |= int.TryParse(faceparts[1].Split('/')[1], out t2); success |= int.TryParse(faceparts[2].Split('/')[1], out t3); success |= int.TryParse(faceparts[0].Split('/')[2], out n1); success |= int.TryParse(faceparts[1].Split('/')[2], out n2); success |= int.TryParse(faceparts[2].Split('/')[2], out n3); } else { if (texs.Count > v1 && texs.Count > v2 && texs.Count > v3) { t1 = v1; t2 = v2; t3 = v3; } else { t1 = 0; t2 = 0; t3 = 0; } if (normals.Count > v1 && normals.Count > v2 && normals.Count > v3) { n1 = v1; n2 = v2; n3 = v3; } else { n1 = 0; n2 = 0; n3 = 0; } } // If any of the parses failed, report the error if (!success) { Console.WriteLine("Error parsing face: {0}", line); } else { TempVertex tv1 = new TempVertex(v1, n1, t1); TempVertex tv2 = new TempVertex(v2, n2, t2); TempVertex tv3 = new TempVertex(v3, n3, t3); face = new Tuple <TempVertex, TempVertex, TempVertex>(tv1, tv2, tv3); faces.Add(face); } } else { Console.WriteLine("Error parsing face: {0}", line); } } } // Create the ObjVolume ObjVolume vol = new ObjVolume(); foreach (var face in faces) { FaceVertex v1 = new FaceVertex(verts[face.Item1.Vertex], normals[face.Item1.Normal], texs[face.Item1.Texcoord]); FaceVertex v2 = new FaceVertex(verts[face.Item2.Vertex], normals[face.Item2.Normal], texs[face.Item2.Texcoord]); FaceVertex v3 = new FaceVertex(verts[face.Item3.Vertex], normals[face.Item3.Normal], texs[face.Item3.Texcoord]); vol.faces.Add(new Tuple <FaceVertex, FaceVertex, FaceVertex>(v1, v2, v3)); } return(vol); }
public static OBJVolume LoadFromString(string obj, string filename = null) { List <string> lines = new List <string>(obj.Split('\n')); List <Vector3> vertices = new List <Vector3>(); List <Vector2> textureCoords = new List <Vector2>(); var faces = new List <Tuple <TempVertex, TempVertex, TempVertex> >(); vertices.Add(new Vector3()); textureCoords.Add(new Vector2()); foreach (string l in lines) { if (l.StartsWith("v ")) { // remove 'v ' string temp = l.Substring(2); Vector3 v = new Vector3(); // Check if there's enough elements for a vertex (3) if (temp.Count((char c) => c == ' ') == 2) { string[] vertParts = temp.Split(' '); bool success = float.TryParse(vertParts[0], out v.X); success |= float.TryParse(vertParts[1], out v.Y); success |= float.TryParse(vertParts[2], out v.Z); if (!success) { if (filename != null) { Console.WriteLine("!!! ERROR: cannot parse vertex (line: {0}, file: {1}) !!!", l, filename); } else { Console.WriteLine("!!! ERROR: cannot parse vertex (line: {0}, from string) !!!", l); } } } vertices.Add(v); } else if (l.StartsWith("vt ")) { // cut off 'vt ' string temp = l.Substring(3); Vector2 v = new Vector2(); // Check if there's enough elements for a vertex if (temp.Trim().Count((char c) => c == ' ') > 0) { string[] textureCoordParts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); bool success = float.TryParse(textureCoordParts[0], out v.X); success |= float.TryParse(textureCoordParts[1], out v.Y); if (filename != null) { Console.WriteLine("!!! ERROR: cannot parse texture coordinate (line: {0}, file: {1}) !!!", l, filename); } else { Console.WriteLine("!!! ERROR: cannot parse texture coordinate (line: {0}, from string) !!!", l); } } else { if (filename != null) { Console.WriteLine("!!! ERROR: cannot parse texture coordinate (line: {0}, file: {1}) !!!", l, filename); } else { Console.WriteLine("!!! ERROR: cannot parse texture coordinate (line: {0}, from string) !!!", l); } } textureCoords.Add(v); } else if (l.StartsWith("f ")) { // remove 'f ' string temp = l.Substring(2); var face = new Tuple <TempVertex, TempVertex, TempVertex> ( new TempVertex(), new TempVertex(), new TempVertex() ); // Check if there's enough elements for a face (3) if (temp.Trim().Count((char c) => c == ' ') == 2) { string[] faceParts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); int i1, i2, i3; int t1, t2, t3; bool success = int.TryParse(faceParts[0].Split('/')[0], out i1); success |= int.TryParse(faceParts[1].Split('/')[0], out i2); success |= int.TryParse(faceParts[2].Split('/')[0], out i3); if (faceParts[0].Count((char c) => c == '/') == 2) { success |= int.TryParse(faceParts[0].Split('/')[1], out t1); success |= int.TryParse(faceParts[1].Split('/')[1], out t2); success |= int.TryParse(faceParts[2].Split('/')[1], out t3); } else { t1 = i1; t2 = i2; t3 = i3; } if (!success) { if (filename != null) { Console.WriteLine("!!! ERROR: cannot parse face (line: {0}, file: {1}) !!!", l, filename); } else { Console.WriteLine("!!! ERROR: cannot parse face (line: {0}, from string) !!!", l); } } else { TempVertex v1 = new TempVertex(i1, 0, t1); TempVertex v2 = new TempVertex(i2, 0, t2); TempVertex v3 = new TempVertex(i3, 0, t3); if (textureCoords.Count < t1) { textureCoords.Add(new Vector2()); } if (textureCoords.Count < t2) { textureCoords.Add(new Vector2()); } if (textureCoords.Count < t3) { textureCoords.Add(new Vector2()); } face = new Tuple <TempVertex, TempVertex, TempVertex>(v1, v2, v3); faces.Add(face); } } } } OBJVolume volume = new OBJVolume(); textureCoords.Add(new Vector2()); textureCoords.Add(new Vector2()); textureCoords.Add(new Vector2()); foreach (var f in faces) { FaceVertex v1 = new FaceVertex ( vertices[f.Item1.Vertex], new Vector3(), textureCoords[f.Item1.TextureCoord] ); FaceVertex v2 = new FaceVertex ( vertices[f.Item2.Vertex], new Vector3(), textureCoords[f.Item2.TextureCoord] ); FaceVertex v3 = new FaceVertex ( vertices[f.Item3.Vertex], new Vector3(), textureCoords[f.Item3.TextureCoord] ); volume.faces.Add(new Tuple <FaceVertex, FaceVertex, FaceVertex>(v1, v2, v3)); } return(volume); }
/// <summary> /// Does not load correctly, yet /// </summary> /// <param name="obj"></param> /// <returns></returns> public static Model LoadFromString(string obj) { List <string> lines = new List <string>(obj.Split('\n')); // Lists to hold model data List <Vector3> verts = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Vector2> texs = new List <Vector2>(); List <Tuple <TempVertex, TempVertex, TempVertex> > faces = new List <Tuple <TempVertex, TempVertex, TempVertex> >(); List <Tuple <int, int, int> > faceIndices = new List <Tuple <int, int, int> >(); // Base values verts.Add(new Vector3()); texs.Add(new Vector2()); normals.Add(new Vector3()); // Read file line by line foreach (string line in lines) { if (line.StartsWith("v ")) // Vertex definition { // Cut off beginning of line string temp = line.Substring(2); Vector3 vec = new Vector3(); if (temp.Trim().Count((char c) => c == ' ') == 2) // Check if there's enough elements for a vertex { string[] vertparts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Attempt to parse each part of the vertice bool success = float.TryParse(vertparts[0], out vec.X); success |= float.TryParse(vertparts[1], out vec.Y); success |= float.TryParse(vertparts[2], out vec.Z); // If any of the parses failed, report the error if (!success) { Console.WriteLine("Error parsing vertex: {0}", line); } } else { Console.WriteLine("Error parsing vertex: {0}", line); } verts.Add(vec); } else if (line.StartsWith("vt ")) // Texture coordinate { // Cut off beginning of line string temp = line.Substring(2); Vector2 vec = new Vector2(); if (temp.Trim().Count((char c) => c == ' ') > 0) // Check if there's enough elements for a vertex { string[] texcoordparts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Attempt to parse each part of the vertice bool success = float.TryParse(texcoordparts[0], out vec.X); success |= float.TryParse(texcoordparts[1], out vec.Y); // If any of the parses failed, report the error if (!success) { Console.WriteLine("Error parsing texture coordinate: {0}", line); } } else { Console.WriteLine("Error parsing texture coordinate: {0}", line); } texs.Add(vec); } else if (line.StartsWith("vn ")) // Normal vector { // Cut off beginning of line string temp = line.Substring(2); Vector3 vec = new Vector3(); if (temp.Trim().Count((char c) => c == ' ') == 2) // Check if there's enough elements for a normal { string[] vertparts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Attempt to parse each part of the vertice bool success = float.TryParse(vertparts[0], out vec.X); success |= float.TryParse(vertparts[1], out vec.Y); success |= float.TryParse(vertparts[2], out vec.Z); // If any of the parses failed, report the error if (!success) { Console.WriteLine("Error parsing normal: {0}", line); } } else { Console.WriteLine("Error parsing normal: {0}", line); } normals.Add(vec); } else if (line.StartsWith("f ")) // Face definition { // Cut off beginning of line string temp = line.Substring(2); Tuple <TempVertex, TempVertex, TempVertex> face = new Tuple <TempVertex, TempVertex, TempVertex>(new TempVertex(), new TempVertex(), new TempVertex()); if (temp.Trim().Count((char c) => c == ' ') == 2) // Check if there's enough elements for a face { string[] faceparts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); int v1, v2, v3; int t1, t2, t3; int n1, n2, n3; // Attempt to parse each part of the face bool success = int.TryParse(faceparts[0].Split('/')[0], out v1); success |= int.TryParse(faceparts[1].Split('/')[0], out v2); success |= int.TryParse(faceparts[2].Split('/')[0], out v3); if (faceparts[0].Count((char c) => c == '/') >= 2) { success |= int.TryParse(faceparts[0].Split('/')[1], out t1); success |= int.TryParse(faceparts[1].Split('/')[1], out t2); success |= int.TryParse(faceparts[2].Split('/')[1], out t3); success |= int.TryParse(faceparts[0].Split('/')[2], out n1); success |= int.TryParse(faceparts[1].Split('/')[2], out n2); success |= int.TryParse(faceparts[2].Split('/')[2], out n3); } else { if (texs.Count > v1 && texs.Count > v2 && texs.Count > v3) { t1 = v1; t2 = v2; t3 = v3; } else { t1 = 0; t2 = 0; t3 = 0; } if (normals.Count > v1 && normals.Count > v2 && normals.Count > v3) { n1 = v1; n2 = v2; n3 = v3; } else { n1 = 0; n2 = 0; n3 = 0; } } // If any of the parses failed, report the error if (!success) { Console.WriteLine("Error parsing face: {0}", line); } else { faceIndices.Add(new Tuple <int, int, int>(v1, v2, v3)); TempVertex tv1 = new TempVertex(v1, n1, t1); TempVertex tv2 = new TempVertex(v2, n2, t2); TempVertex tv3 = new TempVertex(v3, n3, t3); face = new Tuple <TempVertex, TempVertex, TempVertex>(tv1, tv2, tv3); faces.Add(face); } } else { Console.WriteLine("Error parsing face: {0}", line); } } } Mesh mesh = new Mesh(); for (int i = 0; i < faces.Count; i += 3) { var face = faces[i]; Mesh.Vertex vert1 = new Mesh.Vertex { Position = verts[face.Item1.Vertex], Normal = normals[face.Item1.Normal], TextureCoordinate = texs[face.Item1.Texcoord] }; mesh.Vertices.Add(vert1); Mesh.Vertex vert2 = new Mesh.Vertex { Position = verts[face.Item2.Vertex], Normal = normals[face.Item2.Normal], TextureCoordinate = texs[face.Item2.Texcoord] }; mesh.Vertices.Add(vert2); Mesh.Vertex vert3 = new Mesh.Vertex { Position = verts[face.Item3.Vertex], Normal = normals[face.Item3.Normal], TextureCoordinate = texs[face.Item3.Texcoord] }; mesh.Vertices.Add(vert3); mesh.Faces.Add(new Mesh.Face { X = faceIndices[i].Item1, Y = faceIndices[i].Item2, Z = faceIndices[i].Item3 }); } for (int i = 0; i < faces.Count; i++) { mesh.Indices.Add(faceIndices[i].Item1); mesh.Indices.Add(faceIndices[i].Item2); mesh.Indices.Add(faceIndices[i].Item3); } mesh.VertexCount = mesh.Vertices.Count; mesh.FaceCount = mesh.Faces.Count; mesh.IndexCount = mesh.Indices.Count; return(Model.CreateFromMesh(mesh)); }
private static Model LoadFromString(string text) { const NumberStyles style = NumberStyles.Number; var culture = CultureInfo.CreateSpecificCulture("en-GB"); // Separate lines from the file var lines = new List <string>(text.Split('\n')); // Lists to hold model data var vertices = new List <Vector3>(); var normals = new List <Vector3>(); var texs = new List <Vector2>(); var faces = new List <(TempVertex, TempVertex, TempVertex)>(); // Base values vertices.Add(new Vector3()); texs.Add(new Vector2()); normals.Add(new Vector3()); // Read file line by line foreach (var line in lines) { if (line.StartsWith("v ")) // Vertex definition { // Cut off beginning of line var temp = line.Substring(2); var vec = new Vector3(); if (temp.Trim().Count(c => c == ' ') == 2) // Check if there's enough elements for a vertex { var vertparts = temp.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Attempt to parse each part of the vertice var success = float.TryParse(vertparts[0], style, culture, out vec.X); success |= float.TryParse(vertparts[1], style, culture, out vec.Y); success |= float.TryParse(vertparts[2], style, culture, out vec.Z); // If any of the parses failed, report the error if (!success) { Logger.LogConsole($"Error parsing vertex: {line}"); } } else { Logger.LogConsole($"Error parsing vertex: {line}"); } vertices.Add(vec); } else if (line.StartsWith("vt ")) // Texture coordinate { // Cut off beginning of line var temp = line.Substring(2); var vec = new Vector2(); if (temp.Trim().Count(c => c == ' ') > 0) // Check if there's enough elements for a vertex { var texcoordparts = temp.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Attempt to parse each part of the vertice var success = float.TryParse(texcoordparts[0], style, culture, out vec.X); success |= float.TryParse(texcoordparts[1], style, culture, out vec.Y); // If any of the parses failed, report the error if (!success) { Logger.LogConsole($"Error parsing texture coordinate: {line}"); } } else { Logger.LogConsole($"Error parsing texture coordinate: {line}"); } texs.Add(vec); } else if (line.StartsWith("vn ")) // Normal vector { // Cut off beginning of line var temp = line.Substring(2); var vec = new Vector3(); if (temp.Trim().Count(c => c == ' ') == 2) // Check if there's enough elements for a normal { var vertparts = temp.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Attempt to parse each part of the vertice var success = float.TryParse(vertparts[0], style, culture, out vec.X); success |= float.TryParse(vertparts[1], style, culture, out vec.Y); success |= float.TryParse(vertparts[2], style, culture, out vec.Z); // If any of the parses failed, report the error if (!success) { Logger.LogConsole($"Error parsing normal: {line}"); } } else { Logger.LogConsole($"Error parsing normal: {line}"); } normals.Add(vec); } else if (line.StartsWith("f ")) // Face definition { // Cut off beginning of line var temp = line.Substring(2); if (temp.Trim().Count(c => c == ' ') == 2) // Check if there's enough elements for a face { var faceParts = temp.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); int t1, t2, t3; int n1, n2, n3; // Attempt to parse each part of the face var success = int.TryParse(faceParts[0].Split('/')[0], out var v1); success |= int.TryParse(faceParts[1].Split('/')[0], out var v2); success |= int.TryParse(faceParts[2].Split('/')[0], out var v3); if (faceParts[0].Count(c => c == '/') >= 2) { success |= int.TryParse(faceParts[0].Split('/')[1], out t1); success |= int.TryParse(faceParts[1].Split('/')[1], out t2); success |= int.TryParse(faceParts[2].Split('/')[1], out t3); success |= int.TryParse(faceParts[0].Split('/')[2], out n1); success |= int.TryParse(faceParts[1].Split('/')[2], out n2); success |= int.TryParse(faceParts[2].Split('/')[2], out n3); } else { if (texs.Count > v1 && texs.Count > v2 && texs.Count > v3) { t1 = v1; t2 = v2; t3 = v3; } else { t1 = 0; t2 = 0; t3 = 0; } if (normals.Count > v1 && normals.Count > v2 && normals.Count > v3) { n1 = v1; n2 = v2; n3 = v3; } else { n1 = 0; n2 = 0; n3 = 0; } } // If any of the parses failed, report the error if (!success) { Logger.LogConsole($"Error parsing face: {line}"); } else { var tv1 = new TempVertex(v1, n1, t1); var tv2 = new TempVertex(v2, n2, t2); var tv3 = new TempVertex(v3, n3, t3); faces.Add((tv1, tv2, tv3)); } } else { Logger.LogConsole($"Error parsing face: {line}"); } } } // Create the Model var vol = new Model(); foreach (var face in faces) { var v1 = new Model.FaceVertex(vertices[face.Item1.Vertex], normals[face.Item1.Normal], texs[face.Item1.TexCoords]); var v2 = new Model.FaceVertex(vertices[face.Item2.Vertex], normals[face.Item2.Normal], texs[face.Item2.TexCoords]); var v3 = new Model.FaceVertex(vertices[face.Item3.Vertex], normals[face.Item3.Normal], texs[face.Item3.TexCoords]); vol.Faces.Add((v1, v2, v3)); } return(vol); }
private void CalculateTangentBinormal(TempVertex vertex1, TempVertex vertex2, TempVertex vertex3, out Vector tangent, out Vector binormal) { // Calculate the two vectors for the this face. var vector1 = new[] { vertex2.x - vertex1.x, vertex2.y - vertex1.y, vertex2.z - vertex1.z }; var vector2 = new[] { vertex3.x - vertex1.x, vertex3.y - vertex1.y, vertex3.z - vertex1.z }; // Calculate the tu and tv texture space vectors. var tuVector = new[] { vertex2.tu - vertex1.tu, vertex3.tu - vertex1.tu }; var tvVector = new[] { vertex2.tv - vertex1.tv, vertex3.tv - vertex1.tv }; // Calculate the denominator of the tangent / binormal equation. var den = 1.0f / (tuVector[0] * tvVector[1] - tuVector[1] * tvVector[0]); // Calculate the cross products and multiply by the coefficient to get the tangent and binormal. tangent.x = (tvVector[1] * vector1[0] - tvVector[0] * vector2[0]) * den; tangent.y = (tvVector[1] * vector1[1] - tvVector[0] * vector2[1]) * den; tangent.z = (tvVector[1] * vector1[2] - tvVector[0] * vector2[2]) * den; binormal.x = (tuVector[0] * vector2[0] - tuVector[1] * vector1[0]) * den; binormal.y = (tuVector[0] * vector2[1] - tuVector[1] * vector1[1]) * den; binormal.z = (tuVector[0] * vector2[2] - tuVector[1] * vector1[2]) * den; // Calculate the length of this normal. var length = (float)Math.Sqrt(tangent.x * tangent.x + tangent.y * tangent.y + tangent.z * tangent.z); // Normalize the normal and the store it. tangent.x = tangent.x / length; tangent.y = tangent.y / length; tangent.z = tangent.z / length; // Calculate the length of this normal. length = (float)Math.Sqrt(binormal.x * binormal.x + binormal.y * binormal.y + binormal.z * binormal.z); // Normalize the normal and the store it. binormal.x = binormal.x / length; binormal.y = binormal.y / length; binormal.z = binormal.z / length; }
public void myRender() { // List<Vertex> VertList = new List<Vertex>(); GL.GenBuffers(1, out gl_vbo); for (int i = 0; i < vertCount; i++) { TempVertex vert = new TempVertex(); try { foreach (BFRESAttribute att in attributes) { DataOff = (BufferOffsets[att.bufferIndex].DataOffsetData) + (attributes[att.bufferIndex].bufferOffset); FileData d = new FileData(new FileData(BuffSizes[att.bufferIndex].BuffSizes).getSection(0, -1)); d.Endian = Endianness.Little; d.seek(att.bufferOffset + i * BufferOffsets[att.bufferIndex].VertexStrideSizeData); switch (att.Text) { case "_p0": if (att.format.Equals(0x518)) { vert.x = d.readFloat(); vert.y = d.readFloat(); vert.z = d.readFloat(); } else if (att.format.Equals(0x515)) { vert.x = d.readHalfFloat(); vert.y = d.readHalfFloat(); vert.z = d.readHalfFloat(); d.readHalfFloat(); //w } else { Console.WriteLine("Unkown Format!! " + att.format.ToString()); } break; case "_n0": if (att.format.Equals(0x20E)) { int normVal = (int)d.readInt(); vert.nx = FileData.sign10Bit((normVal) & 0x3FF) / 511f; vert.ny = FileData.sign10Bit((normVal >> 10) & 0x3FF) / 511f; vert.nz = FileData.sign10Bit((normVal >> 20) & 0x3FF) / 511f; break; } else { Console.WriteLine("Unkown Format!! " + att.format.ToString() + " " + att.Text); } break; case "_i0": if (att.format.Equals(0x20B)) { vert.i1 = d.readByte(); vert.i2 = d.readByte(); vert.i3 = d.readByte(); vert.i4 = d.readByte(); } else if (att.format.Equals(0x302)) { vert.i1 = d.readByte(); vert.w1 = 1; } else if (att.format.Equals(0x309)) { vert.i1 = d.readByte(); vert.i2 = d.readByte(); } else if (att.format.Equals(0x30B)) { vert.i1 = d.readByte(); vert.i2 = d.readByte(); vert.i3 = d.readByte(); vert.i4 = d.readByte(); } else if (att.format.Equals(0x118)) { vert.i1 = d.readInt(); vert.i2 = d.readInt(); vert.i3 = d.readInt(); } else if (att.format.Equals(0x117)) { vert.i1 = d.readInt(); vert.i2 = d.readInt(); } else if (att.format.Equals(0x115)) { vert.i1 = d.readShort(); vert.i2 = d.readShort(); } else { Console.WriteLine("Unkown Format!! " + att.format.ToString() + " " + att.Text); } break; case "_u0": if (att.format.Equals(0x112)) { vert.uv0.X = ((float)d.readShort()) / 65535; vert.uv0.Y = ((float)d.readShort()) / 65535; } else if (att.format.Equals(0x109)) { vert.uv0.X = d.readByte() / (float)255; vert.uv0.Y = d.readByte() / (float)255; } else if (att.format.Equals(0x209)) { vert.uv0.X = d.readByte() / (float)127; vert.uv0.Y = d.readByte() / (float)127; } else if (att.format.Equals(0x212)) { vert.uv0.X = d.readShort() / (float)32767; vert.uv0.Y = d.readShort() / (float)32767; } else if (att.format.Equals(0x512)) { vert.uv0.X = d.readHalfFloat(); vert.uv0.Y = d.readHalfFloat(); } else if (att.format.Equals(0x517)) { vert.uv0.X = d.readFloat(); vert.uv0.Y = d.readFloat(); } else { Console.WriteLine("Unkown Format!! " + att.format.ToString() + " " + att.Text); } break; case "_w0": if (att.format.Equals(0x102)) { vert.w1 = d.readByte(); } else if (att.format.Equals(0x109)) { vert.w1 = d.readByte() / (float)255; vert.w2 = d.readByte() / (float)255; } else if (att.format.Equals(0x10B)) { vert.w1 = d.readByte() / (float)255; vert.w2 = d.readByte() / (float)255; vert.w3 = d.readByte() / (float)255; vert.w4 = d.readByte() / (float)255; } else if (att.format.Equals(0x112)) { vert.w1 = d.readShort() / (float)0xFFFF; vert.w2 = d.readShort() / (float)0xFFFF; } break; default: //d.skip(d.size()); // Console.WriteLine(Text + " Unknown type " + att.format.ToString("x") + " 0x"); break; } } VertData.Add(new BaseRenderData.Vertex() { x = vert.x, y = vert.y, z = vert.z, nx = vert.nx, ny = vert.ny, nz = vert.nz, uv0 = vert.uv0, i1 = vert.i1, i2 = vert.i2, i3 = vert.i3, i4 = vert.i4, w1 = vert.w1, w2 = vert.w2, w3 = vert.w3, w4 = vert.w4, }); } catch (Exception ex) { MessageBox.Show("A buffer broke :( \n\n" + ex, "Error"); } } /*(Vertex item in data) * { * Console.WriteLine("X = " + item.x + " Y = " + item.y + " Z = " + item.z); * }*/ GL.BindBuffer(BufferTarget.ArrayBuffer, gl_vbo); GL.BufferData <BaseRenderData.Vertex>(BufferTarget.ArrayBuffer, (IntPtr)(VertData.Count * BaseRenderData.Vertex.Stride), VertData.ToArray(), BufferUsageHint.StaticDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); }
private void myRender() { GL.GenBuffers(1, out gl_vbo); Console.WriteLine("Prerender start"); for (int i = 0; i < vertCount; i++) { TempVertex vert = new TempVertex(); foreach (BFRESAttribute att in attributes) { FileData d = new FileData(buffers[att.bufferIndex].data); d.seek(att.bufferOffset + i * buffers[att.bufferIndex].stride); switch (att.format) { /* * case 0x10C: data.Add(d.readFloat()); break; * case 0x20A: data.Add(((sbyte)d.readByte()) / 128); break; * case 0x80D: data.Add(d.readFloat()); break; * case 0x813: data.Add(d.readFloat()); break;*/ case 0x004: vert.w1 = d.readByte() / (float)255; vert.w2 = d.readByte() / (float)255; break; case 0x007: if (att.Text.Equals("_u2")) { vert.uv0.X = d.readShort() / (float)0xFFFF; vert.uv0.Y = d.readShort() / (float)0xFFFF; } else { vert.w1 = d.readShort() / (float)0xFFFF; vert.w2 = d.readShort() / (float)0xFFFF; } break; case 0x00A: vert.w1 = d.readByte() / (float)255; vert.w2 = d.readByte() / (float)255; vert.w3 = d.readByte() / (float)255; vert.w4 = d.readByte() / (float)255; break; case 0x100: vert.i1 = d.readByte(); vert.w1 = 1; break; case 0x104: vert.i1 = d.readByte(); vert.i2 = d.readByte(); break; case 0x10A: vert.i1 = d.readByte(); vert.i2 = d.readByte(); vert.i3 = d.readByte(); vert.i4 = d.readByte(); break; case 0x20B: int normVal = (int)d.readInt(); vert.nx = FileData.sign10Bit((normVal) & 0x3FF) / 511f; vert.ny = FileData.sign10Bit((normVal >> 10) & 0x3FF) / 511f; vert.nz = FileData.sign10Bit((normVal >> 20) & 0x3FF) / 511f; break; case 0x80F: vert.x = d.readHalfFloat(); vert.y = d.readHalfFloat(); vert.z = d.readHalfFloat(); d.readHalfFloat(); //w break; case 0x811: vert.x = d.readFloat(); vert.y = d.readFloat(); vert.z = d.readFloat(); d.readFloat(); //w break; default: //d.skip(d.size()); //Console.WriteLine(Text + " Unknown type " + att.format.ToString("x") + " 0x" + (att.bufferOffset + buffers[bufferIndex].dataOffset).ToString("x")); break; } } data.Add(new Vertex() { x = vert.x, y = vert.y, z = vert.z, nx = vert.nx, ny = vert.ny, nz = vert.nz, uv0 = vert.uv0, i1 = vert.i1, i2 = vert.i2, i3 = vert.i3, i4 = vert.i4, w1 = vert.i1, w2 = vert.i2, w3 = vert.i3, w4 = vert.i4, }); } Console.WriteLine("Prerender end"); GL.BindBuffer(BufferTarget.ArrayBuffer, gl_vbo); GL.BufferData <Vertex>(BufferTarget.ArrayBuffer, (IntPtr)(data.Count * Vertex.Stride), data.ToArray(), BufferUsageHint.StaticDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); }
public static OBJVolume LoadFromString(string obj, string filename = null) { List<string> lines = new List<string>(obj.Split('\n')); List<Vector3> vertices = new List<Vector3>(); List<Vector2> textureCoords = new List<Vector2>(); var faces = new List<Tuple<TempVertex, TempVertex, TempVertex>>(); vertices.Add(new Vector3()); textureCoords.Add(new Vector2()); foreach (string l in lines) { if (l.StartsWith("v ")) { // remove 'v ' string temp = l.Substring(2); Vector3 v = new Vector3(); // Check if there's enough elements for a vertex (3) if (temp.Count((char c) => c == ' ') == 2) { string[] vertParts = temp.Split(' '); bool success = float.TryParse(vertParts[0], out v.X); success |= float.TryParse(vertParts[1], out v.Y); success |= float.TryParse(vertParts[2], out v.Z); if (!success) { if (filename != null) { Console.WriteLine("!!! ERROR: cannot parse vertex (line: {0}, file: {1}) !!!", l, filename); } else { Console.WriteLine("!!! ERROR: cannot parse vertex (line: {0}, from string) !!!", l); } } } vertices.Add(v); } else if (l.StartsWith("vt ")) { // cut off 'vt ' string temp = l.Substring(3); Vector2 v = new Vector2(); // Check if there's enough elements for a vertex if (temp.Trim().Count((char c) => c == ' ') > 0) { string[] textureCoordParts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); bool success = float.TryParse(textureCoordParts[0], out v.X); success |= float.TryParse(textureCoordParts[1], out v.Y); if (filename != null) { Console.WriteLine("!!! ERROR: cannot parse texture coordinate (line: {0}, file: {1}) !!!", l, filename); } else { Console.WriteLine("!!! ERROR: cannot parse texture coordinate (line: {0}, from string) !!!", l); } } else { if (filename != null) { Console.WriteLine("!!! ERROR: cannot parse texture coordinate (line: {0}, file: {1}) !!!", l, filename); } else { Console.WriteLine("!!! ERROR: cannot parse texture coordinate (line: {0}, from string) !!!", l); } } textureCoords.Add(v); } else if (l.StartsWith("f ")) { // remove 'f ' string temp = l.Substring(2); var face = new Tuple<TempVertex, TempVertex, TempVertex> ( new TempVertex(), new TempVertex(), new TempVertex() ); // Check if there's enough elements for a face (3) if (temp.Trim().Count((char c) => c == ' ') == 2) { string[] faceParts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); int i1, i2, i3; int t1, t2, t3; bool success = int.TryParse(faceParts[0].Split('/')[0], out i1); success |= int.TryParse(faceParts[1].Split('/')[0], out i2); success |= int.TryParse(faceParts[2].Split('/')[0], out i3); if (faceParts[0].Count((char c) => c == '/') == 2) { success |= int.TryParse(faceParts[0].Split('/')[1], out t1); success |= int.TryParse(faceParts[1].Split('/')[1], out t2); success |= int.TryParse(faceParts[2].Split('/')[1], out t3); } else { t1 = i1; t2 = i2; t3 = i3; } if (!success) { if (filename != null) { Console.WriteLine("!!! ERROR: cannot parse face (line: {0}, file: {1}) !!!", l, filename); } else { Console.WriteLine("!!! ERROR: cannot parse face (line: {0}, from string) !!!", l); } } else { TempVertex v1 = new TempVertex(i1, 0, t1); TempVertex v2 = new TempVertex(i2, 0, t2); TempVertex v3 = new TempVertex(i3, 0, t3); if (textureCoords.Count < t1) { textureCoords.Add(new Vector2()); } if (textureCoords.Count < t2) { textureCoords.Add(new Vector2()); } if (textureCoords.Count < t3) { textureCoords.Add(new Vector2()); } face = new Tuple<TempVertex, TempVertex, TempVertex>(v1, v2, v3); faces.Add(face); } } } } OBJVolume volume = new OBJVolume(); textureCoords.Add(new Vector2()); textureCoords.Add(new Vector2()); textureCoords.Add(new Vector2()); foreach (var f in faces) { FaceVertex v1 = new FaceVertex ( vertices[f.Item1.Vertex], new Vector3(), textureCoords[f.Item1.TextureCoord] ); FaceVertex v2 = new FaceVertex ( vertices[f.Item2.Vertex], new Vector3(), textureCoords[f.Item2.TextureCoord] ); FaceVertex v3 = new FaceVertex ( vertices[f.Item3.Vertex], new Vector3(), textureCoords[f.Item3.TextureCoord] ); volume.faces.Add(new Tuple<FaceVertex, FaceVertex, FaceVertex>(v1, v2, v3)); } return volume; }
public void BuildData(List <Model3D.MeshData> meshes) { if (meshes.Count != 0) { System.Console.WriteLine("duplicate"); } { int target_c = (int)TempMeshes.count + meshes.Count; if (meshes.Capacity < target_c) { meshes.Capacity = target_c; } } Dictionary <TempVertex, TempVertex> vert_temp = null; Model3D.MeshData md; TempMesh mesh_iter; TempVertex vert_iter; uint mesh_iter_n, vert_iter_n, next_ind, u_pos; int v_count; float fw, fh; for (mesh_iter = TempMeshes.first, mesh_iter_n = TempMeshes.count; 0 != mesh_iter_n; mesh_iter = mesh_iter.next, --mesh_iter_n) { v_count = null == (object)( vert_temp = TempVertex.Process(ref mesh_iter.references.list, utilize: vert_temp) ) ? 0 : vert_temp.Count; md = new Model3D.MeshData() { vertices = new Vector3[v_count], normals = new Vector3[v_count], colors = new Vector4[v_count], texCoord = new Vector2[v_count], indices = new uint[mesh_iter.references.list.count], texture = ContentPipe.LoadTexture( mesh_iter.references.bmp, mesh_iter.value.info.wrapS, mesh_iter.value.info.wrapT), material = mesh_iter.value.getMaterial(), }; fw = ((uint)mesh_iter.references.bmp.Width << 5); fh = ((uint)mesh_iter.references.bmp.Height << 5); for ( u_pos = 0, next_ind = 0, vert_iter = mesh_iter.references.list.first, vert_iter_n = mesh_iter.references.list.count; 0 != vert_iter_n; vert_iter = vert_iter.next, u_pos++, --vert_iter_n) { md.indices[u_pos] = vert_iter.index; if (vert_iter.index != next_ind) { continue; } md.vertices[next_ind] = vert_iter.value.position; md.texCoord[next_ind].X = vert_iter.value.texCoord.X / fw; md.texCoord[next_ind].Y = vert_iter.value.texCoord.Y / fh; md.normals[next_ind] = vert_iter.value.normal; md.colors[next_ind] = vert_iter.value.color; next_ind++; } meshes.Add(md); } }
public Mesh LoadFromString(string objModel) { // Seperate lines from the file List <string> lines = new List <string>(objModel.Split('\n')); // Lists to hold model data List <Vector3> verts = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Vector2> texs = new List <Vector2>(); List <Vector3> decodedVertices = new List <Vector3>(); List <Vector3> decodedNormals = new List <Vector3>(); List <Vector2> decodedUvCoords = new List <Vector2>(); List <Tuple <TempVertex, TempVertex, TempVertex> > faces = new List <Tuple <TempVertex, TempVertex, TempVertex> >(); // Base values verts.Add(new Vector3()); texs.Add(new Vector2()); normals.Add(new Vector3()); // Read file line by line foreach (String line in lines) { if (line.StartsWith("v ")) // Vertex definition { // Cut off beginning of line String temp = line.Substring(2); Vector3 vec = new Vector3(); if (temp.Trim().Count((char c) => c == ' ') == 2) // Check if there's enough elements for a vertex { String[] vertparts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Attempt to parse each part of the vertice bool success = float.TryParse(vertparts[0], NumberStyles.Any, CultureInfo.InvariantCulture, out vec.X); success |= float.TryParse(vertparts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out vec.Y); success |= float.TryParse(vertparts[2], NumberStyles.Any, CultureInfo.InvariantCulture, out vec.Z); // If any of the parses failed, report the error if (!success) { Console.WriteLine("Error parsing vertex: {0}", line); } } else { Console.WriteLine("Error parsing vertex: {0}", line); } verts.Add(vec); } else if (line.StartsWith("vt ")) // Texture coordinate { // Cut off beginning of line String temp = line.Substring(2); Vector2 vec = new Vector2(); if (temp.Trim().Count((char c) => c == ' ') > 0) // Check if there's enough elements for a vertex { String[] texcoordparts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Attempt to parse each part of the vertice bool success = float.TryParse(texcoordparts[0], NumberStyles.Any, CultureInfo.InvariantCulture, out vec.X); success |= float.TryParse(texcoordparts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out vec.Y); // If any of the parses failed, report the error if (!success) { Console.WriteLine("Error parsing texture coordinate: {0}", line); } } else { Console.WriteLine("Error parsing texture coordinate: {0}", line); } texs.Add(vec); } else if (line.StartsWith("vn ")) // Normal vector { // Cut off beginning of line String temp = line.Substring(2); Vector3 vec = new Vector3(); if (temp.Trim().Count((char c) => c == ' ') == 2) // Check if there's enough elements for a normal { String[] vertparts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Attempt to parse each part of the vertice bool success = float.TryParse(vertparts[0], NumberStyles.Any, CultureInfo.InvariantCulture, out vec.X); success |= float.TryParse(vertparts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out vec.Y); success |= float.TryParse(vertparts[2], NumberStyles.Any, CultureInfo.InvariantCulture, out vec.Z); // If any of the parses failed, report the error if (!success) { Console.WriteLine("Error parsing normal: {0}", line); } } else { Console.WriteLine("Error parsing normal: {0}", line); } normals.Add(vec); } else if (line.StartsWith("f ")) // Face definition { // Cut off beginning of line String temp = line.Substring(2); Tuple <TempVertex, TempVertex, TempVertex> face = new Tuple <TempVertex, TempVertex, TempVertex>(new TempVertex(), new TempVertex(), new TempVertex()); if (temp.Trim().Count((char c) => c == ' ') == 2) // Check if there's enough elements for a face { String[] faceparts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); int v1, v2, v3; int t1, t2, t3; int n1, n2, n3; // Attempt to parse each part of the face bool success = int.TryParse(faceparts[0].Split('/')[0], out v1); success |= int.TryParse(faceparts[1].Split('/')[0], out v2); success |= int.TryParse(faceparts[2].Split('/')[0], out v3); if (faceparts[0].Count((char c) => c == '/') >= 2) { success |= int.TryParse(faceparts[0].Split('/')[1], out t1); success |= int.TryParse(faceparts[1].Split('/')[1], out t2); success |= int.TryParse(faceparts[2].Split('/')[1], out t3); success |= int.TryParse(faceparts[0].Split('/')[2], out n1); success |= int.TryParse(faceparts[1].Split('/')[2], out n2); success |= int.TryParse(faceparts[2].Split('/')[2], out n3); } else { if (texs.Count > v1 && texs.Count > v2 && texs.Count > v3) { t1 = v1; t2 = v2; t3 = v3; } else { t1 = 0; t2 = 0; t3 = 0; } if (normals.Count > v1 && normals.Count > v2 && normals.Count > v3) { n1 = v1; n2 = v2; n3 = v3; } else { n1 = 0; n2 = 0; n3 = 0; } } // If any of the parses failed, report the error if (!success) { Console.WriteLine("Error parsing face: {0}", line); } else { TempVertex tv1 = new TempVertex(v1, n1, t1); TempVertex tv2 = new TempVertex(v2, n2, t2); TempVertex tv3 = new TempVertex(v3, n3, t3); face = new Tuple <TempVertex, TempVertex, TempVertex>(tv1, tv2, tv3); faces.Add(face); } } else { Console.WriteLine("Error parsing face: {0}", line); } } } // Create the ObjVolume Mesh loadedModel = new Mesh(); foreach (var face in faces) { FaceVertex v1 = new FaceVertex(verts[face.Item1.Vertex], normals[face.Item1.Normal], texs[face.Item1.Texcoord]); FaceVertex v2 = new FaceVertex(verts[face.Item2.Vertex], normals[face.Item2.Normal], texs[face.Item2.Texcoord]); FaceVertex v3 = new FaceVertex(verts[face.Item3.Vertex], normals[face.Item3.Normal], texs[face.Item3.Texcoord]); Vector2 calculatedUV = new Vector2(texs[face.Item1.Texcoord].X, 1.0f - texs[face.Item1.Texcoord].Y); Vector2 calculatedUV2 = new Vector2(texs[face.Item2.Texcoord].X, 1.0f - texs[face.Item2.Texcoord].Y); Vector2 calculatedUV3 = new Vector2(texs[face.Item3.Texcoord].X, 1.0f - texs[face.Item3.Texcoord].Y); decodedVertices.AddRange(new Vector3[] { verts[face.Item1.Vertex], verts[face.Item2.Vertex], verts[face.Item3.Vertex] }); decodedNormals.AddRange(new Vector3[] { normals[face.Item1.Normal], normals[face.Item2.Normal], normals[face.Item3.Normal] }); decodedUvCoords.AddRange(new Vector2[] { calculatedUV, calculatedUV2, calculatedUV3 }); } loadedModel.Indeces = Enumerable.Range(0, decodedVertices.Count).ToArray(); loadedModel.Vertices = decodedVertices.ToArray(); loadedModel.Normals = decodedNormals.ToArray(); loadedModel.UvCoords = decodedUvCoords.ToArray(); return(loadedModel); }
public static MyComplexObjectFactory3 LoadFromString(string obj) { Dictionary <String, int> materials = new Dictionary <string, int>(); String curMaterial = ""; NumberStyles style = NumberStyles.Float; CultureInfo culture = CultureInfo.CreateSpecificCulture("en-US"); // Seperate lines from the file List <String> lines = new List <string>(obj.Split('\n')); // Lists to hold model data List <Vector3> verts = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Vector2> texs = new List <Vector2>(); List <Tuple <TempVertex, TempVertex, TempVertex> > faces = new List <Tuple <TempVertex, TempVertex, TempVertex> >(); // Base values verts.Add(new Vector3()); texs.Add(new Vector2()); normals.Add(new Vector3()); // Read file line by line foreach (String line in lines) { if (line.StartsWith("v ")) // Vertex definition { // Cut off beginning of line String temp = line.Substring(2); Vector3 vec = new Vector3(); if (temp.Trim().Count((char c) => c == ' ') == 2) // Check if there's enough elements for a vertex { String[] vertparts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Attempt to parse each part of the vertice bool success = float.TryParse(vertparts[0], style, culture, out vec.X); success |= float.TryParse(vertparts[1], style, culture, out vec.Y); success |= float.TryParse(vertparts[2], style, culture, out vec.Z); // If any of the parses failed, report the error if (!success) { Console.WriteLine("Error parsing vertex: {0}", line); } } else { Console.WriteLine("Error parsing vertex: {0}", line); } verts.Add(vec); } else if (line.StartsWith("vt ")) // Texture coordinate { // Cut off beginning of line String temp = line.Substring(2); Vector2 vec = new Vector2(); if (temp.Trim().Count((char c) => c == ' ') > 0) // Check if there's enough elements for a vertex { String[] texcoordparts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Attempt to parse each part of the vertice bool success = float.TryParse(texcoordparts[0], style, culture, out vec.X); success |= float.TryParse(texcoordparts[1], style, culture, out vec.Y); // If any of the parses failed, report the error if (!success) { Console.WriteLine("Error parsing texture coordinate: {0}", line); } } else { Console.WriteLine("Error parsing texture coordinate: {0}", line); } texs.Add(vec); } else if (line.StartsWith("vn ")) // Normal vector { // Cut off beginning of line String temp = line.Substring(2); Vector3 vec = new Vector3(); if (temp.Trim().Count((char c) => c == ' ') == 2) // Check if there's enough elements for a normal { String[] vertparts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Attempt to parse each part of the vertice bool success = float.TryParse(vertparts[0], style, culture, out vec.X); success |= float.TryParse(vertparts[1], style, culture, out vec.Y); success |= float.TryParse(vertparts[2], style, culture, out vec.Z); // If any of the parses failed, report the error if (!success) { Console.WriteLine("Error parsing normal: {0}", line); } } else { Console.WriteLine("Error parsing normal: {0}", line); } normals.Add(vec); } else if (line.StartsWith("f ")) // Face definition { // Cut off beginning of line String temp = line.Substring(2); Tuple <TempVertex, TempVertex, TempVertex> face = new Tuple <TempVertex, TempVertex, TempVertex>(new TempVertex(), new TempVertex(), new TempVertex()); if (temp.Trim().Count((char c) => c == ' ') >= 2) // Check if there's enough elements for a face { String[] faceparts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); bool success = true; if (temp.Trim().Count((char c) => c == ' ') == 3) { int v1, v2, v3; int v11, v22, v33; int t1, t2, t3; int t11, t22, t33; int n1, n2, n3; int n11, n22, n33; // Attempt to parse each part of the face success = int.TryParse(faceparts[0].Split('/')[0], out v1); success |= int.TryParse(faceparts[1].Split('/')[0], out v2); success |= int.TryParse(faceparts[2].Split('/')[0], out v3); success |= int.TryParse(faceparts[0].Split('/')[0], out v11); success |= int.TryParse(faceparts[2].Split('/')[0], out v22); success |= int.TryParse(faceparts[3].Split('/')[0], out v33); if (faceparts[0].Count((char c) => c == '/') >= 2) { success |= int.TryParse(faceparts[0].Split('/')[1], out t1); success |= int.TryParse(faceparts[1].Split('/')[1], out t2); success |= int.TryParse(faceparts[2].Split('/')[1], out t3); success |= int.TryParse(faceparts[0].Split('/')[1], out t11); success |= int.TryParse(faceparts[2].Split('/')[1], out t22); success |= int.TryParse(faceparts[3].Split('/')[1], out t33); success |= int.TryParse(faceparts[0].Split('/')[2], out n1); success |= int.TryParse(faceparts[1].Split('/')[2], out n2); success |= int.TryParse(faceparts[2].Split('/')[2], out n3); success |= int.TryParse(faceparts[0].Split('/')[2], out n11); success |= int.TryParse(faceparts[2].Split('/')[2], out n22); success |= int.TryParse(faceparts[3].Split('/')[2], out n33); } else { t1 = t2 = t3 = t11 = t22 = t33 = n1 = n2 = n3 = n11 = n22 = n33 = 0; } // If any of the parses failed, report the error if (!success) { Console.WriteLine("Error parsing face: {0}", line); } else { TempVertex tv1 = new TempVertex(v1, n1, t1, curMaterial); TempVertex tv2 = new TempVertex(v2, n2, t2, curMaterial); TempVertex tv3 = new TempVertex(v3, n3, t3, curMaterial); TempVertex tv11 = new TempVertex(v11, n11, t11, curMaterial); TempVertex tv22 = new TempVertex(v22, n22, t22, curMaterial); TempVertex tv33 = new TempVertex(v33, n33, t33, curMaterial); face = new Tuple <TempVertex, TempVertex, TempVertex>(tv1, tv2, tv3); faces.Add(face); face = new Tuple <TempVertex, TempVertex, TempVertex>(tv11, tv22, tv33); faces.Add(face); } } else { int v1, v2, v3; int t1, t2, t3; int n1, n2, n3; // Attempt to parse each part of the face success = int.TryParse(faceparts[0].Split('/')[0], out v1); success |= int.TryParse(faceparts[1].Split('/')[0], out v2); success |= int.TryParse(faceparts[2].Split('/')[0], out v3); if (faceparts[0].Count((char c) => c == '/') >= 2) { success |= int.TryParse(faceparts[0].Split('/')[1], out t1); success |= int.TryParse(faceparts[1].Split('/')[1], out t2); success |= int.TryParse(faceparts[2].Split('/')[1], out t3); success |= int.TryParse(faceparts[0].Split('/')[2], out n1); success |= int.TryParse(faceparts[1].Split('/')[2], out n2); success |= int.TryParse(faceparts[2].Split('/')[2], out n3); } else { if (texs.Count > v1 && texs.Count > v2 && texs.Count > v3) { t1 = v1; t2 = v2; t3 = v3; } else { t1 = 0; t2 = 0; t3 = 0; } if (normals.Count > v1 && normals.Count > v2 && normals.Count > v3) { n1 = v1; n2 = v2; n3 = v3; } else { n1 = 0; n2 = 0; n3 = 0; } } // If any of the parses failed, report the error if (!success) { Console.WriteLine("Error parsing face: {0}", line); } else { TempVertex tv1 = new TempVertex(v1, n1, t1, curMaterial); TempVertex tv2 = new TempVertex(v2, n2, t2, curMaterial); TempVertex tv3 = new TempVertex(v3, n3, t3, curMaterial); face = new Tuple <TempVertex, TempVertex, TempVertex>(tv1, tv2, tv3); faces.Add(face); } } } else { Console.WriteLine("Error parsing face: {0}", line); } } else if (line.StartsWith("usemtl ")) { String temp = line.Substring(7); curMaterial = temp; } } // Create the ObjVolume MyComplexObjectFactory3 vol = new MyComplexObjectFactory3(); foreach (var face in faces) { FaceVertex2 v1 = new FaceVertex2(verts[face.Item1.Vertex], normals[face.Item1.Normal], texs[face.Item1.Texcoord], face.Item1.matName); FaceVertex2 v2 = new FaceVertex2(verts[face.Item2.Vertex], normals[face.Item2.Normal], texs[face.Item2.Texcoord], face.Item2.matName); FaceVertex2 v3 = new FaceVertex2(verts[face.Item3.Vertex], normals[face.Item3.Normal], texs[face.Item3.Texcoord], face.Item3.matName); vol.faces.Add(new Tuple <FaceVertex2, FaceVertex2, FaceVertex2>(v1, v2, v3)); } vol.mapIndices(vol.faces); return(vol); }
public void AddValue(TempVertex vertex, Rectangle rect) { _values.Add((vertex, rect)); }