import java.util.BitSet; /** * Bitmap of screen areas for Jevans temporal coherence algorithm * See "Object Space Temporal Coherence for Ray Tracing" * by David A. Jevans, Graphics Interface, 1992 * Dimensions and usage must match Grid * Each BitSet could be in Voxel, but 3D array duplicated here * to allow multiple cameras to each have temporal coherence * Bitmaps have one extra row and column for panning * TBD fix some shift bugs! * @see Grid.java * @author: Phil Gage */ class TemporalBitmap { /** Bitmap for Jevans algorithm */ private BitSet bitmap[][][]; /** Number of grid divisions for each axis */ private VoxelIndex size; Grid grid; int rows, cols; int width, height; int indexWidth, indexHeight; int bitmapSize; int currentIndex; BitSet clearmask; int xshift = 0, yshift = 0; boolean debug = true; /** Create bitmap grid with specified size same as grid */ TemporalBitmap (Grid grid, int rows, int cols, int width, int height) { if (grid == null) System.out.println("Error, null grid in TemporalBitmap"); this.grid = grid; this.rows = rows; this.cols = cols; this.width = width; this.height = height; this.size = grid.size; indexWidth = width/cols; indexHeight = height/rows; bitmapSize = (rows+1)*(cols+1); clearmask = new BitSet(bitmapSize); // Allocate 3D array of references to all grid cells // Only creates pointers left null until used to save memory bitmap = new BitSet[size.xyz[0]][size.xyz[1]][size.xyz[2]]; } /** Return screen X coordinate for current bitmap index */ // int getX (int index) { int getX () { // return (currentIndex % (cols+1)) * indexWidth; // return ((currentIndex % (cols+1)) * indexWidth + xshift) % width; //new int x = (currentIndex % (cols+1)) * indexWidth + xshift; //newer if (x > width) return x - width - indexWidth; else return x; } /** Return screen Y coordinate for current bitmap index */ // int getY (int index) { int getY () { // return (currentIndex / (cols+1)) * indexHeight; // return ((currentIndex / (cols+1)) * indexHeight + yshift) % height; //new int y = (currentIndex / (cols+1)) * indexHeight + yshift; //newer if (y > height) return y - height - indexHeight; else return y; } /** Set current bitmap index for screen XY coordinates */ void setIndex (int x, int y) { // int col = x / indexWidth; // int col = ((x - xshift) % width) / indexWidth; //new // int col = ((x + xshift) / indexWidth)%(cols+1); //newer // int row = y / indexHeight; // int row = ((y - yshift) % height) / indexHeight; //new // int row = ((y + yshift) / indexHeight)%(rows+1); //newer // return col + row * cols; // currentIndex = col + row * cols; int col = x - xshift; //newest if (col < 0) col += width + indexWidth; col = (col / indexWidth) % (cols+1); int row = y - yshift; if (row < 0) row += height + indexHeight; row = (row / indexHeight) % (rows+1); currentIndex = col + row * (cols+1); //if(debug)System.out.println("setIndex "); } /** Set voxel bitmap entry for current index, called by Grid when a ray originating from screen area corresponding to current index traverses through the voxel */ void set (VoxelIndex index) { if (bitmap[index.xyz[0]][index.xyz[1]][index.xyz[2]] == null) bitmap[index.xyz[0]][index.xyz[1]][index.xyz[2]] = new BitSet(bitmapSize); bitmap[index.xyz[0]][index.xyz[1]][index.xyz[2]].set(currentIndex); } /** Clear all bits in a bit set */ void clear (BitSet bits) { bits.and(clearmask); //size prob, loop??? } /** Clear all bitmaps in all voxels */ void clearBitmaps () { for (int x=0; x