Exemplo n.º 1
0
        public override bool TryToIntersect(Ray ray, ref Intersection intersection)
        {
            float rayT = 0, t = 0;

            if (_bbox.Inside(ray.PointAtTime(ray.Start)))
            {
                rayT = ray.Start;
            }
            else if (!_bbox.IntersectP(ray, ref rayT, ref t))
            {
                return(false);
            }
            var gridIntersect = ray.PointAtTime(rayT);

            float[] nextCrossingT = new float[3], deltaT = new float[3];
            int[]   step          = new int[3], _out = new int[3], pos = new int[3];

            for (var i = 0; i < 3; i++)
            {
                pos[i] = PosToVoxel(gridIntersect, i);
                if (ray.Direction[i] >= 0)
                {
                    nextCrossingT[i] = rayT + (VoxelToPos(pos[i] + 1, i) - gridIntersect[i]) / ray.Direction[i];
                    deltaT[i]        = _width[i] / ray.Direction[i];
                    step[i]          = 1;
                    _out[i]          = _nVoxels[i];
                }
                else
                {
                    nextCrossingT[i] = rayT + (VoxelToPos(pos[i], i) - gridIntersect[i]) / ray.Direction[i];
                    deltaT[i]        = -_width[i] / ray.Direction[i];
                    step[i]          = -1;
                    _out[i]          = -1;
                }
            }

            var hitSomething = false;

            for (;;)
            {
                var voxel = _voxels[Offset(pos[0], pos[1], pos[2])];
                if (voxel != null)
                {
                    hitSomething |= voxel.TryToIntersect(ray, ref intersection);
                }
                var bits = (((nextCrossingT[0] < nextCrossingT[1]) ? 1 : 0) << 2) +
                           (((nextCrossingT[0] < nextCrossingT[2]) ? 1 : 0) << 1) +
                           (((nextCrossingT[1] < nextCrossingT[2]) ? 1 : 0));
                var stepAxis = _cmpToAxis[bits];
                if (ray.End < nextCrossingT[stepAxis])
                {
                    break;
                }
                pos[stepAxis] += step[stepAxis];
                if (pos[stepAxis] == _out[stepAxis])
                {
                    break;
                }
                nextCrossingT[stepAxis] += deltaT[stepAxis];
            }
            return(hitSomething);
        }