public Scene(string n, AABBTree t, Sphere[] bs, Sphere[] l, Camera c) { rdm = new Random(); name = n; spheresTree = t; bigSpheres = bs; lights = l; camera = c; }
static void Main(string[] args) { Sphere leftWall = new Sphere(new Vector3((float)-1e5, 360, 500), (float)1e5, new Material(MaterialType.Difuse, new Vector3(0.1f, 1, 0.1f))); Sphere rightWall = new Sphere(new Vector3((float)1e5 + 1280, 360, 500), (float)1e5, new Material(MaterialType.Difuse, new Vector3(1, 0.1f, 0.1f))); Sphere topWall = new Sphere(new Vector3(640, (float)-1e5, 500), (float)1e5, new Material(MaterialType.Difuse, new Vector3(0.1f, 1, 1))); Sphere bottomWall = new Sphere(new Vector3(640, (float)1e5 + 720, 500), (float)1e5, new Material(MaterialType.Difuse, new Vector3(1, 1, 0.1f))); Sphere backWall = new Sphere(new Vector3(640, 360, (float)1e5 + 1000), (float)1e5, new Material(MaterialType.Difuse, new Vector3(0.1f, 0.1f, 1))); Sphere frontWall = new Sphere(new Vector3(640, 360, (float)-1e5), (float)1e5, new Material(MaterialType.Difuse, new Vector3(0.1f, 0.1f, 1))); //Sphere leftWall = new Sphere(new Vector3((float)-1e5, 360, 500), (float)1e5, new Material(MaterialType.Mirror, new Vector3(0.9f, 0.9f, 0.9f))); //Sphere rightWall = new Sphere(new Vector3((float)1e5 + 1280, 360, 500), (float)1e5, new Material(MaterialType.Mirror, new Vector3(0.9f, 0.9f, 0.9f))); //Sphere topWall = new Sphere(new Vector3(640, (float)-1e5, 500), (float)1e5, new Material(MaterialType.Mirror, new Vector3(0.9f, 0.9f, 0.9f))); //Sphere bottomWall = new Sphere(new Vector3(640, (float)1e5 + 720, 500), (float)1e5, new Material(MaterialType.Mirror, new Vector3(0.9f, 0.9f, 0.9f))); //Sphere backWall = new Sphere(new Vector3(640, 360, (float)1e5 + 1000), (float)1e5, new Material(MaterialType.Mirror, new Vector3(0.9f, 0.9f, 0.9f))); //Sphere frontWall = new Sphere(new Vector3(640, 360, (float)-1e5), (float)1e5, new Material(MaterialType.Mirror, new Vector3(0.9f, 0.9f, 0.9f))); Sphere sLeft = new Sphere(new Vector3(100, 360, 100), 100, new Material(MaterialType.Difuse, new Vector3(1, 0.1f, 0.1f))); Sphere sLeftDown = new Sphere(new Vector3(370, 490, 300), 50, new Material(MaterialType.Mirror, new Vector3(0.1f, 0.1f, 1))); Sphere sLeftUp = new Sphere(new Vector3(370, 230, 300), 50, new Material(MaterialType.Mirror, new Vector3(1, 0.1f, 0.1f))); Sphere sDown = new Sphere(new Vector3(640, 620, 500), 100, new Material(MaterialType.Difuse, new Vector3(0.1f, 0.1f, 1))); Sphere sUp = new Sphere(new Vector3(640, 100, 500), 100, new Material(MaterialType.Difuse, new Vector3(1, 1, 0.1f))); Sphere sRightDown = new Sphere(new Vector3(910, 490, 700), 50, new Material(MaterialType.Mirror, new Vector3(0.1f, 1, 0.1f))); Sphere sRightUp = new Sphere(new Vector3(910, 230, 700), 50, new Material(MaterialType.Mirror, new Vector3(1, 1, 0.1f))); Sphere sRight = new Sphere(new Vector3(1180, 360, 900), 100, new Material(MaterialType.Difuse, new Vector3(0.1f, 1, 0.1f))); Sphere light = new Sphere(new Vector3(640, 360, 500), 10, new Material(MaterialType.Light, new Vector3(1000000, 1000000, 1000000))); Sphere light2 = new Sphere(new Vector3(100, 100, 100), 30, new Material(MaterialType.Light, new Vector3(1000000, 10000, 10000))); Sphere[] spheres = { light, light2, sDown, sUp, sLeft, sRight, sLeftDown, sLeftUp, sRightDown, sRightUp }; List <Sphere> sphL = new List <Sphere>(); sphL.AddRange(spheres); Random rdm = new Random(); for (int i = 0; i < 100; i++) { sphL.Add(new Sphere(new Vector3((float)(rdm.NextDouble() * 1280), (float)(rdm.NextDouble() * 720), (float)(rdm.NextDouble() * 1000)), (float)((rdm.NextDouble() * 15) + 5), new Material(MaterialType.Difuse, new Vector3((float)(rdm.NextDouble()), (float)(rdm.NextDouble()), (float)(rdm.NextDouble()))))); } AABBox parentBox = new AABBox(sphL[0]); for (int i = 1; i < sphL.Count; i++) { parentBox = new AABBox(parentBox, new AABBox(sphL[i])); } AABBTree spheresTree = new AABBTree(sphL, parentBox); Sphere[] bigSpheres = { leftWall, rightWall, topWall, bottomWall, backWall, frontWall }; Sphere[] lights = { light, light2 }; Camera cam = new Camera(new Vector3(0, 0, 0), 1280, 720, new Vector3(640, 360, -1000)); Scene scn = new Scene("Scene", spheresTree, bigSpheres, lights, cam); scn.DrawScene(10); }
//====================================================================================================================== //== INTERSECT TREE - test l'intersection du rayon r avec un arbre de boîtes englobantes == //====================================================================================================================== public ResIntersect intersectTree(AABBTree tree, Ray r) { ResIntersect res; res.t = -1; res.sph = null; if (tree.leaf) { res = Intersect(r, tree.sph); } else { if (AABBoxIntersect(tree.box, r)) { ResIntersect res1 = intersectTree(tree.tree1, r); ResIntersect res2 = intersectTree(tree.tree2, r); if (res1.t != -1) { if (res2.t != -1) { if (res1.t < res2.t) { res = res1; } else { res = res2; } } else { res = res1; } } else if (res2.t != -1) { res = res2; } } } return(res); }
public AABBTree(List <Sphere> spheres, AABBox b) { if (spheres.Count == 1) { leaf = true; sph = spheres[0]; } else { leaf = false; box = b; AABBox actualBox; List <AABBox> Xforward = new List <AABBox>(); spheres = spheres.OrderBy(v => v.center.X).ToList(); actualBox = new AABBox(spheres[0]); Xforward.Add(actualBox); for (int i = 1; i < spheres.Count - 1; i++) { actualBox = new AABBox(actualBox, new AABBox(spheres[i])); Xforward.Add(actualBox); } List <AABBox> Xbackward = new List <AABBox>(); spheres.Reverse(); actualBox = new AABBox(spheres[0]); Xbackward.Add(actualBox); for (int i = 1; i < spheres.Count - 1; i++) { actualBox = new AABBox(actualBox, new AABBox(spheres[i])); Xbackward.Add(actualBox); } List <AABBox> Yforward = new List <AABBox>(); spheres = spheres.OrderBy(v => v.center.Y).ToList(); actualBox = new AABBox(spheres[0]); Yforward.Add(actualBox); for (int i = 1; i < spheres.Count - 1; i++) { actualBox = new AABBox(actualBox, new AABBox(spheres[i])); Yforward.Add(actualBox); } List <AABBox> Ybackward = new List <AABBox>(); spheres.Reverse(); actualBox = new AABBox(spheres[0]); Ybackward.Add(actualBox); for (int i = 1; i < spheres.Count - 1; i++) { actualBox = new AABBox(actualBox, new AABBox(spheres[i])); Ybackward.Add(actualBox); } List <AABBox> Zforward = new List <AABBox>(); spheres = spheres.OrderBy(v => v.center.Z).ToList(); actualBox = new AABBox(spheres[0]); Zforward.Add(actualBox); for (int i = 1; i < spheres.Count - 1; i++) { actualBox = new AABBox(actualBox, new AABBox(spheres[i])); Zforward.Add(actualBox); } List <AABBox> Zbackward = new List <AABBox>(); spheres.Reverse(); actualBox = new AABBox(spheres[0]); Zbackward.Add(actualBox); for (int i = 1; i < spheres.Count - 1; i++) { actualBox = new AABBox(actualBox, new AABBox(spheres[i])); Zbackward.Add(actualBox); } List <AABBox> Forward = new List <AABBox>(); Forward.AddRange(Xforward); Forward.AddRange(Yforward); Forward.AddRange(Zforward); List <AABBox> Backward = new List <AABBox>(); Xbackward.Reverse(); Backward.AddRange(Xbackward); Ybackward.Reverse(); Backward.AddRange(Ybackward); Zbackward.Reverse(); Backward.AddRange(Zbackward); int indBestBox = 0; float bestCost = float.MaxValue; int nbForward = 1; int nbBackward = spheres.Count - 1; for (int i = 0; i < Forward.Count; i++) { float cost = Forward[i].getSurface() * nbForward + Backward[i].getSurface() * nbBackward; if (cost < bestCost) { bestCost = cost; indBestBox = i; } nbForward++; if (nbForward == spheres.Count) { nbForward = 1; } nbBackward--; if (nbBackward == 0) { nbBackward = spheres.Count - 1; } } int axis = (int)((indBestBox + 1) / (spheres.Count - 1)); switch (axis) { case 0: spheres = spheres.OrderBy(v => v.center.X).ToList(); break; case 1: spheres = spheres.OrderBy(v => v.center.Y).ToList(); break; case 2: spheres = spheres.OrderBy(v => v.center.Z).ToList(); break; } int pivot = (indBestBox + 1) % (spheres.Count - 1); if (pivot == 0) { pivot = spheres.Count - 1; } List <Sphere> spheresLeft = new List <Sphere>(); List <Sphere> spheresRight = new List <Sphere>(); for (int i = 0; i < spheres.Count; i++) { if (i < pivot) { spheresLeft.Add(spheres[i]); } else { spheresRight.Add(spheres[i]); } } tree1 = new AABBTree(spheresLeft, Forward[indBestBox]); tree2 = new AABBTree(spheresRight, Backward[indBestBox]); } }