Exemplo n.º 1
0
        public void intersect(Ray r, IntersectionState state)
        {
            float intervalMin = r.getMin();
            float intervalMax = r.getMax();
            float orgX = r.ox;
            float dirX = r.dx, invDirX = 1 / dirX;
            float t1, t2;

            t1 = (bounds.getMinimum().x - orgX) * invDirX;
            t2 = (bounds.getMaximum().x - orgX) * invDirX;
            if (invDirX > 0)
            {
                if (t1 > intervalMin)
                {
                    intervalMin = t1;
                }
                if (t2 < intervalMax)
                {
                    intervalMax = t2;
                }
            }
            else
            {
                if (t2 > intervalMin)
                {
                    intervalMin = t2;
                }
                if (t1 < intervalMax)
                {
                    intervalMax = t1;
                }
            }
            if (intervalMin > intervalMax)
            {
                return;
            }
            float orgY = r.oy;
            float dirY = r.dy, invDirY = 1 / dirY;

            t1 = (bounds.getMinimum().y - orgY) * invDirY;
            t2 = (bounds.getMaximum().y - orgY) * invDirY;
            if (invDirY > 0)
            {
                if (t1 > intervalMin)
                {
                    intervalMin = t1;
                }
                if (t2 < intervalMax)
                {
                    intervalMax = t2;
                }
            }
            else
            {
                if (t2 > intervalMin)
                {
                    intervalMin = t2;
                }
                if (t1 < intervalMax)
                {
                    intervalMax = t1;
                }
            }
            if (intervalMin > intervalMax)
            {
                return;
            }
            float orgZ = r.oz;
            float dirZ = r.dz, invDirZ = 1 / dirZ;

            t1 = (bounds.getMinimum().z - orgZ) * invDirZ;
            t2 = (bounds.getMaximum().z - orgZ) * invDirZ;
            if (invDirZ > 0)
            {
                if (t1 > intervalMin)
                {
                    intervalMin = t1;
                }
                if (t2 < intervalMax)
                {
                    intervalMax = t2;
                }
            }
            else
            {
                if (t2 > intervalMin)
                {
                    intervalMin = t2;
                }
                if (t1 < intervalMax)
                {
                    intervalMax = t1;
                }
            }
            if (intervalMin > intervalMax)
            {
                return;
            }
            // box is hit at [intervalMin, intervalMax]
            orgX += intervalMin * dirX;
            orgY += intervalMin * dirY;
            orgZ += intervalMin * dirZ;
            // locate starting point inside the grid
            // and set up 3D-DDA vars
            int   indxX, indxY, indxZ;
            int   stepX, stepY, stepZ;
            int   stopX, stopY, stopZ;
            float deltaX, deltaY, deltaZ;
            float tnextX, tnextY, tnextZ;

            // stepping factors along X
            indxX = (int)((orgX - bounds.getMinimum().x) * invVoxelwx);
            if (indxX < 0)
            {
                indxX = 0;
            }
            else if (indxX >= nx)
            {
                indxX = nx - 1;
            }
            if (Math.Abs(dirX) < 1e-6f)
            {
                stepX  = 0;
                stopX  = indxX;
                deltaX = 0;
                tnextX = float.PositiveInfinity;
            }
            else if (dirX > 0)
            {
                stepX  = 1;
                stopX  = nx;
                deltaX = voxelwx * invDirX;
                tnextX = intervalMin + ((indxX + 1) * voxelwx + bounds.getMinimum().x - orgX) * invDirX;
            }
            else
            {
                stepX  = -1;
                stopX  = -1;
                deltaX = -voxelwx * invDirX;
                tnextX = intervalMin + (indxX * voxelwx + bounds.getMinimum().x - orgX) * invDirX;
            }
            // stepping factors along Y
            indxY = (int)((orgY - bounds.getMinimum().y) * invVoxelwy);
            if (indxY < 0)
            {
                indxY = 0;
            }
            else if (indxY >= ny)
            {
                indxY = ny - 1;
            }
            if (Math.Abs(dirY) < 1e-6f)
            {
                stepY  = 0;
                stopY  = indxY;
                deltaY = 0;
                tnextY = float.PositiveInfinity;
            }
            else if (dirY > 0)
            {
                stepY  = 1;
                stopY  = ny;
                deltaY = voxelwy * invDirY;
                tnextY = intervalMin + ((indxY + 1) * voxelwy + bounds.getMinimum().y - orgY) * invDirY;
            }
            else
            {
                stepY  = -1;
                stopY  = -1;
                deltaY = -voxelwy * invDirY;
                tnextY = intervalMin + (indxY * voxelwy + bounds.getMinimum().y - orgY) * invDirY;
            }
            // stepping factors along Z
            indxZ = (int)((orgZ - bounds.getMinimum().z) * invVoxelwz);
            if (indxZ < 0)
            {
                indxZ = 0;
            }
            else if (indxZ >= nz)
            {
                indxZ = nz - 1;
            }
            if (Math.Abs(dirZ) < 1e-6f)
            {
                stepZ  = 0;
                stopZ  = indxZ;
                deltaZ = 0;
                tnextZ = float.PositiveInfinity;
            }
            else if (dirZ > 0)
            {
                stepZ  = 1;
                stopZ  = nz;
                deltaZ = voxelwz * invDirZ;
                tnextZ = intervalMin + ((indxZ + 1) * voxelwz + bounds.getMinimum().z - orgZ) * invDirZ;
            }
            else
            {
                stepZ  = -1;
                stopZ  = -1;
                deltaZ = -voxelwz * invDirZ;
                tnextZ = intervalMin + (indxZ * voxelwz + bounds.getMinimum().z - orgZ) * invDirZ;
            }
            int cellstepX = stepX;
            int cellstepY = stepY * nx;
            int cellstepZ = stepZ * ny * nx;
            int cell      = indxX + indxY * nx + indxZ * ny * nx;

            // trace through the grid
            for (; ;)
            {
                if (tnextX < tnextY && tnextX < tnextZ)
                {
                    if (cells[cell] != null)
                    {
                        foreach (int i in cells[cell])
                        {
                            primitives.intersectPrimitive(r, i, state);
                        }
                        if (state.hit() && (r.getMax() < tnextX && r.getMax() < intervalMax))
                        {
                            return;
                        }
                    }
                    intervalMin = tnextX;
                    if (intervalMin > intervalMax)
                    {
                        return;
                    }
                    indxX += stepX;
                    if (indxX == stopX)
                    {
                        return;
                    }
                    tnextX += deltaX;
                    cell   += cellstepX;
                }
                else if (tnextY < tnextZ)
                {
                    if (cells[cell] != null)
                    {
                        foreach (int i in cells[cell])
                        {
                            primitives.intersectPrimitive(r, i, state);
                        }
                        if (state.hit() && (r.getMax() < tnextY && r.getMax() < intervalMax))
                        {
                            return;
                        }
                    }
                    intervalMin = tnextY;
                    if (intervalMin > intervalMax)
                    {
                        return;
                    }
                    indxY += stepY;
                    if (indxY == stopY)
                    {
                        return;
                    }
                    tnextY += deltaY;
                    cell   += cellstepY;
                }
                else
                {
                    if (cells[cell] != null)
                    {
                        foreach (int i in cells[cell])
                        {
                            primitives.intersectPrimitive(r, i, state);
                        }
                        if (state.hit() && (r.getMax() < tnextZ && r.getMax() < intervalMax))
                        {
                            return;
                        }
                    }
                    intervalMin = tnextZ;
                    if (intervalMin > intervalMax)
                    {
                        return;
                    }
                    indxZ += stepZ;
                    if (indxZ == stopZ)
                    {
                        return;
                    }
                    tnextZ += deltaZ;
                    cell   += cellstepZ;
                }
            }
        }