예제 #1
0
 // Create sphere
 public Sphere(VPoint location, float radius, Material mat)
 {
     Mat      = mat;
     Location = location;
     Radius   = radius;
     Radius2  = radius * radius;
 }
예제 #2
0
 // Intersects with a ray, returns the length at which the ray hits the sphere, -1 if no intersection
 override public float Intersect(Ray ray)
 {
     // If the ray starts inside of the sphere
     if ((Location - ray.Location).Length < Radius - 0.001f)
     {
         float a = ray.Direction * ray.Direction;
         float b = ray.Direction * (ray.Location - Location) * 2;
         float c = (ray.Location - Location) * (ray.Location - Location) - Radius2;
         float d = b * b - 4 * a * c;
         d = (float)Math.Sqrt(d);
         float distance = Math.Max((-b + d) / (2 * a), (-b - d) / (2 * a));
         return(distance);
     }
     // Otherwise the ray starts outside of the sphere
     else
     {
         VPoint c = Location - ray.Location;
         float  t = c * ray.Direction;
         VPoint q = c - t * ray.Direction;
         float  p = q * q;
         if (p > Radius2)
         {
             return(-1);
         }
         t -= (float)Math.Sqrt(Radius2 - p);
         return(t);
     }
 }
예제 #3
0
        abstract public float Intersect(Ray ray); // Misschien naar abstract public void Intersect en de intersection opslaan in class Intersect?

        // Reflect a ray
        public Ray Reflect(Ray ray, VPoint location)
        {
            VPoint d = ray.Direction;
            VPoint n = normal(location).Direction;

            return(new Ray(location, (d - (2 * (d * n) * n)).Normalize()));
        }
예제 #4
0
 // Create a light source
 public Light(VPoint location, float r, float g, float b)
 {
     Location = location;
     Red      = r;
     Green    = g;
     Blue     = b;
 }
예제 #5
0
 // Create ray
 public Ray(VPoint Locationinit, VPoint Directioninit)
 {
     Location  = Locationinit;
     Direction = Directioninit.Normalize();
     Distance  = float.PositiveInfinity;
     recursion = 0;
 }
예제 #6
0
 // Create an intersection
 public Intersection(Ray ray, VPoint location, Primitive p)
 {
     Distance = (location - ray.Location).Length;
     Ray      = ray;
     Location = location;
     ThingWeIntersectedWith = p;
 }
예제 #7
0
        public override void debug(Surface screen)
        {
            float  newradius = (float)Math.Sqrt(Radius2 - Location.Y);
            VPoint middle    = Location;

            middle.Y = 0;
            VPoint previousDrawPoint = new VPoint(0, 0, 1);

            previousDrawPoint  = previousDrawPoint.Normalize() * Radius;
            previousDrawPoint += middle;
            for (int i = 1; i < 121; i++)
            {
                VPoint DrawPoint = new VPoint(Game.SinTable[(i * 3) % 360], 0, Game.SinTable[(i * 3 + 90) % 360]);
                DrawPoint  = DrawPoint.Normalize() * Radius;
                DrawPoint += middle;
                int x1, x2;
                x1 = DrawPoint.transform("x");
                x2 = previousDrawPoint.transform("x");
                if (x1 <= 512 && x2 <= 512)
                {
                    screen.Line(x1, DrawPoint.transform("y"), x2, previousDrawPoint.transform("y"), Mat.GetColor(new VPoint(0, 0, 0)).getColor());
                }
                previousDrawPoint = DrawPoint;
            }
        }
예제 #8
0
 //Sets the vertical direction of the virtual screen after the camera is rotated.
 private void setYDirection()
 {
     YDirection = XDirection % Orientation;
     if (YDirection.Y > 0)
     {
         YDirection *= -1;
     }
 }
예제 #9
0
        // Get a ray through given coordinates
        public Ray getRay(float x, float y)
        {
            x /= 256;
            y /= 256;
            VPoint positionOnScreen = Upperleft;

            positionOnScreen += x * XDirection + y * YDirection;
            return(new Ray(Position, (positionOnScreen - Position).Normalize()));
        }
예제 #10
0
 //To translate the camera
 public void moveCamera(VPoint direction)
 {
     Position   += direction;
     Upperleft  += direction;
     Upperright += direction;
     Lowerleft  += direction;
     Lowerright += direction;
     Target     += direction;
 }
예제 #11
0
 //To rotate the camera
 public void turnCamera(VPoint direction)
 {
     Orientation = (Orientation + direction).Normalize();
     Target      = Position + Orientation;
     setXDirection();
     setYDirection();
     Upperleft  = Target - XDirection - YDirection;
     Upperright = Target + XDirection - YDirection;
     Lowerleft  = Target - XDirection + YDirection;
     Lowerright = Target + XDirection - YDirection;
 }
예제 #12
0
 // Create camera
 public Camera()
 {
     Position    = new VPoint(0, 0, 0);
     Orientation = new VPoint(0, 0, 1);
     Target      = Position + Orientation;
     Upperleft   = new VPoint(-1, 1, 1);
     XDirection  = new VPoint(1, 0, 0);
     YDirection  = new VPoint(0, -1, 0);
     Upperright  = new VPoint(1, 1, 1);
     Lowerleft   = new VPoint(-1, -1, 1);
     Lowerright  = new VPoint(1, -1, 1);
 }
