diff --git a/core/.classpath b/core/.classpath
index d171cd4c1..f7cad2025 100644
--- a/core/.classpath
+++ b/core/.classpath
@@ -1,6 +1,6 @@
-
-
+ * Implementation notes: + *
+ * cache all the points of the sphere in a static array + * top and bottom are just a bunch of triangles that land + * in the center point + *
+ * sphere is a series of concentric circles who radii vary + * along the shape, based on, er.. cos or something + *
+ * [toxi 031031] new sphere code. removed all multiplies with + * radius, as scale() will take care of that anyway + * + * [toxi 031223] updated sphere code (removed modulos) + * and introduced sphereAt(x,y,z,r) + * to avoid additional translate()'s on the user/sketch side + * + * [davbol 080801] now using separate sphereDetailU/V + *+ */ public void sphere(float r) { - depthError("sphere"); + if ((sphereDetailU < 3) || (sphereDetailV < 2)) { + sphereDetail(30); + } + + pushMatrix(); + scale(r); + + // 1st ring from south pole + beginShape(TRIANGLE_STRIP); + for (int i = 0; i < sphereDetailU; i++) { + normal(0, -1, 0); + vertex(0, -1, 0); + normal(sphereX[i], sphereY[i], sphereZ[i]); + vertex(sphereX[i], sphereY[i], sphereZ[i]); + } + //normal(0, -1, 0); + vertex(0, -1, 0); + normal(sphereX[0], sphereY[0], sphereZ[0]); + vertex(sphereX[0], sphereY[0], sphereZ[0]); + endShape(); + + int v1,v11,v2; + + // middle rings + int voff = 0; + for (int i = 2; i < sphereDetailV; i++) { + v1 = v11 = voff; + voff += sphereDetailU; + v2 = voff; + beginShape(TRIANGLE_STRIP); + for (int j = 0; j < sphereDetailU; j++) { + normal(sphereX[v1], sphereY[v1], sphereZ[v1]); + vertex(sphereX[v1], sphereY[v1], sphereZ[v1++]); + normal(sphereX[v2], sphereY[v2], sphereZ[v2]); + vertex(sphereX[v2], sphereY[v2], sphereZ[v2++]); + } + // close each ring + v1 = v11; + v2 = voff; + normal(sphereX[v1], sphereY[v1], sphereZ[v1]); + vertex(sphereX[v1], sphereY[v1], sphereZ[v1]); + normal(sphereX[v2], sphereY[v2], sphereZ[v2]); + vertex(sphereX[v2], sphereY[v2], sphereZ[v2]); + endShape(); + } + + // add the northern cap + beginShape(TRIANGLE_STRIP); + for (int i = 0; i < sphereDetailU; i++) { + v2 = voff + i; + normal(sphereX[v2], sphereY[v2], sphereZ[v2]); + vertex(sphereX[v2], sphereY[v2], sphereZ[v2]); + normal(0, 1, 0); + vertex(0, 1, 0); + } + normal(sphereX[voff], sphereY[voff], sphereZ[voff]); + vertex(sphereX[voff], sphereY[voff], sphereZ[voff]); + normal(0, 1, 0); + vertex(0, 1, 0); + endShape(); + + popMatrix(); } @@ -1836,11 +1946,17 @@ public class PGraphics extends PImage implements PConstants { protected void bezierInitCheck() { if (!bezierInited) { - bezierDetail(bezierDetail); + bezierInit(); } } + + protected void bezierInit() { + // overkill to be broken out, but better parity with the curve stuff below + bezierDetail(bezierDetail); + } + public void bezierDetail(int detail) { bezierDetail = detail; @@ -1954,18 +2070,20 @@ public class PGraphics extends PImage implements PConstants { public void curveDetail(int detail) { - curveInit(detail, curveTightness); + curveDetail = detail; + curveInit(); } public void curveTightness(float tightness) { - curveInit(curveDetail, tightness); + curveTightness = tightness; + curveInit(); } protected void curveInitCheck() { if (!curveInited) { - curveInit(curveDetail, curveTightness); + curveInit(); } } @@ -1981,10 +2099,7 @@ public class PGraphics extends PImage implements PConstants { * opimizations in here, but it's probably better to keep the * code more readable) */ - protected void curveInit(int segments, float s) { - curveDetail = segments; - curveTightness = s; - + protected void curveInit() { // allocate only if/when used to save startup time if (curveDrawMatrix == null) { curveBasisMatrix = new PMatrix3D(); @@ -1992,13 +2107,14 @@ public class PGraphics extends PImage implements PConstants { curveInited = true; } + float s = curveTightness; curveBasisMatrix.set((s-1)/2f, (s+3)/2f, (-3-s)/2f, (1-s)/2f, (1-s), (-5-s)/2f, (s+2), (s-1)/2f, (s-1)/2f, 0, (1-s)/2f, 0, 0, 1, 0, 0); //setup_spline_forward(segments, curveForwardMatrix); - splineForward(segments, curveDrawMatrix); + splineForward(curveDetail, curveDrawMatrix); if (bezierBasisInverse == null) { bezierBasisInverse = bezierBasisMatrix.get(); @@ -2073,20 +2189,21 @@ public class PGraphics extends PImage implements PConstants { * vertex of the segment, rather than running the mathematically * expensive cubic equation. * @param segments number of curve segments to use when drawing - * @param fwd target object for the new matrix + * @param matrix target object for the new matrix */ - protected void splineForward(int segments, PMatrix3D fwd) { + protected void splineForward(int segments, PMatrix3D matrix) { float f = 1.0f / segments; float ff = f * f; float fff = ff * f; - fwd.set(0, 0, 0, 1, - fff, ff, f, 0, - 6*fff, 2*ff, 0, 0, - 6*fff, 0, 0, 0); + matrix.set(0, 0, 0, 1, + fff, ff, f, 0, + 6*fff, 2*ff, 0, 0, + 6*fff, 0, 0, 0); } + ////////////////////////////////////////////////////////////// // IMAGE @@ -2103,8 +2220,7 @@ public class PGraphics extends PImage implements PConstants { } - public void image(PImage image, - float x, float y, float c, float d) { + public void image(PImage image, float x, float y, float c, float d) { image(image, x, y, c, d, 0, 0, image.width, image.height); } @@ -2216,7 +2332,7 @@ public class PGraphics extends PImage implements PConstants { ////////////////////////////////////////////////////////////// - // SHAPE OBJECTS + // SHAPE /** @@ -3189,6 +3305,40 @@ public class PGraphics extends PImage implements PConstants { } +// public PMatrix getMatrix() { +// return null; +// } + + +// public PMatrix2D getMatrix2D() { +// return null; +// } + + + public void getMatrix(PMatrix2D target) { + } + + + public void getMatrix(PMatrix3D target) { + } + + + public void setMatrix(PMatrix2D source) { + } + + + public void setMatrix(PMatrix3D source) { + } + + + public void applyMatrix(PMatrix2D source) { + } + + + public void applyMatrix(PMatrix3D source) { + } + + /** * Apply a 3x2 affine transformation matrix. */ @@ -3397,8 +3547,8 @@ public class PGraphics extends PImage implements PConstants { ////////////////////////////////////////////////////////////// // STYLE - - + + public void pushStyle() { if (styleStackDepth == styleStack.length) { styleStack = (PStyle[]) PApplet.expand(styleStack); @@ -3420,6 +3570,81 @@ public class PGraphics extends PImage implements PConstants { } + public void style(PStyle s) { + // if (s.smooth) { + // smooth(); + // } else { + // noSmooth(); + // } + + imageMode(s.imageMode); + rectMode(s.rectMode); + ellipseMode(s.ellipseMode); + shapeMode(s.shapeMode); + + if (s.tint) { + tint(s.tintColor); + } else { + noTint(); + } + if (s.fill) { + fill(s.fillColor); + } else { + noFill(); + } + if (s.stroke) { + stroke(s.strokeColor); + } else { + noStroke(); + } + strokeWeight(s.strokeWeight); + strokeCap(s.strokeCap); + strokeJoin(s.strokeJoin); + + // Set the colorMode() for the material properties. + // TODO this is really inefficient, need to just have a material() method, + // but this has the least impact to the API. + colorMode(RGB, 1); + ambient(s.ambientR, s.ambientG, s.ambientB); + emissive(s.emissiveR, s.emissiveG, s.emissiveB); + specular(s.specularR, s.specularG, s.specularB); + shininess(s.shininess); + + /* + s.ambientR = ambientR; + s.ambientG = ambientG; + s.ambientB = ambientB; + s.specularR = specularR; + s.specularG = specularG; + s.specularB = specularB; + s.emissiveR = emissiveR; + s.emissiveG = emissiveG; + s.emissiveB = emissiveB; + s.shininess = shininess; + */ + // material(s.ambientR, s.ambientG, s.ambientB, + // s.emissiveR, s.emissiveG, s.emissiveB, + // s.specularR, s.specularG, s.specularB, + // s.shininess); + + // Set this after the material properties. + colorMode(s.colorMode, + s.colorModeX, s.colorModeY, s.colorModeZ, s.colorModeA); + + // This is a bit asymmetric, since there's no way to do "noFont()", + // and a null textFont will produce an error (since usually that means that + // the font couldn't load properly). So in some cases, the font won't be + // 'cleared' to null, even though that's technically correct. + if (s.textFont != null) { + textFont(s.textFont, s.textSize); + textLeading(s.textLeading); + } + // These don't require a font to be set. + textAlign(s.textAlign, s.textAlignY); + textMode(s.textMode); + } + + public PStyle getStyle() { // ignore PStyle s = new PStyle(); getStyle(s); @@ -4533,7 +4758,15 @@ public class PGraphics extends PImage implements PConstants { * showFrame, displayable, isVisible, visible, shouldDisplay, * what to call this? */ - public boolean displayable() { + public boolean displayable() { // ignore return true; } + + + /** + * Return true if this renderer supports 3D drawing. + */ + public boolean dimensional() { // ignore + return false; + } } diff --git a/core/src/processing/core/PGraphics2D.java b/core/src/processing/core/PGraphics2D.java index f15f60a45..ae626c84f 100644 --- a/core/src/processing/core/PGraphics2D.java +++ b/core/src/processing/core/PGraphics2D.java @@ -402,33 +402,6 @@ public class PGraphics2D extends PGraphics { - ////////////////////////////////////////////////////////////// - - // BOX & SPHERE - - - public void box(float size) { - depthError("box"); - } - - public void box(float w, float h, float d) { - depthError("box"); - } - - public void sphereDetail(int res) { - depthError("sphereDetail"); - } - - public void sphereDetail(int ures, int vres) { - depthError("sphereDetail"); - } - - public void sphere(float r) { - depthError("sphere"); - } - - - ////////////////////////////////////////////////////////////// // CONCAVE/CONVEX POLYGONS @@ -991,12 +964,37 @@ public class PGraphics2D extends PGraphics { ////////////////////////////////////////////////////////////// - // BOX & SPHERE + // BOX - // The PGraphics superclass will throw errors for these fellas + public void box(float size) { + depthError("box"); + } + + public void box(float w, float h, float d) { + depthError("box"); + } + + + + ////////////////////////////////////////////////////////////// + + // SPHERE + public void sphereDetail(int res) { + depthError("sphereDetail"); + } + + public void sphereDetail(int ures, int vres) { + depthError("sphereDetail"); + } + + public void sphere(float r) { + depthError("sphere"); + } + + ////////////////////////////////////////////////////////////// diff --git a/core/src/processing/core/PGraphics3D.java b/core/src/processing/core/PGraphics3D.java index 042a06c1e..876512731 100644 --- a/core/src/processing/core/PGraphics3D.java +++ b/core/src/processing/core/PGraphics3D.java @@ -908,7 +908,7 @@ public class PGraphics3D extends PGraphics { ////////////////////////////////////////////////////////////// - // CURVE/BEZIER VERTEX HANDLING + // CURVE/BEZIER VERTEX //protected void bezierVertexCheck(); @@ -2288,68 +2288,15 @@ public class PGraphics3D extends PGraphics { // BOX - public void box(float size) { - box(size, size, size); - } + //public void box(float size) - // OPT this isn't the least bit efficient - // because it redraws lines along the vertices - // ugly ugly ugly! public void box(float w, float h, float d) { - float x1 = -w/2f; float x2 = w/2f; - float y1 = -h/2f; float y2 = h/2f; - float z1 = -d/2f; float z2 = d/2f; - if (triangle != null) { // triangle is null in gl triangle.setCulling(true); } - beginShape(QUADS); - - // front - normal(0, 0, 1); - vertex(x1, y1, z1); - vertex(x2, y1, z1); - vertex(x2, y2, z1); - vertex(x1, y2, z1); - - // right - normal(1, 0, 0); - vertex(x2, y1, z1); - vertex(x2, y1, z2); - vertex(x2, y2, z2); - vertex(x2, y2, z1); - - // back - normal(0, 0, -1); - vertex(x2, y1, z2); - vertex(x1, y1, z2); - vertex(x1, y2, z2); - vertex(x2, y2, z2); - - // left - normal(-1, 0, 0); - vertex(x1, y1, z2); - vertex(x1, y1, z1); - vertex(x1, y2, z1); - vertex(x1, y2, z2); - - // top - normal(0, 1, 0); - vertex(x1, y1, z2); - vertex(x2, y1, z2); - vertex(x2, y1, z1); - vertex(x1, y1, z1); - - // bottom - normal(0, -1, 0); - vertex(x1, y2, z1); - vertex(x2, y2, z1); - vertex(x2, y2, z2); - vertex(x1, y2, z2); - - endShape(); + super.box(w, h, d); if (triangle != null) { // triangle is null in gl triangle.setCulling(false); @@ -2363,152 +2310,18 @@ public class PGraphics3D extends PGraphics { // SPHERE - public void sphereDetail(int res) { - sphereDetail(res, res); - } + //public void sphereDetail(int res) - /** - * Set the detail level for approximating a sphere. The ures and vres params - * control the horizontal and vertical resolution. - * - * Code for sphereDetail() submitted by toxi [031031]. - * Code for enhanced u/v version from davbol [080801]. - */ - public void sphereDetail(int ures, int vres) { - if (ures < 3) ures = 3; // force a minimum res - if (vres < 2) vres = 2; // force a minimum res - if ((ures == sphereDetailU) && (vres == sphereDetailV)) return; - - float delta = (float)SINCOS_LENGTH/ures; - float[] cx = new float[ures]; - float[] cz = new float[ures]; - // calc unit circle in XZ plane - for (int i = 0; i < ures; i++) { - cx[i] = cosLUT[(int) (i*delta) % SINCOS_LENGTH]; - cz[i] = sinLUT[(int) (i*delta) % SINCOS_LENGTH]; - } - // computing vertexlist - // vertexlist starts at south pole - int vertCount = ures * (vres-1) + 2; - int currVert = 0; - - // re-init arrays to store vertices - sphereX = new float[vertCount]; - sphereY = new float[vertCount]; - sphereZ = new float[vertCount]; - - float angle_step = (SINCOS_LENGTH*0.5f)/vres; - float angle = angle_step; - - // step along Y axis - for (int i = 1; i < vres; i++) { - float curradius = sinLUT[(int) angle % SINCOS_LENGTH]; - float currY = -cosLUT[(int) angle % SINCOS_LENGTH]; - for (int j = 0; j < ures; j++) { - sphereX[currVert] = cx[j] * curradius; - sphereY[currVert] = currY; - sphereZ[currVert++] = cz[j] * curradius; - } - angle += angle_step; - } - sphereDetailU = ures; - sphereDetailV = vres; - } + //public void sphereDetail(int ures, int vres) - /** - * Draw a sphere with radius r centered at coordinate 0, 0, 0. - *
- * Implementation notes: - *
- * cache all the points of the sphere in a static array - * top and bottom are just a bunch of triangles that land - * in the center point - *
- * sphere is a series of concentric circles who radii vary - * along the shape, based on, er.. cos or something - *
- * [toxi 031031] new sphere code. removed all multiplies with - * radius, as scale() will take care of that anyway - * - * [toxi 031223] updated sphere code (removed modulos) - * and introduced sphereAt(x,y,z,r) - * to avoid additional translate()'s on the user/sketch side - * - * [davbol 080801] now using separate sphereDetailU/V - *- */ public void sphere(float r) { - float x = 0; // TODO clean this back up again - float y = 0; - float z = 0; - - if ((sphereDetailU < 3) || (sphereDetailV < 2)) { - sphereDetail(30); - } - - int v1,v11,v2; - pushMatrix(); - if (x != 0f && y != 0f && z != 0f) translate(x,y,z); - scale(r); - if (triangle != null) { // triangle is null in gl triangle.setCulling(true); } - - // 1st ring from south pole - beginShape(TRIANGLE_STRIP); - for (int i = 0; i < sphereDetailU; i++) { - normal(0, -1, 0); - vertex(0, -1, 0); - normal(sphereX[i], sphereY[i], sphereZ[i]); - vertex(sphereX[i], sphereY[i], sphereZ[i]); - } - //normal(0, -1, 0); - vertex(0, -1, 0); - normal(sphereX[0], sphereY[0], sphereZ[0]); - vertex(sphereX[0], sphereY[0], sphereZ[0]); - endShape(); - - // middle rings - int voff = 0; - for(int i = 2; i < sphereDetailV; i++) { - v1 = v11 = voff; - voff += sphereDetailU; - v2 = voff; - beginShape(TRIANGLE_STRIP); - for (int j = 0; j < sphereDetailU; j++) { - normal(sphereX[v1], sphereY[v1], sphereZ[v1]); - vertex(sphereX[v1], sphereY[v1], sphereZ[v1++]); - normal(sphereX[v2], sphereY[v2], sphereZ[v2]); - vertex(sphereX[v2], sphereY[v2], sphereZ[v2++]); - } - // close each ring - v1 = v11; - v2 = voff; - normal(sphereX[v1], sphereY[v1], sphereZ[v1]); - vertex(sphereX[v1], sphereY[v1], sphereZ[v1]); - normal(sphereX[v2], sphereY[v2], sphereZ[v2]); - vertex(sphereX[v2], sphereY[v2], sphereZ[v2]); - endShape(); - } - - // add the northern cap - beginShape(TRIANGLE_STRIP); - for (int i = 0; i < sphereDetailU; i++) { - v2 = voff + i; - normal(sphereX[v2], sphereY[v2], sphereZ[v2]); - vertex(sphereX[v2], sphereY[v2], sphereZ[v2]); - normal(0, 1, 0); - vertex(0, 1, 0); - } - normal(sphereX[voff], sphereY[voff], sphereZ[voff]); - vertex(sphereX[voff], sphereY[voff], sphereZ[voff]); - normal(0, 1, 0); - vertex(0, 1, 0); - endShape(); - popMatrix(); + + super.sphere(r); if (triangle != null) { // triangle is null in gl triangle.setCulling(false); diff --git a/core/src/processing/core/PMatrix2D.java b/core/src/processing/core/PMatrix2D.java index 2bdce0ab3..b6bbcee87 100644 --- a/core/src/processing/core/PMatrix2D.java +++ b/core/src/processing/core/PMatrix2D.java @@ -27,7 +27,7 @@ package processing.core; /** * 3x2 affine matrix implementation. */ -public final class PMatrix2D implements PMatrix { +public final class PMatrix2D /*implements PMatrix*/ { public float m00, m01, m02; public float m10, m11, m12; diff --git a/core/src/processing/core/PMatrix3D.java b/core/src/processing/core/PMatrix3D.java index 4618f5b76..7a4f94721 100644 --- a/core/src/processing/core/PMatrix3D.java +++ b/core/src/processing/core/PMatrix3D.java @@ -27,7 +27,7 @@ package processing.core; /** * 4x4 matrix implementation. */ -public final class PMatrix3D implements PMatrix /*, PConstants*/ { +public final class PMatrix3D /*implements PMatrix*/ /*, PConstants*/ { public float m00, m01, m02, m03; public float m10, m11, m12, m13; @@ -390,8 +390,8 @@ public final class PMatrix3D implements PMatrix /*, PConstants*/ { } return target; } - - + + /** * Multiply a three or four element vector against this matrix. If out is * null or not length 3 or 4, a new float array (length 3) will be returned.