示例#1
0
        public override bool Hit(Ray ray, ref double tmin, ShadeRec sr)
        {
            Ray invRay = new Ray(MathUtils.TransformPoint(invMatrix, ray.O),
                                 MathUtils.TransformDirection(invMatrix, ray.D));

            if (obj.Hit(invRay, ref tmin, sr))
            {
                sr.Normal = MathUtils.TransformNormal(invMatrix, sr.Normal);

                if (obj.Material != null)
                {
                    material = obj.Material;
                }

                if (!transformTheTexture)
                {
                    sr.LocalHitPoint = ray.HitPoint(tmin);
                }

                return(true);
            }

            return(false);
        }
示例#2
0
        public override bool Hit(Ray ray, ref double tmin, ShadeRec sr)
        {
            if (!bbox.Hit(ray))
            {
                return(false);
            }

            double ox = ray.O.X;
            double oy = ray.O.Y;
            double oz = ray.O.Z;
            double dx = ray.D.X;
            double dy = ray.D.Y;
            double dz = ray.D.Z;

            double x0 = bbox.x0;
            double y0 = bbox.y0;
            double z0 = bbox.z0;
            double x1 = bbox.x1;
            double y1 = bbox.y1;
            double z1 = bbox.z1;

            double txMin = 0, tyMin = 0, tzMin = 0;
            double txMax = 0, tyMax = 0, tzMax = 0;

            double a = 1.0 / dx;

            if (a >= 0)
            {
                txMin = (x0 - ox) * a;
                txMax = (x1 - ox) * a;
            }
            else
            {
                txMin = (x1 - ox) * a;
                txMax = (x0 - ox) * a;
            }

            double b = 1.0 / dy;

            if (b >= 0)
            {
                tyMin = (y0 - oy) * b;
                tyMax = (y1 - oy) * b;
            }
            else
            {
                tyMin = (y1 - oy) * b;
                tyMax = (y0 - oy) * b;
            }

            double c = 1.0 / dz;

            if (c >= 0)
            {
                tzMin = (z0 - oz) * c;
                tzMax = (z1 - oz) * c;
            }
            else
            {
                tzMin = (z1 - oz) * c;
                tzMax = (z0 - oz) * c;
            }

            double t0, t1;

            if (txMin > tyMin)
            {
                t0 = txMin;
            }
            else
            {
                t0 = tyMin;
            }

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

            if (txMax < tyMax)
            {
                t1 = txMax;
            }
            else
            {
                t1 = tyMax;
            }

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

            if (t0 > t1)
            {
                return(false);
            }

            int ix, iy, iz;

            if (bbox.Inside(ray.O))
            {
                ix = (int)MathUtils.Clamp((ox - x0) * nx / (x1 - x0), 0, nx - 1);
                iy = (int)MathUtils.Clamp((oy - y0) * ny / (y1 - y0), 0, ny - 1);
                iz = (int)MathUtils.Clamp((oz - z0) * nz / (z1 - z0), 0, nz - 1);
            }
            else
            {
                Vec3 p = ray.HitPoint(t0);
                ix = (int)MathUtils.Clamp((p.X - x0) * nx / (x1 - x0), 0, nx - 1);
                iy = (int)MathUtils.Clamp((p.Y - y0) * ny / (y1 - y0), 0, ny - 1);
                iz = (int)MathUtils.Clamp((p.Z - z0) * nz / (z1 - z0), 0, nz - 1);
            }

            double dtx = (txMax - txMin) / nx;
            double dty = (tyMax - tyMin) / ny;
            double dtz = (tzMax - tzMin) / nz;

            double txNext, tyNext, tzNext;
            int    ixStep, iyStep, izStep;
            int    ixStop, iyStop, izStop;

            if (dx > 0)
            {
                txNext = txMin + (ix + 1) * dtx;
                ixStep = +1;
                ixStop = nx;
            }
            else
            {
                txNext = txMin + (nx - ix) * dtx;
                ixStep = -1;
                ixStop = -1;
            }

            if (dx == 0.0)
            {
                txNext = MathUtils.HugeValue;
                ixStep = -1;
                ixStop = -1;
            }

            if (dy > 0)
            {
                tyNext = tyMin + (iy + 1) * dty;
                iyStep = +1;
                iyStop = ny;
            }
            else
            {
                tyNext = tyMin + (ny - iy) * dty;
                iyStep = -1;
                iyStop = -1;
            }

            if (dy == 0.0)
            {
                tyNext = MathUtils.HugeValue;
                iyStep = -1;
                iyStop = -1;
            }

            if (dz > 0)
            {
                tzNext = tzMin + (iz + 1) * dtz;
                izStep = +1;
                izStop = nz;
            }
            else
            {
                tzNext = tzMin + (nz - iz) * dtz;
                izStep = -1;
                izStop = -1;
            }

            if (dz == 0.0)
            {
                tzNext = MathUtils.HugeValue;
                izStep = -1;
                izStop = -1;
            }

            while (true)
            {
                GeometricObject obj = cells[ix + nx * iy + nx * ny * iz];

                if (txNext < tyNext && txNext < tzNext)
                {
                    if (obj != null && obj.Hit(ray, ref tmin, sr) && tmin < txNext)
                    {
                        material = obj.Material;
                        return(true);
                    }

                    txNext += dtx;
                    ix     += ixStep;

                    if (ix == ixStop)
                    {
                        return(false);
                    }
                }
                else
                {
                    if (tyNext < tzNext)
                    {
                        if (obj != null && obj.Hit(ray, ref tmin, sr) && tmin < tyNext)
                        {
                            material = obj.Material;
                            return(true);
                        }

                        tyNext += dty;
                        iy     += iyStep;

                        if (iy == iyStop)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        if (obj != null && obj.Hit(ray, ref tmin, sr) && tmin < tzNext)
                        {
                            material = obj.Material;
                            return(true);
                        }

                        tzNext += dtz;
                        iz     += izStep;

                        if (iz == izStop)
                        {
                            return(false);
                        }
                    }
                }
            }
        }
示例#3
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);
                        }
                    }
                }
            }
        }