예제 #13
0
 // Determine the colors on the scene
 public VPoint color(Scene scene)
 {
     if (ThingWeIntersectedWith != null)
     {
         ShadowRays = new Ray[scene.Lights.Length];
         VPoint diffusion = new VPoint();
         for (int i = 0; i < scene.Lights.Length; i++)
         {
             Light  light = scene.Lights[i];
             VPoint shadowRayDirection = (light.Location - Location);
             ShadowRays[i]          = new Ray(Location + 0.00001f * shadowRayDirection.Normalize(), shadowRayDirection.Normalize());
             ShadowRays[i].Distance = shadowRayDirection.Length;
             float distance = scene.intersect(ShadowRays[i]).Distance;
             if (distance >= shadowRayDirection.Length - 2 * 0.00001)
             {
                 ShadowRays[i].Distance = distance;
                 VPoint j = ThingWeIntersectedWith.normal(Location).Direction;
                 if (j * Ray.Direction > 0)
                 {
                     j *= -1;
                 }
                 diffusion += light.reflectedColor(ThingWeIntersectedWith.Mat.GetColor(Location), 60 * Math.Max(0, j * ShadowRays[i].Direction.Normalize()) * (1 / (shadowRayDirection.Length * shadowRayDirection.Length)));
             }
         }
         diffusion = new VPoint(Math.Min(diffusion.X, 255), Math.Min(diffusion.Y, 255), Math.Min(diffusion.Z, 255));
         if (ThingWeIntersectedWith.Mat.Reflects != 0 && Ray.recursion < Game.Recursion)
         {
             secondaryRay           = ThingWeIntersectedWith.Reflect(Ray, Location);
             secondaryRay.recursion = Ray.recursion + 1;
             Intersection inter = scene.intersect(secondaryRay);
             if (inter.ThingWeIntersectedWith == scene.Primitives[0])
             {
                 secondaryRay.Distance = 3;
             }
             else
             {
                 secondaryRay.Distance = inter.Distance;
             }
             return(VPoint.colorStuff(inter.color(scene), diffusion, ThingWeIntersectedWith.Mat.Reflects));
         }
         else
         {
             return(diffusion);
         }
     }
     return(new VPoint());
 }
예제 #14
0
        //Sets the horizontal direction of the virtual screen after the camera is rotated.
        private void setXDirection()
        {
            float dX;

            if (Orientation.Z > 0)
            {
                dX = 1;
            }
            else if (Orientation.Z < 0)
            {
                dX = -1;
            }
            else
            {
                XDirection = new VPoint(0, 0, -Orientation.X).Normalize();
                return;
            }
            XDirection = new VPoint(dX, 0, -Orientation.X * dX / Orientation.Z).Normalize();
        }
예제 #15
0
        public VPoint GetColor(VPoint p)
        {
            switch (Texture)
            {
            case 0: return(Color);

            case 1: return(new VPoint(231, 231, 231) * ((((Math.Abs((int)Math.Floor(p.X) + (int)Math.Floor(p.Z)))) % 2) + 0.1f));

            case 2:
            {
                int   x     = Modulo((int)(p.X * 600) + 3000, 6000);
                int   y     = Modulo((int)(p.Z * 400) + 1600, 4000);
                Color Pixel = Game.Space.GetPixel(x, y);
                return(new VPoint(Pixel.R, Pixel.G, Pixel.B));
            }

            default: return(Color);
            }
        }
예제 #16
0
        public void debug(Surface screen, VPoint endPoint, int type)
        {
            int color = 0;

            switch (type)
            {
            case 0:
                color = 0xFF0000;
                break;

            case 1:
                color = 0x00FF00;
                break;

            case 2:
                color = 0x0000FF;
                break;

            case 3:
                color = 0xFFFFFF;
                break;

            case 4:
                color = 0x888800;
                break;
            }
            // Make sure that the debug output isn't drawn in the scene (in other words, limit the x value to 512, if it exceeds 512 don't draw the line in question)
            int x1, x2;

            x1 = Location.transform("x");
            x2 = endPoint.transform("x");
            if (x1 <= 512 && x2 <= 512)
            {
                screen.Line(x1, Location.transform("y"), x2, endPoint.transform("y"), color);
            }
        }
예제 #17
0
 abstract public Ray normal(VPoint location);
예제 #18
0
 // Determine the color based on reflection and diffusion
 public static VPoint colorStuff(VPoint reflection, VPoint diffusion, float r)
 {
     return(diffusion * (1 - r) + r * new VPoint((diffusion.X * reflection.X) / 255, (diffusion.Y * reflection.Y) / 255, (diffusion.Z * reflection.Z) / 255));
 }
예제 #19
0
 // Determine the reflected color
 public VPoint reflectedColor(VPoint colorOfObject, float intensity)
 {
     return(new VPoint((int)(colorOfObject.X * intensity * Red), (int)(colorOfObject.Y * intensity * Green), (int)(colorOfObject.Z * intensity * Blue)));
 }
예제 #20
0
 // Since the plane is defined by its normal and distance to the origin, we simply return the normal as a ray
 public override Ray normal(VPoint location)
 {
     return(new Ray(location, Normal));
 }
예제 #21
0
 // Create the plane
 public Plane(VPoint normal, float distance, Material mat)
 {
     Mat      = mat;
     Normal   = normal.Normalize();
     Distance = distance;
 }
예제 #22
0
 // Normal on the sphere given the location of the intersection
 public override Ray normal(VPoint location)
 {
     return(new Ray(location, (location - Location).Normalize()));
 }
예제 #23
0
 // Create reflective material
 public Material(VPoint c, float r)
 {
     Color    = c;
     Reflects = r;
     Texture  = 0;
 }