using System; using System.IO; using System.Collections.Generic; using System.Globalization; using OpenTK; namespace org.budnhead.graphics { public class LoadedModel : Model3D { string sourceName; public LoadedModel(string filename) { sourceName = filename; load(new StreamReader(filename)); } public LoadedModel(string filename,float scale) { sourceName = filename; load(new StreamReader(filename),scale); } public LoadedModel(Stream stream){ load(new StreamReader(stream),1.0f); } private void load(TextReader reader){ load(reader,1); } private void load(TextReader reader,float scale){ List vertexes,normals; List triangles; string line; float[] min = new float[3]; float[] max = new float[3]; vertexes = new List(); normals = new List(); triangles = new List(); vertexes.Add(new Vector3()); normals.Add(new Vector3()); while ( (line = reader.ReadLine()) != null){ string[] fields = line.Split(new string[0],StringSplitOptions.RemoveEmptyEntries); if (fields.Length > 0) switch (fields[0]){ case "v": float x,y,z; x = (float)Double.Parse(fields[1],CultureInfo.InvariantCulture); y = (float)Double.Parse(fields[2],CultureInfo.InvariantCulture); z = (float)Double.Parse(fields[3],CultureInfo.InvariantCulture); x *= scale; y *= scale; z *= scale; vertexes.Add( new Vector3(x,y,z) ); min[0] = min[0] > x ? x : min[0]; min[1] = min[1] > y ? y : min[1]; min[2] = min[2] > z ? z : min[2]; max[0] = max[0] < x ? x : max[0]; max[1] = max[1] < y ? y : max[1]; max[2] = max[2] < z ? z : max[2]; break; case "vn": normals.Add( (new Vector3( float.Parse(fields[1],CultureInfo.InvariantCulture), float.Parse(fields[2],CultureInfo.InvariantCulture), float.Parse(fields[3],CultureInfo.InvariantCulture) ) )); break; case "f": surfaceindeces si0,si1,si2; si0 = new surfaceindeces(fields[1]); si1 = new surfaceindeces(fields[2]); si2 = new surfaceindeces(fields[3]); triangles.Add(new triangle( vertexes[si0.vertex], vertexes[si1.vertex], vertexes[si2.vertex], normals[si0.normal], normals[si1.normal], normals[si2.normal])); break; } } Console.WriteLine("Loaded {0}: {1} vertexes {2} normals",sourceName,vertexes.Count,normals.Count); Console.WriteLine("Dimensions: {0}/{1}/{2} - {3}/{4}/{5}",min[0],min[1],min[2],max[0],max[1],max[2]); vertexes.Clear(); normals.Clear(); foreach (triangle t in triangles){ vertexes.Add( t.a ); vertexes.Add( t.b ); vertexes.Add( t.c ); normals.Add( -t.na ); normals.Add( -t.nb ); normals.Add( -t.nc ); } this.vertexes = vertexes.ToArray(); this.normals = normals.ToArray(); bind(); } struct triangle{ public Vector3 a,b,c; public Vector3 na,nb,nc; public triangle(Vector3 a,Vector3 b,Vector3 c,Vector3 na,Vector3 nb,Vector3 nc){ this.a = a; this.b = b; this.c = c; this.na = na; this.nb = nb; this.nc = nc; } } struct surfaceindeces { public int vertex,texture,normal; public surfaceindeces(string token){ string[] l = token.Split('/'); vertex = l[0].Length == 0 ? 0 : int.Parse(l[0]); texture = l[1].Length == 0 ? 0 : int.Parse(l[1]); normal = l[2].Length == 0 ? 0 : int.Parse(l[2]); } } } }