mirror of
https://github.com/processing/processing4.git
synced 2026-06-16 04:26:26 +02:00
cleaning up curve/bezier drawing, vertex() functions, and separation of
PGraphics, P2D, and P3D.
This commit is contained in:
+30
-16
@@ -27,25 +27,26 @@ style(PStyle s)
|
||||
|
||||
//
|
||||
|
||||
setParent()
|
||||
setPrimary()
|
||||
setPath()
|
||||
setSize(int w, int h)
|
||||
allocate()
|
||||
public void setParent(PApplet parent)
|
||||
public void setPrimary(boolean primary)
|
||||
public void setPath(String path)
|
||||
public void setSize(int iwidth, int iheight)
|
||||
protected void allocate()
|
||||
|
||||
canDraw()
|
||||
beginDraw()
|
||||
endDraw()
|
||||
flush()
|
||||
public boolean canDraw()
|
||||
public void beginDraw()
|
||||
public void endDraw()
|
||||
public void flush()
|
||||
|
||||
checkSettings()
|
||||
defaultSettings()
|
||||
reapplySettings()
|
||||
protected void checkSettings()
|
||||
protected void defaultSettings()
|
||||
protected void reapplySettings()
|
||||
|
||||
hint()
|
||||
public void hint(int which)
|
||||
|
||||
public void beginShape()
|
||||
public void beginShape(int kind)
|
||||
public void edge(boolean e)
|
||||
public void normal(float nx, float ny, float nz)
|
||||
public void textureMode(int mode)
|
||||
public void texture(PImage image)
|
||||
@@ -53,17 +54,30 @@ style(PStyle s)
|
||||
public void vertex(float x, float y, float z)
|
||||
public void vertex(float x, float y, float u, float v)
|
||||
public void vertex(float x, float y, float z, float u, float v)
|
||||
protected void vertexTexture(float u, float v);
|
||||
public void breakShape()
|
||||
public void endShape()
|
||||
public void endShape(int mode)
|
||||
|
||||
protected void bezierVertexCheck();
|
||||
public void bezierVertex(float x2, float y2,
|
||||
float x3, float y3,
|
||||
float x4, float y4)
|
||||
public void bezierVertex(float x2, float y2, float z2,
|
||||
float x3, float y3, float z3,
|
||||
float x4, float y4, float z4)
|
||||
|
||||
protected void curveVertexCheck();
|
||||
public void curveVertex(float x, float y)
|
||||
public void curveVertex(float x, float y, float z)
|
||||
public void breakShape()
|
||||
public void endShape()
|
||||
public void endShape(int mode)
|
||||
protected void curveVertexSegment(float x1, float y1,
|
||||
float x2, float y2,
|
||||
float x3, float y3,
|
||||
float x4, float y4)
|
||||
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)
|
||||
|
||||
public void point(float x, float y)
|
||||
public void point(float x, float y, float z)
|
||||
|
||||
@@ -6661,6 +6661,12 @@ public class PApplet extends Applet
|
||||
// public functions for processing.core
|
||||
|
||||
|
||||
public void flush() {
|
||||
if (recorder != null) recorder.flush();
|
||||
g.flush();
|
||||
}
|
||||
|
||||
|
||||
public void hint(int which) {
|
||||
if (recorder != null) recorder.hint(which);
|
||||
g.hint(which);
|
||||
@@ -6679,6 +6685,12 @@ public class PApplet extends Applet
|
||||
}
|
||||
|
||||
|
||||
public void edge(boolean e) {
|
||||
if (recorder != null) recorder.edge(e);
|
||||
g.edge(e);
|
||||
}
|
||||
|
||||
|
||||
public void normal(float nx, float ny, float nz) {
|
||||
if (recorder != null) recorder.normal(nx, ny, nz);
|
||||
g.normal(nx, ny, nz);
|
||||
@@ -6721,6 +6733,24 @@ public class PApplet extends Applet
|
||||
}
|
||||
|
||||
|
||||
public void breakShape() {
|
||||
if (recorder != null) recorder.breakShape();
|
||||
g.breakShape();
|
||||
}
|
||||
|
||||
|
||||
public void endShape() {
|
||||
if (recorder != null) recorder.endShape();
|
||||
g.endShape();
|
||||
}
|
||||
|
||||
|
||||
public void endShape(int mode) {
|
||||
if (recorder != null) recorder.endShape(mode);
|
||||
g.endShape(mode);
|
||||
}
|
||||
|
||||
|
||||
public void bezierVertex(float x2, float y2,
|
||||
float x3, float y3,
|
||||
float x4, float y4) {
|
||||
@@ -6749,24 +6779,6 @@ public class PApplet extends Applet
|
||||
}
|
||||
|
||||
|
||||
public void breakShape() {
|
||||
if (recorder != null) recorder.breakShape();
|
||||
g.breakShape();
|
||||
}
|
||||
|
||||
|
||||
public void endShape() {
|
||||
if (recorder != null) recorder.endShape();
|
||||
g.endShape();
|
||||
}
|
||||
|
||||
|
||||
public void endShape(int mode) {
|
||||
if (recorder != null) recorder.endShape(mode);
|
||||
g.endShape(mode);
|
||||
}
|
||||
|
||||
|
||||
public void style(PStyle s) {
|
||||
if (recorder != null) recorder.style(s);
|
||||
g.style(s);
|
||||
|
||||
@@ -374,7 +374,6 @@ public class PGraphics extends PImage implements PConstants {
|
||||
|
||||
static final int MATRIX_STACK_DEPTH = 32;
|
||||
|
||||
|
||||
// ........................................................
|
||||
|
||||
/**
|
||||
@@ -442,9 +441,8 @@ public class PGraphics extends PImage implements PConstants {
|
||||
|
||||
// spline vertices
|
||||
|
||||
static final int DEFAULT_SPLINE_VERTICES = 128;
|
||||
protected float splineVertices[][];
|
||||
protected int splineVertexCount;
|
||||
protected float curveVertices[][];
|
||||
protected int curveVertexCount;
|
||||
|
||||
// ........................................................
|
||||
|
||||
@@ -492,92 +490,32 @@ public class PGraphics extends PImage implements PConstants {
|
||||
protected int[] textBreakStop;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// VARIABLES FOR 3D (used to prevent the need for a subclass)
|
||||
|
||||
/** The modelview matrix. */
|
||||
public PMatrix3D modelview;
|
||||
|
||||
/** Inverse modelview matrix, used for lighting. */
|
||||
protected PMatrix3D modelviewInv;
|
||||
|
||||
/**
|
||||
* The camera matrix, the modelview will be set to this on beginDraw.
|
||||
*/
|
||||
public PMatrix3D camera;
|
||||
|
||||
/** Inverse camera matrix */
|
||||
protected PMatrix3D cameraInv;
|
||||
static final String ERROR_PUSHMATRIX_OVERFLOW =
|
||||
"Too many calls to pushMatrix().";
|
||||
static final String ERROR_PUSHMATRIX_UNDERFLOW =
|
||||
"Too many calls to popMatrix(), and not enough to pushMatrix().";
|
||||
|
||||
// ........................................................
|
||||
|
||||
/** Camera field of view. */
|
||||
public float cameraFOV;
|
||||
|
||||
/** Position of the camera. */
|
||||
public float cameraX, cameraY, cameraZ;
|
||||
public float cameraNear, cameraFar;
|
||||
/** Aspect ratio of camera's view. */
|
||||
public float cameraAspect;
|
||||
|
||||
/** Current projection matrix. */
|
||||
public PMatrix3D projection;
|
||||
|
||||
public boolean edge;
|
||||
|
||||
// ........................................................
|
||||
|
||||
/** The depth buffer. */
|
||||
public float[] zbuffer;
|
||||
/// normal calculated per triangle
|
||||
static protected final int NORMAL_MODE_AUTO = 0;
|
||||
/// one normal manually specified per shape
|
||||
static protected final int NORMAL_MODE_SHAPE = 1;
|
||||
/// normals specified for each shape vertex
|
||||
static protected final int NORMAL_MODE_VERTEX = 2;
|
||||
|
||||
// ........................................................
|
||||
/// Current mode for normals, one of AUTO, SHAPE, or VERTEX
|
||||
protected int normalMode;
|
||||
|
||||
/**
|
||||
* Maximum lights by default is 8, which is arbitrary for this renderer,
|
||||
* but is the minimum defined by OpenGL
|
||||
*/
|
||||
public static final int MAX_LIGHTS = 8;
|
||||
/// Keep track of how many calls to normal, to determine the mode.
|
||||
protected int normalCount;
|
||||
|
||||
public int lightCount = 0;
|
||||
|
||||
/** Light types */
|
||||
public int[] lightType;
|
||||
|
||||
/** Light positions */
|
||||
public float[][] lightPosition;
|
||||
|
||||
/** Light direction (normalized vector) */
|
||||
public float[][] lightNormal;
|
||||
|
||||
/** Light falloff */
|
||||
public float[] lightFalloffConstant;
|
||||
public float[] lightFalloffLinear;
|
||||
public float[] lightFalloffQuadratic;
|
||||
|
||||
/** Light spot angle */
|
||||
public float[] lightSpotAngle;
|
||||
|
||||
/** Cosine of light spot angle */
|
||||
public float[] lightSpotAngleCos;
|
||||
|
||||
/** Light spot concentration */
|
||||
public float[] lightSpotConcentration;
|
||||
|
||||
/** Diffuse colors for lights.
|
||||
* For an ambient light, this will hold the ambient color.
|
||||
* Internally these are stored as numbers between 0 and 1. */
|
||||
public float[][] lightDiffuse;
|
||||
|
||||
/** Specular colors for lights.
|
||||
Internally these are stored as numbers between 0 and 1. */
|
||||
public float[][] lightSpecular;
|
||||
|
||||
/** Current specular color for lighting */
|
||||
public float[] currentLightSpecular;
|
||||
|
||||
/** Current light falloff */
|
||||
public float currentLightFalloffConstant;
|
||||
public float currentLightFalloffLinear;
|
||||
public float currentLightFalloffQuadratic;
|
||||
/** Current normal vector. */
|
||||
public float normalX, normalY, normalZ;
|
||||
|
||||
// ........................................................
|
||||
|
||||
@@ -600,25 +538,6 @@ public class PGraphics extends PImage implements PConstants {
|
||||
/** Current image being used as a texture */
|
||||
public PImage textureImage;
|
||||
|
||||
// ........................................................
|
||||
|
||||
/// normal calculated per triangle
|
||||
static protected final int NORMAL_MODE_AUTO = 0;
|
||||
/// one normal manually specified per shape
|
||||
static protected final int NORMAL_MODE_SHAPE = 1;
|
||||
/// normals specified for each shape vertex
|
||||
static protected final int NORMAL_MODE_VERTEX = 2;
|
||||
|
||||
/// Current mode for normals, one of AUTO, SHAPE, or VERTEX
|
||||
protected int normalMode;
|
||||
|
||||
/// Keep track of how many calls to normal, to determine the mode.
|
||||
protected int normalCount;
|
||||
|
||||
/** Current normal vector. */
|
||||
public float normalX, normalY, normalZ;
|
||||
|
||||
|
||||
// ........................................................
|
||||
|
||||
// [toxi031031] new & faster sphere code w/ support flexibile resolutions
|
||||
@@ -684,9 +603,9 @@ public class PGraphics extends PImage implements PConstants {
|
||||
* event thread (EDT), causing a nasty crash as it collides with the
|
||||
* animation thread.
|
||||
*/
|
||||
public void setSize(int iwidth, int iheight) { // ignore
|
||||
width = iwidth;
|
||||
height = iheight;
|
||||
public void setSize(int w, int h) { // ignore
|
||||
width = w;
|
||||
height = h;
|
||||
width1 = width - 1;
|
||||
height1 = height - 1;
|
||||
|
||||
@@ -705,22 +624,6 @@ public class PGraphics extends PImage implements PConstants {
|
||||
// FRAME
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this is a 2D renderer.
|
||||
*/
|
||||
public boolean is2D() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this is a 3D renderer (rather than using instanceof).
|
||||
*/
|
||||
public boolean is3D() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Some renderers have requirements re: when they are ready to draw.
|
||||
*/
|
||||
@@ -749,7 +652,7 @@ public class PGraphics extends PImage implements PConstants {
|
||||
}
|
||||
|
||||
|
||||
protected void flush() {
|
||||
public void flush() {
|
||||
// no-op, mostly for P3D to write sorted stuff
|
||||
}
|
||||
|
||||
@@ -944,10 +847,53 @@ public class PGraphics extends PImage implements PConstants {
|
||||
* that's how things are implemented.
|
||||
*/
|
||||
public void beginShape(int kind) {
|
||||
shape = kind;
|
||||
}
|
||||
|
||||
|
||||
public void edge(boolean e) {
|
||||
this.edge = edge;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the current normal vector. Only applies with 3D rendering
|
||||
* and inside a beginShape/endShape block.
|
||||
* <P/>
|
||||
* This is for drawing three dimensional shapes and surfaces,
|
||||
* allowing you to specify a vector perpendicular to the surface
|
||||
* of the shape, which determines how lighting affects it.
|
||||
* <P/>
|
||||
* For the most part, PGraphics3D will attempt to automatically
|
||||
* assign normals to shapes, but since that's imperfect,
|
||||
* this is a better option when you want more control.
|
||||
* <P/>
|
||||
* For people familiar with OpenGL, this function is basically
|
||||
* identical to glNormal3f().
|
||||
*/
|
||||
public void normal(float nx, float ny, float nz) {
|
||||
normalX = nx;
|
||||
normalY = ny;
|
||||
normalZ = nz;
|
||||
|
||||
// if drawing a shape and the normal hasn't been set yet,
|
||||
// then we need to set the normals for each vertex so far
|
||||
if (shape != 0) {
|
||||
if (normalMode == NORMAL_MODE_AUTO) {
|
||||
// either they set the normals, or they don't [0149]
|
||||
// for (int i = vertex_start; i < vertexCount; i++) {
|
||||
// vertices[i][NX] = normalX;
|
||||
// vertices[i][NY] = normalY;
|
||||
// vertices[i][NZ] = normalZ;
|
||||
// }
|
||||
// One normal per begin/end shape
|
||||
normalMode = NORMAL_MODE_SHAPE;
|
||||
|
||||
} else if (normalMode == NORMAL_MODE_SHAPE) {
|
||||
// a separate normal for each vertex
|
||||
normalMode = NORMAL_MODE_VERTEX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -970,150 +916,26 @@ public class PGraphics extends PImage implements PConstants {
|
||||
textureImage = image;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set (U, V) coords for the next vertex in the current shape.
|
||||
* This is ugly as its own function, and will (almost?) always be
|
||||
* coincident with a call to vertex. As of beta, this was moved to
|
||||
* the protected method you see here, and called from an optional
|
||||
* param of and overloaded vertex().
|
||||
* <p/>
|
||||
* The parameters depend on the current textureMode. When using
|
||||
* textureMode(IMAGE), the coordinates will be relative to the size
|
||||
* of the image texture, when used with textureMode(NORMAL),
|
||||
* they'll be in the range 0..1.
|
||||
* <p/>
|
||||
* Used by both PGraphics2D (for images) and PGraphics3D.
|
||||
*/
|
||||
protected void textureVertex(float u, float v) {
|
||||
if (textureImage == null) {
|
||||
throw new RuntimeException("need to set an image with texture() " +
|
||||
"before using u and v coordinates");
|
||||
|
||||
protected void vertexCheck() {
|
||||
if (vertexCount == vertices.length) {
|
||||
float temp[][] = new float[vertexCount << 1][VERTEX_FIELD_COUNT];
|
||||
System.arraycopy(vertices, 0, temp, 0, vertexCount);
|
||||
vertices = temp;
|
||||
}
|
||||
if (textureMode == IMAGE) {
|
||||
u /= (float) textureImage.width;
|
||||
v /= (float) textureImage.height;
|
||||
}
|
||||
|
||||
textureU = u;
|
||||
textureV = v;
|
||||
|
||||
if (textureU < 0) textureU = 0;
|
||||
else if (textureU > 1) textureU = 1;
|
||||
|
||||
if (textureV < 0) textureV = 0;
|
||||
else if (textureV > 1) textureV = 1;
|
||||
}
|
||||
|
||||
|
||||
// eventually need to push a "default" setup down to this class
|
||||
public void vertex(float x, float y) {
|
||||
}
|
||||
float[] vertex = vertices[vertexCount];
|
||||
|
||||
|
||||
public void vertex(float x, float y, float z) {
|
||||
}
|
||||
|
||||
|
||||
public void vertex(float x, float y, float u, float v) {
|
||||
}
|
||||
|
||||
|
||||
public void vertex(float x, float y, float z, float u, float v) {
|
||||
}
|
||||
|
||||
|
||||
public void bezierVertex(float x2, float y2,
|
||||
float x3, float y3,
|
||||
float x4, float y4) {
|
||||
if (shape != POLYGON || vertexCount == 0) {
|
||||
throw new RuntimeException("beginShape() and vertex() " +
|
||||
"must be used before bezierVertex()");
|
||||
}
|
||||
|
||||
PMatrix3D dm = bezierDrawMatrix;
|
||||
|
||||
float[] prev = vertices[vertexCount-1];
|
||||
float x1 = prev[X];
|
||||
float y1 = prev[Y];
|
||||
|
||||
float xplot1 = dm.m10*x1 + dm.m11*x2 + dm.m12*x3 + dm.m13*x4;
|
||||
float xplot2 = dm.m20*x1 + dm.m21*x2 + dm.m22*x3 + dm.m23*x4;
|
||||
float xplot3 = dm.m30*x1 + dm.m31*x2 + dm.m32*x3 + dm.m33*x4;
|
||||
|
||||
float yplot1 = dm.m10*y1 + dm.m11*y2 + dm.m12*y3 + dm.m13*y4;
|
||||
float yplot2 = dm.m20*y1 + dm.m21*y2 + dm.m22*y3 + dm.m23*y4;
|
||||
float yplot3 = dm.m30*y1 + dm.m31*y2 + dm.m32*y3 + dm.m33*y4;
|
||||
|
||||
for (int j = 0; j < bezierDetail; j++) {
|
||||
x1 += xplot1; xplot1 += xplot2; xplot2 += xplot3;
|
||||
y1 += yplot1; yplot1 += yplot2; yplot2 += yplot3;
|
||||
vertex(x1, y1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void bezierVertex(float x2, float y2, float z2,
|
||||
float x3, float y3, float z3,
|
||||
float x4, float y4, float z4) {
|
||||
if (shape != POLYGON || vertexCount == 0) {
|
||||
throw new RuntimeException("beginShape() and vertex() " +
|
||||
"must be used before bezierVertex()");
|
||||
}
|
||||
|
||||
PMatrix3D dm = bezierDrawMatrix;
|
||||
|
||||
float[] prev = vertices[vertexCount-1];
|
||||
float x1 = prev[X];
|
||||
float y1 = prev[Y];
|
||||
float z1 = prev[Z];
|
||||
|
||||
float xplot1 = dm.m10*x1 + dm.m11*x2 + dm.m12*x3 + dm.m13*x4;
|
||||
float xplot2 = dm.m20*x1 + dm.m21*x2 + dm.m22*x3 + dm.m23*x4;
|
||||
float xplot3 = dm.m30*x1 + dm.m31*x2 + dm.m32*x3 + dm.m33*x4;
|
||||
|
||||
float yplot1 = dm.m10*y1 + dm.m11*y2 + dm.m12*y3 + dm.m13*y4;
|
||||
float yplot2 = dm.m20*y1 + dm.m21*y2 + dm.m22*y3 + dm.m23*y4;
|
||||
float yplot3 = dm.m30*y1 + dm.m31*y2 + dm.m32*y3 + dm.m33*y4;
|
||||
|
||||
float zplot1 = dm.m10*z1 + dm.m11*z2 + dm.m12*z3 + dm.m13*z4;
|
||||
float zplot2 = dm.m20*z1 + dm.m21*z2 + dm.m22*z3 + dm.m23*z4;
|
||||
float zplot3 = dm.m30*z1 + dm.m31*z2 + dm.m32*z3 + dm.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;
|
||||
vertex(x1, y1, z1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void curveVertexCheck() {
|
||||
if (shape != POLYGON) {
|
||||
throw new RuntimeException("You must use beginShape() or " +
|
||||
"beginShape(POLYGON) before curveVertex()");
|
||||
}
|
||||
// to improve processing applet load times, don't allocate
|
||||
// space for the vertex data until actual use
|
||||
if (splineVertices == null) {
|
||||
splineVertices = new float[DEFAULT_SPLINE_VERTICES][VERTEX_FIELD_COUNT];
|
||||
}
|
||||
|
||||
if (splineVertexCount == splineVertices.length) {
|
||||
splineVertices = (float[][]) PApplet.expand(splineVertices);
|
||||
}
|
||||
curveInitCheck();
|
||||
}
|
||||
|
||||
|
||||
public void curveVertex(float x, float y) {
|
||||
curveVertexCheck();
|
||||
float[] vertex = splineVertices[splineVertexCount];
|
||||
curveVertexCount = 0;
|
||||
|
||||
vertex[X] = x;
|
||||
vertex[Y] = y;
|
||||
|
||||
vertex[EDGE] = edge ? 1 : 0;
|
||||
|
||||
if (fill) {
|
||||
vertex[R] = fillR;
|
||||
vertex[G] = fillG;
|
||||
@@ -1133,36 +955,76 @@ public class PGraphics extends PImage implements PConstants {
|
||||
vertex[U] = textureU;
|
||||
vertex[V] = textureV;
|
||||
}
|
||||
|
||||
splineVertexCount++;
|
||||
|
||||
// draw a segment if there are enough points
|
||||
if (splineVertexCount > 3) {
|
||||
curveVertexSegment(splineVertices[splineVertexCount-4][X],
|
||||
splineVertices[splineVertexCount-4][Y],
|
||||
splineVertices[splineVertexCount-3][X],
|
||||
splineVertices[splineVertexCount-3][Y],
|
||||
splineVertices[splineVertexCount-2][X],
|
||||
splineVertices[splineVertexCount-2][Y],
|
||||
splineVertices[splineVertexCount-1][X],
|
||||
splineVertices[splineVertexCount-1][Y]);
|
||||
}
|
||||
|
||||
vertexCount++;
|
||||
}
|
||||
|
||||
|
||||
public void curveVertex(float x, float y, float z) {
|
||||
curveVertexCheck();
|
||||
float[] vertex = splineVertices[splineVertexCount];
|
||||
|
||||
|
||||
public void vertex(float x, float y, float z) {
|
||||
float[] vertex = vertices[vertexCount];
|
||||
|
||||
// only do this if we're using an irregular (POLYGON) shape that
|
||||
// will go through the triangulator. otherwise it'll do thinks like
|
||||
// disappear in mathematically odd ways
|
||||
// http://dev.processing.org/bugs/show_bug.cgi?id=444
|
||||
if (shape == POLYGON) {
|
||||
if (vertexCount > 0) {
|
||||
float pvertex[] = vertices[vertexCount-1];
|
||||
if ((Math.abs(pvertex[X] - x) < EPSILON) &&
|
||||
(Math.abs(pvertex[Y] - y) < EPSILON) &&
|
||||
(Math.abs(pvertex[Z] - z) < EPSILON)) {
|
||||
// this vertex is identical, don't add it,
|
||||
// because it will anger the triangulator
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// User called vertex(), so that invalidates anything queued up for curve
|
||||
// vertices. If this is internally called by curveVertexSegment,
|
||||
// then curveVertexCount will be saved and restored.
|
||||
curveVertexCount = 0;
|
||||
|
||||
vertex[X] = x;
|
||||
vertex[Y] = y;
|
||||
vertex[Z] = z;
|
||||
|
||||
vertex[EDGE] = edge ? 1 : 0;
|
||||
|
||||
if (fill) {
|
||||
vertex[R] = fillR;
|
||||
vertex[G] = fillG;
|
||||
vertex[B] = fillB;
|
||||
vertex[A] = fillA;
|
||||
if (textureImage != null) {
|
||||
if (tint) {
|
||||
vertex[R] = tintR;
|
||||
vertex[G] = tintG;
|
||||
vertex[B] = tintB;
|
||||
vertex[A] = tintA;
|
||||
} else {
|
||||
vertex[R] = 1;
|
||||
vertex[G] = 1;
|
||||
vertex[B] = 1;
|
||||
vertex[A] = 1;
|
||||
}
|
||||
} else {
|
||||
vertex[R] = fillR;
|
||||
vertex[G] = fillG;
|
||||
vertex[B] = fillB;
|
||||
vertex[A] = fillA;
|
||||
}
|
||||
|
||||
vertex[AR] = ambientR;
|
||||
vertex[AG] = ambientG;
|
||||
vertex[AB] = ambientB;
|
||||
|
||||
vertex[SPR] = specularR;
|
||||
vertex[SPG] = specularG;
|
||||
vertex[SPB] = specularB;
|
||||
//vertex[SPA] = specularA;
|
||||
|
||||
vertex[SHINE] = shininess;
|
||||
|
||||
vertex[ER] = emissiveR;
|
||||
vertex[EG] = emissiveG;
|
||||
vertex[EB] = emissiveB;
|
||||
}
|
||||
|
||||
if (stroke) {
|
||||
@@ -1182,26 +1044,230 @@ public class PGraphics extends PImage implements PConstants {
|
||||
vertex[NY] = normalY;
|
||||
vertex[NZ] = normalZ;
|
||||
|
||||
splineVertexCount++;
|
||||
vertex[BEEN_LIT] = 0;
|
||||
|
||||
vertexCount++;
|
||||
}
|
||||
|
||||
// draw a segment if there are enough points
|
||||
if (splineVertexCount > 3) {
|
||||
curveVertexSegment(splineVertices[splineVertexCount-4][X],
|
||||
splineVertices[splineVertexCount-4][Y],
|
||||
splineVertices[splineVertexCount-4][Z],
|
||||
splineVertices[splineVertexCount-3][X],
|
||||
splineVertices[splineVertexCount-3][Y],
|
||||
splineVertices[splineVertexCount-3][Z],
|
||||
splineVertices[splineVertexCount-2][X],
|
||||
splineVertices[splineVertexCount-2][Y],
|
||||
splineVertices[splineVertexCount-2][Z],
|
||||
splineVertices[splineVertexCount-1][X],
|
||||
splineVertices[splineVertexCount-1][Y],
|
||||
splineVertices[splineVertexCount-1][Z]);
|
||||
|
||||
public void vertex(float x, float y, float u, float v) {
|
||||
vertexTexture(u, v);
|
||||
vertex(x, y);
|
||||
}
|
||||
|
||||
|
||||
public void vertex(float x, float y, float z, float u, float v) {
|
||||
vertexTexture(u, v);
|
||||
vertex(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Internal method to copy all style information for the given vertex.
|
||||
* Can be overridden by subclasses to handle only properties pertinent to
|
||||
* that renderer. (e.g. no need to copy the emissive color in P2D)
|
||||
*/
|
||||
// protected void vertexStyle() {
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* Set (U, V) coords for the next vertex in the current shape.
|
||||
* This is ugly as its own function, and will (almost?) always be
|
||||
* coincident with a call to vertex. As of beta, this was moved to
|
||||
* the protected method you see here, and called from an optional
|
||||
* param of and overloaded vertex().
|
||||
* <p/>
|
||||
* The parameters depend on the current textureMode. When using
|
||||
* textureMode(IMAGE), the coordinates will be relative to the size
|
||||
* of the image texture, when used with textureMode(NORMAL),
|
||||
* they'll be in the range 0..1.
|
||||
* <p/>
|
||||
* Used by both PGraphics2D (for images) and PGraphics3D.
|
||||
*/
|
||||
protected void vertexTexture(float u, float v) {
|
||||
if (textureImage == null) {
|
||||
throw new RuntimeException("need to set an image with texture() " +
|
||||
"before using u and v coordinates");
|
||||
}
|
||||
if (textureMode == IMAGE) {
|
||||
u /= (float) textureImage.width;
|
||||
v /= (float) textureImage.height;
|
||||
}
|
||||
|
||||
textureU = u;
|
||||
textureV = v;
|
||||
|
||||
if (textureU < 0) textureU = 0;
|
||||
else if (textureU > 1) textureU = 1;
|
||||
|
||||
if (textureV < 0) textureV = 0;
|
||||
else if (textureV > 1) textureV = 1;
|
||||
}
|
||||
|
||||
|
||||
/** This feature is in testing, do not use or rely upon its implementation */
|
||||
public void breakShape() {
|
||||
}
|
||||
|
||||
|
||||
public void endShape() {
|
||||
endShape(OPEN);
|
||||
}
|
||||
|
||||
|
||||
public void endShape(int mode) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
// CURVE/BEZIER VERTEX HANDLING
|
||||
|
||||
|
||||
protected void bezierVertexCheck() {
|
||||
if (shape == 0 || shape != POLYGON) {
|
||||
throw new RuntimeException("beginShape() or beginShape(POLYGON) " +
|
||||
"must be used before bezierVertex()");
|
||||
}
|
||||
if (vertexCount == 0) {
|
||||
throw new RuntimeException("vertex() must be used at least once" +
|
||||
"before bezierVertex()");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void bezierVertex(float x2, float y2,
|
||||
float x3, float y3,
|
||||
float x4, float y4) {
|
||||
bezierVertexCheck();
|
||||
PMatrix3D draw = bezierDrawMatrix;
|
||||
|
||||
float[] prev = vertices[vertexCount-1];
|
||||
float x1 = prev[X];
|
||||
float y1 = prev[Y];
|
||||
|
||||
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;
|
||||
|
||||
for (int j = 0; j < bezierDetail; j++) {
|
||||
x1 += xplot1; xplot1 += xplot2; xplot2 += xplot3;
|
||||
y1 += yplot1; yplot1 += yplot2; yplot2 += yplot3;
|
||||
vertex(x1, y1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void bezierVertex(float x2, float y2, float z2,
|
||||
float x3, float y3, float z3,
|
||||
float x4, float y4, float z4) {
|
||||
bezierVertexCheck();
|
||||
PMatrix3D draw = bezierDrawMatrix;
|
||||
|
||||
float[] prev = vertices[vertexCount-1];
|
||||
float x1 = prev[X];
|
||||
float y1 = prev[Y];
|
||||
float z1 = prev[Z];
|
||||
|
||||
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;
|
||||
vertex(x1, y1, z1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform initialization specific to curveVertex(), and handle standard
|
||||
* error modes. Can be overridden by subclasses that need the flexibility.
|
||||
*/
|
||||
protected void curveVertexCheck() {
|
||||
if (shape != POLYGON) {
|
||||
throw new RuntimeException("You must use beginShape() or " +
|
||||
"beginShape(POLYGON) before curveVertex()");
|
||||
}
|
||||
// to improve code init time, allocate on first use.
|
||||
if (curveVertices == null) {
|
||||
curveVertices = new float[128][3];
|
||||
}
|
||||
|
||||
if (curveVertexCount == curveVertices.length) {
|
||||
curveVertices = (float[][]) PApplet.expand(curveVertices);
|
||||
}
|
||||
curveInitCheck();
|
||||
}
|
||||
|
||||
|
||||
public void curveVertex(float x, float y) {
|
||||
curveVertexCheck();
|
||||
float[] vertex = curveVertices[curveVertexCount];
|
||||
vertex[X] = x;
|
||||
vertex[Y] = y;
|
||||
curveVertexCount++;
|
||||
|
||||
// draw a segment if there are enough points
|
||||
if (curveVertexCount > 3) {
|
||||
curveVertexSegment(curveVertices[curveVertexCount-4][X],
|
||||
curveVertices[curveVertexCount-4][Y],
|
||||
curveVertices[curveVertexCount-3][X],
|
||||
curveVertices[curveVertexCount-3][Y],
|
||||
curveVertices[curveVertexCount-2][X],
|
||||
curveVertices[curveVertexCount-2][Y],
|
||||
curveVertices[curveVertexCount-1][X],
|
||||
curveVertices[curveVertexCount-1][Y]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 x2, float y2,
|
||||
float x3, float y3,
|
||||
@@ -1220,7 +1286,7 @@ public class PGraphics extends PImage implements PConstants {
|
||||
float yplot3 = draw.m30*y1 + draw.m31*y2 + draw.m32*y3 + draw.m33*y4;
|
||||
|
||||
// vertex() will reset splineVertexCount, so save it
|
||||
int savedCount = splineVertexCount;
|
||||
int savedCount = curveVertexCount;
|
||||
|
||||
vertex(x0, y0);
|
||||
for (int j = 0; j < curveDetail; j++) {
|
||||
@@ -1228,10 +1294,14 @@ public class PGraphics extends PImage implements PConstants {
|
||||
y0 += yplot1; yplot1 += yplot2; yplot2 += yplot3;
|
||||
vertex(x0, y0);
|
||||
}
|
||||
splineVertexCount = savedCount;
|
||||
curveVertexCount = savedCount;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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,
|
||||
@@ -1251,7 +1321,7 @@ public class PGraphics extends PImage implements PConstants {
|
||||
float yplot3 = draw.m30*y1 + draw.m31*y2 + draw.m32*y3 + draw.m33*y4;
|
||||
|
||||
// vertex() will reset splineVertexCount, so save it
|
||||
int savedCount = splineVertexCount;
|
||||
int savedCount = curveVertexCount;
|
||||
|
||||
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;
|
||||
@@ -1264,21 +1334,7 @@ public class PGraphics extends PImage implements PConstants {
|
||||
z0 += zplot1; zplot1 += zplot2; zplot2 += zplot3;
|
||||
vertex(x0, y0, z0);
|
||||
}
|
||||
splineVertexCount = savedCount;
|
||||
}
|
||||
|
||||
|
||||
/** This feature is in testing, do not use or rely upon its implementation */
|
||||
public void breakShape() {
|
||||
}
|
||||
|
||||
|
||||
public void endShape() {
|
||||
endShape(OPEN);
|
||||
}
|
||||
|
||||
|
||||
public void endShape(int mode) {
|
||||
curveVertexCount = savedCount;
|
||||
}
|
||||
|
||||
|
||||
@@ -3112,12 +3168,6 @@ public class PGraphics extends PImage implements PConstants {
|
||||
// TRANSFORMATION MATRIX
|
||||
|
||||
|
||||
static final String ERROR_PUSHMATRIX_OVERFLOW =
|
||||
"Too many calls to pushMatrix().";
|
||||
static final String ERROR_PUSHMATRIX_UNDERFLOW =
|
||||
"Too many calls to popMatrix(), and not enough to pushMatrix().";
|
||||
|
||||
|
||||
/**
|
||||
* Push a copy of the current transformation matrix onto the stack.
|
||||
*/
|
||||
@@ -4148,9 +4198,10 @@ public class PGraphics extends PImage implements PConstants {
|
||||
|
||||
|
||||
static protected void depthErrorXYZ(String method) {
|
||||
showError(method + "(x, y, z) can only be used with a renderer that " +
|
||||
showError(method + "() with x, y, and z coordinates " +
|
||||
"can only be used with a renderer that " +
|
||||
"supports 3D, such as P3D or OPENGL. " +
|
||||
"Use " + method + "(x, y) instead.");
|
||||
"Use a version without a z-coordinate instead.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -30,9 +30,10 @@ import java.util.Arrays;
|
||||
|
||||
|
||||
/**
|
||||
* Subclass of PGraphics that handles fast 2D rendering,
|
||||
* more commonly referred to as P2D. This class uses no Java2D
|
||||
* and will run with Java 1.1.
|
||||
* Subclass of PGraphics that handles fast 2D rendering using a
|
||||
* MemoryImageSource. The renderer found in this class is not as accurate as
|
||||
* PGraphicsJava2D, but offers certain speed tradeoffs, particular when
|
||||
* messing with the pixels array, or displaying image or video data.
|
||||
*/
|
||||
public class PGraphics2D extends PGraphics {
|
||||
|
||||
@@ -51,9 +52,9 @@ public class PGraphics2D extends PGraphics {
|
||||
boolean strokeChanged = true;
|
||||
boolean fillChanged = true;
|
||||
|
||||
static final int CVERTEX_ALLOC = 128;
|
||||
float cvertex[][] = new float[CVERTEX_ALLOC][VERTEX_FIELD_COUNT];
|
||||
int cvertexIndex;
|
||||
// static final int CVERTEX_ALLOC = 128;
|
||||
// float cvertex[][] = new float[CVERTEX_ALLOC][VERTEX_FIELD_COUNT];
|
||||
// int cvertexIndex;
|
||||
|
||||
float[][] matrixStack = new float[MATRIX_STACK_DEPTH][6];
|
||||
int matrixStackDepth;
|
||||
@@ -142,7 +143,7 @@ public class PGraphics2D extends PGraphics {
|
||||
public void beginShape(int kind) {
|
||||
shape = kind;
|
||||
vertexCount = 0;
|
||||
splineVertexCount = 0;
|
||||
curveVertexCount = 0;
|
||||
|
||||
polygon.reset(0);
|
||||
fpolygon.reset(4);
|
||||
@@ -152,46 +153,8 @@ public class PGraphics2D extends PGraphics {
|
||||
}
|
||||
|
||||
|
||||
// PGraphics will throw a depthError
|
||||
//public void normal(float nx, float ny, float nz)
|
||||
|
||||
// PGraphics will handle setting these
|
||||
//public void textureMode(int mode)
|
||||
//public void texture(PImage image)
|
||||
//protected void textureVertex(float u, float v)
|
||||
|
||||
|
||||
public void vertex(float x, float y) {
|
||||
float vertex[] = polygon.nextVertex();
|
||||
cvertexIndex = 0; // reset curves to start
|
||||
|
||||
vertex[X] = x;
|
||||
vertex[Y] = y;
|
||||
|
||||
if (fill) {
|
||||
vertex[R] = fillR;
|
||||
vertex[G] = fillG;
|
||||
vertex[B] = fillB;
|
||||
vertex[A] = fillA;
|
||||
}
|
||||
|
||||
if (stroke) {
|
||||
vertex[SR] = strokeR;
|
||||
vertex[SG] = strokeG;
|
||||
vertex[SB] = strokeB;
|
||||
vertex[SA] = strokeA;
|
||||
vertex[SW] = strokeWeight;
|
||||
}
|
||||
|
||||
if (textureImage != null) {
|
||||
vertex[U] = textureU;
|
||||
vertex[V] = textureV;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void vertex(float x, float y, float u, float v) {
|
||||
textureVertex(u, v);
|
||||
vertexTexture(u, v);
|
||||
vertex(x, y);
|
||||
}
|
||||
|
||||
@@ -1185,14 +1148,12 @@ public class PGraphics2D extends PGraphics {
|
||||
private void thin_pointAt(int x, int y, float z, int color) {
|
||||
int index = y*width+x; // offset values are pre-calced in constructor
|
||||
pixels[index] = color;
|
||||
zbuffer[index] = z;
|
||||
}
|
||||
|
||||
// expects offset/index in pixelbuffer array instead of x/y coords
|
||||
// used by optimized parts of thin_flat_line() [toxi]
|
||||
private void thin_pointAtIndex(int offset, float z, int color) {
|
||||
pixels[offset] = color;
|
||||
zbuffer[offset] = z;
|
||||
}
|
||||
|
||||
// points are inherently flat, but always tangent
|
||||
@@ -1621,7 +1582,6 @@ public class PGraphics2D extends PGraphics {
|
||||
a2 * ( color & 0xff)) >> 8));
|
||||
*/
|
||||
}
|
||||
zbuffer[index] = z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -41,6 +41,93 @@ import java.util.*;
|
||||
*/
|
||||
public class PGraphics3D extends PGraphics {
|
||||
|
||||
/** The depth buffer. */
|
||||
public float[] zbuffer;
|
||||
|
||||
/** The modelview matrix. */
|
||||
public PMatrix3D modelview;
|
||||
|
||||
/** Inverse modelview matrix, used for lighting. */
|
||||
protected PMatrix3D modelviewInv;
|
||||
|
||||
/**
|
||||
* The camera matrix, the modelview will be set to this on beginDraw.
|
||||
*/
|
||||
public PMatrix3D camera;
|
||||
|
||||
/** Inverse camera matrix */
|
||||
protected PMatrix3D cameraInv;
|
||||
|
||||
// ........................................................
|
||||
|
||||
/** Camera field of view. */
|
||||
public float cameraFOV;
|
||||
|
||||
/** Position of the camera. */
|
||||
public float cameraX, cameraY, cameraZ;
|
||||
public float cameraNear, cameraFar;
|
||||
/** Aspect ratio of camera's view. */
|
||||
public float cameraAspect;
|
||||
|
||||
/** Current projection matrix. */
|
||||
public PMatrix3D projection;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* Maximum lights by default is 8, which is arbitrary for this renderer,
|
||||
* but is the minimum defined by OpenGL
|
||||
*/
|
||||
public static final int MAX_LIGHTS = 8;
|
||||
|
||||
public int lightCount = 0;
|
||||
|
||||
/** Light types */
|
||||
public int[] lightType;
|
||||
|
||||
/** Light positions */
|
||||
public float[][] lightPosition;
|
||||
|
||||
/** Light direction (normalized vector) */
|
||||
public float[][] lightNormal;
|
||||
|
||||
/** Light falloff */
|
||||
public float[] lightFalloffConstant;
|
||||
public float[] lightFalloffLinear;
|
||||
public float[] lightFalloffQuadratic;
|
||||
|
||||
/** Light spot angle */
|
||||
public float[] lightSpotAngle;
|
||||
|
||||
/** Cosine of light spot angle */
|
||||
public float[] lightSpotAngleCos;
|
||||
|
||||
/** Light spot concentration */
|
||||
public float[] lightSpotConcentration;
|
||||
|
||||
/** Diffuse colors for lights.
|
||||
* For an ambient light, this will hold the ambient color.
|
||||
* Internally these are stored as numbers between 0 and 1. */
|
||||
public float[][] lightDiffuse;
|
||||
|
||||
/** Specular colors for lights.
|
||||
Internally these are stored as numbers between 0 and 1. */
|
||||
public float[][] lightSpecular;
|
||||
|
||||
/** Current specular color for lighting */
|
||||
public float[] currentLightSpecular;
|
||||
|
||||
/** Current light falloff */
|
||||
public float currentLightFalloffConstant;
|
||||
public float currentLightFalloffLinear;
|
||||
public float currentLightFalloffQuadratic;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
static public final int TRI_DIFFUSE_R = 0;
|
||||
static public final int TRI_DIFFUSE_G = 1;
|
||||
static public final int TRI_DIFFUSE_B = 2;
|
||||
@@ -71,8 +158,8 @@ public class PGraphics3D extends PGraphics {
|
||||
protected float[] tempLightingContribution = new float[LIGHT_COLOR_COUNT];
|
||||
protected float[] worldNormal = new float[4];
|
||||
|
||||
/// Used in light_triangle(). Allocated here once to avoid re-allocating
|
||||
protected float[] norm = new float[3];
|
||||
/// Used in lightTriangle(). Allocated here once to avoid re-allocating
|
||||
protected PVector lightTriangleNorm = new PVector();
|
||||
|
||||
// ........................................................
|
||||
|
||||
@@ -108,15 +195,15 @@ public class PGraphics3D extends PGraphics {
|
||||
// ........................................................
|
||||
|
||||
// pos of first vertex of current shape in vertices array
|
||||
protected int vertex_start;
|
||||
protected int shapeFirst;
|
||||
|
||||
// i think vertex_end is actually the last vertex in the current shape
|
||||
// and is separate from vertexCount for occasions where drawing happens
|
||||
// on endDraw() with all the triangles being depth sorted
|
||||
protected int vertex_end;
|
||||
protected int shapeLast;
|
||||
|
||||
// vertices may be added during clipping against the near plane.
|
||||
protected int vertex_end_including_clip_verts;
|
||||
protected int shapeLastPlusClipped;
|
||||
|
||||
// used for sorting points when triangulating a polygon
|
||||
// warning - maximum number of vertices for a polygon is DEFAULT_VERTICES
|
||||
@@ -124,6 +211,9 @@ public class PGraphics3D extends PGraphics {
|
||||
|
||||
// ........................................................
|
||||
|
||||
// this is done to keep track of start/stop information for lines in the
|
||||
// line array, so that lines can be shown as a single path, rather than just
|
||||
// individual segments. (currently not in use)
|
||||
protected int pathCount;
|
||||
protected int pathOffset[] = new int[64];
|
||||
protected int pathLength[] = new int[64];
|
||||
@@ -131,16 +221,16 @@ public class PGraphics3D extends PGraphics {
|
||||
// ........................................................
|
||||
|
||||
// line & triangle fields (note that these overlap)
|
||||
static protected final int INDEX = 0; // shape index
|
||||
static protected final int VERTEX1 = 1;
|
||||
static protected final int VERTEX2 = 2;
|
||||
static protected final int VERTEX3 = 3; // (triangles only)
|
||||
static protected final int TEXTURE_INDEX = 4; // (triangles only)
|
||||
static protected final int STROKE_MODE = 3; // (lines only)
|
||||
static protected final int STROKE_WEIGHT = 4; // (lines only)
|
||||
// static protected final int INDEX = 0; // shape index
|
||||
static protected final int VERTEX1 = 0;
|
||||
static protected final int VERTEX2 = 1;
|
||||
static protected final int VERTEX3 = 2; // (triangles only)
|
||||
static protected final int TEXTURE_INDEX = 3; // (triangles only)
|
||||
static protected final int STROKE_MODE = 2; // (lines only)
|
||||
static protected final int STROKE_WEIGHT = 3; // (lines only)
|
||||
|
||||
static protected final int LINE_FIELD_COUNT = 5;
|
||||
static protected final int TRIANGLE_FIELD_COUNT = 5;
|
||||
static protected final int LINE_FIELD_COUNT = 4;
|
||||
static protected final int TRIANGLE_FIELD_COUNT = 4;
|
||||
|
||||
// lines
|
||||
static final int DEFAULT_LINES = 512;
|
||||
@@ -158,7 +248,7 @@ public class PGraphics3D extends PGraphics {
|
||||
protected int triangleCount; // total number of triangles
|
||||
|
||||
// cheap picking someday
|
||||
public int shape_index;
|
||||
//public int shape_index;
|
||||
|
||||
// ........................................................
|
||||
|
||||
@@ -178,6 +268,15 @@ public class PGraphics3D extends PGraphics {
|
||||
public PGraphics3D() { }
|
||||
|
||||
|
||||
//public void setParent(PApplet parent)
|
||||
|
||||
|
||||
//public void setPrimary(boolean primary)
|
||||
|
||||
|
||||
//public void setPath(String path)
|
||||
|
||||
|
||||
/**
|
||||
* Called in repsonse to a resize event, handles setting the
|
||||
* new width and height internally, as well as re-allocating
|
||||
@@ -282,6 +381,9 @@ public class PGraphics3D extends PGraphics {
|
||||
}
|
||||
|
||||
|
||||
//public boolean canDraw()
|
||||
|
||||
|
||||
public void beginDraw() {
|
||||
// insideResizeWait();
|
||||
// insideDraw = true;
|
||||
@@ -314,7 +416,7 @@ public class PGraphics3D extends PGraphics {
|
||||
triangleCount = 0;
|
||||
if (triangle != null) triangle.reset(); // necessary?
|
||||
|
||||
vertex_start = 0;
|
||||
shapeFirst = 0;
|
||||
//vertex_end = 0;
|
||||
|
||||
// reset textures
|
||||
@@ -354,7 +456,7 @@ public class PGraphics3D extends PGraphics {
|
||||
/**
|
||||
* Emit any sorted geometry that's been collected on this frame.
|
||||
*/
|
||||
protected void flush() {
|
||||
public void flush() {
|
||||
if (triangleCount > 0) {
|
||||
if (hints[ENABLE_DEPTH_SORT]) {
|
||||
sortTriangles();
|
||||
@@ -375,7 +477,10 @@ public class PGraphics3D extends PGraphics {
|
||||
}
|
||||
|
||||
|
||||
public void defaultSettings() {
|
||||
//protected void checkSettings()
|
||||
|
||||
|
||||
protected void defaultSettings() {
|
||||
super.defaultSettings();
|
||||
|
||||
manipulatingCamera = false;
|
||||
@@ -393,6 +498,9 @@ public class PGraphics3D extends PGraphics {
|
||||
}
|
||||
|
||||
|
||||
//protected void reapplySettings()
|
||||
|
||||
|
||||
public void hint(int which) {
|
||||
if (which == DISABLE_DEPTH_SORT) {
|
||||
flush();
|
||||
@@ -404,19 +512,22 @@ public class PGraphics3D extends PGraphics {
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//public void beginShape()
|
||||
|
||||
|
||||
public void beginShape(int kind) {
|
||||
shape = kind;
|
||||
|
||||
shape_index = shape_index + 1;
|
||||
if (shape_index == -1) {
|
||||
shape_index = 0;
|
||||
}
|
||||
// shape_index = shape_index + 1;
|
||||
// if (shape_index == -1) {
|
||||
// shape_index = 0;
|
||||
// }
|
||||
|
||||
if (hints[ENABLE_DEPTH_SORT]) {
|
||||
// continue with previous vertex, line and triangle count
|
||||
// all shapes are rendered at endDraw();
|
||||
vertex_start = vertexCount;
|
||||
vertex_end = 0;
|
||||
shapeFirst = vertexCount;
|
||||
shapeLast = 0;
|
||||
|
||||
} else {
|
||||
// reset vertex, line and triangle information
|
||||
@@ -430,56 +541,18 @@ public class PGraphics3D extends PGraphics {
|
||||
}
|
||||
textureImage = null;
|
||||
|
||||
splineVertexCount = 0;
|
||||
curveVertexCount = 0;
|
||||
normalMode = NORMAL_MODE_AUTO;
|
||||
normalCount = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the current normal vector.
|
||||
* <P/>
|
||||
* This is for drawing three dimensional shapes and surfaces,
|
||||
* allowing you to specify a vector perpendicular to the surface
|
||||
* of the shape, which determines how lighting affects it.
|
||||
* <P/>
|
||||
* For the most part, PGraphics3D will attempt to automatically
|
||||
* assign normals to shapes, but since that's imperfect,
|
||||
* this is a better option when you want more control.
|
||||
* <P/>
|
||||
* For people familiar with OpenGL, this function is basically
|
||||
* identical to glNormal3f().
|
||||
* <P/>
|
||||
* Only applies inside a beginShape/endShape block.
|
||||
*/
|
||||
public void normal(float nx, float ny, float nz) {
|
||||
normalX = nx;
|
||||
normalY = ny;
|
||||
normalZ = nz;
|
||||
|
||||
// if drawing a shape and the normal hasn't been set yet,
|
||||
// then we need to set the normals for each vertex so far
|
||||
if (shape != 0) {
|
||||
if (normalCount == 0) {
|
||||
for (int i = vertex_start; i < vertexCount; i++) {
|
||||
vertices[i][NX] = normalX;
|
||||
vertices[i][NY] = normalY;
|
||||
vertices[i][NZ] = normalZ;
|
||||
}
|
||||
}
|
||||
|
||||
normalCount++;
|
||||
if (normalCount == 1) {
|
||||
// One normal per begin/end shape
|
||||
normalMode = NORMAL_MODE_SHAPE;
|
||||
} else {
|
||||
// a separate normal for each vertex
|
||||
normalMode = NORMAL_MODE_VERTEX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//public void normal(float nx, float ny, float nz)
|
||||
|
||||
|
||||
//public void textureMode(int mode)
|
||||
|
||||
|
||||
public void texture(PImage image) {
|
||||
textureImage = image;
|
||||
|
||||
@@ -494,128 +567,29 @@ public class PGraphics3D extends PGraphics {
|
||||
|
||||
|
||||
public void vertex(float x, float y) {
|
||||
setup_vertex(x, y, 0);
|
||||
// override to properly pick up all 3D settings
|
||||
vertex(x, y, 0);
|
||||
}
|
||||
|
||||
|
||||
//public void vertex(float x, float y, float z)
|
||||
|
||||
|
||||
public void vertex(float x, float y, float u, float v) {
|
||||
textureVertex(u, v);
|
||||
setup_vertex(x, y, 0);
|
||||
// override to properly pick up all 3D settings
|
||||
vertex(x, y, 0, u, v);
|
||||
}
|
||||
|
||||
|
||||
public void vertex(float x, float y, float z) {
|
||||
setup_vertex(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
public void vertex(float x, float y, float z,
|
||||
float u, float v) {
|
||||
textureVertex(u, v);
|
||||
setup_vertex(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
protected void setup_vertex(float x, float y, float z) {
|
||||
if (vertexCount == vertices.length) {
|
||||
float temp[][] = new float[vertexCount << 1][VERTEX_FIELD_COUNT];
|
||||
System.arraycopy(vertices, 0, temp, 0, vertexCount);
|
||||
vertices = temp;
|
||||
int temp2[] = new int[vertexCount << 1];
|
||||
System.arraycopy(vertex_order, 0, temp2, 0, vertexCount);
|
||||
vertex_order = temp2;
|
||||
//System.out.println("allocating more vertices " + vertices.length);
|
||||
}
|
||||
float vertex[] = vertices[vertexCount];
|
||||
|
||||
// only do this if we're using an irregular (POLYGON) shape that
|
||||
// will go through the triangulator. otherwise it'll do thinks like
|
||||
// disappear in mathematically odd ways
|
||||
// http://dev.processing.org/bugs/show_bug.cgi?id=444
|
||||
if (shape == POLYGON) {
|
||||
if (vertexCount > 0) {
|
||||
float pvertex[] = vertices[vertexCount-1];
|
||||
if ((abs(pvertex[X] - x) < EPSILON) &&
|
||||
(abs(pvertex[Y] - y) < EPSILON) &&
|
||||
(abs(pvertex[Z] - z) < EPSILON)) {
|
||||
// this vertex is identical, don't add it,
|
||||
// because it will anger the triangulator
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// user called vertex(), so that invalidates anything queued
|
||||
// up for curve vertices. if this is internally called by
|
||||
// spline_segment, then splineVertexCount will be saved and restored.
|
||||
splineVertexCount = 0;
|
||||
|
||||
vertex[X] = x;
|
||||
vertex[Y] = y;
|
||||
vertex[Z] = z;
|
||||
|
||||
if (fill) {
|
||||
if (textureImage != null) {
|
||||
if (tint) {
|
||||
vertex[R] = tintR;
|
||||
vertex[G] = tintG;
|
||||
vertex[B] = tintB;
|
||||
vertex[A] = tintA;
|
||||
} else {
|
||||
vertex[R] = 1;
|
||||
vertex[G] = 1;
|
||||
vertex[B] = 1;
|
||||
vertex[A] = 1;
|
||||
}
|
||||
} else {
|
||||
vertex[R] = fillR;
|
||||
vertex[G] = fillG;
|
||||
vertex[B] = fillB;
|
||||
vertex[A] = fillA;
|
||||
}
|
||||
|
||||
vertex[AR] = ambientR;
|
||||
vertex[AG] = ambientG;
|
||||
vertex[AB] = ambientB;
|
||||
|
||||
vertex[SPR] = specularR;
|
||||
vertex[SPG] = specularG;
|
||||
vertex[SPB] = specularB;
|
||||
//vertex[SPA] = specularA;
|
||||
|
||||
vertex[SHINE] = shininess;
|
||||
|
||||
vertex[ER] = emissiveR;
|
||||
vertex[EG] = emissiveG;
|
||||
vertex[EB] = emissiveB;
|
||||
}
|
||||
|
||||
if (stroke) {
|
||||
vertex[SR] = strokeR;
|
||||
vertex[SG] = strokeG;
|
||||
vertex[SB] = strokeB;
|
||||
vertex[SA] = strokeA;
|
||||
vertex[SW] = strokeWeight;
|
||||
}
|
||||
|
||||
if (textureImage != null) {
|
||||
vertex[U] = textureU;
|
||||
vertex[V] = textureV;
|
||||
}
|
||||
|
||||
vertex[NX] = normalX;
|
||||
vertex[NY] = normalY;
|
||||
vertex[NZ] = normalZ;
|
||||
|
||||
vertex[BEEN_LIT] = 0;
|
||||
|
||||
vertexCount++;
|
||||
}
|
||||
|
||||
//public void vertex(float x, float y, float z, float u, float v)
|
||||
|
||||
|
||||
//public void endShape()
|
||||
|
||||
|
||||
public void endShape(int mode) {
|
||||
vertex_end = vertexCount;
|
||||
vertex_end_including_clip_verts = vertex_end;
|
||||
shapeLast = vertexCount;
|
||||
shapeLastPlusClipped = shapeLast;
|
||||
|
||||
// don't try to draw if there are no vertices
|
||||
// (fixes a bug in LINE_LOOP that re-adds a nonexistent vertex)
|
||||
@@ -630,7 +604,7 @@ public class PGraphics3D extends PGraphics {
|
||||
// It is necessary to do this now because we will be clipping them on
|
||||
// add_triangle.
|
||||
|
||||
for (int i = vertex_start; i < vertex_end; i++) {
|
||||
for (int i = shapeFirst; i < shapeLast; i++) {
|
||||
float vertex[] = vertices[i];
|
||||
|
||||
vertex[VX] =
|
||||
@@ -667,8 +641,8 @@ public class PGraphics3D extends PGraphics {
|
||||
|
||||
case POINTS:
|
||||
{
|
||||
stop = vertex_end;
|
||||
for (int i = vertex_start; i < stop; i++) {
|
||||
stop = shapeLast;
|
||||
for (int i = shapeFirst; i < stop; i++) {
|
||||
add_path(); // total overkill for points
|
||||
add_line(i, i);
|
||||
}
|
||||
@@ -681,13 +655,13 @@ public class PGraphics3D extends PGraphics {
|
||||
{
|
||||
// store index of first vertex
|
||||
int first = lineCount;
|
||||
stop = vertex_end - 1;
|
||||
stop = shapeLast - 1;
|
||||
increment = (shape == LINES) ? 2 : 1;
|
||||
|
||||
// for LINE_STRIP and LINE_LOOP, make this all one path
|
||||
if (shape != LINES) add_path();
|
||||
|
||||
for (int i = vertex_start; i < stop; i+=increment) {
|
||||
for (int i = shapeFirst; i < stop; i+=increment) {
|
||||
// for LINES, make a new path for each segment
|
||||
if (shape == LINES) add_path();
|
||||
add_line(i, i+1);
|
||||
@@ -703,7 +677,7 @@ public class PGraphics3D extends PGraphics {
|
||||
|
||||
case TRIANGLES:
|
||||
{
|
||||
for (int i = vertex_start; i < vertex_end-2; i += 3) {
|
||||
for (int i = shapeFirst; i < shapeLast-2; i += 3) {
|
||||
add_path();
|
||||
//counter = i - vertex_start;
|
||||
add_line(i+0, i+1);
|
||||
@@ -716,17 +690,17 @@ public class PGraphics3D extends PGraphics {
|
||||
case TRIANGLE_STRIP:
|
||||
{
|
||||
// first draw all vertices as a line strip
|
||||
stop = vertex_end-1;
|
||||
stop = shapeLast-1;
|
||||
|
||||
add_path();
|
||||
for (int i = vertex_start; i < stop; i++) {
|
||||
for (int i = shapeFirst; i < stop; i++) {
|
||||
//counter = i - vertex_start;
|
||||
add_line(i, i+1);
|
||||
}
|
||||
|
||||
// then draw from vertex (n) to (n+2)
|
||||
stop = vertex_end-2;
|
||||
for (int i = vertex_start; i < stop; i++) {
|
||||
stop = shapeLast-2;
|
||||
for (int i = shapeFirst; i < stop; i++) {
|
||||
add_path();
|
||||
add_line(i, i+2);
|
||||
}
|
||||
@@ -737,24 +711,24 @@ public class PGraphics3D extends PGraphics {
|
||||
{
|
||||
// this just draws a series of line segments
|
||||
// from the center to each exterior point
|
||||
for (int i = vertex_start + 1; i < vertex_end; i++) {
|
||||
for (int i = shapeFirst + 1; i < shapeLast; i++) {
|
||||
add_path();
|
||||
add_line(vertex_start, i);
|
||||
add_line(shapeFirst, i);
|
||||
}
|
||||
|
||||
// then a single line loop around the outside.
|
||||
add_path();
|
||||
for (int i = vertex_start + 1; i < vertex_end-1; i++) {
|
||||
for (int i = shapeFirst + 1; i < shapeLast-1; i++) {
|
||||
add_line(i, i+1);
|
||||
}
|
||||
// closing the loop
|
||||
add_line(vertex_end-1, vertex_start + 1);
|
||||
add_line(shapeLast-1, shapeFirst + 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case QUADS:
|
||||
{
|
||||
for (int i = vertex_start; i < vertex_end; i += 4) {
|
||||
for (int i = shapeFirst; i < shapeLast; i += 4) {
|
||||
add_path();
|
||||
//counter = i - vertex_start;
|
||||
add_line(i+0, i+1);
|
||||
@@ -767,7 +741,7 @@ public class PGraphics3D extends PGraphics {
|
||||
|
||||
case QUAD_STRIP:
|
||||
{
|
||||
for (int i = vertex_start; i < vertex_end - 3; i += 2) {
|
||||
for (int i = shapeFirst; i < shapeLast - 3; i += 2) {
|
||||
add_path();
|
||||
add_line(i+0, i+2);
|
||||
add_line(i+2, i+3);
|
||||
@@ -802,16 +776,16 @@ public class PGraphics3D extends PGraphics {
|
||||
{
|
||||
// store index of first vertex
|
||||
//int first = lineCount;
|
||||
stop = vertex_end - 1;
|
||||
stop = shapeLast - 1;
|
||||
|
||||
add_path();
|
||||
for (int i = vertex_start; i < stop; i++) {
|
||||
for (int i = shapeFirst; i < stop; i++) {
|
||||
add_line(i, i+1);
|
||||
//System.out.println("adding line " + i);
|
||||
}
|
||||
if (mode == CLOSE) {
|
||||
// draw the last line connecting back to the first point in poly
|
||||
add_line(stop, vertex_start); //lines[first][VERTEX1]);
|
||||
add_line(stop, shapeFirst); //lines[first][VERTEX1]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -825,9 +799,9 @@ public class PGraphics3D extends PGraphics {
|
||||
switch (shape) {
|
||||
case TRIANGLE_FAN:
|
||||
{
|
||||
stop = vertex_end - 1;
|
||||
for (int i = vertex_start + 1; i < stop; i++) {
|
||||
add_triangle(vertex_start, i, i+1);
|
||||
stop = shapeLast - 1;
|
||||
for (int i = shapeFirst + 1; i < stop; i++) {
|
||||
add_triangle(shapeFirst, i, i+1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -835,9 +809,9 @@ public class PGraphics3D extends PGraphics {
|
||||
case TRIANGLES:
|
||||
case TRIANGLE_STRIP:
|
||||
{
|
||||
stop = vertex_end - 2;
|
||||
stop = shapeLast - 2;
|
||||
increment = (shape == TRIANGLES) ? 3 : 1;
|
||||
for (int i = vertex_start; i < stop; i += increment) {
|
||||
for (int i = shapeFirst; i < stop; i += increment) {
|
||||
// have to switch between clockwise/counter-clockwise
|
||||
// otherwise the feller is backwards and renderer won't draw
|
||||
if ((i % 2) == 0) {
|
||||
@@ -853,7 +827,7 @@ public class PGraphics3D extends PGraphics {
|
||||
{
|
||||
stop = vertexCount-3;
|
||||
|
||||
for (int i = vertex_start; i < stop; i += 4) {
|
||||
for (int i = shapeFirst; i < stop; i += 4) {
|
||||
// first triangle
|
||||
add_triangle(i, i+1, i+2);
|
||||
// second triangle
|
||||
@@ -866,7 +840,7 @@ public class PGraphics3D extends PGraphics {
|
||||
{
|
||||
stop = vertexCount-3;
|
||||
|
||||
for (int i = vertex_start; i < stop; i += 2) {
|
||||
for (int i = shapeFirst; i < stop; i += 2) {
|
||||
// first triangle
|
||||
add_triangle(i+0, i+2, i+1);
|
||||
// second triangle
|
||||
@@ -901,7 +875,7 @@ public class PGraphics3D extends PGraphics {
|
||||
// POINTS FROM CAMERA SPACE (VX, VY, VZ) TO SCREEN SPACE (X, Y, Z)
|
||||
// this appears to be wasted time with the opengl renderer
|
||||
|
||||
for (int i = vertex_start; i < vertex_end_including_clip_verts; i++) {
|
||||
for (int i = shapeFirst; i < shapeLastPlusClipped; i++) {
|
||||
float vx[] = vertices[i];
|
||||
|
||||
float ox =
|
||||
@@ -1020,7 +994,7 @@ public class PGraphics3D extends PGraphics {
|
||||
}
|
||||
lines[lineCount][VERTEX1] = a;
|
||||
lines[lineCount][VERTEX2] = b;
|
||||
lines[lineCount][INDEX] = -1;
|
||||
// lines[lineCount][INDEX] = -1;
|
||||
|
||||
lines[lineCount][STROKE_MODE] = strokeCap | strokeJoin;
|
||||
lines[lineCount][STROKE_WEIGHT] = (int) (strokeWeight + 0.5f); // hmm
|
||||
@@ -1161,7 +1135,7 @@ public class PGraphics3D extends PGraphics {
|
||||
pa * va[Y] + pb * vb[Y],
|
||||
pa * va[Z] + pb * vb[Z]);
|
||||
int irv = vertexCount - 1;
|
||||
vertex_end_including_clip_verts++;
|
||||
shapeLastPlusClipped++;
|
||||
|
||||
float[] rv = vertices[irv];
|
||||
|
||||
@@ -1234,7 +1208,7 @@ public class PGraphics3D extends PGraphics {
|
||||
triangles[triangleCount][TEXTURE_INDEX] = textureIndex;
|
||||
}
|
||||
|
||||
triangles[triangleCount][INDEX] = shape_index;
|
||||
// triangles[triangleCount][INDEX] = shape_index;
|
||||
triangleCount++;
|
||||
}
|
||||
|
||||
@@ -1309,7 +1283,7 @@ public class PGraphics3D extends PGraphics {
|
||||
float b[] = vertices[triangles[i][VERTEX2]];
|
||||
float c[] = vertices[triangles[i][VERTEX3]];
|
||||
int tex = triangles[i][TEXTURE_INDEX];
|
||||
int index = triangles[i][INDEX];
|
||||
// int index = triangles[i][INDEX];
|
||||
|
||||
// ewjordan: hack to 'fix' accuracy issues when drawing in 2d
|
||||
// see also render_lines() where similar hack is employed
|
||||
@@ -1366,7 +1340,7 @@ public class PGraphics3D extends PGraphics {
|
||||
c[VX], c[VY], c[VZ]);
|
||||
}
|
||||
|
||||
triangle.setIndex(index);
|
||||
// triangle.setIndex(index);
|
||||
triangle.render();
|
||||
|
||||
//System.out.println(i + " " + a[Z] + " " + b[Z] + " " + c[Z]);
|
||||
@@ -1428,7 +1402,7 @@ public class PGraphics3D extends PGraphics {
|
||||
for (int i = 0; i < lineCount; i ++) {
|
||||
float a[] = vertices[lines[i][VERTEX1]];
|
||||
float b[] = vertices[lines[i][VERTEX2]];
|
||||
int index = lines[i][INDEX];
|
||||
// int index = lines[i][INDEX];
|
||||
|
||||
// 2D hack added by ewjordan 6/13/07
|
||||
// Offset coordinates by a little bit if drawing 2D graphics.
|
||||
@@ -1499,7 +1473,7 @@ public class PGraphics3D extends PGraphics {
|
||||
}
|
||||
*/
|
||||
|
||||
line.setIndex(index);
|
||||
// line.setIndex(index);
|
||||
line.draw();
|
||||
}
|
||||
|
||||
@@ -1518,6 +1492,13 @@ public class PGraphics3D extends PGraphics {
|
||||
* bit of code from the web.
|
||||
*/
|
||||
private void triangulate_polygon() {
|
||||
if (vertex_order.length != vertices.length) {
|
||||
int[] temp = new int[vertices.length];
|
||||
// since vertex_start may not be zero, might need to keep old stuff around
|
||||
PApplet.arraycopy(vertex_order, temp, vertexCount);
|
||||
vertex_order = temp;
|
||||
}
|
||||
|
||||
// this clipping algorithm only works in 2D, so in cases where a
|
||||
// polygon is drawn perpendicular to the z-axis, the area will be zero,
|
||||
// and triangulation will fail. as such, when the area calculates to
|
||||
@@ -1549,7 +1530,7 @@ public class PGraphics3D extends PGraphics {
|
||||
|
||||
// first we check if the polygon goes clockwise or counterclockwise
|
||||
float area = 0;
|
||||
for (int p = vertex_end - 1, q = vertex_start; q < vertex_end; p = q++) {
|
||||
for (int p = shapeLast - 1, q = shapeFirst; q < shapeLast; p = q++) {
|
||||
area += (vertices[q][d1] * vertices[p][d2] -
|
||||
vertices[p][d1] * vertices[q][d2]);
|
||||
}
|
||||
@@ -1561,8 +1542,8 @@ public class PGraphics3D extends PGraphics {
|
||||
boolean foundValidX = false;
|
||||
boolean foundValidY = false;
|
||||
|
||||
for (int i = vertex_start; i < vertex_end; i++) {
|
||||
for (int j = i; j < vertex_end; j++){
|
||||
for (int i = shapeFirst; i < shapeLast; i++) {
|
||||
for (int j = i; j < shapeLast; j++){
|
||||
if ( vertices[i][X] != vertices[j][X] ) foundValidX = true;
|
||||
if ( vertices[i][Y] != vertices[j][Y] ) foundValidY = true;
|
||||
}
|
||||
@@ -1581,7 +1562,7 @@ public class PGraphics3D extends PGraphics {
|
||||
}
|
||||
|
||||
// re-calculate the area, with what should be good values
|
||||
for (int p = vertex_end - 1, q = vertex_start; q < vertex_end; p = q++) {
|
||||
for (int p = shapeLast - 1, q = shapeFirst; q < shapeLast; p = q++) {
|
||||
area += (vertices[q][d1] * vertices[p][d2] -
|
||||
vertices[p][d1] * vertices[q][d2]);
|
||||
}
|
||||
@@ -1590,30 +1571,30 @@ public class PGraphics3D extends PGraphics {
|
||||
// don't allow polygons to come back and meet themselves,
|
||||
// otherwise it will anger the triangulator
|
||||
// http://dev.processing.org/bugs/show_bug.cgi?id=97
|
||||
float vfirst[] = vertices[vertex_start];
|
||||
float vlast[] = vertices[vertex_end-1];
|
||||
float vfirst[] = vertices[shapeFirst];
|
||||
float vlast[] = vertices[shapeLast-1];
|
||||
if ((abs(vfirst[X] - vlast[X]) < EPSILON) &&
|
||||
(abs(vfirst[Y] - vlast[Y]) < EPSILON) &&
|
||||
(abs(vfirst[Z] - vlast[Z]) < EPSILON)) {
|
||||
vertex_end--;
|
||||
shapeLast--;
|
||||
}
|
||||
|
||||
// then sort the vertices so they are always in a counterclockwise order
|
||||
int j = 0;
|
||||
if (area > 0) {
|
||||
for (int i = vertex_start; i < vertex_end; i++) {
|
||||
j = i - vertex_start;
|
||||
for (int i = shapeFirst; i < shapeLast; i++) {
|
||||
j = i - shapeFirst;
|
||||
vertex_order[j] = i;
|
||||
}
|
||||
} else {
|
||||
for (int i = vertex_start; i < vertex_end; i++) {
|
||||
j = i - vertex_start;
|
||||
vertex_order[j] = (vertex_end - 1) - j;
|
||||
for (int i = shapeFirst; i < shapeLast; i++) {
|
||||
j = i - shapeFirst;
|
||||
vertex_order[j] = (shapeLast - 1) - j;
|
||||
}
|
||||
}
|
||||
|
||||
// remove vc-2 Vertices, creating 1 triangle every time
|
||||
int vc = vertex_end - vertex_start;
|
||||
int vc = shapeLast - shapeFirst;
|
||||
int count = 2*vc; // complex polygon detection
|
||||
|
||||
for (int m = 0, v = vc - 1; vc > 2; ) {
|
||||
@@ -2053,15 +2034,12 @@ public class PGraphics3D extends PGraphics {
|
||||
vertices[vIndex2][VZ] - vertices[vIndex][VZ],
|
||||
vertices[vIndex3][VX] - vertices[vIndex][VX],
|
||||
vertices[vIndex3][VY] - vertices[vIndex][VY],
|
||||
vertices[vIndex3][VZ] - vertices[vIndex][VZ], norm);
|
||||
|
||||
float nmag = mag(norm[X], norm[Y], norm[Z]);
|
||||
if (nmag != 0 && nmag != 1) {
|
||||
norm[X] /= nmag; norm[Y] /= nmag; norm[Z] /= nmag;
|
||||
}
|
||||
vertices[vIndex][NX] = norm[X];
|
||||
vertices[vIndex][NY] = norm[Y];
|
||||
vertices[vIndex][NZ] = norm[Z];
|
||||
vertices[vIndex3][VZ] - vertices[vIndex][VZ], lightTriangleNorm);
|
||||
|
||||
lightTriangleNorm.normalize();
|
||||
vertices[vIndex][NX] = lightTriangleNorm.x;
|
||||
vertices[vIndex][NY] = lightTriangleNorm.y;
|
||||
vertices[vIndex][NZ] = lightTriangleNorm.z;
|
||||
|
||||
// The true at the end says the normal is already in world coordinates
|
||||
calc_lighting_contribution(vIndex, tempLightingContribution, true);
|
||||
@@ -2077,25 +2055,25 @@ public class PGraphics3D extends PGraphics {
|
||||
else {
|
||||
if (normalMode == NORMAL_MODE_SHAPE) {
|
||||
vIndex = triangles[triIndex][VERTEX1];
|
||||
vertices[vIndex][NX] = vertices[vertex_start][NX];
|
||||
vertices[vIndex][NY] = vertices[vertex_start][NY];
|
||||
vertices[vIndex][NZ] = vertices[vertex_start][NZ];
|
||||
vertices[vIndex][NX] = vertices[shapeFirst][NX];
|
||||
vertices[vIndex][NY] = vertices[shapeFirst][NY];
|
||||
vertices[vIndex][NZ] = vertices[shapeFirst][NZ];
|
||||
calc_lighting_contribution(vIndex, tempLightingContribution);
|
||||
copy_vertex_color_to_triangle(triIndex, vIndex, 0,
|
||||
tempLightingContribution);
|
||||
|
||||
vIndex = triangles[triIndex][VERTEX2];
|
||||
vertices[vIndex][NX] = vertices[vertex_start][NX];
|
||||
vertices[vIndex][NY] = vertices[vertex_start][NY];
|
||||
vertices[vIndex][NZ] = vertices[vertex_start][NZ];
|
||||
vertices[vIndex][NX] = vertices[shapeFirst][NX];
|
||||
vertices[vIndex][NY] = vertices[shapeFirst][NY];
|
||||
vertices[vIndex][NZ] = vertices[shapeFirst][NZ];
|
||||
calc_lighting_contribution(vIndex, tempLightingContribution);
|
||||
copy_vertex_color_to_triangle(triIndex, vIndex, 1,
|
||||
tempLightingContribution);
|
||||
|
||||
vIndex = triangles[triIndex][VERTEX3];
|
||||
vertices[vIndex][NX] = vertices[vertex_start][NX];
|
||||
vertices[vIndex][NY] = vertices[vertex_start][NY];
|
||||
vertices[vIndex][NZ] = vertices[vertex_start][NZ];
|
||||
vertices[vIndex][NX] = vertices[shapeFirst][NX];
|
||||
vertices[vIndex][NY] = vertices[shapeFirst][NY];
|
||||
vertices[vIndex][NZ] = vertices[shapeFirst][NZ];
|
||||
calc_lighting_contribution(vIndex, tempLightingContribution);
|
||||
copy_vertex_color_to_triangle(triIndex, vIndex, 2,
|
||||
tempLightingContribution);
|
||||
@@ -2124,30 +2102,31 @@ public class PGraphics3D extends PGraphics {
|
||||
vertices[vIndex2][VZ] - vertices[vIndex][VZ],
|
||||
vertices[vIndex3][VX] - vertices[vIndex][VX],
|
||||
vertices[vIndex3][VY] - vertices[vIndex][VY],
|
||||
vertices[vIndex3][VZ] - vertices[vIndex][VZ], norm);
|
||||
float nmag = mag(norm[X], norm[Y], norm[Z]);
|
||||
if (nmag != 0 && nmag != 1) {
|
||||
norm[X] /= nmag; norm[Y] /= nmag; norm[Z] /= nmag;
|
||||
}
|
||||
vertices[vIndex][NX] = norm[X];
|
||||
vertices[vIndex][NY] = norm[Y];
|
||||
vertices[vIndex][NZ] = norm[Z];
|
||||
vertices[vIndex3][VZ] - vertices[vIndex][VZ], lightTriangleNorm);
|
||||
// float nmag = mag(norm[X], norm[Y], norm[Z]);
|
||||
// if (nmag != 0 && nmag != 1) {
|
||||
// norm[X] /= nmag; norm[Y] /= nmag; norm[Z] /= nmag;
|
||||
// }
|
||||
lightTriangleNorm.normalize();
|
||||
vertices[vIndex][NX] = lightTriangleNorm.x;
|
||||
vertices[vIndex][NY] = lightTriangleNorm.y;
|
||||
vertices[vIndex][NZ] = lightTriangleNorm.z;
|
||||
// The true at the end says the normal is already in world coordinates
|
||||
calc_lighting_contribution(vIndex, tempLightingContribution, true);
|
||||
copy_vertex_color_to_triangle(triIndex, vIndex, 0,
|
||||
tempLightingContribution);
|
||||
|
||||
vertices[vIndex2][NX] = norm[X];
|
||||
vertices[vIndex2][NY] = norm[Y];
|
||||
vertices[vIndex2][NZ] = norm[Z];
|
||||
vertices[vIndex2][NX] = lightTriangleNorm.x;
|
||||
vertices[vIndex2][NY] = lightTriangleNorm.y;
|
||||
vertices[vIndex2][NZ] = lightTriangleNorm.z;
|
||||
// The true at the end says the normal is already in world coordinates
|
||||
calc_lighting_contribution(vIndex2, tempLightingContribution, true);
|
||||
copy_vertex_color_to_triangle(triIndex, vIndex2, 1,
|
||||
tempLightingContribution);
|
||||
|
||||
vertices[vIndex3][NX] = norm[X];
|
||||
vertices[vIndex3][NY] = norm[Y];
|
||||
vertices[vIndex3][NZ] = norm[Z];
|
||||
vertices[vIndex3][NX] = lightTriangleNorm.x;
|
||||
vertices[vIndex3][NY] = lightTriangleNorm.y;
|
||||
vertices[vIndex3][NZ] = lightTriangleNorm.z;
|
||||
// The true at the end says the normal is already in world coordinates
|
||||
calc_lighting_contribution(vIndex3, tempLightingContribution, true);
|
||||
copy_vertex_color_to_triangle(triIndex, vIndex3, 2,
|
||||
@@ -2162,7 +2141,7 @@ public class PGraphics3D extends PGraphics {
|
||||
// normal specified for this shape, go ahead and apply the same lighting
|
||||
// contribution to every vertex in this shape (one lighting calc!)
|
||||
if (!lightingDependsOnVertexPosition && normalMode == NORMAL_MODE_SHAPE) {
|
||||
calc_lighting_contribution(vertex_start, tempLightingContribution);
|
||||
calc_lighting_contribution(shapeFirst, tempLightingContribution);
|
||||
for (int tri = 0; tri < triangleCount; tri++) {
|
||||
light_triangle(tri, tempLightingContribution);
|
||||
}
|
||||
@@ -3878,6 +3857,7 @@ public class PGraphics3D extends PGraphics {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
private final void cross(float a0, float a1, float a2,
|
||||
float b0, float b1, float b2,
|
||||
float[] out) {
|
||||
@@ -3885,6 +3865,16 @@ public class PGraphics3D extends PGraphics {
|
||||
out[1] = a2*b0 - a0*b2;
|
||||
out[2] = a0*b1 - a1*b0;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
private final void cross(float a0, float a1, float a2,
|
||||
float b0, float b1, float b2,
|
||||
PVector out) {
|
||||
out.x = a1*b2 - a2*b1;
|
||||
out.y = a2*b0 - a0*b2;
|
||||
out.z = a0*b1 - a1*b0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -52,6 +52,15 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
|
||||
public Graphics2D g2;
|
||||
GeneralPath gpath;
|
||||
|
||||
/// break the shape at the next vertex (next vertex() call is a moveto())
|
||||
boolean breakShape;
|
||||
|
||||
/// coordinates for internal curve calculation
|
||||
float[] curveCoordX = new float[4];
|
||||
float[] curveCoordY = new float[4];
|
||||
float[] curveDrawX = new float[4];
|
||||
float[] curveDrawY = new float[4];
|
||||
|
||||
int transformCount;
|
||||
AffineTransform transformStack[] =
|
||||
new AffineTransform[MATRIX_STACK_DEPTH];
|
||||
@@ -160,7 +169,7 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
|
||||
//super.beginShape(kind);
|
||||
shape = kind;
|
||||
vertexCount = 0;
|
||||
splineVertexCount = 0;
|
||||
curveVertexCount = 0;
|
||||
|
||||
// set gpath to null, because when mixing curves and straight
|
||||
// lines, vertexCount will be set back to zero, so vertexCount == 1
|
||||
@@ -182,7 +191,7 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
|
||||
|
||||
|
||||
public void vertex(float x, float y) {
|
||||
splineVertexCount = 0;
|
||||
curveVertexCount = 0;
|
||||
//float vertex[];
|
||||
|
||||
if (vertexCount == vertices.length) {
|
||||
@@ -303,13 +312,13 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
|
||||
}
|
||||
|
||||
|
||||
public void vertex(float x, float y, float u, float v) {
|
||||
variationError("vertex(x, y, u, v)");
|
||||
public void vertex(float x, float y, float z) {
|
||||
depthErrorXYZ("vertex");
|
||||
}
|
||||
|
||||
|
||||
public void vertex(float x, float y, float z) {
|
||||
depthErrorXYZ("vertex");
|
||||
public void vertex(float x, float y, float u, float v) {
|
||||
variationError("vertex(x, y, u, v)");
|
||||
}
|
||||
|
||||
|
||||
@@ -321,26 +330,60 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
|
||||
public void bezierVertex(float x1, float y1,
|
||||
float x2, float y2,
|
||||
float x3, float y3) {
|
||||
if (gpath == null) {
|
||||
throw new RuntimeException("Must call vertex() at least once " +
|
||||
"before using bezierVertex()");
|
||||
}
|
||||
|
||||
if (shape == POLYGON) {
|
||||
gpath.curveTo(x1, y1, x2, y2, x3, y3);
|
||||
|
||||
} else {
|
||||
throw new RuntimeException("bezierVertex() can only be used with " +
|
||||
"LINE_STRIP, LINE_LOOP, or POLYGON");
|
||||
}
|
||||
bezierVertexCheck();
|
||||
gpath.curveTo(x1, y1, x2, y2, x3, y3);
|
||||
}
|
||||
|
||||
|
||||
float curveCoordX[] = new float[4];
|
||||
float curveCoordY[] = new float[4];
|
||||
float curveDrawX[] = new float[4];
|
||||
float curveDrawY[] = new float[4];
|
||||
public void bezierVertex(float x2, float y2, float z2,
|
||||
float x3, float y3, float z3,
|
||||
float x4, float y4, float z4) {
|
||||
depthErrorXYZ("bezierVertex");
|
||||
}
|
||||
|
||||
|
||||
protected void curveVertexCheck() {
|
||||
super.curveVertexCheck();
|
||||
|
||||
curveCoordX = new float[4];
|
||||
curveCoordY = new float[4];
|
||||
curveDrawX = new float[4];
|
||||
curveDrawY = new float[4];
|
||||
}
|
||||
|
||||
|
||||
protected void curveVertexSegment(float x1, float y1,
|
||||
float x2, float y2,
|
||||
float x3, float y3,
|
||||
float x4, float y4) {
|
||||
curveCoordX[0] = x1;
|
||||
curveCoordY[0] = y1;
|
||||
|
||||
curveCoordX[1] = x2;
|
||||
curveCoordY[1] = y2;
|
||||
|
||||
curveCoordX[2] = x3;
|
||||
curveCoordY[2] = y3;
|
||||
|
||||
curveCoordX[3] = x4;
|
||||
curveCoordY[3] = y4;
|
||||
|
||||
curveToBezierMatrix.mult(curveCoordX, curveDrawX);
|
||||
curveToBezierMatrix.mult(curveCoordY, curveDrawY);
|
||||
|
||||
// since the paths are continuous,
|
||||
// only the first point needs the actual moveto
|
||||
if (gpath == null) {
|
||||
gpath = new GeneralPath();
|
||||
gpath.moveTo(curveDrawX[0], curveDrawY[0]);
|
||||
}
|
||||
|
||||
gpath.curveTo(curveDrawX[1], curveDrawY[1],
|
||||
curveDrawX[2], curveDrawY[2],
|
||||
curveDrawX[3], curveDrawY[3]);
|
||||
}
|
||||
|
||||
/*
|
||||
public void curveVertex(float x, float y) {
|
||||
if (shape != POLYGON) {
|
||||
throw new RuntimeException("curveVertex() can only be used with " +
|
||||
@@ -350,32 +393,32 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
|
||||
curveInitCheck();
|
||||
vertexCount = 0;
|
||||
|
||||
if (splineVertices == null) {
|
||||
splineVertices = new float[DEFAULT_SPLINE_VERTICES][VERTEX_FIELD_COUNT];
|
||||
if (curveVertices == null) {
|
||||
curveVertices = new float[DEFAULT_SPLINE_VERTICES][VERTEX_FIELD_COUNT];
|
||||
}
|
||||
|
||||
// if more than 128 points, shift everything back to the beginning
|
||||
if (splineVertexCount == DEFAULT_SPLINE_VERTICES) {
|
||||
System.arraycopy(splineVertices[DEFAULT_SPLINE_VERTICES - 3], 0,
|
||||
splineVertices[0], 0, VERTEX_FIELD_COUNT);
|
||||
System.arraycopy(splineVertices[DEFAULT_SPLINE_VERTICES - 2], 0,
|
||||
splineVertices[1], 0, VERTEX_FIELD_COUNT);
|
||||
System.arraycopy(splineVertices[DEFAULT_SPLINE_VERTICES - 1], 0,
|
||||
splineVertices[2], 0, VERTEX_FIELD_COUNT);
|
||||
splineVertexCount = 3;
|
||||
if (curveVertexCount == DEFAULT_SPLINE_VERTICES) {
|
||||
System.arraycopy(curveVertices[DEFAULT_SPLINE_VERTICES - 3], 0,
|
||||
curveVertices[0], 0, VERTEX_FIELD_COUNT);
|
||||
System.arraycopy(curveVertices[DEFAULT_SPLINE_VERTICES - 2], 0,
|
||||
curveVertices[1], 0, VERTEX_FIELD_COUNT);
|
||||
System.arraycopy(curveVertices[DEFAULT_SPLINE_VERTICES - 1], 0,
|
||||
curveVertices[2], 0, VERTEX_FIELD_COUNT);
|
||||
curveVertexCount = 3;
|
||||
}
|
||||
|
||||
// this new guy will be the fourth point (or higher),
|
||||
// which means it's time to draw segments of the curve
|
||||
if (splineVertexCount >= 3) {
|
||||
curveCoordX[0] = splineVertices[splineVertexCount-3][X];
|
||||
curveCoordY[0] = splineVertices[splineVertexCount-3][Y];
|
||||
if (curveVertexCount >= 3) {
|
||||
curveCoordX[0] = curveVertices[curveVertexCount-3][X];
|
||||
curveCoordY[0] = curveVertices[curveVertexCount-3][Y];
|
||||
|
||||
curveCoordX[1] = splineVertices[splineVertexCount-2][X];
|
||||
curveCoordY[1] = splineVertices[splineVertexCount-2][Y];
|
||||
curveCoordX[1] = curveVertices[curveVertexCount-2][X];
|
||||
curveCoordY[1] = curveVertices[curveVertexCount-2][Y];
|
||||
|
||||
curveCoordX[2] = splineVertices[splineVertexCount-1][X];
|
||||
curveCoordY[2] = splineVertices[splineVertexCount-1][Y];
|
||||
curveCoordX[2] = curveVertices[curveVertexCount-1][X];
|
||||
curveCoordY[2] = curveVertices[curveVertexCount-1][Y];
|
||||
|
||||
curveCoordX[3] = x;
|
||||
curveCoordY[3] = y;
|
||||
@@ -396,10 +439,11 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
|
||||
}
|
||||
|
||||
// add the current point to the list
|
||||
splineVertices[splineVertexCount][X] = x;
|
||||
splineVertices[splineVertexCount][Y] = y;
|
||||
splineVertexCount++;
|
||||
curveVertices[curveVertexCount][X] = x;
|
||||
curveVertices[curveVertexCount][Y] = y;
|
||||
curveVertexCount++;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public void curveVertex(float x, float y, float z) {
|
||||
@@ -407,7 +451,6 @@ public class PGraphicsJava2D extends PGraphics /*PGraphics2D*/ {
|
||||
}
|
||||
|
||||
|
||||
boolean breakShape;
|
||||
public void breakShape() {
|
||||
breakShape = true;
|
||||
}
|
||||
|
||||
@@ -125,7 +125,9 @@ public class PLine implements PConstants
|
||||
|
||||
m_pixels = parent.pixels;
|
||||
//m_stencil = parent.stencil;
|
||||
m_zbuffer = parent.zbuffer;
|
||||
if (parent instanceof PGraphics3D) {
|
||||
m_zbuffer = ((PGraphics3D) parent).zbuffer;
|
||||
}
|
||||
|
||||
// other things to reset
|
||||
|
||||
|
||||
@@ -389,47 +389,27 @@ public final class PMatrix3D implements PMatrix /*, PConstants*/ {
|
||||
|
||||
|
||||
/**
|
||||
* Multiply a three or four element vector against this matrix.
|
||||
* If out is null or not length four, a new float array will be returned.
|
||||
* The values for vec and out can be the same (though that's less efficient).
|
||||
* 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.
|
||||
*/
|
||||
public float[] mult(float[] source, float[] target) {
|
||||
if (target == null || target.length < 3) {
|
||||
target = new float[3];
|
||||
}
|
||||
if (source == target) {
|
||||
throw new RuntimeException("The source and target vectors used in " +
|
||||
"PMatrix3D.mult() cannot be identical.");
|
||||
}
|
||||
if (target.length == 3) {
|
||||
if (source == target) {
|
||||
float tmpx = m00*source[0] + m01*source[1] + m02*source[2] + m03;
|
||||
float tmpy = m10*source[0] + m11*source[1] + m12*source[2] + m13;
|
||||
float tmpz = m20*source[0] + m21*source[1] + m22*source[2] + m23;
|
||||
|
||||
target[0] = tmpx;
|
||||
target[1] = tmpy;
|
||||
target[2] = tmpz;
|
||||
|
||||
} else {
|
||||
target[0] = m00*source[0] + m01*source[1] + m02*source[2] + m03;
|
||||
target[1] = m10*source[0] + m11*source[1] + m12*source[2] + m13;
|
||||
target[2] = m20*source[0] + m21*source[1] + m22*source[2] + m23;
|
||||
}
|
||||
target[0] = m00*source[0] + m01*source[1] + m02*source[2] + m03;
|
||||
target[1] = m10*source[0] + m11*source[1] + m12*source[2] + m13;
|
||||
target[2] = m20*source[0] + m21*source[1] + m22*source[2] + m23;
|
||||
|
||||
} else if (target.length > 3) {
|
||||
if (source == target) {
|
||||
float tmpx = m00*source[0] + m01*source[1] + m02*source[2] + m03*source[3];
|
||||
float tmpy = m10*source[0] + m11*source[1] + m12*source[2] + m13*source[3];
|
||||
float tmpz = m20*source[0] + m21*source[1] + m22*source[2] + m23*source[3];
|
||||
float tmpw = m30*source[0] + m31*source[1] + m32*source[2] + m33*source[3];
|
||||
|
||||
target[0] = tmpx;
|
||||
target[1] = tmpy;
|
||||
target[2] = tmpz;
|
||||
target[3] = tmpw;
|
||||
|
||||
} else {
|
||||
target[0] = m00*source[0] + m01*source[1] + m02*source[2] + m03*source[3];
|
||||
target[1] = m10*source[0] + m11*source[1] + m12*source[2] + m13*source[3];
|
||||
target[2] = m20*source[0] + m21*source[1] + m22*source[2] + m23*source[3];
|
||||
target[3] = m30*source[0] + m31*source[1] + m32*source[2] + m33*source[3];
|
||||
}
|
||||
target[0] = m00*source[0] + m01*source[1] + m02*source[2] + m03*source[3];
|
||||
target[1] = m10*source[0] + m11*source[1] + m12*source[2] + m13*source[3];
|
||||
target[2] = m20*source[0] + m21*source[1] + m22*source[2] + m23*source[3];
|
||||
target[3] = m30*source[0] + m31*source[1] + m32*source[2] + m33*source[3];
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user