public MainWindow() { InitializeComponent(); const int image_width = 400; const int image_height = 236; double aspect_ratio = (double)image_width / (double)image_height; const int samples_per_pixel = 10; const int max_depth = 50; //World var world = new hittable_list(); var material = new Metal(new Vektor(.7, .7, .7), 0.7); var material1 = new Metal(new Vektor(1, 0.32, 0.36), 0); var material2 = new Metal(new Vektor(0.90, 0.76, 0.46), 0); var material3 = new Metal(new Vektor(0.65, 0.77, 0.97), 0); var material4 = new Metal(new Vektor(0.90, 0.90, 0.90), 0); world.Add(new sphere(new Vektor(0.0, -10004, -20), 10000, material)); world.Add(new sphere(new Vektor(0, 0, -20), 4, material1)); world.Add(new sphere(new Vektor(5, -1, -15), 2, material2)); world.Add(new sphere(new Vektor(5, 0, -25), 3, material3)); world.Add(new sphere(new Vektor(-5.5, 0, -15), 3, material4)); //Camera Vektor lookfrom = new Vektor(0, 0, 0); Vektor lookat = new Vektor(0, 0, -1); Vektor vup = new Vektor(0, 1, 0); var dist_to_focus = 10; var aperture = 0.1; Camera cam = new Camera(lookfrom, lookat, vup, 50, aspect_ratio, aperture, dist_to_focus); Vektor[,] vArr = new Vektor[image_height, image_width]; Bitmap bmp = new Bitmap(image_width, image_height); Parallel.For(0, image_height, j => { for (int i = 0; i < image_width; i++) { Vektor pixel_color = new Vektor(0, 0, 0); for (int s = 0; s < samples_per_pixel; s++) { var u = ((double)i + Mathe.random_double()) / (image_width - 1); var v = ((double)j + Mathe.random_double()) / (image_height - 1); ray r = cam.get_ray(u, v); pixel_color += ray.ray_color(r, world, max_depth); } vArr[j, i] = pixel_color; } }); for (int j = 0; j < image_height; j++) { for (int i = 0; i < image_width; i++) { bmp.SetPixel(i, (j - (image_height - 1)) * -1, Vektor.toColor(vArr[j, i], samples_per_pixel)); } } image.Source = BitmapToImageSource(bmp); }
public static Model FromObjFile(string path, IMaterial defaultMaterial) { var root = Path.GetDirectoryName(path); var model = new Model(); var lastMaterial = defaultMaterial; using (var file = new FileStream(path, FileMode.Open)) using (var reader = new StreamReader(file)) { while (!reader.EndOfStream) { var line = reader.ReadLine(); // dismiss blank space if (string.IsNullOrWhiteSpace(line)) { continue; } // use comment to inform texture if (line.StartsWith("#m")) { var words = line.Split(' '); var materialStr = words[1]; switch (materialStr) { case "metal": { var arg1 = float.Parse(words[2]); var arg2 = words[3]; Debug.Assert(root != null, nameof(root) + " != null"); var imagePath = Path.Combine(root, arg2); if (!Directory.Exists(imagePath)) { throw new FileNotFoundException(imagePath); } lastMaterial = new Metal(new BitmapTexture(imagePath), arg1); break; } } } // dismiss comment if (line.StartsWith("#")) { continue; } var seps = line.Split(' '); var pattern = seps[0]; if (pattern == "f") { // define face // only get index of vertex seps = seps.Select(it => { var p = it.IndexOf("/", StringComparison.Ordinal); return(p == -1 ? it : it.Substring(0, p)); }).ToArray(); switch (seps.Length) { case 4: { var arg1 = int.Parse(seps[1]) - 1; var arg2 = int.Parse(seps[2]) - 1; var arg3 = int.Parse(seps[3]) - 1; model.AddFace(arg1, arg2, arg3, lastMaterial); break; } case 5: { var arg1 = int.Parse(seps[1]) - 1; var arg2 = int.Parse(seps[2]) - 1; var arg3 = int.Parse(seps[3]) - 1; var arg4 = int.Parse(seps[4]) - 1; model.AddFace(arg1, arg2, arg3, lastMaterial); model.AddFace(arg1, arg2, arg4, lastMaterial); break; } default: throw new InvalidDataException(path); } } else if (pattern == "v") { // is vertex var arg1 = float.Parse(seps[1]); var arg2 = float.Parse(seps[2]); var arg3 = float.Parse(seps[3]); model.AddVertex(arg1, arg2, arg3); } } } return(model); }