예제 #1
0
        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);
        }
예제 #2
0
        //======================================================================================================================
        //==            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);
        }
예제 #3
0
        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]);
            }
        }