curve and bezier vertex code moved to InGeometry

This commit is contained in:
codeanticode
2012-04-23 01:19:47 +00:00
parent ce8cd2f652
commit 78495202b1
3 changed files with 551 additions and 854 deletions
File diff suppressed because it is too large Load Diff
@@ -47,9 +47,9 @@ import java.util.HashSet;
import java.util.Hashtable;
// TODO:
// 3) Move tessellateSphere to InGeometry and implement rest of primitive tessellation functions.
// 1) Complete the get/set API (getTextureU/V setTextureUV), set/get for fill, stroke, tint, ambient, etc.
// 3) Implement rest of primitive tessellation functions.
// 2) Determine if PATH type is necessary, since it is equivalent to use POLYGON with fill disabled.
// 4) strokeWeight() should update the attributes of lines and points when called after tessellation.
/**
* This class holds a 3D model composed of vertices, normals, colors (per vertex) and
@@ -230,46 +230,30 @@ public class PShape3D extends PShape {
protected VertexCache pointColorsCache;
protected VertexCache pointAttributesCache;
boolean modifiedFillVertices;
boolean modifiedFillColors;
boolean modifiedFillNormals;
boolean modifiedFillTexCoords;
boolean modifiedFillAmbient;
boolean modifiedFillSpecular;
boolean modifiedFillEmissive;
boolean modifiedFillShininess;
protected boolean modifiedFillVertices;
protected boolean modifiedFillColors;
protected boolean modifiedFillNormals;
protected boolean modifiedFillTexCoords;
protected boolean modifiedFillAmbient;
protected boolean modifiedFillSpecular;
protected boolean modifiedFillEmissive;
protected boolean modifiedFillShininess;
boolean modifiedLineVertices;
boolean modifiedLineColors;
boolean modifiedLineAttributes;
protected boolean modifiedLineVertices;
protected boolean modifiedLineColors;
protected boolean modifiedLineAttributes;
boolean modifiedPointVertices;
boolean modifiedPointColors;
boolean modifiedPointAttributes;
protected boolean modifiedPointVertices;
protected boolean modifiedPointColors;
protected boolean modifiedPointAttributes;
// ........................................................
// Bezier and Catmull-Rom curves
protected boolean bezierInited = false;
public int bezierDetail = 20;
protected PMatrix3D bezierDrawMatrix;
protected boolean curveInited = false;
// Bezier and Catmull-Rom curves
protected int bezierDetail = 20;
protected int curveDetail = 20;
public float curveTightness = 0;
// catmull-rom basis matrix, perhaps with optional s parameter
protected PMatrix3D curveBasisMatrix;
protected PMatrix3D curveDrawMatrix;
protected PMatrix3D bezierBasisInverse;
protected PMatrix3D curveToBezierMatrix;
protected float curveVertices[][];
protected int curveVertexCount;
protected float curveTightness = 0;
public PShape3D(PApplet parent, int family) {
@@ -319,8 +303,8 @@ public class PShape3D extends PShape {
rectMode = pg.rectMode;
ellipseMode = pg.ellipseMode;
shapeMode = pg.shapeMode;
imageMode = pg.imageMode;
imageMode = pg.imageMode;
colorMode(pg.colorMode, pg.colorModeX, pg.colorModeY, pg.colorModeZ, pg.colorModeA);
// Initial values for fill, stroke and tint colors are also imported from the renderer.
@@ -1733,97 +1717,52 @@ public class PShape3D extends PShape {
// Bezier curves
public void bezierDetail(int detail) {
bezierDetail = detail;
if (bezierDrawMatrix == null) {
bezierDrawMatrix = new PMatrix3D();
}
// setup matrix for forward differencing to speed up drawing
pg.splineForward(detail, bezierDrawMatrix);
// multiply the basis and forward diff matrices together
// saves much time since this needn't be done for each curve
bezierDrawMatrix.apply(pg.bezierBasisMatrix);
pg.bezierDetail(detail);
}
public void bezierVertex(float x2, float y2,
float x3, float y3,
float x4, float y4) {
bezierVertex(x2, y2, 0, x3, y3, 0, x4, y4, 0);
}
public void bezierVertex(float x2, float y2, float z2,
float x3, float y3, float z3,
float x4, float y4, float z4) {
bezierInitCheck();
bezierVertexCheck();
PMatrix3D draw = bezierDrawMatrix;
float x1 = in.getLastVertexX();
float y1 = in.getLastVertexY();
float z1 = in.getLastVertexZ();
float xplot1 = draw.m10*x1 + draw.m11*x2 + draw.m12*x3 + draw.m13*x4;
float xplot2 = draw.m20*x1 + draw.m21*x2 + draw.m22*x3 + draw.m23*x4;
float xplot3 = draw.m30*x1 + draw.m31*x2 + draw.m32*x3 + draw.m33*x4;
float yplot1 = draw.m10*y1 + draw.m11*y2 + draw.m12*y3 + draw.m13*y4;
float yplot2 = draw.m20*y1 + draw.m21*y2 + draw.m22*y3 + draw.m23*y4;
float yplot3 = draw.m30*y1 + draw.m31*y2 + draw.m32*y3 + draw.m33*y4;
float zplot1 = draw.m10*z1 + draw.m11*z2 + draw.m12*z3 + draw.m13*z4;
float zplot2 = draw.m20*z1 + draw.m21*z2 + draw.m22*z3 + draw.m23*z4;
float zplot3 = draw.m30*z1 + draw.m31*z2 + draw.m32*z3 + draw.m33*z4;
for (int j = 0; j < bezierDetail; j++) {
x1 += xplot1; xplot1 += xplot2; xplot2 += xplot3;
y1 += yplot1; yplot1 += yplot2; yplot2 += yplot3;
z1 += zplot1; zplot1 += zplot2; zplot2 += zplot3;
vertexImpl(x1, y1, z1, 0, 0, BEZIER_VERTEX);
}
in.addBezierVertex(x2, y2, z2,
x3, y3, z3,
x4, y4, z4,
normalX, normalY, normalZ,
bezierDetail, fill, fillColor,
stroke, strokeColor, strokeWeight,
ambientColor, specularColor, emissiveColor,
shininess,
kind);
}
public void quadraticVertex(float cx, float cy,
float x3, float y3) {
quadraticVertex(cx, cy, 0,
x3, y3, 0);
}
public void quadraticVertex(float cx, float cy, float cz,
float x3, float y3, float z3) {
float x1 = in.getLastVertexX();
float y1 = in.getLastVertexY();
float z1 = in.getLastVertexZ();
bezierVertex(x1 + ((cx-x1)*2/3.0f), y1 + ((cy-y1)*2/3.0f), z1 + ((cz-z1)*2/3.0f),
x3 + ((cx-x3)*2/3.0f), y3 + ((cy-y3)*2/3.0f), z3 + ((cz-z3)*2/3.0f),
x3, y3, z3);
}
protected void bezierInitCheck() {
if (!bezierInited) {
bezierInit();
}
}
protected void bezierInit() {
// overkill to be broken out, but better parity with the curve stuff below
bezierDetail(bezierDetail);
bezierInited = true;
}
protected void bezierVertexCheck() {
if (kind != POLYGON) {
throw new RuntimeException("createGeometry() or createGeometry(POLYGON) " +
"must be used before bezierVertex() or quadraticVertex()");
}
if (in.vertexCount == 0) {
throw new RuntimeException("vertex() must be used at least once" +
"before bezierVertex() or quadraticVertex()");
}
}
///////////////////////////////////////////////////////////
@@ -1831,137 +1770,33 @@ public class PShape3D extends PShape {
// Catmull-Rom curves
public void curveDetail(int detail) {
curveDetail = detail;
curveInit();
pg.curveDetail(detail);
}
public void curveTightness(float tightness) {
curveTightness = tightness;
curveInit();
pg.curveTightness(tightness);
}
public void curveVertex(float x, float y) {
curveVertex(x, y, 0);
}
public void curveVertex(float x, float y, float z) {
curveVertexCheck();
float[] vertex = curveVertices[curveVertexCount];
vertex[X] = x;
vertex[Y] = y;
vertex[Z] = z;
curveVertexCount++;
// draw a segment if there are enough points
if (curveVertexCount > 3) {
curveVertexSegment(curveVertices[curveVertexCount-4][X],
curveVertices[curveVertexCount-4][Y],
curveVertices[curveVertexCount-4][Z],
curveVertices[curveVertexCount-3][X],
curveVertices[curveVertexCount-3][Y],
curveVertices[curveVertexCount-3][Z],
curveVertices[curveVertexCount-2][X],
curveVertices[curveVertexCount-2][Y],
curveVertices[curveVertexCount-2][Z],
curveVertices[curveVertexCount-1][X],
curveVertices[curveVertexCount-1][Y],
curveVertices[curveVertexCount-1][Z]);
}
in.addCurveVertex(x, y, z,
normalX, normalY, normalZ,
curveDetail, fill, fillColor,
stroke, strokeColor, strokeWeight,
ambientColor, specularColor, emissiveColor,
shininess,
kind);
}
protected void curveVertexCheck() {
if (kind != POLYGON) {
throw new RuntimeException("You must use createGeometry() or " +
"createGeometry(POLYGON) before curveVertex()");
}
// to improve code init time, allocate on first use.
if (curveVertices == null) {
curveVertices = new float[128][3];
}
if (curveVertexCount == curveVertices.length) {
// Can't use PApplet.expand() cuz it doesn't do the copy properly
float[][] temp = new float[curveVertexCount << 1][3];
System.arraycopy(curveVertices, 0, temp, 0, curveVertexCount);
curveVertices = temp;
}
curveInitCheck();
}
protected void curveInitCheck() {
if (!curveInited) {
curveInit();
}
}
protected void curveInit() {
// allocate only if/when used to save startup time
if (curveDrawMatrix == null) {
curveBasisMatrix = new PMatrix3D();
curveDrawMatrix = new PMatrix3D();
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);
pg.splineForward(curveDetail, curveDrawMatrix);
if (bezierBasisInverse == null) {
bezierBasisInverse = pg.bezierBasisMatrix.get();
bezierBasisInverse.invert();
curveToBezierMatrix = new PMatrix3D();
}
curveToBezierMatrix.set(curveBasisMatrix);
curveToBezierMatrix.preApply(bezierBasisInverse);
// multiply the basis and forward diff matrices together
// saves much time since this needn't be done for each curve
curveDrawMatrix.apply(curveBasisMatrix);
}
/**
* Handle emitting a specific segment of Catmull-Rom curve. This can be
* overridden by subclasses that need more efficient rendering options.
*/
protected void curveVertexSegment(float x1, float y1, float z1,
float x2, float y2, float z2,
float x3, float y3, float z3,
float x4, float y4, float z4) {
float x0 = x2;
float y0 = y2;
float z0 = z2;
PMatrix3D draw = curveDrawMatrix;
float xplot1 = draw.m10*x1 + draw.m11*x2 + draw.m12*x3 + draw.m13*x4;
float xplot2 = draw.m20*x1 + draw.m21*x2 + draw.m22*x3 + draw.m23*x4;
float xplot3 = draw.m30*x1 + draw.m31*x2 + draw.m32*x3 + draw.m33*x4;
float yplot1 = draw.m10*y1 + draw.m11*y2 + draw.m12*y3 + draw.m13*y4;
float yplot2 = draw.m20*y1 + draw.m21*y2 + draw.m22*y3 + draw.m23*y4;
float yplot3 = draw.m30*y1 + draw.m31*y2 + draw.m32*y3 + draw.m33*y4;
float zplot1 = draw.m10*z1 + draw.m11*z2 + draw.m12*z3 + draw.m13*z4;
float zplot2 = draw.m20*z1 + draw.m21*z2 + draw.m22*z3 + draw.m23*z4;
float zplot3 = draw.m30*z1 + draw.m31*z2 + draw.m32*z3 + draw.m33*z4;
vertexImpl(x0, y0, z0, 0, 0, CURVE_VERTEX);
for (int j = 0; j < curveDetail; j++) {
x0 += xplot1; xplot1 += xplot2; xplot2 += xplot3;
y0 += yplot1; yplot1 += yplot2; yplot2 += yplot3;
z0 += zplot1; zplot1 += zplot2; zplot2 += zplot3;
vertexImpl(x0, y0, z0, 0, 0, CURVE_VERTEX);
}
}
///////////////////////////////////////////////////////////