Beispiel #1
0
        public override bool Hit(Ray ray, ref float t, ref ShadeRec sr)
        {
            float ox = ray.Position.X;
            float oy = ray.Position.Y;
            float oz = ray.Position.Z;
            float dx = ray.Direction.X;
            float dy = ray.Direction.Y;
            float dz = ray.Direction.Z;
            float x0 = bbox.Min.X;
            float y0 = bbox.Min.Y;
            float z0 = bbox.Min.Z;
            float x1 = bbox.Max.X;
            float y1 = bbox.Max.Y;
            float z1 = bbox.Max.Z;
            float tx_min, ty_min, tz_min;
            float tx_max, ty_max, tz_max;
            float a = 1.0f / dx;

            if (a >= 0)
            {
                tx_min = (x0 - ox) * a;
                tx_max = (x1 - ox) * a;
            }
            else
            {
                tx_min = (x1 - ox) * a;
                tx_max = (x0 - ox) * a;
            }
            float b = 1.0f / dy;

            if (b >= 0)
            {
                ty_min = (y0 - oy) * b;
                ty_max = (y1 - oy) * b;
            }
            else
            {
                ty_min = (y1 - oy) * b;
                ty_max = (y0 - oy) * b;
            }
            float c = 1.0f / dz;

            if (c >= 0)
            {
                tz_min = (z0 - oz) * c;
                tz_max = (z1 - oz) * c;
            }
            else
            {
                tz_min = (z1 - oz) * c;
                tz_max = (z0 - oz) * c;
            }
            float t0, t1;

            if (tx_min > ty_min)
            {
                t0 = tx_min;
            }
            else
            {
                t0 = ty_min;
            }

            if (tz_min > t0)
            {
                t0 = tz_min;
            }

            if (tx_max < ty_max)
            {
                t1 = tx_max;
            }
            else
            {
                t1 = ty_max;
            }

            if (tz_max < t1)
            {
                t1 = tz_max;
            }

            if (t0 > t1)
            {
                return(false);
            }
            else
            {
                Console.WriteLine("wtf");
            }
            int ix, iy, iz;

            if (bbox.Inside(ray.Position))
            {                   // does the ray start inside the grid?
                ix = clamp((ox - x0) * nx / (x1 - x0), 0, nx - 1);
                iy = clamp((oy - y0) * ny / (y1 - y0), 0, ny - 1);
                iz = clamp((oz - z0) * nz / (z1 - z0), 0, nz - 1);
            }
            else
            {
                Vector3 p = ray.Position + t0 * ray.Direction;  // initial hit point with grid's bounding box
                ix = clamp((p.X - x0) * nx / (x1 - x0), 0, nx - 1);
                iy = clamp((p.Y - y0) * ny / (y1 - y0), 0, ny - 1);
                iz = clamp((p.Z - z0) * nz / (z1 - z0), 0, nz - 1);
            }
            float dtx = (tx_max - tx_min) / nx;
            float dty = (ty_max - ty_min) / ny;
            float dtz = (tz_max - tz_min) / nz;
            float tx_next, ty_next, tz_next;
            int   ix_step, iy_step, iz_step;
            int   ix_stop, iy_stop, iz_stop;

            if (dx > 0)
            {
                tx_next = tx_min + (ix + 1) * dtx;
                ix_step = +1;
                ix_stop = nx;
            }
            else
            {
                tx_next = tx_min + (nx - ix) * dtx;
                ix_step = -1;
                ix_stop = -1;
            }

            if (dx == 0.0)
            {
                tx_next = float.MaxValue;
                ix_step = -1;
                ix_stop = -1;
            }
            if (dy > 0)
            {
                ty_next = ty_min + (iy + 1) * dty;
                iy_step = +1;
                iy_stop = ny;
            }
            else
            {
                ty_next = ty_min + (ny - iy) * dty;
                iy_step = -1;
                iy_stop = -1;
            }

            if (dy == 0.0)
            {
                ty_next = float.MaxValue;
                iy_step = -1;
                iy_stop = -1;
            }

            if (dz > 0)
            {
                tz_next = tz_min + (iz + 1) * dtz;
                iz_step = +1;
                iz_stop = nz;
            }
            else
            {
                tz_next = tz_min + (nz - iz) * dtz;
                iz_step = -1;
                iz_stop = -1;
            }

            if (dz == 0.0)
            {
                tz_next = float.MaxValue;
                iz_step = -1;
                iz_stop = -1;
            }
            while (true)
            {
                GeometricObject object_ptr = cells[ix + nx * iy + nx * ny * iz];
                if (tx_next < ty_next && tx_next < tz_next)
                {
                    if (object_ptr != null && object_ptr.Hit(ray, ref t, ref sr) && t < tx_next)
                    {
                        Material = object_ptr.GetMaterial();
                        return(true);
                    }
                    tx_next += dtx;
                    ix      += ix_step;

                    if (ix == ix_stop)
                    {
                        return(false);
                    }
                }
                else
                {
                    if (ty_next < tz_next)
                    {
                        if (object_ptr != null && object_ptr.Hit(ray, ref t, ref sr) && t < ty_next)
                        {
                            Material = object_ptr.GetMaterial();
                            return(true);
                        }
                        ty_next += dty;
                        iy      += iy_step;

                        if (iy == iy_stop)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        if (object_ptr != null && object_ptr.Hit(ray, ref t, ref sr) && t < tz_next)
                        {
                            Material = object_ptr.GetMaterial();
                            return(true);
                        }
                        tz_next += dtz;
                        iz      += iz_step;

                        if (iz == iz_stop)
                        {
                            return(false);
                        }
                    }
                }
            }
        }
 public void SetObject(GeometricObject obj)
 {
     Object   = obj;
     Material = Object.GetMaterial();
 }