Exemple #1
0
        public override void trace(Ray r)
        {
            double v = r.dir * norm;

            if (r.is_outside && v > 0 || !r.is_outside && v < 0)
            {
                return;
            }

            double dist = ((p0 - r.pos) * norm) / v;

            if (dist > 0 && dist < r.hit_dist)
            {
                vect3d hit_pos = r.pos + r.dir * dist;

                // find barycentric coordinates;
                double b0 = ((p1 - hit_pos) % (p2 - hit_pos)) * N;
                double b1 = ((p2 - hit_pos) % (p0 - hit_pos)) * N;
                double b2 = 1 - b0 - b1;

                if (b0 >= 0 && b1 >= 0 && b2 >= 0)
                {
                    r.hit_dist      = dist;
                    r.hit_pos       = hit_pos;
                    r.hit_tex_coord = t0 * b0 + t1 * b1 + t2 * b2;
                    r.hit_norm      = n0 * b0 + n1 * b1 + n2 * b2;
                    r.hit_norm.normalize();
                    r.hit_object = this;
                }
            }
        }
Exemple #2
0
        public static bool rayTriangleIntersect(vect3d ray_pos, vect3d ray_dir, vect3d v0, vect3d v1, vect3d v2, out double dist)
        {
            vect3d u = v1 - v0;
            vect3d v = v2 - v0;
            vect3d n = u % v;                             // normal

            dist = -((ray_pos - v0) * n) / (ray_dir * n); // distance to plane
            vect3d pos = ray_pos + ray_dir * dist;        // point in plane of triangle
            vect3d w   = pos - v0;

            double uv = u * v;
            double wv = w * v;
            double vv = v * v;
            double wu = w * u;
            double uu = u * u;

            double denom = uv * uv - uu * vv;
            double s     = (uv * wv - vv * wu) / denom;
            double t     = (uv * wu - uu * wv) / denom;

            if (s >= 0 && t >= 0 && s + t <= 1)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemple #3
0
        protected void lightDirectPointSpecNoShadow(Ray r, double specular_coeff, ref vect3d diff_accum, ref vect3d spec_accum)
        {
            Ray shadow_ray = new Ray();

            shadow_ray.pos = r.hit_pos;

            foreach (var l in r.scene.lights)
            {
                vect3d dir   = l.pos - r.hit_pos;
                double dist2 = 1.0 / dir.length2();
                dir *= Math.Sqrt(dist2);

                // diffuse
                double incidence_dif = (dir * r.hit_norm);
                if (incidence_dif > 0)
                {
                    diff_accum += l.color * incidence_dif * dist2;
                }

                // specular highlight
                vect3d dir_r          = r.hit_norm * ((dir * r.hit_norm) * 2) - dir;
                double incidence_spec = (dir_r * r.hit_norm);
                if (incidence_spec > 0)
                {
                    spec_accum += l.color * Math.Pow(incidence_spec, specular_coeff) * dist2;
                }
            }
        }
Exemple #4
0
 public Sphere(vect3d pos, double r, Shader shader)
 {
     this.shader  = shader;
     this.radius  = r;
     this.radius2 = r * r;
     this.pos     = pos;
 }
Exemple #5
0
        public override void trace(Ray r)
        {
            vect3d dst = r.pos - this.pos;
            double B   = dst * r.dir;
            double C   = dst.length2() - this.radius2;
            double D   = B * B - C;

            if (D > 0)
            {
                double dist;
                double flip_norm = 1;
                if (r.is_outside)
                {
                    dist = -B - Math.Sqrt(D);
                }
                else
                {
                    dist      = -B + Math.Sqrt(D);
                    flip_norm = -1;
                }

                if (dist > 0 && dist < r.hit_dist)
                {
                    r.hit_dist = dist;
                    r.hit_pos  = r.pos + r.dir * dist;
                    r.hit_norm = (r.hit_pos - this.pos) * flip_norm;
                    r.hit_norm.normalize();
                    r.hit_tex_coord = r.hit_norm;
                    r.hit_object    = this;
                }
            }
        }
Exemple #6
0
        public override void colorize(Ray r)
        {
            vect3d diff_accum = new vect3d(0, 0, 0);
            vect3d spec_accum = new vect3d(0, 0, 0);

            lightDirectPointSpec(r, specular_coeff, ref diff_accum, ref spec_accum);

            r.color = diff_accum.times(diffuse_color) + spec_accum.times(specular_color);
        }
Exemple #7
0
 public static bool rayBoxIntersectPos(vect3d ray_pos, vect3d ray_dir, box3d box, out double dist, out vect3d pos, out int d, out int n)
 {
     if (rayBoxIntersectDist(ray_pos, ray_dir, box, out dist, out d, out n))
     {
         pos = ray_pos + ray_dir * dist;
         return(true);
     }
     pos = new vect3d(0);
     return(false);
 }
Exemple #8
0
        public static vect3d rand_in_sphere()
        {
            vect3d p;

            do
            {
                p = new vect3d(rand.NextDouble() * 2 - 1, rand.NextDouble() * 2 - 1, rand.NextDouble() * 2 - 1);
            } while (p.length2() > 1);

            return(p);
        }
Exemple #9
0
        public override void trace(Ray r)
        {
            vect3d o = r.pos, d = r.dir;
            double t = Double.MaxValue;

            double Aq = A * d.x * d.x + D * d.x * d.y + B * d.y * d.y + C * d.z * d.z + d.x * d.z * E + d.y * d.z * F;
            double Bq = d.x * G + d.y * H + d.z * I + 2 * A * d.x * o.x + D * d.y * o.x + d.z * E * o.x + D * d.x * o.y + 2 * B * d.y * o.y + d.z * F * o.y + 2 * C * d.z * o.z + d.x * E * o.z + d.y * F * o.z;
            double Cq = J + G * o.x + A * o.x * o.x + H * o.y + D * o.x * o.y + B * o.y * o.y + I * o.z + E * o.x * o.z + F * o.y * o.z + C * o.z * o.z;

            if (Aq == 0)
            {
                if (Bq != 0)
                {
                    t = -Cq / Bq;
                }
            }
            else
            {
                double Dq = Bq * Bq - 4 * Aq * Cq;
                if (Dq > 0)
                {
                    if (r.is_outside)
                    {
                        t = (-Bq - Math.Sqrt(Dq)) / (2 * Aq);
                    }
                    else
                    {
                        t = (-Bq + Math.Sqrt(Dq)) / (2 * Aq);
                    }
                }
            }

            if (t > 0 && t < r.hit_dist)
            {
                r.hit_dist   = t;
                r.hit_object = this;

                vect3d p = r.pos + r.dir * t;
                r.hit_pos       = p;
                r.hit_tex_coord = p;

                r.hit_norm = new vect3d(
                    2 * A * p.x + D * p.y + E * p.z + G,
                    2 * B * p.y + D * p.x + F * p.z + H,
                    2 * C * p.z + E * p.x + F * p.y + I);
                r.hit_norm.normalize();

                if (r.dir * r.hit_norm > 0)
                {
                    r.hit_norm *= -1;
                }
            }
        }
Exemple #10
0
        public Plane(vect3d p0, vect3d p1, vect3d p2, Shader shader)
        {
            this.shader = shader;
            this.pos    = p0;

            z = (p1 - p0) % (p2 - p0);
            z.normalize();

            x = p2 % z;
            x.normalize();

            y = z % x;
        }
Exemple #11
0
        vect3d norm;              // unit normal for getting plane intersection

        public Triangle(vect3d p0, vect3d p1, vect3d p2, Shader shader)
        {
            this.shader = shader;

            this.p0 = p0;
            this.p1 = p1;
            this.p2 = p2;

            N  = (p1 - p0) % (p2 - p0);
            N /= N * N;

            norm = N;
            norm.normalize();

            n0 = n1 = n2 = norm;
        }
Exemple #12
0
        protected void lightDirectPointSpec(Ray r, double specular_coeff, ref vect3d diff_accum, ref vect3d spec_accum)
        {
            Ray shadow_ray = new Ray();

            shadow_ray.pos = r.hit_pos;

            foreach (var l in r.scene.lights)
            {
                vect3d dir       = l.pos - r.hit_pos;
                double dist2     = dir.length2();
                double dist2_inv = 1.0 / dist2;
                dir *= Math.Sqrt(dist2_inv);

                // calculate incidences to do early reject of shadow ray
                double incidence_dif  = (dir * r.hit_norm);
                vect3d dir_r          = r.hit_norm * ((dir * r.hit_norm) * 2) - dir;
                double incidence_spec = (dir_r * r.hit_norm);

                if (incidence_dif < 0 && incidence_spec < 0)
                {
                    continue;
                }

                // shadow ray test
                shadow_ray.dir      = dir;
                shadow_ray.hit_dist = Double.MaxValue;
                r.scene.trace(shadow_ray);
                if (shadow_ray.hit_dist * shadow_ray.hit_dist < dist2)
                {
                    continue;
                }

                // diffuse
                if (incidence_dif > 0)
                {
                    diff_accum += l.color * incidence_dif * dist2_inv;
                }

                // specular highlight
                if (incidence_spec > 0)
                {
                    spec_accum += l.color * Math.Pow(incidence_spec, specular_coeff) * dist2_inv;
                }
            }
        }
        public override void colorize(Ray r)
        {
            vect3d diff_accum = new vect3d(0, 0, 0);
            vect3d spec_accum = new vect3d(0, 0, 0);

            lightDirectPointSpec(r, specular_coeff, ref diff_accum, ref spec_accum);

            // calculate the polar coordinates
            vect3d sp;

            sp.x = -Math.Atan2(r.hit_tex_coord.z, r.hit_tex_coord.x) / (2 * Math.PI);
            sp.y = -Math.Atan2(Math.Sqrt(r.hit_tex_coord.x * r.hit_tex_coord.x + r.hit_tex_coord.z * r.hit_tex_coord.z), r.hit_tex_coord.y) / (Math.PI);
            sp.z = 0;

            vect3d diffuse_color = tex.sample(sp);

            r.color = diff_accum.times(diffuse_color) + spec_accum.times(specular_color);
        }
        public override vect3d sample(vect3d pos)
        {
            // find modulo value (texture wrapping)
            vect2d p = new vect2d((pos.x % 1) * bmp.Width, ((1 - pos.y) % 1) * bmp.Height);

            if (p.x < 0)
            {
                p.x += bmp.Width;
            }
            if (p.y < 0)
            {
                p.y += bmp.Height;
            }

            // get color out of bmp
            Color color = bmp.GetPixel((int)p.x, (int)p.y);

            return(new vect3d(color.R / 255.0, color.G / 255.0, color.B / 255.0));
        }
Exemple #15
0
        public override void trace(Ray r)
        {
            double v = r.dir * z;

            if (r.is_outside && v > 0 || !r.is_outside && v < 0)
            {
                return;
            }

            double dist = ((pos - r.pos) * z) / v;

            if (dist > 0 && dist < r.hit_dist)
            {
                r.hit_dist = dist;
                r.hit_pos  = r.pos + r.dir * dist;
                vect3d rp = r.hit_pos - pos;
                r.hit_tex_coord = new vect3d(x * rp, y * rp, 0);
                r.hit_norm      = z;
                r.hit_object    = this;
            }
        }
Exemple #16
0
        public static double dist2_aabb_pt(vect3d mine, vect3d maxe, vect3d pt)
        {
            double d2 = 0;

            for (int i = 0; i < 3; i++)
            {
                double d = pt[i] - mine[i];
                if (d < 0)
                {
                    d2 += d * d;
                    continue;
                }

                d = pt[i] - maxe[i];
                if (d > 0)
                {
                    d2 += d * d;
                }
            }

            return(d2);
        }
Exemple #17
0
        public override vect3d sample(vect3d pos)
        {
            // find modulo value (texture wrapping)
            vect2d p = new vect2d((pos.x % 1) * bmp.Width, ((1 - pos.y) % 1) * bmp.Height);

            if (p.x < 0)
            {
                p.x += bmp.Width;
            }
            if (p.y < 0)
            {
                p.y += bmp.Height;
            }

            // get color out of bmp
            int    i = (int)p.x, j = (int)p.y;
            int    ip = (i + 1) % bmp.Width, jp = (j + 1) % bmp.Height;
            double dx = p.x - i, dy = p.y - j;

            Color color;

            color = bmp.GetPixel(i, j);
            vect3d c00 = new vect3d(color.R, color.G, color.B);

            color = bmp.GetPixel(i, jp);
            vect3d c01 = new vect3d(color.R, color.G, color.B);

            color = bmp.GetPixel(ip, j);
            vect3d c10 = new vect3d(color.R, color.G, color.B);

            color = bmp.GetPixel(ip, jp);
            vect3d c11 = new vect3d(color.R, color.G, color.B);

            // combine samples with lerp
            return(((1 - dx) * (1 - dy) * c00 + (1 - dx) * dy * c01 + dx * (1 - dy) * c10 + dx * dy * c11) * (1.0 / 255.0));
        }
Exemple #18
0
 public vect3i(vect3d v)
 {
     x = (int)System.Math.Floor(v.x);
     y = (int)System.Math.Floor(v.y);
     z = (int)System.Math.Floor(v.z);
 }
Exemple #19
0
        public Bitmap create_image(Scene scene)
        {
            Bitmap bmp = new Bitmap(width, height);

            // get the orientation of the camera
            matrix4d rotmat = orient.getMatrix();
            vect3d   rt     = new vect3d(rotmat.m[0], rotmat.m[1], rotmat.m[2]);
            vect3d   up     = new vect3d(rotmat.m[4], rotmat.m[5], rotmat.m[6]);
            vect3d   fwd    = new vect3d(rotmat.m[8], rotmat.m[9], rotmat.m[10]);

            // convert the orientation to a 3D screen
            double aspect = (double)width / (double)height;
            double h      = Math.Tan(fov_y * Math.PI / 360.0);

            up  *= -h * 2;
            rt  *= aspect * h * 2;
            fwd *= -1;

            // 2D screen conversions
            vect3d dx     = rt / width;
            vect3d dy     = up / height;
            vect3d corner = fwd - rt * .5 - up * .5;

            // expose each pixel
            Ray r = new Ray();

            r.scene = scene;

            double subsample_res = 1.0 / subsamples;

            for (int j = 0; j < bmp.Height; j++)
            {
                for (int i = 0; i < bmp.Width; i++)
                {
                    vect3d color = new vect3d(0, 0, 0);

                    for (int jj = 0; jj < subsamples; jj++)
                    {
                        for (int ii = 0; ii < subsamples; ii++)
                        {
                            // set ray properties
                            r.pos        = this.pos;
                            r.hit_dist   = Double.MaxValue;
                            r.color      = new vect3d(0, 0, 0);
                            r.hit_object = null;

                            r.dir = corner + dx * (i + (ii + .5 /*Rand.rand.NextDouble()*/) * subsample_res) + dy * (j + (jj + .5 /*Rand.rand.NextDouble()*/) * subsample_res);
                            r.dir.normalize();

                            // trace the ray
                            scene.trace(r);
                            if (r.hit_object != null)
                            {
                                r.hit_object.shader.colorize(r);
                                color += r.color;
                            }
                        }
                    }

                    color *= subsample_res * subsample_res;

                    // gamma correct the color
                    double brightness = color.length();
                    color /= Math.Sqrt(brightness);

                    // store the color
                    int red   = clamp(color.x);
                    int green = clamp(color.y);
                    int blue  = clamp(color.z);

                    bmp.SetPixel(i, j, Color.FromArgb(255, red, green, blue));
                }
            }

            return(bmp);
        }
Exemple #20
0
 public vect3f(vect3d v)
 {
     x = (float)v.x;
     y = (float)v.y;
     z = (float)v.z;
 }
Exemple #21
0
 public vect3f(vect3d v)
 {
     x = (float)v.x;
     y = (float)v.y;
     z = (float)v.z;
 }
Exemple #22
0
 public virtual vect3d sample(vect3d p)
 {
     return(new vect3d(1, 1, 1));
 }
Exemple #23
0
        public static bool rayBoxIntersectDist(vect3d ray_pos, vect3d ray_dir, box3d box, out double dist, out int face_d, out int face_n)
        {
            vect3d box_low  = box[0];
            vect3d box_high = box[1];

            dist = 0;
            double Tnear = -1e30;
            double Tfar = 1e30;
            double T1, T2;

            face_d = -1;
            face_n = -1;
            // check bounding box to see if it enters level
            // this method assumes bounding box is already in coordinate system of the level
            for (int d = 0; d < 3; d++)
            {
                int n_temp = 0;
                if (ray_dir[d] == 0)
                {
                    if (ray_pos[d] > box_high[d] || ray_pos[d] < box_low[d])
                    {
                        return(false);
                    }

                    //int dp = (d + 1) % 3;
                    //int dpp = (d + 2) % 3;

                    //if (ray_pos[dp] > box_high[dp] || ray_pos[dp] < box_low[dp])
                    //    return false;
                    //if (ray_pos[dpp] > box_high[dpp] || ray_pos[dpp] < box_low[dpp])
                    //    return false;
                }
                else
                {
                    T1 = (box_low[d] - ray_pos[d]) / ray_dir[d];
                    T2 = (box_high[d] - ray_pos[d]) / ray_dir[d];
                    if (T1 > T2)
                    {
                        //swap(T1, T2); // since T1 intersection should be the nearest
                        double t = T1;
                        T1     = T2;
                        T2     = t;
                        n_temp = (n_temp + 1) % 2;
                    }
                    if (T1 > Tnear)
                    {
                        face_d = d;
                        face_n = n_temp;
                        Tnear  = T1; // largest Tnear
                    }
                    if (T2 < Tfar)
                    {
                        Tfar = T2;    // smallest Tfar
                    }
                    if (Tnear > Tfar) // box is missed
                    {
                        return(false);
                    }
                    if (Tfar < 0)
                    {
                        return(false); // box is behind ray
                    }
                }
            }
            dist = Tnear;
            if (dist < 0)
            {
                return(false);
            }
            return(true);
        }
Exemple #24
0
        public static bool intersect_aabb_tri(vect3d mine, vect3d maxe, vect3d v0, vect3d v1, vect3d v2)
        {
            //** use separating axes to determine intersection

            // create points
            vect3d[] tri     = { v0, v1, v2 };
            vect3d[] box_ext = { mine, maxe };
            vect3d[] box     = new vect3d[8];

            for (int i = 0; i < 8; i++)
            {
                box[i] = new vect3d((box_ext[i & 1])[0], (box_ext[(i >> 1) & 1])[1], (box_ext[i >> 2])[2]);
            }

            // create axes
            vect3d[] axes = new vect3d[13];
            axes[0] = new vect3d(1, 0, 0);
            axes[1] = new vect3d(0, 1, 0);
            axes[2] = new vect3d(0, 0, 1);
            axes[3] = (v1 - v0) % (v2 - v0);
            for (int i = 0; i < 3; i++)
            {
                int ip = (i + 1) % 3;
                for (int j = 0; j < 3; j++)
                {
                    axes[4 + i * 3 + j] = axes[j] % ((tri[i]) - (tri[ip]));
                }
            }

            // check overlaps
            for (int i = 0; i < 13; i++)
            {
                // tri extents
                double tri_min, tri_max;
                tri_min = tri_max = (tri[0]) * axes[i];
                for (int k = 1; k < 3; k++)
                {
                    double d = (tri[k]) * axes[i];
                    if (d < tri_min)
                    {
                        tri_min = d;
                    }
                    if (d > tri_max)
                    {
                        tri_max = d;
                    }
                }

                // box extents
                double box_min, box_max;
                box_min = box_max = box[0] * axes[i];
                for (int j = 1; j < 8; j++)
                {
                    double d = box[j] * axes[i];
                    if (d < box_min)
                    {
                        box_min = d;
                    }
                    if (d > box_max)
                    {
                        box_max = d;
                    }
                }

                // if disjoint, they don't intersect
                if (box_max < tri_min || tri_max < box_min)
                {
                    return(false);
                }
            }

            return(true);
        }
Exemple #25
0
 public vect3i(vect3d v)
 {
     x = (int)System.Math.Floor(v.x);
     y = (int)System.Math.Floor(v.y);
     z = (int)System.Math.Floor(v.z);
 }