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); }
//====================================================================================================================== //== AXE ALIGNED BOUNDIND BOX INTERSECT - l'intersection rayon/boite englobante == //====================================================================================================================== public bool AABBoxIntersect(AABBox box, Ray r) { float txmin = (box.pmin.X - r.point.X) / r.direction.X; float txmax = (box.pmax.X - r.point.X) / r.direction.X; if (txmin > txmax) { float tmp = txmin; txmin = txmax; txmax = tmp; } float tymin = (box.pmin.Y - r.point.Y) / r.direction.Y; float tymax = (box.pmax.Y - r.point.Y) / r.direction.Y; if (tymin > tymax) { float tmp = tymin; tymin = tymax; tymax = tmp; } float tzmin = (box.pmin.Z - r.point.Z) / r.direction.Z; float tzmax = (box.pmax.Z - r.point.Z) / r.direction.Z; if (tzmin > tzmax) { float tmp = tzmin; tzmin = tzmax; tzmax = tmp; } if ((txmin > tymax) || (tymin > txmax)) { return(false); } if ((txmin > tzmax) || (tzmin > txmax)) { return(false); } return(true); }
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]); } }