From: Michael T H. <mic...@us...> - 2003-10-22 20:58:37
|
Update of /cvsroot/jmol/Jmol/src/org/openscience/jmol/viewer/g3d In directory sc8-pr-cvs1:/tmp/cvs-serv29075/src/org/openscience/jmol/viewer/g3d Modified Files: Graphics3D.java Line3D.java Log Message: a little more work on slab clipping Index: Graphics3D.java =================================================================== RCS file: /cvsroot/jmol/Jmol/src/org/openscience/jmol/viewer/g3d/Graphics3D.java,v retrieving revision 1.35 retrieving revision 1.36 diff -u -r1.35 -r1.36 --- Graphics3D.java 22 Oct 2003 10:42:10 -0000 1.35 +++ Graphics3D.java 22 Oct 2003 20:50:07 -0000 1.36 @@ -124,8 +124,6 @@ public void setSlabValue(int slab) { this.slab = slab; - System.out.println("width=" + width + " height=" + height + - " slab=" + slab); } private void downSample() { @@ -395,7 +393,8 @@ } int argb2 = Colix.getArgb(colix2); if (x1 < 0 || x1 >= width || x2 < 0 || x2 >= width || - y1 < 0 || y1 >= height || y2 < 0 || y2 >= height) { + y1 < 0 || y1 >= height || y2 < 0 || y2 >= height || + z1 < slab || z2 < slab) { int xMid = (x1 + x2) / 2; int yMid = (y1 + y2) / 2; int zMid = (z1 + z2) / 2; @@ -713,7 +712,8 @@ void plotLineDelta(int argb, int x, int y, int z, int dx, int dy, int dz) { if (x < 0 || x >= width || x + dx < 0 || x + dx >= width || - y < 0 || y >= height || y + dy < 0 || y + dy >= height) + y < 0 || y >= height || y + dy < 0 || y + dy >= height || + z < slab || z + dz < slab) line3d.plotLineDeltaClipped(argb, argb, x, y, z, dx, dy, dz); else line3d.plotLineDeltaUnclipped(argb, x, y, z, dx, dy, dz); @@ -722,7 +722,8 @@ void plotLineDelta(int argb1, int argb2, int x, int y, int z, int dx, int dy, int dz) { if (x < 0 || x >= width || x + dx < 0 || x + dx >= width || - y < 0 || y >= height || y + dy < 0 || y + dy >= height) + y < 0 || y >= height || y + dy < 0 || y + dy >= height || + z < slab || z + dz < slab) line3d.plotLineDeltaClipped(argb1, argb2, x, y, z, dx, dy, dz); else if (argb1 == argb2) line3d.plotLineDeltaUnclipped(argb1, x, y, z, dx, dy, dz); Index: Line3D.java =================================================================== RCS file: /cvsroot/jmol/Jmol/src/org/openscience/jmol/viewer/g3d/Line3D.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- Line3D.java 6 Oct 2003 12:46:03 -0000 1.3 +++ Line3D.java 22 Oct 2003 20:50:08 -0000 1.4 @@ -34,20 +34,41 @@ this.g3d = g3d; } - void drawLine(int argb, int x1, int y1, int z1, int x2, int y2, int z2, + final static boolean useCohenSutherland = false; + + void drawLine(int argb, int xA, int yA, int zA, int xB, int yB, int zB, boolean tDotted) { - int cc1 = clipCode(x1, y1); - int cc2 = clipCode(x2, y2); + int dxBA = xB - xA, dyBA = yB - yA, dzBA = zB - zA; + int cc1 = clipCode(xA, yA, zA); + int cc2 = clipCode(xB, yB, zB); + if ((cc1 | cc2) == 0) { + if (tDotted) + plotDottedLineDeltaUnclipped(argb, xA, yA, zA, dxBA, dyBA, dzBA); + else + plotLineDeltaUnclipped(argb, xA, yA, zA, dxBA, dyBA, dzBA); + return; + } + + /* + if (tDotted) + plotDottedLineDeltaClipped(argb, xA, yA, zA, dxBA, dyBA, dzBA); + else + plotLineDeltaClipped(argb, argb, xA, yA, zA, dxBA, dyBA, dzBA); + if (true) + return; + */ + + int x1 = xA, y1 = yA, z1 = zA, x2 = xB, y2 = yB, z2 = zB; int xLast = g3d.xLast; int yLast = g3d.yLast; - while ((cc1 | cc2) != 0) { + int slab = g3d.slab; + do { if ((cc1 & cc2) != 0) return; int dx = x2 - x1; int dy = y2 - y1; int dz = z2 - z1; - if (cc1 != 0) { //cohen-sutherland line clipping if ((cc1 & xLT) != 0) { y1 += (-x1 * dy)/dx; z1 += (-x1 * dz)/dx; x1 = 0; } @@ -55,9 +76,11 @@ { y1 += ((xLast-x1)*dy)/dx; z1 += ((xLast-x1)*dz)/dx; x1 = xLast; } else if ((cc1 & yLT) != 0) { x1 += (-y1 * dx)/dy; z1 += (-y1 * dz)/dy; y1 = 0; } - else + else if ((cc1 & yGT) != 0) { x1 += ((yLast-y1)*dx)/dy; z1 += ((yLast-y1)*dz)/dy; y1 = yLast; } - cc1 = clipCode(x1, y1); + else + { x1 += ((slab-z1)*dx)/dz; y1 += ((slab-z1)*dy)/dz; z1 = slab; } + cc1 = clipCode(x1, y1, z1); } else { if ((cc2 & xLT) != 0) { y2 += (-x2 * dy)/dx; z2 += (-x2 * dz)/dx; x2 = 0; } @@ -65,33 +88,48 @@ { y2 += ((xLast-x2)*dy)/dx; z2 += ((xLast-x2)*dz)/dx; x2 = xLast; } else if ((cc2 & yLT) != 0) { x2 += (-y2 * dx)/dy; z2 += (-y2 * dz)/dy; y2 = 0; } - else + else if ((cc2 & yGT) != 0) { x2 += ((yLast-y2)*dx)/dy; z2 += ((yLast-y2)*dz)/dy; y2 = yLast; } - cc2 = clipCode(x2, y2); + else + { x2 += ((slab-z2)*dx)/dz; y2 += ((slab-z2)*dy)/dz; z2 = slab; } + cc2 = clipCode(x2, y2, z2); } + } while ((cc1 | cc2) != 0); + + if (useCohenSutherland) { + if (tDotted) + plotDottedLineDeltaUnclipped(argb, x1, y1, z1, x2-x1, y2-y1, z2-z1); + else + plotLineDeltaUnclipped(argb, argb, x1, y1, z1, x2-x1, y2-y1, z2-z1); + } else { + if (tDotted) + plotDottedLineDeltaClipped(argb, xA, yA, zA, dxBA, dyBA, dzBA); + else + plotLineDeltaClipped(argb, argb, xA, yA, zA, dxBA, dyBA, dzBA); } - if (tDotted) - plotDottedLineDeltaUnclipped(argb, x1, y1, z1, x2 - x1, y2 - y1, z2 - z1); - else - plotLineDeltaUnclipped(argb, x1, y1, z1, x2 - x1, y2 - y1, z2 - z1); } + final static int zLT = 16; final static int xLT = 8; final static int xGT = 4; final static int yLT = 2; final static int yGT = 1; - private final int clipCode(int x, int y) { + private final int clipCode(int x, int y, int z) { int code = 0; if (x < 0) - code |= 8; + code |= xLT; else if (x >= g3d.width) - code |= 4; + code |= xGT; if (y < 0) - code |= 2; + code |= yLT; else if (y >= g3d.height) - code |= 1; + code |= yGT; + + if (z < g3d.slab) + code |= zLT; + return code; } @@ -175,8 +213,8 @@ } while (--n > 0); } - void plotDottedLineDeltaUnclipped(int argb, - int x1, int y1, int z1, int dx, int dy, int dz) { + void plotDottedLineDeltaUnclipped(int argb, int x1, int y1, int z1, + int dx, int dy, int dz) { boolean flipFlop = true; int[] pbuf = g3d.pbuf; short[] zbuf = g3d.zbuf; @@ -258,6 +296,91 @@ } while (--n > 0); } + void plotDottedLineDeltaClipped(int argb, int x, int y, int z, + int dx, int dy, int dz) { + boolean flipFlop = true; + int[] pbuf = g3d.pbuf; + short[] zbuf = g3d.zbuf; + int width = g3d.width, height = g3d.height, slab = g3d.slab; + int offset = y * width + x; + if (x >= 0 && x < width && y >= 0 && y < height) { + if (z >= slab && z < zbuf[offset]) { + zbuf[offset] = (short)z; + pbuf[offset] = argb; + } + } + if (dx == 0 && dy == 0) + return; + + // int xCurrent = x; + // int yCurrent = y; + int xIncrement = 1; + // int yIncrement = 1; + int yOffsetIncrement = width; + + if (dx < 0) { + dx = -dx; + xIncrement = -1; + } + if (dy < 0) { + dy = -dy; + // yIncrement = -1; + yOffsetIncrement = -width; + } + int twoDx = dx + dx, twoDy = dy + dy; + + // the z dimension and the z increment are stored with a fractional + // component in the bottom 10 bits. + int zCurrentScaled = z << 10; + if (dy <= dx) { + int roundingFactor = dx - 1; + if (dz < 0) roundingFactor = -roundingFactor; + int zIncrementScaled = ((dz << 10) + roundingFactor) / dx; + int twoDxAccumulatedYError = 0; + int n = dx; + do { + // xCurrent += xIncrement; + offset += xIncrement; + zCurrentScaled += zIncrementScaled; + twoDxAccumulatedYError += twoDy; + if (twoDxAccumulatedYError > dx) { + // yCurrent += yIncrement; + offset += yOffsetIncrement; + twoDxAccumulatedYError -= twoDx; + } + int zCurrent = zCurrentScaled >> 10; + if (flipFlop && zCurrent >= slab && zCurrent < zbuf[offset]) { + zbuf[offset] = (short)zCurrent; + pbuf[offset] = argb; + } + flipFlop = !flipFlop; + } while (--n > 0); + return; + } + int roundingFactor = dy - 1; + if (dy < 0) roundingFactor = -roundingFactor; + int zIncrementScaled = ((dz << 10) + roundingFactor) / dy; + int twoDyAccumulatedXError = 0; + int n = dy; + do { + // yCurrent += yIncrement; + offset += yOffsetIncrement; + zCurrentScaled += zIncrementScaled; + twoDyAccumulatedXError += twoDx; + if (twoDyAccumulatedXError > dy) { + // xCurrent += xIncrement; + offset += xIncrement; + twoDyAccumulatedXError -= twoDy; + } + int zCurrent = zCurrentScaled >> 10; + if (flipFlop && zCurrent >= slab && zCurrent < zbuf[offset]) { + zbuf[offset] = (short)zCurrent; + pbuf[offset] = argb; + } + flipFlop = !flipFlop; + } while (--n > 0); + } + void plotLineDeltaUnclippedGradient(int argb1, int argb2, int x1, int y1, int z1, int dx, int dy, int dz) { int[] pbuf = g3d.pbuf; @@ -473,12 +596,11 @@ int x1, int y1, int z1, int dx, int dy, int dz) { int[] pbuf = g3d.pbuf; short[] zbuf = g3d.zbuf; - int width = g3d.width; - int height = g3d.height; + int width = g3d.width, height = g3d.height, slab = g3d.slab; int offset = y1 * width + x1; if (x1 >= 0 && x1 < width && y1 >= 0 && y1 < height) { - if (z1 < zbuf[offset]) { + if (z1 >= slab && z1 < zbuf[offset]) { zbuf[offset] = (short)z1; pbuf[offset] = argb1; } @@ -525,7 +647,7 @@ if (xCurrent >= 0 && xCurrent < width && yCurrent >= 0 && yCurrent < height) { int zCurrent = zCurrentScaled >> 10; - if (zCurrent < zbuf[offset]) { + if (zCurrent >= slab && zCurrent < zbuf[offset]) { zbuf[offset] = (short)zCurrent; pbuf[offset] = n > nMid ? argb1 : argb2; } @@ -551,7 +673,7 @@ if (xCurrent >= 0 && xCurrent < width && yCurrent >= 0 && yCurrent < height) { int zCurrent = zCurrentScaled >> 10; - if (zCurrent < zbuf[offset]) { + if (zCurrent >= slab && zCurrent < zbuf[offset]) { zbuf[offset] = (short)zCurrent; pbuf[offset] = n > nMid ? argb1 : argb2; } |