public static Scene FromString(string fileContent) { Scene scene = new Scene(); fileContent = fileContent.ToLower().Replace("\r", string.Empty).Replace("\t", string.Empty).Replace(".", ","); var splitted = fileContent.Split('}'); foreach (var split in splitted) { var innerSplit = split.Split('{'); var name = innerSplit[0].Trim(); switch (name) { case "camera": Camera camera = Camera.FromString(innerSplit[1]); scene.camera = camera; break; case "light": Light light = Light.FromString(innerSplit[1]); scene.lights.Add(light); break; case "material": Material material = Material.FromString(innerSplit[1]); scene.materials.Add(material); break; case "solid": Solid solid = Solid.FromString(innerSplit[1]); scene.solids.Add(solid); break; case "image": Enox.Framework.Image image = Enox.Framework.Image.FromString(innerSplit[1]); scene.image = image; break; } } return scene; }
public static Color Trace(Scene scene, Ray r, int max) { IntersectionResult tr = NearestIntersection(scene, r); if (tr.triangle != null) { //v1: //return scene.Materials[tr.MaterialIndex].Color; // v2: Color c = new Color(0, 0, 0, 1); // contribuição luz ambiente: foreach (var light in scene.Lights) { c += light.Color * scene.Materials[tr.triangle.MaterialIndex].Color * scene.Materials[tr.triangle.MaterialIndex].Ambient; } // contribuição luz difusa foreach (var light in scene.Lights) { Vector3 l = light.Position - tr.point; float dist = Vector3.Length(l); l = Vector3.Normalize(l); float cost = tr.triangle.Normal.Dot(l); Ray s = new Ray() { origin = tr.point, direction = l }; if (IsExposedToLight(scene, s, dist) && cost > 0) c = c + light.Color * scene.Materials[tr.triangle.MaterialIndex].Color * scene.Materials[tr.triangle.MaterialIndex].Diffuse * cost; } // reflection, material reflective? if (scene.Materials[tr.triangle.MaterialIndex].Reflection > 0.0f) { float c1 = -tr.triangle.Normal.Dot(r.direction); Vector3 rl = Vector3.Normalize(r.direction + (tr.triangle.Normal * 2.0f * c1)); Ray refl = new Ray() { origin = tr.point, direction = rl }; c += (max > 0 ? Ray.Trace(scene, refl, --max) : new Color(0, 0, 0)) * scene.Materials[tr.triangle.MaterialIndex].Reflection * scene.Materials[tr.triangle.MaterialIndex].Color; } else if (scene.Materials[tr.triangle.MaterialIndex].RefractionCoef > 0.0f) { Vector3 n1 = new Vector3(); double m1, m2; if (RayEnters(r.direction, tr.triangle.Normal)) { n1 = tr.triangle.Normal; m1 = 1.0f; // air m2 = scene.Materials[tr.triangle.MaterialIndex].RefractionIndex; } else { n1 = tr.triangle.Normal * -1; m1 = scene.Materials[tr.triangle.MaterialIndex].RefractionIndex; m2 = 1.0f; } double c1 = -(n1).Dot(r.direction); double m = m1 / m2; double c2 = Math.Sqrt(1 - m * m * (1 - c1 * c1)); Vector3 rr = Vector3.Normalize((r.direction * (float)m) + n1 * (float)(m * c1 - c2)); Ray refr = new Ray() { origin = tr.point, direction = rr }; c += (max > 0 ? Ray.Trace(scene, refr, --max) : new Color(0, 0, 0)) * scene.Materials[tr.triangle.MaterialIndex].RefractionCoef * scene.Materials[tr.triangle.MaterialIndex].Color; } return c; } return scene.Image.Color; }
private static IntersectionResult NearestIntersection(Scene scene, Ray r) { Vector3 intersectionPoint = new Vector3(0, 0, 0); double tmin = double.MaxValue; Triangle nearestTriangle = null; foreach (Solid s in scene.Solids) { foreach (Triangle tr in s.Triangles) { float t = (float)Intersection(r, tr); if (t > 0 && t < tmin) { tmin = t; nearestTriangle = tr; intersectionPoint = r.origin + (r.direction * t); // p(t) } } } return new IntersectionResult() { triangle = nearestTriangle, point = intersectionPoint }; }
private static bool IsExposedToLight(Scene scene, Ray r, float dist) { // if (intersection => light : triangles) return true; // basta encontrar 1 (mas dentro da largura entre a luz e o ponto) foreach (Solid s in scene.Solids) { foreach (Triangle tr in s.Triangles) { float t = (float)Intersection(r, tr); if (t > 0 && t < dist) return false; } } return true; }
private void loadToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "Text Files (*.txt)|*.txt|SceneX Files (.scx)|*.scx"; ofd.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory + "\\Content\\"; if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK && ofd.FileName != string.Empty) { try { if (ofd.FileName.ToLower().EndsWith(".scx")) { myScene = (Scene)Serializer.DeserializeObject(ofd.FileName); } else { myScene = Scene.FromFile(ofd.FileName); } SetScene(); SetViewport(); SetDisplayList(); sceneViewGLControl.Invalidate(); propertyGrid1.SelectedObject = myScene; //MessageBox.Show("Scene loaded with success!", "Sucess!"); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error!"); } } }