From: <ha...@us...> - 2006-07-24 17:52:24
|
Revision: 5353 Author: hansonr Date: 2006-07-24 10:52:09 -0700 (Mon, 24 Jul 2006) ViewCVS: http://svn.sourceforge.net/jmol/?rev=5353&view=rev Log Message: ----------- Bob200603/10.x.34/11.0 beta g3d make-over all core/infrastructure -more comprehensive implemenation of Cohen-Sutherland 3D-line clipping -streamlining/reorganization of g3d methods -faster rendering for clipped lines Modified Paths: -------------- branches/bob200603/Jmol/src/org/jmol/g3d/Circle3D.java branches/bob200603/Jmol/src/org/jmol/g3d/Cylinder3D.java branches/bob200603/Jmol/src/org/jmol/g3d/Graphics3D.java branches/bob200603/Jmol/src/org/jmol/g3d/Line3D.java branches/bob200603/Jmol/src/org/jmol/g3d/Triangle3D.java branches/bob200603/Jmol/src/org/jmol/viewer/AxesRenderer.java branches/bob200603/Jmol/src/org/jmol/viewer/BallsRenderer.java branches/bob200603/Jmol/src/org/jmol/viewer/DotsRenderer.java branches/bob200603/Jmol/src/org/jmol/viewer/FrameRenderer.java branches/bob200603/Jmol/src/org/jmol/viewer/FrankRenderer.java branches/bob200603/Jmol/src/org/jmol/viewer/HoverRenderer.java branches/bob200603/Jmol/src/org/jmol/viewer/LabelsRenderer.java branches/bob200603/Jmol/src/org/jmol/viewer/MeasuresRenderer.java branches/bob200603/Jmol/src/org/jmol/viewer/MeshRenderer.java branches/bob200603/Jmol/src/org/jmol/viewer/MolecularOrbitalRenderer.java branches/bob200603/Jmol/src/org/jmol/viewer/UccageRenderer.java Modified: branches/bob200603/Jmol/src/org/jmol/g3d/Circle3D.java =================================================================== --- branches/bob200603/Jmol/src/org/jmol/g3d/Circle3D.java 2006-07-24 17:45:36 UTC (rev 5352) +++ branches/bob200603/Jmol/src/org/jmol/g3d/Circle3D.java 2006-07-24 17:52:09 UTC (rev 5353) @@ -43,6 +43,7 @@ void plotCircleCenteredClipped(int xCenter, int yCenter, int zCenter, int diameter) { + // halo only -- simple window clip { int r = (diameter + 1) >> 1; if (xCenter + r < 0 || xCenter - r >= g3d.width || Modified: branches/bob200603/Jmol/src/org/jmol/g3d/Cylinder3D.java =================================================================== --- branches/bob200603/Jmol/src/org/jmol/g3d/Cylinder3D.java 2006-07-24 17:45:36 UTC (rev 5352) +++ branches/bob200603/Jmol/src/org/jmol/g3d/Cylinder3D.java 2006-07-24 17:52:09 UTC (rev 5353) @@ -36,10 +36,12 @@ */ class Cylinder3D { - Graphics3D g3d; + final Graphics3D g3d; + final Line3D line3d; Cylinder3D(Graphics3D g3d) { this.g3d = g3d; + this.line3d = g3d.line3d; } private short colixA, colixB; @@ -62,15 +64,26 @@ private float radius, radius2, cosTheta, cosPhi, sinPhi; int sampleCount; - //private float[] samples = new float[32]; + boolean notClipped; void render(short colixA, short colixB, byte endcaps, int diameter, int xA, int yA, int zA, int xB, int yB, int zB) { - if (isFullyClipped(diameter, xA, yA, zA, xB, yB, zB)) - return; + + int r = diameter / 2 + 1; + int codeMinA = line3d.clipCode(xA - r, yA - r, zA - r); + int codeMaxA = line3d.clipCode(xA + r, yA + r, zA + r); + int codeMinB = line3d.clipCode(xB - r, yB - r, zB - r); + int codeMaxB = line3d.clipCode(xB + r, yB + r, zB + r); + //all bits 0 --> no clipping + notClipped = ((codeMinA | codeMaxA | codeMinB | codeMaxB) == 0); + //any two bits same in all cases --> fully clipped + if ((codeMinA & codeMaxB & codeMaxA & codeMinB) != 0) + return; // fully clipped; dxB = xB - xA; dyB = yB - yA; dzB = zB - zA; if (diameter <= 1) { - g3d.plotLineDelta(colixA, colixB, xA, yA, zA, dxB, dyB, dzB); + line3d.plotLineDelta(g3d.getColixArgb(colixA), + Graphics3D.isColixTranslucent(colixA), g3d.getColixArgb(colixB), + Graphics3D.isColixTranslucent(colixB), xA, yA, zA, dxB, dyB, dzB, notClipped); return; } this.diameter = diameter; @@ -93,7 +106,38 @@ renderSphericalEndcaps(); } - void generateBaseEllipse() { + int xTip, yTip, zTip; + + void renderCone(short colix, byte endcap, int diameter, + int xA, int yA, int zA, + int xTip, int yTip, int zTip) { + dxB = (this.xTip = xTip) - (this.xA = xA); + dyB = (this.yTip = yTip) - (this.yA = yA); + dzB = (this.zTip = zTip) - (this.zA = zA); + + this.colixA = colix; + this.shadesA = g3d.getShades(colix); + this.isScreenedA = (colixA & Graphics3D.TRANSLUCENT_MASK) != 0; + int intensityTip = Shade3D.calcIntensity(dxB, dyB, -dzB); + g3d.plotPixelClipped(shadesA[intensityTip], isScreenedA, xTip, yTip, zTip); + + this.diameter = diameter; + if (diameter <= 1) { + if (diameter == 1) + line3d.plotLineDelta(colixA, isScreenedA, colixA, isScreenedA, + xA, yA, zA, dxB, dyB, dzB, notClipped); + return; + } + this.endcaps = endcap; + calcArgbEndcap(false); + generateBaseEllipse(); + if (endcaps == Graphics3D.ENDCAPS_FLAT) + renderFlatEndcap(false); + for (int i = rasterCount; --i >= 0; ) + plotRasterCone(i); + } + + private void generateBaseEllipse() { tEvenDiameter = (diameter & 1) == 0; //Logger.debug("diameter=" + diameter); radius = diameter / 2.0f; @@ -119,39 +163,7 @@ interpolate(1, 2); } - boolean isFullyClipped(int diameter, - int xA, int yA, int zA, - int xB, int yB, int zB) { - // miguel 2006 03 25 - // probably this should use the Cohen-Sutherland line clipping - // in Line3D - // but right now it seems too difficult to me to figure out - // where all the edges are on the bonds - int slab = g3d.slab; - int depth = g3d.depth; - int width = g3d.width; - int height = g3d.height; - - int r = diameter / 2 + 1; - int xMinA = xA - r, xMaxA = xA + r; - int xMinB = xB - r, xMaxB = xB + r; - if (xMaxA < 0 && xMaxB < 0 || - xMinA >= width && xMinB >= width) - return true; - int yMinA = yA - r, yMaxA = yA + r; - int yMinB = yB - r, yMaxB = yB + r; - if (yMaxA < 0 && yMaxB < 0 || - yMinA >= height && yMinB >= height) - return true; - int zMinA = zA - r, zMaxA = zA + r; - int zMinB = zB - r, zMaxB = zB + r; - if (zMaxA < slab && zMaxB < slab || - zMinA >= depth && zMinB >= depth) - return true; - return false; - } - - void interpolate(int iLower, int iUpper) { + private void interpolate(int iLower, int iUpper) { int dx = xRaster[iUpper] - xRaster[iLower]; if (dx < 0) dx = -dx; @@ -186,40 +198,43 @@ yRaster[iMid] = yRaster[iUpper]; } - void plotRaster(int i) { + private void plotRaster(int i) { int fp8Up = fp8IntensityUp[i]; int x = xRaster[i]; int y = yRaster[i]; int z = zRaster[i]; if (tEndcapOpen) { - g3d.plotPixelClipped(argbEndcap, xEndcap+x, yEndcap+y, zEndcap-z-1); - g3d.plotPixelClipped(argbEndcap, xEndcap-x, yEndcap-y, zEndcap+z-1); + if (notClipped) { + g3d.plotPixelUnclipped(argbEndcap, xEndcap+x, yEndcap+y, zEndcap-z-1); + g3d.plotPixelUnclipped(argbEndcap, xEndcap-x, yEndcap-y, zEndcap+z-1); + }else { + g3d.plotPixelClipped(argbEndcap, xEndcap+x, yEndcap+y, zEndcap-z-1); + g3d.plotPixelClipped(argbEndcap, xEndcap-x, yEndcap-y, zEndcap+z-1); + } } - g3d.plotLineDelta(shadesA, isScreenedA, shadesB, isScreenedB, fp8Up, - xA + x, yA + y, zA - z, - dxB, dyB, dzB); + line3d.plotLineDelta(shadesA, isScreenedA, shadesB, isScreenedB, fp8Up >> 8, + xA + x, yA + y, zA - z, dxB, dyB, dzB, notClipped); if (endcaps == Graphics3D.ENDCAPS_OPEN) { - g3d.plotLineDelta(shadesA[0], isScreenedA, shadesB[0], isScreenedB, - xA - x, yA - y, zA + z, - dxB, dyB, dzB); + line3d.plotLineDelta(shadesA[0], isScreenedA, shadesB[0], isScreenedB, + xA - x, yA - y, zA + z, dxB, dyB, dzB, notClipped); } } - int[] realloc(int[] a) { + private int[] realloc(int[] a) { int[] t; t = new int[a.length * 2]; System.arraycopy(a, 0, t, 0, a.length); return t; } - float[] realloc(float[] a) { + private float[] realloc(float[] a) { float[] t; t = new float[a.length * 2]; System.arraycopy(a, 0, t, 0, a.length); return t; } - int allocRaster() { + private int allocRaster() { if (rasterCount == xRaster.length) { xRaster = realloc(xRaster); yRaster = realloc(yRaster); @@ -238,7 +253,7 @@ int[] zRaster = new int[32]; int[] fp8IntensityUp = new int[32]; - void calcRotatedPoint(float t, int i) { + private void calcRotatedPoint(float t, int i) { tRaster[i] = t; double tPI = t * Math.PI; double xT = Math.sin(tPI) * cosTheta; @@ -265,7 +280,7 @@ int xMin, xMax; int zXMin, zXMax; - void findMinMaxY() { + private void findMinMaxY() { yMin = yMax = yRaster[0]; for (int i = rasterCount; --i > 0; ) { int y = yRaster[i]; @@ -283,7 +298,7 @@ } } - void findMinMaxX(int y) { + private void findMinMaxX(int y) { xMin = Integer.MAX_VALUE; xMax = Integer.MIN_VALUE; for (int i = rasterCount; --i >= 0; ) { @@ -314,7 +329,7 @@ } } - void renderFlatEndcap(boolean tCylinder) { + private void renderFlatEndcap(boolean tCylinder) { if (dzB == 0 || (!tCylinder && dzB < 0)) return; int xT = xA, yT = yA, zT = zA; @@ -333,43 +348,12 @@ } } - void renderSphericalEndcaps() { + private void renderSphericalEndcaps() { g3d.fillSphereCentered(colixA, diameter, xA, yA, zA + 1); g3d.fillSphereCentered(colixB, diameter, xA + dxB, yA + dyB, zA + dzB + 1); } - int xTip, yTip, zTip; - - void renderCone(short colix, byte endcap, int diameter, - int xA, int yA, int zA, - int xTip, int yTip, int zTip) { - dxB = (this.xTip = xTip) - (this.xA = xA); - dyB = (this.yTip = yTip) - (this.yA = yA); - dzB = (this.zTip = zTip) - (this.zA = zA); - - this.colixA = colix; - this.shadesA = g3d.getShades(colix); - this.isScreenedA = (colixA & Graphics3D.TRANSLUCENT_MASK) != 0; - int intensityTip = Shade3D.calcIntensity(dxB, dyB, -dzB); - g3d.plotPixelClipped(shadesA[intensityTip], isScreenedA, xTip, yTip, zTip); - - this.diameter = diameter; - if (diameter <= 1) { - if (diameter == 1) - g3d.plotLineDelta(colixA, isScreenedA, colixA, isScreenedA, - xA, yA, zA, dxB, dyB, dzB); - return; - } - this.endcaps = endcap; - calcArgbEndcap(false); - generateBaseEllipse(); - if (endcaps == Graphics3D.ENDCAPS_FLAT) - renderFlatEndcap(false); - for (int i = rasterCount; --i >= 0; ) - plotRasterCone(i); - } - - void plotRasterCone(int i) { + private void plotRasterCone(int i) { int x = xRaster[i]; int y = yRaster[i]; int z = zRaster[i]; @@ -381,16 +365,16 @@ g3d.plotPixelClipped(argbEndcap, isScreenedA, xDn, yDn, zDn); } int fp8Up = fp8IntensityUp[i]; - g3d.plotLineDelta(shadesA, isScreenedA, shadesA, isScreenedA, fp8Up, - xUp, yUp, zUp, xTip - xUp, yTip - yUp, zTip - zUp); + line3d.plotLineDelta(shadesA, isScreenedA, shadesA, isScreenedA, fp8Up >> 8, + xUp, yUp, zUp, xTip - xUp, yTip - yUp, zTip - zUp, notClipped); if (! (endcaps == Graphics3D.ENDCAPS_FLAT && dzB > 0)) { int argb = shadesA[0]; - g3d.plotLineDelta(argb, isScreenedA, argb, isScreenedA, - xDn, yDn, zDn, xTip - xDn, yTip - yDn, zTip - zDn); + line3d.plotLineDelta(argb, isScreenedA, argb, isScreenedA, + xDn, yDn, zDn, xTip - xDn, yTip - yDn, zTip - zDn, notClipped); } } - void calcArgbEndcap(boolean tCylinder) { + private void calcArgbEndcap(boolean tCylinder) { tEndcapOpen = false; if ((endcaps == Graphics3D.ENDCAPS_SPHERICAL) || (dzB == 0) || Modified: branches/bob200603/Jmol/src/org/jmol/g3d/Graphics3D.java =================================================================== --- branches/bob200603/Jmol/src/org/jmol/g3d/Graphics3D.java 2006-07-24 17:45:36 UTC (rev 5352) +++ branches/bob200603/Jmol/src/org/jmol/g3d/Graphics3D.java 2006-07-24 17:52:09 UTC (rev 5353) @@ -175,23 +175,6 @@ } /** - * Return a greyscale rgb value 0-FF using NTSC color luminance algorithm - *<p> - * the alpha component is set to 0xFF. If you want a value in the - * range 0-255 then & the result with 0xFF; - * - * @param rgb the rgb value - * @return a grayscale value in the range 0 - 255 decimal - */ - public static int calcGreyscaleRgbFromRgb(int rgb) { - int grey = ((2989 * ((rgb >> 16) & 0xFF)) + - (5870 * ((rgb >> 8) & 0xFF)) + - (1140 * (rgb & 0xFF)) + 5000) / 10000; - int greyRgb = (grey << 16) | (grey << 8) | grey | 0xFF000000; - return greyRgb; - } - - /** * controls greyscale rendering * @param greyscaleMode Flag for greyscale rendering */ @@ -298,51 +281,6 @@ int[] imageBuf = new int[0]; - /* * - * draws a circle of the specified color at the specified location - * - * @param colix the color index - * @param diameter pixel diameter - * @param x center x - * @param y center y - * @param z center z - */ - /* no refs - public void drawCircleCentered(short colix, int diameter, - int x, int y, int z) { - if (z < slab || z > depth) - return; - int r = (diameter + 1) / 2; - setColix(colix); - if ((x >= r && x + r < width) && (y >= r && y + r < height)) { - switch (diameter) { - case 2: - plotPixelUnclipped( x, y-1, z); - plotPixelUnclipped(x-1, y-1, z); - plotPixelUnclipped(x-1, y, z); - case 1: - plotPixelUnclipped(x, y, z); - case 0: - break; - default: - circle3d.plotCircleCenteredUnclipped(x, y, z, diameter); - } - } else { - switch (diameter) { - case 2: - plotPixelClipped( x, y-1, z); - plotPixelClipped(x-1, y-1, z); - plotPixelClipped(x-1, y, z); - case 1: - plotPixelClipped(x, y, z); - case 0: - break; - default: - circle3d.plotCircleCenteredClipped(x, y, z, diameter); - } - } - } - */ /** * draws a screened circle ... every other dot is turned on @@ -355,8 +293,8 @@ */ public void fillScreenedCircleCentered(short colixFill, int diameter, int x, int y, int z) { - // halo only - if (diameter == 0 || z < slab || z > depth) + // halo only -- simple Z/window clip + if (isClippedZ(x, y, z)) return; int r = (diameter + 1) / 2; setColix(colixFill); @@ -365,37 +303,13 @@ circle3d.plotFilledCircleCenteredUnclipped(x, y, z, diameter); isTranslucent = false; circle3d.plotCircleCenteredUnclipped(x, y, z, diameter); - } else { + } else if (!isClippedXY(diameter, x, y)) { circle3d.plotFilledCircleCenteredClipped(x, y, z, diameter); isTranslucent = false; circle3d.plotCircleCenteredClipped(x, y, z, diameter); } } - /* * - * fills a solid circle - * - * @param colixFill the color index - * @param diameter the pixel diameter - * @param x center x - * @param y center y - * @param z center z - */ - /* no refs - public void fillCircleCentered(short colixFill, int diameter, - int x, int y, int z) { - if (diameter == 0 || z < slab || z > depth) - return; - int r = (diameter + 1) / 2; - setColix(colixFill); - if (x >= r && x + r < width && y >= r && y + r < height) { - circle3d.plotFilledCircleCenteredUnclipped(x, y, z, diameter); - } else { - circle3d.plotFilledCircleCenteredClipped(x, y, z, diameter); - } - } - */ - /** * fills a solid sphere * @@ -408,7 +322,7 @@ public void fillSphereCentered(short colix, int diameter, int x, int y, int z) { if (diameter <= 1) { - plotPixelClipped(colix, x, y, z); + plotPixelClipped(getColixArgb(colix), x, y, z); } else { sphere3d.render(getShades(colix), ((colix & TRANSLUCENT_MASK) != 0), diameter, x, y, z); @@ -451,7 +365,7 @@ */ public void drawRect(short colix, int x, int y, int z, int zSlab, int rWidth, int rHeight) { // labels (and rubberband, not implemented) - if (zSlab < slab || zSlab > depth) + if (isClippedZ(x, y, zSlab)) return; int w = rWidth - 1; int h = rHeight - 1; @@ -498,10 +412,9 @@ public void fillRect(short colix, int x, int y, int z, int zSlab, int widthFill, int heightFill) { - // labels only -- slab at atom; - if (zSlab < slab || zSlab > depth) + // labels and hover only -- slab at atom or front -- simple Z/window clip + if (isClippedZ(x, y, zSlab)) return; - setColix(colix); if (x < 0) { widthFill += x; if (widthFill <= 0) @@ -510,69 +423,26 @@ } if (x + widthFill > width) { widthFill = width - x; - if (widthFill == 0) - return; - } - if (y < 0) { - heightFill += y; - if (heightFill <= 0) - return; - y = 0; - } - if (y + heightFill > height) - heightFill = height - y; - while (--heightFill >= 0) - plotPixelsUnclipped(widthFill, x, y++, z); - } - - - public void fillRectNoSlab(short colix, - int x, int y, int z, int widthFill, int heightFill) { - //hover only - setColix(colix); - if (x < 0) { - widthFill += x; if (widthFill <= 0) return; - x = 0; } - if (x + widthFill > width) { - widthFill = width - x; - if (widthFill == 0) - return; - } if (y < 0) { heightFill += y; if (heightFill <= 0) return; y = 0; } + setColix(colix); if (y + heightFill > height) heightFill = height - y; while (--heightFill >= 0) plotPixelsUnclipped(widthFill, x, y++, z); } - /** * draws the specified string in the current font. - * no line wrapping + * no line wrapping -- axis, labels, measures * - * @param str the string - * @param colix the color index - * @param xBaseline baseline x - * @param yBaseline baseline y - * @param z baseline z - */ - public void drawString(String str, short colix, - int xBaseline, int yBaseline, int z) { - drawString(str, font3dCurrent, colix, (short)0, xBaseline, yBaseline, z); - } - - /** - * draws the specified string in the current font. - * no line wrapping - * * @param str the String * @param font3d the Font3D * @param colix the color index @@ -584,42 +454,31 @@ public void drawString(String str, Font3D font3d, short colix, int xBaseline, int yBaseline, int z, int zSlab) { - drawString(str, font3d, colix, (short)0, xBaseline, yBaseline, z, zSlab); + //axis, labels, measures + if (isClippedZ(xBaseline, yBaseline, zSlab)) + return; + drawStringNoSlab(str, font3d, colix, (short) 0, xBaseline, yBaseline, z); } - + /** * draws the specified string in the current font. - * no line wrapping + * no line wrapping -- echo, frank, hover, molecularOrbital, uccage * * @param str the String * @param font3d the Font3D * @param colix the color index - * @param bgcolix the color index of the background + * @param bgcolix the background color index * @param xBaseline baseline x * @param yBaseline baseline y * @param z baseline z - * @param zSlab z for slab check */ - - public void drawString(String str, Font3D font3d, short colix, short bgcolix, - int xBaseline, int yBaseline, int z, int zSlab) { - //Logger.debug("Graphics3D.drawString(" + str + "," + font3d + - // ", ...)"); - - font3dCurrent = font3d; - setColix(colix); - if (zSlab < slab || zSlab > depth) - return; - //Logger.debug("ready to call"); - Text3D.plot(xBaseline, yBaseline - font3d.fontMetrics.getAscent(), - z, argbCurrent, getColixArgb(bgcolix), str, font3dCurrent, this); - //Logger.debug("done"); - } - + public void drawStringNoSlab(String str, Font3D font3d, short colix, short bgcolix, int xBaseline, int yBaseline, int z) { - font3dCurrent = font3d; + // echo, frank, hover, molecularOrbital, uccage + if(font3d != null) + font3dCurrent = font3d; setColix(colix); Text3D.plot(xBaseline, yBaseline - font3d.fontMetrics.getAscent(), z, argbCurrent, getColixArgb(bgcolix), str, font3dCurrent, this); @@ -748,179 +607,178 @@ platform.clearScreenBufferThreaded(); } - public void drawDashedLine(short colix, int run, int rise, - int x1, int y1, int z1, int x2, int y2, int z2) { - int argb = getColixArgb(colix); - line3d.drawDashedLine(argb, isTranslucent, argb, isTranslucent, - run, rise, x1, y1, z1, x2, y2, z2); - } + //mostly public drawing methods -- add "public" if you need to - /* - public void drawDashedLine(short colix1, short colix2, int run, int rise, - int x1, int y1, int z1, int x2, int y2, int z2) { - - line3d.drawDashedLine(getColixArgb(colix1), isColixTranslucent(colix1), - getColixArgb(colix2), isColixTranslucent(colix2), - run, rise, x1, y1, z1, x2, y2, z2); - } - */ + /* *************************************************************** + * points + * ***************************************************************/ - public void drawLine(Point3i pointA, Point3i pointB) { - line3d.drawLine(argbCurrent, isTranslucent, argbCurrent, isTranslucent, - pointA.x, pointA.y, pointA.z, - pointB.x, pointB.y, pointB.z); + + public void drawPixel(int x, int y, int z) { + // measures - render angle + plotPixelClipped(x, y, z); } - /* - public void drawLine(short colix, Point3i pointA, Point3i pointB) { + public void drawPoints(short colix, int count, int[] coordinates) { + // for dots only setColix(colix); - line3d.drawLine(argbCurrent, isTranslucent, argbCurrent, isTranslucent, - pointA.x, pointA.y, pointA.z, - pointB.x, pointB.y, pointB.z); + plotPoints(count, coordinates); } - */ - - public void drawDottedLine(short colix, Point3i pointA, Point3i pointB) { - drawDashedLine(colix, 2, 1, pointA, pointB); + + /* *************************************************************** + * lines and cylinders + * ***************************************************************/ + + public void drawDashedLine(short colix, int run, int rise, + int x1, int y1, int z1, int x2, int y2, int z2) { + // measures only + int argb = getColixArgb(colix); + line3d.plotDashedLine(argb, isTranslucent, argb, isTranslucent, + run, rise, x1, y1, z1, x2, y2, z2, false); } - - public void drawDashedLine(short colix, int run, int rise, - Point3i pointA, Point3i pointB) { + + public void drawDottedLine(short colix, Point3i pointA, Point3i pointB) { + //axes, bbcage only setColix(colix); - line3d.drawDashedLine(argbCurrent, isTranslucent, - argbCurrent, isTranslucent, - run, rise, + line3d.plotDashedLine(argbCurrent, isTranslucent, + argbCurrent, isTranslucent, 2, 1, pointA.x, pointA.y, pointA.z, - pointB.x, pointB.y, pointB.z); + pointB.x, pointB.y, pointB.z, false); } - /* no refs - public void drawDashedLine(int run, int rise, - int x1, int y1, int z1, int x2, int y2, int z2) { - line3d.drawDashedLine(argbCurrent, isTranslucent, - argbCurrent, isTranslucent, - run, rise, x1, y1, z1, x2, y2, z2); - } - */ - - public void drawLine(int x1, int y1, int z1, int x2, int y2, int z2) { - line3d.drawLine(argbCurrent, isTranslucent, argbCurrent, isTranslucent, - x1, y1, z1, x2, y2, z2); - } - public void drawLine(short colix, int x1, int y1, int z1, int x2, int y2, int z2) { + // stars setColix(colix); - line3d.drawLine(argbCurrent, isTranslucent, argbCurrent, isTranslucent, - x1, y1, z1, x2, y2, z2); + line3d.plotLine(argbCurrent, isTranslucent, argbCurrent, isTranslucent, + x1, y1, z1, x2, y2, z2, false); } public void drawLine(short colix1, short colix2, int x1, int y1, int z1, int x2, int y2, int z2) { - line3d.drawLine(getColixArgb(colix1), isColixTranslucent(colix1), + // backbone and sticks + line3d.plotLine(getColixArgb(colix1), isColixTranslucent(colix1), getColixArgb(colix2), isColixTranslucent(colix2), - x1, y1, z1, x2, y2, z2); + x1, y1, z1, x2, y2, z2, false); } - /* - public void drawPolygon4(int[] ax, int[] ay, int[] az) { - drawLine(ax[0], ay[0], az[0], ax[3], ay[3], az[3]); - for (int i = 3; --i >= 0; ) - drawLine(ax[i], ay[i], az[i], ax[i+1], ay[i+1], az[i+1]); + void drawLine(Point3i pointA, Point3i pointB) { + // draw quadrilateral and hermite + line3d.plotLine(argbCurrent, isTranslucent, argbCurrent, isTranslucent, + pointA.x, pointA.y, pointA.z, + pointB.x, pointB.y, pointB.z, false); } - */ - public void fillQuadrilateral(short colix, - Point3f screenA, Point3f screenB, - Point3f screenC, Point3f screenD) { - setColorNoisy(colix, calcIntensityScreen(screenA, screenB, screenC)); - fillTriangle(screenA, screenB, screenC); - fillTriangle(screenA, screenC, screenD); + public final static byte ENDCAPS_NONE = 0; + public final static byte ENDCAPS_OPEN = 1; + public final static byte ENDCAPS_FLAT = 2; + public final static byte ENDCAPS_SPHERICAL = 3; + + public void fillCylinder(short colixA, short colixB, byte endcaps, + int diameter, + int xA, int yA, int zA, int xB, int yB, int zB) { + cylinder3d.render(colixA, colixB, endcaps, diameter, + xA, yA, zA, xB, yB, zB); } - public void fillTriangle(short colix, - Point3i screenA, short normixA, - Point3i screenB, short normixB, - Point3i screenC, short normixC) { - int[] t; - t = triangle3d.ax; - t[0] = screenA.x; t[1] = screenB.x; t[2] = screenC.x; - t = triangle3d.ay; - t[0] = screenA.y; t[1] = screenB.y; t[2] = screenC.y; - t = triangle3d.az; - t[0] = screenA.z; t[1] = screenB.z; t[2] = screenC.z; + public void fillCylinder(short colix, byte endcaps, + int diameter, + int xA, int yA, int zA, int xB, int yB, int zB) { + cylinder3d.render(colix, colix, endcaps, diameter, + xA, yA, zA, xB, yB, zB); + } - if (normixA == normixB && normixA == normixC) { - setColorNoisy(colix, normix3d.getIntensity(normixA)); - triangle3d.fillTriangle(false); - } else { - setColix(colix); - triangle3d.setGouraud(shadesCurrent[normix3d.getIntensity(normixA)], - shadesCurrent[normix3d.getIntensity(normixB)], - shadesCurrent[normix3d.getIntensity(normixC)]); - triangle3d.fillTriangle(true); - } + public void fillCylinder(short colix, byte endcaps, int diameter, + Point3i screenA, Point3i screenB) { + cylinder3d.render(colix, colix, endcaps, diameter, + screenA.x, screenA.y, screenA.z, + screenB.x, screenB.y, screenB.z); } - public void fillTriangle(Point3i screenA, short colixA, short normixA, - Point3i screenB, short colixB, short normixB, - Point3i screenC, short colixC, short normixC) { - int[] t; - t = triangle3d.ax; - t[0] = screenA.x; t[1] = screenB.x; t[2] = screenC.x; - t = triangle3d.ay; - t[0] = screenA.y; t[1] = screenB.y; t[2] = screenC.y; - t = triangle3d.az; - t[0] = screenA.z; t[1] = screenB.z; t[2] = screenC.z; + public void fillCone(short colix, byte endcap, int diameter, + Point3i screenBase, Point3i screenTip) { + cylinder3d.renderCone(colix, endcap, diameter, + screenBase.x, screenBase.y, screenBase.z, + screenTip.x, screenTip.y, screenTip.z); + } - if (normixA == normixB && normixA == normixC && - colixA == colixB && colixA == colixC) { - setColorNoisy(colixA, normix3d.getIntensity(normixA)); - triangle3d.fillTriangle(false); - } else { - triangle3d.setGouraud(getShades(colixA)[normix3d.getIntensity(normixA)], - getShades(colixB)[normix3d.getIntensity(normixB)], - getShades(colixC)[normix3d.getIntensity(normixC)]); - int translucentCount = 0; - if (isColixTranslucent(colixA)) - ++translucentCount; - if (isColixTranslucent(colixB)) - ++translucentCount; - if (isColixTranslucent(colixC)) - ++translucentCount; - isTranslucent = translucentCount >= 2; - triangle3d.fillTriangle(true); - } + public void drawHermite(short colix, int tension, + Point3i s0, Point3i s1, Point3i s2, Point3i s3) { + hermite3d.render(false, colix, tension, 0, 0, 0, s0, s1, s2, s3); } - public void fillTriangleTest(Point3i screenA, short colixA, short normixA, - Point3i screenB, short colixB, short normixB, - Point3i screenC, short colixC, short normixC) { + public void drawHermite(boolean fill, boolean border, + short colix, int tension, + Point3i s0, Point3i s1, Point3i s2, Point3i s3, + Point3i s4, Point3i s5, Point3i s6, Point3i s7) { + hermite3d.render2(fill, border, colix, tension, + s0, s1, s2, s3, s4, s5, s6, s7); + } - try{ - if (false && (!normix3d.isDirectedTowardsCamera(normixA) - || ! normix3d.isDirectedTowardsCamera(normixB) - || ! normix3d.isDirectedTowardsCamera(normixC))){ - return; - } - }catch(Exception e) { - Logger.debug("can't check this one:"); - } - int[] t; - t = triangle3d.ax; - t[0] = screenA.x; t[1] = screenB.x; t[2] = screenC.x; - testAdjust(t, 0.1f); - t = triangle3d.ay; - t[0] = screenA.y; t[1] = screenB.y; t[2] = screenC.y; - testAdjust(t, 0.1f); - t = triangle3d.az; - t[0] = screenA.z; t[1] = screenB.z; t[2] = screenC.z; - testAdjust(t, 0.1f); + public void fillHermite(short colix, int tension, int diameterBeg, + int diameterMid, int diameterEnd, + Point3i s0, Point3i s1, Point3i s2, Point3i s3) { + hermite3d.render(true, colix, tension, + diameterBeg, diameterMid, diameterEnd, + s0, s1, s2, s3); + } + /* *************************************************************** + * triangles + * ***************************************************************/ + + public void drawTriangle(short colix, Point3i screenA, Point3i screenB, + Point3i screenC) { + // primary method for Mesh + drawTriangle(colix, screenA.x, screenA.y, screenA.z, screenB.x, screenB.y, + screenB.z, screenC.x, screenC.y, screenC.z, false); + } + + void drawTriangle(short colix, int xA, int yA, int zA, int xB, int yB, + int zB, int xC, int yC, int zC, boolean notClipped) { + setColix(colix); + line3d.plotLine(argbCurrent, isTranslucent, argbCurrent, isTranslucent, xA, + yA, zA, xB, yB, zB, notClipped); + line3d.plotLine(argbCurrent, isTranslucent, argbCurrent, isTranslucent, xA, + yA, zA, xC, yC, zC, notClipped); + line3d.plotLine(argbCurrent, isTranslucent, argbCurrent, isTranslucent, xB, + yB, zB, xC, yC, zC, notClipped); + } + + public void drawCylinderTriangle(short colix, int xA, int yA, int zA, int xB, + int yB, int zB, int xC, int yC, int zC, + int diameter) { + // polyhedra + fillCylinder(colix, colix, Graphics3D.ENDCAPS_SPHERICAL, diameter, xA, yA, + zA, xB, yB, zB); + fillCylinder(colix, colix, Graphics3D.ENDCAPS_SPHERICAL, diameter, xA, yA, + zA, xC, yC, zC); + fillCylinder(colix, colix, Graphics3D.ENDCAPS_SPHERICAL, diameter, xB, yB, + zB, xC, yC, zC); + } + + public void drawfillTriangle(short colix, int xA, int yA, int zA, int xB, + int yB, int zB, int xC, int yC, int zC) { + // sticks -- sterochemical wedge notation -- not implemented? + setColix(colix); + line3d.plotLine(argbCurrent, isTranslucent, argbCurrent, isTranslucent, xA, + yA, zA, xB, yB, zB, false); + line3d.plotLine(argbCurrent, isTranslucent, argbCurrent, isTranslucent, xA, + yA, zA, xC, yC, zC, false); + line3d.plotLine(argbCurrent, isTranslucent, argbCurrent, isTranslucent, xB, + yB, zB, xC, yC, zC, false); + triangle3d.fillTriangle(xA, yA, zA, xB, yB, zB, xC, yC, zC, false); + } + + public void fillTriangle(Point3i screenA, short colixA, short normixA, + Point3i screenB, short colixB, short normixB, + Point3i screenC, short colixC, short normixC) { + // mesh + boolean useGouraud; if (normixA == normixB && normixA == normixC && colixA == colixB && colixA == colixC) { setColorNoisy(colixA, normix3d.getIntensity(normixA)); - triangle3d.fillTriangle(false); + useGouraud = false; } else { triangle3d.setGouraud(getShades(colixA)[normix3d.getIntensity(normixA)], getShades(colixB)[normix3d.getIntensity(normixB)], @@ -933,77 +791,97 @@ if (isColixTranslucent(colixC)) ++translucentCount; isTranslucent = translucentCount >= 2; - triangle3d.fillTriangle(true); + useGouraud = true; } + triangle3d.fillTriangle(screenA, screenB, screenC, useGouraud); } - void testAdjust(int[] t, float fraction) { - float av = (t[0] + t[1] + t[2]) / 3f; - for (int i=0;i<3;i++) - t[i] += fraction * (av - t[i]); - } - public void fillTriangle(short colix, Point3i screenA, Point3i screenB, Point3i screenC) { + // geodesic (Dots.java) calcSurfaceShade(colix, screenA, screenB, screenC); - int[] t; - t = triangle3d.ax; - t[0] = screenA.x; t[1] = screenB.x; t[2] = screenC.x; - t = triangle3d.ay; - t[0] = screenA.y; t[1] = screenB.y; t[2] = screenC.y; - t = triangle3d.az; - t[0] = screenA.z; t[1] = screenB.z; t[2] = screenC.z; - - triangle3d.fillTriangle(false); + triangle3d.fillTriangle(screenA, screenB, screenC, false); } public void fillTriangle(short colix, short normix, int xScreenA, int yScreenA, int zScreenA, int xScreenB, int yScreenB, int zScreenB, int xScreenC, int yScreenC, int zScreenC) { + // polyhedra setColorNoisy(colix, normix3d.getIntensity(normix)); - int[] t; - t = triangle3d.ax; - t[0] = xScreenA; t[1] = xScreenB; t[2] = xScreenC; - t = triangle3d.ay; - t[0] = yScreenA; t[1] = yScreenB; t[2] = yScreenC; - t = triangle3d.az; - t[0] = zScreenA; t[1] = zScreenB; t[2] = zScreenC; - triangle3d.fillTriangle(false); + triangle3d.fillTriangle( xScreenA, yScreenA, zScreenA, + xScreenB, yScreenB, zScreenB, + xScreenC, yScreenC, zScreenC, false); } public void fillTriangle(short colix, Point3f screenA, Point3f screenB, Point3f screenC) { + // rockets setColorNoisy(colix, calcIntensityScreen(screenA, screenB, screenC)); - fillTriangle(screenA, screenB, screenC); + triangle3d.fillTriangle(screenA, screenB, screenC, false); } - public void fillQuadrilateral(short colix, - Point3i screenA, Point3i screenB, + public void fillTriangle(Point3i screenA, Point3i screenB, Point3i screenC) { + // cartoon, hermite + triangle3d.fillTriangle(screenA, screenB, screenC, false); + } + + public void fillTriangle(Point3i screenA, short colixA, + short normixA, Point3i screenB, + short colixB, short normixB, + Point3i screenC, short colixC, + short normixC, float factor) { + // isosurface + boolean useGouraud; + if (normixA == normixB && normixA == normixC && colixA == colixB + && colixA == colixC) { + setColorNoisy(colixA, normix3d.getIntensity(normixA)); + useGouraud = false; + } else { + triangle3d.setGouraud(getShades(colixA)[normix3d.getIntensity(normixA)], + getShades(colixB)[normix3d.getIntensity(normixB)], + getShades(colixC)[normix3d.getIntensity(normixC)]); + int translucentCount = 0; + if (isColixTranslucent(colixA)) + ++translucentCount; + if (isColixTranslucent(colixB)) + ++translucentCount; + if (isColixTranslucent(colixC)) + ++translucentCount; + isTranslucent = translucentCount >= 2; + useGouraud = true; + } + triangle3d.fillTriangle(screenA, screenB, screenC, factor, + useGouraud); + } + + /* *************************************************************** + * quadrilaterals + * ***************************************************************/ + + public void drawQuadrilateral(short colix, Point3i screenA, Point3i screenB, Point3i screenC, Point3i screenD) { - fillTriangle(colix, screenA, screenB, screenC); - fillTriangle(colix, screenA, screenC, screenD); + setColix(colix); + drawLine(screenA, screenB); + drawLine(screenB, screenC); + drawLine(screenC, screenD); + drawLine(screenD, screenA); } public void fillQuadrilateral(short colix, - Point3i screenA, short normixA, - Point3i screenB, short normixB, - Point3i screenC, short normixC, - Point3i screenD, short normixD) { - fillTriangle(colix, - screenA, normixA, - screenB, normixB, - screenC, normixC); - fillTriangle(colix, - screenA, normixA, - screenC, normixC, - screenD, normixD); + Point3f screenA, Point3f screenB, + Point3f screenC, Point3f screenD) { + // hermite, rockets + setColorNoisy(colix, calcIntensityScreen(screenA, screenB, screenC)); + triangle3d.fillTriangle(screenA, screenB, screenC, false); + triangle3d.fillTriangle(screenA, screenC, screenD, false); } public void fillQuadrilateral(Point3i screenA, short colixA, short normixA, Point3i screenB, short colixB, short normixB, Point3i screenC, short colixC, short normixC, Point3i screenD, short colixD, short normixD) { + // mesh fillTriangle(screenA, colixA, normixA, screenB, colixB, normixB, screenC, colixC, normixC); @@ -1012,243 +890,30 @@ screenD, colixD, normixD); } - public void fillTriangle(Point3i screenA, Point3i screenB, Point3i screenC) { - - int[] t; - t = triangle3d.ax; - t[0] = screenA.x; t[1] = screenB.x; t[2] = screenC.x; - t = triangle3d.ay; - t[0] = screenA.y; t[1] = screenB.y; t[2] = screenC.y; - t = triangle3d.az; - t[0] = screenA.z; t[1] = screenB.z; t[2] = screenC.z; + /* *************************************************************** + * lower-level plotting routines + * ***************************************************************/ - triangle3d.fillTriangle(false); + private boolean isClipped(int x, int y, int z) { + // this is the one that could be augmented with slabPlane + return (x < 0 || x >= width || y < 0 || y >= height || z < slab || z > depth); } - - public void fillTriangle(Point3f screenA, Point3f screenB, Point3f screenC) { - int[] t; - t = triangle3d.ax; - t[0] = (int)screenA.x; t[1] = (int)screenB.x; t[2] = (int)screenC.x; - t = triangle3d.ay; - t[0] = (int)screenA.y; t[1] = (int)screenB.y; t[2] = (int)screenC.y; - t = triangle3d.az; - t[0] = (int)screenA.z; t[1] = (int)screenB.z; t[2] = (int)screenC.z; - - triangle3d.fillTriangle(false); - } - - int intensity = 0; - void diff(Vector3f v, Point3i s1, Point3i s2) { - v.x = s1.x - s2.x; - v.y = s1.y - s2.y; - v.z = s1.z - s2.z; + private boolean isClipped(int x, int y) { + return (x < 0 || x >= width || y < 0 || y >= height); } - public void calcSurfaceShade(short colix, Point3i screenA, - Point3i screenB, Point3i screenC) { - diff(vectorAB, screenB, screenA); - diff(vectorAC, screenC, screenA); - vectorNormal.cross(vectorAB, vectorAC); - int intensity = - vectorNormal.z >= 0 - ? calcIntensity(-vectorNormal.x, -vectorNormal.y, vectorNormal.z) - : calcIntensity(vectorNormal.x, vectorNormal.y, -vectorNormal.z); - if (intensity > intensitySpecularSurfaceLimit) - intensity = intensitySpecularSurfaceLimit; - setColorNoisy(colix, intensity); + private boolean isClippedXY(int diameter, int x, int y) { + int r = (diameter + 1) >> 1; + return (x < -r || x >= width + r || y < -r || y >= height + r); } - - public void drawfillTriangle(short colix, int xA, int yA, int zA, int xB, - int yB, int zB, int xC, int yC, int zC) { - setColix(colix); - int argb = argbCurrent; - line3d.drawLine(argb, isTranslucent, argb, isTranslucent, - xA, yA, zA, xB, yB, zB); - line3d.drawLine(argb, isTranslucent, argb, isTranslucent, - xA, yA, zA, xC, yC, zC); - line3d.drawLine(argb, isTranslucent, argb, isTranslucent, - xB, yB, zB, xC, yC, zC); - int[] t; - t = triangle3d.ax; - t[0] = xA; t[1] = xB; t[2] = xC; - t = triangle3d.ay; - t[0] = yA; t[1] = yB; t[2] = yC; - t = triangle3d.az; - t[0] = zA; t[1] = zB; t[2] = zC; - - triangle3d.fillTriangle(false); + + private boolean isClippedZ(int x, int y, int z) { + return (z < slab || z > depth); } - - public void fillTriangle(short colix, boolean translucent, - int xA, int yA, int zA, - int xB, int yB, int zB, int xC, int yC, int zC) { - setColix(colix); - int[] t; - t = triangle3d.ax; - t[0] = xA; t[1] = xB; t[2] = xC; - t = triangle3d.ay; - t[0] = yA; t[1] = yB; t[2] = yC; - t = triangle3d.az; - t[0] = zA; t[1] = zB; t[2] = zC; - - triangle3d.fillTriangle(false); - } - - /* - final Point3i warrenA = new Point3i(); - final Point3i warrenB = new Point3i(); - final Point3i warrenC = new Point3i(); - - public void fillTriangleWarren(int argb, - int xA, int yA, int zA, - int xB, int yB, int zB, - int xC, int yC, int zC) { - warrenA.x = xA; warrenA.y = yA; warrenA.z = zA; - warrenB.x = xB; warrenB.y = yB; warrenB.z = zB; - warrenC.x = xC; warrenC.y = yC; warrenC.z = zC; - - short colix = getColix(argb); - - calcSurfaceShade(colix, false, warrenA, warrenB, warrenC); - - int[] t; - t = triangle3d.ax; - t[0] = xA; t[1] = xB; t[2] = xC; - t = triangle3d.ay; - t[0] = yA; t[1] = yB; t[2] = yC; - t = triangle3d.az; - t[0] = zA; t[1] = zB; t[2] = zC; - - triangle3d.fillTriangle(false, false); - } - */ - - public void drawTriangle(short colix, - int xA, int yA, int zA, - int xB, int yB, int zB, - int xC, int yC, int zC) { - setColix(colix); - drawLine(xA, yA, zA, xB, yB, zB); - drawLine(xA, yA, zA, xC, yC, zC); - drawLine(xB, yB, zB, xC, yC, zC); - } - - public void drawCylinderTriangle(short colix, - int xA, int yA, int zA, - int xB, int yB, int zB, - int xC, int yC, int zC, int diameter) { - fillCylinder(colix, colix, Graphics3D.ENDCAPS_SPHERICAL, diameter, - xA, yA, zA, xB, yB, zB); - fillCylinder(colix, colix, Graphics3D.ENDCAPS_SPHERICAL, diameter, - xA, yA, zA, xC, yC, zC); - fillCylinder(colix, colix, Graphics3D.ENDCAPS_SPHERICAL, diameter, - xB, yB, zB, xC, yC, zC); - } - - public void drawTriangle(short colix, Point3i screenA, - Point3i screenB, Point3i screenC) { - drawTriangle(colix, - screenA.x, screenA.y, screenA.z, - screenB.x, screenB.y, screenB.z, - screenC.x, screenC.y, screenC.z); - } - - public void drawQuadrilateral(short colix, - Point3i screenA, Point3i screenB, - Point3i screenC, Point3i screenD) { - setColix(colix); - drawLine(screenA, screenB); - drawLine(screenB, screenC); - drawLine(screenC, screenD); - drawLine(screenD, screenA); - } - - public final static byte ENDCAPS_NONE = 0; - public final static byte ENDCAPS_OPEN = 1; - public final static byte ENDCAPS_FLAT = 2; - public final static byte ENDCAPS_SPHERICAL = 3; - - public void fillCylinder(short colixA, short colixB, byte endcaps, - int diameter, - int xA, int yA, int zA, int xB, int yB, int zB) { - cylinder3d.render(colixA, colixB, endcaps, diameter, - xA, yA, zA, xB, yB, zB); - } - - public void fillCylinder(short colix, byte endcaps, - int diameter, - int xA, int yA, int zA, int xB, int yB, int zB) { - cylinder3d.render(colix, colix, endcaps, diameter, - xA, yA, zA, xB, yB, zB); - } - - public void fillCylinder(short colix, byte endcaps, int diameter, - Point3i screenA, Point3i screenB) { - cylinder3d.render(colix, colix, endcaps, diameter, - screenA.x, screenA.y, screenA.z, - screenB.x, screenB.y, screenB.z); - } - - /* no refs - public void fillCone(short colix, byte endcap, int diameter, - int xBase, int yBase, int zBase, - int xTip, int yTip, int zTip) { - cylinder3d.renderCone(colix, endcap, diameter, - xBase, yBase, zBase, xTip, yTip, zTip); - } - */ - public void fillCone(short colix, byte endcap, int diameter, - Point3i screenBase, Point3i screenTip) { - cylinder3d.renderCone(colix, endcap, diameter, - screenBase.x, screenBase.y, screenBase.z, - screenTip.x, screenTip.y, screenTip.z); - } - - public void fillHermite(short colix, int tension, int diameterBeg, - int diameterMid, int diameterEnd, - Point3i s0, Point3i s1, Point3i s2, Point3i s3) { - hermite3d.render(true, colix, tension, - diameterBeg, diameterMid, diameterEnd, - s0, s1, s2, s3); - } - - public void drawHermite(short colix, int tension, - Point3i s0, Point3i s1, Point3i s2, Point3i s3) { - hermite3d.render(false, colix, tension, 0, 0, 0, s0, s1, s2, s3); - } - - public void drawHermite(boolean fill, boolean border, - short colix, int tension, - Point3i s0, Point3i s1, Point3i s2, Point3i s3, - Point3i s4, Point3i s5, Point3i s6, Point3i s7) { - hermite3d.render2(fill, border, colix, tension, - s0, s1, s2, s3, s4, s5, s6, s7); - } - - /* - public void drawPixel(Point3i point) { - plotPixelClipped(point); - } - */ - - public void drawPixel(int x, int y, int z) { - plotPixelClipped(x, y, z); - } - /* - public void drawPixel(Point3i point, int normix) { - plotPixelClipped(shadesCurrent[normix3d.intensities[normix]], - point.x, point.y, point.z); - } - */ - /* *************************************************************** - * the plotting routines - * ***************************************************************/ - - void plotPixelClipped(int x, int y, int z) { - if (x < 0 || x >= width || y < 0 || y >= height || z < slab || z > depth) + if (isClipped(x, y, z)) return; int offset = y * width + x; if (z < zbuf[offset]) { @@ -1258,18 +923,13 @@ } void plotPixelClipped(Point3i screen) { - int x = screen.x; if (x < 0 || x >= width) return; - int y = screen.y; if (y < 0 || y >= height) return; - int z = screen.z; if (z < slab || z > depth) return; - int offset = y * width + x; - if (z < zbuf[offset]) { - zbuf[offset] = z; - pbuf[offset] = argbCurrent; - } + // hermite only + plotPixelClipped(screen.x, screen.y, screen.z); } void plotPixelClipped(int argb, int x, int y, int z) { - if (x < 0 || x >= width || y < 0 || y >= height || z < slab || z > depth) + // cylinder3d plotRaster + if (isClipped(x, y, z)) return; int offset = y * width + x; if (z < zbuf[offset]) { @@ -1279,7 +939,8 @@ } void plotPixelClippedNoSlab(int argb, int x, int y, int z) { - if (x < 0 || x >= width || y < 0 || y >= height) + // drawString via text3d.plotClipped + if (isClipped(x, y)) return; int offset = y * width + x; if (z < zbuf[offset]) { @@ -1289,7 +950,7 @@ } void plotPixelClipped(int argb, boolean isTranslucent, int x, int y, int z) { - if (x < 0 || x >= width || y < 0 || y >= height || z < slab || z > depth) + if (isClipped(x, y, z)) return; if (isTranslucent && ((x ^ y) & 1) != 0) return; @@ -1300,34 +961,28 @@ } } - void plotPixelClipped(short colix, int x, int y, int z) { - if (x < 0 || x >= width || y < 0 || y >= height || z < slab || z > depth) - return; - int offset = y * width + x; - if (z < zbuf[offset]) { - zbuf[offset] = z; - pbuf[offset] = getColixArgb(colix); - } - } - void plotPixelUnclipped(int x, int y, int z) { + // circle (halo) int offset = y * width + x; if (z < zbuf[offset]) { zbuf[offset] = z; pbuf[offset] = argbCurrent; } } - /* + void plotPixelUnclipped(int argb, int x, int y, int z) { + // cylinder plotRaster int offset = y * width + x; if (z < zbuf[offset]) { zbuf[offset] = z; pbuf[offset] = argb; } } - */ + void plotPixelsClipped(int count, int x, int y, int z) { - if (y < 0 || y >= height || x >= width) //only x,y vary + // for circle only; i.e. halo + // simple Z/window clip + if (y < 0 || y >= height || x >= width) return; if (x < 0) { count += x; // x is negative, so this is subtracting -x @@ -1358,6 +1013,7 @@ void plotPixelsClipped(int count, int x, int y, int zAtLeft, int zPastRight, Rgb16 rgb16Left, Rgb16 rgb16Right) { + // cylinder3d.renderFlatEndcap, triangle3d.fillRaster if (count <= 0 || y < 0 || y >= height || x >= width || (zAtLeft < slab && zPastRight < slab) || (zAtLeft > depth && zPastRight > depth)) @@ -1433,6 +1089,7 @@ void plotPixelsUnclipped(int count, int x, int y, int zAtLeft, int zPastRight, Rgb16 rgb16Left, Rgb16 rgb16Right) { + // for Triangle3D.fillRaster if (count <= 0) return; int seed = (x << 16) + (y << 1) ^ 0x33333333; @@ -1569,113 +1226,14 @@ } while (offsetPbuf < offsetMax); } } - /* no refs - void plotPixelsClipped(int[] pixels, int offset, int count, - int x, int y, int z) { - if (y < 0 || y >= height || x >= width || z < slab || z > depth) - return; - if (x < 0) { - count += x; // x is negative, so this is subtracting -x - if (count < 0) - return; - offset -= x; // and this is adding -x - x = 0; - } - if (count + x > width) - count = width - x; - int offsetPbuf = y * width + x; - while (--count >= 0) { - int pixel = pixels[offset++]; - int alpha = pixel & 0xFF000000; - if (alpha >= 0x80000000) { - if (z < zbuf[offsetPbuf]) { - zbuf[offsetPbuf] = z; - pbuf[offsetPbuf] = pixel; - } - } - ++offsetPbuf; - } - } - */ - - /* - void plotPixelsUnclipped(int[] pixels, int offset, int count, - int x, int y, int z) { - int offsetPbuf = y * width + x; - while (--count >= 0) { - int pixel = pixels[offset++]; - int alpha = pixel & 0xFF000000; - if ((alpha & 0x80000000) != 0) { - if (z < zbuf[offsetPbuf]) { - zbuf[offsetPbuf] = z; - pbuf[offsetPbuf] = pixel; - } - } - ++offsetPbuf; - } - } - */ - - void plotLineDelta(int[] shades1, boolean isTranslucent1, - int[] shades2, boolean isTranslucent2, - int fp8Intensity, - 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 || - z < slab || z + dz < slab || z > depth || z + dz > depth) - line3d.plotLineDeltaClipped(shades1, isTranslucent1, - shades2, isTranslucent2, - fp8Intensity, - x, y, z, dx, dy, dz); - else - line3d.plotLineDeltaUnclipped(shades1, isTranslucent1, - shades2, isTranslucent2, - fp8Intensity, - x, y, z, dx, dy, dz); - } - void plotLineDelta(short colixA, short colixB, - 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 || - z < slab || z + dz < slab || z > depth || z + dz > depth) - line3d.plotLineDeltaClipped(getColixArgb(colixA), - isColixTranslucent(colixA), - getColixArgb(colixB), - isColixTranslucent(colixB), - x, y, z, dx, dy, dz); - else - line3d.plotLineDeltaUnclipped(getColixArgb(colixA), - isColixTranslucent(colixA), - getColixArgb(colixB), - isColixTranslucent(colixB), - x, y, z, dx, dy, dz); - } - - void plotLineDelta(int argb1, boolean isTranslucent1, - int argb2, boolean isTranslucent2, - 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 || - z < slab || z + dz < slab || z > depth || z + dz > depth) - line3d.plotLineDeltaClipped(argb1, isTranslucent1, - argb2, isTranslucent2, - x, y, z, dx, dy, dz); - else - line3d.plotLineDeltaUnclipped(argb1, isTranslucent1, - argb2, isTranslucent2, - x, y, z, dx, dy, dz); - } - - public void plotPoints(short colix, int count, int[] coordinates) { - // for dots only - setColix(colix); + void plotPoints(int count, int[] coordinates) { int argb = argbCurrent; for (int i = count * 3; i > 0; ) { int z = coordinates[--i]; int y = coordinates[--i]; int x = coordinates[--i]; - if (x < 0 || x >= width || y < 0 || y >= height || z < slab || z > depth) + if (isClipped(x, y, z)) continue; int offset = y * width + x; if (z < zbuf[offset]) { @@ -1684,31 +1242,12 @@ } } } - /* - public void plotPoints(int count, - short colix, byte[] intensities, int[] coordinates) { - int[] shades = getShades(colix); - for (int i = count * 3, j = count-1; i > 0; --j) { - int z = coordinates[--i]; - int y = coordinates[--i]; - int x = coordinates[--i]; - if (x < 0 || x >= width || y < 0 || y >= height || z < slab || z > depth) - continue; - int offset = y * width + x; - if (z < zbuf[offset]) { - zbuf[offset] = z; - // pbuf[offset] = getColixArgb(colix); - pbuf[offset] = shades[intensities[j]]; - } - } - } - */ - void averageOffsetArgb(int offset, int argb) { - pbuf[offset] =((((pbuf[offset] >> 1) & 0x007F7F7F) + - ((argb >> 1) & 0xFF7F7F7F)) | - (argb & 0xFF010101)); - } + + /* *************************************************************** + * color indexes -- colix + * ***************************************************************/ + /* entries 0 through 3 are reserved and are special TRANSLUCENT and OPAQUE are used to inherit the underlying color, but change the translucency @@ -1778,6 +1317,34 @@ throw new NullPointerException(); } + + /* no refs + * + void averageOffsetArgb(int offset, int argb) { + pbuf[offset] =((((pbuf[offset] >> 1) & 0x007F7F7F) + + ((argb >> 1) & 0xFF7F7F7F)) | + (argb & 0xFF010101)); + } + + */ + + /** + * Return a greyscale rgb value 0-FF using NTSC color luminance algorithm + *<p> + * the alpha component is set to 0xFF. If you want a value in the + * range 0-255 then & the result with 0xFF; + * + * @param rgb the rgb value + * @return a grayscale value in the range 0 - 255 decimal + */ + public static int calcGreyscaleRgbFromRgb(int rgb) { + int grey = ((2989 * ((rgb >> 16) & 0xFF)) + + (5870 * ((rgb >> 8) & 0xFF)) + + (1140 * (rgb & 0xFF)) + 5000) / 10000; + int greyRgb = (grey << 16) | (grey << 8) | grey | 0xFF000000; + return greyRgb; + } + public int getColixArgb(short colix) { if (colix < 0) colix = changableColixMap[colix & UNMASK_CHANGABLE_TRANSLUCENT]; @@ -1929,6 +1496,10 @@ changableColixMap[id] = getColix(argb); } + /* *************************************************************** + * shading and lighting + * ***************************************************************/ + public void flushShadesAndImageCaches() { Colix.flushShades(); Sphere3D.flushImageCache(); @@ -1971,8 +1542,28 @@ private final Vector3f vectorAB = new Vector3f(); private final Vector3f vectorAC = new Vector3f(); private final Vector3f vectorNormal = new Vector3f(); + // these points are in screen coordinates even though 3f - // these points are in screen coordinates + public void calcSurfaceShade(short colix, Point3i screenA, + Point3i scr... [truncated message content] |