mirror of
https://github.com/processing/processing4.git
synced 2026-06-08 16:40:46 +02:00
android sync
This commit is contained in:
@@ -664,6 +664,122 @@ public class PShape implements PConstants {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The new copy methods to put an SVG into a PShape3D, for example
|
||||
|
||||
public PShape copy(PGraphics g) {
|
||||
PShape res = null;
|
||||
if (family == GROUP) {
|
||||
res = g.createShape(GROUP);
|
||||
copyGroup(g, res);
|
||||
} else if (family == PRIMITIVE) {
|
||||
res = g.createShape(kind, params);
|
||||
copyPrimitive(res);
|
||||
} else if (family == GEOMETRY) {
|
||||
res = g.createShape(kind);
|
||||
copyGeometry(res);
|
||||
} else if (family == PATH) {
|
||||
res = g.createShape(PATH);
|
||||
copyPath(res);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
protected void copyGroup(PGraphics g, PShape s) {
|
||||
if (matrix != null) {
|
||||
s.applyMatrix(matrix);
|
||||
}
|
||||
copyStyles(s);
|
||||
copyImage(s);
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
PShape c = children[i].copy(g);
|
||||
s.addChild(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void copyPrimitive(PShape s) {
|
||||
if (matrix != null) {
|
||||
s.applyMatrix(matrix);
|
||||
}
|
||||
copyStyles(s);
|
||||
copyImage(s);
|
||||
}
|
||||
|
||||
protected void copyGeometry(PShape s) {
|
||||
if (matrix != null) {
|
||||
s.applyMatrix(matrix);
|
||||
}
|
||||
copyStyles(s);
|
||||
copyImage(s);
|
||||
|
||||
if (style) {
|
||||
for (int i = 0; i < vertexCount; i++) {
|
||||
float[] vert = vertices[i];
|
||||
// s.ambient(vert[AR] * 255, vert[AG] * 255, vert[AB] * 255);
|
||||
// s.specular(vert[SPR] * 255, vert[SPG] * 255, vert[SPB] * 255);
|
||||
// s.emissive(vert[ER] * 255, vert[EG] * 255, vert[EB] * 255);
|
||||
// s.shininess(vert[SHINE]);
|
||||
|
||||
s.normal(vert[NX], vert[NY], vert[NZ]);
|
||||
s.vertex(vert[X], vert[Y], vert[Z], vert[U], vert[V]);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < vertexCount; i++) {
|
||||
float[] vert = vertices[i];
|
||||
if (vert[PGraphics.Z] == 0) {
|
||||
s.vertex(vert[X], vert[Y]);
|
||||
} else {
|
||||
s.vertex(vert[X], vert[Y], vert[Z]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s.end();
|
||||
}
|
||||
|
||||
protected void copyPath(PShape s) {
|
||||
if (matrix != null) {
|
||||
s.applyMatrix(matrix);
|
||||
}
|
||||
copyStyles(s);
|
||||
copyImage(s);
|
||||
s.close = close;
|
||||
s.setPath(vertexCount, vertices, vertexCodeCount, vertexCodes);
|
||||
|
||||
}
|
||||
|
||||
protected void copyStyles(PShape s) {
|
||||
if (stroke) {
|
||||
s.stroke = true;
|
||||
s.strokeColor = strokeColor;
|
||||
s.strokeWeight = strokeWeight;
|
||||
s.strokeCap = strokeCap;
|
||||
s.strokeJoin = strokeJoin;
|
||||
} else {
|
||||
s.stroke = false;
|
||||
}
|
||||
|
||||
if (fill) {
|
||||
s.fill = true;
|
||||
s.fillColor = fillColor;
|
||||
} else {
|
||||
s.fill = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void copyImage(PShape s) {
|
||||
if (image != null) {
|
||||
s.texture(image);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* Called by the following (the shape() command adds the g)
|
||||
@@ -1143,42 +1259,27 @@ public class PShape implements PConstants {
|
||||
}
|
||||
|
||||
|
||||
public void setPath(float[][] coords) {
|
||||
setPath(coords, null);
|
||||
public void setPath(int vcount, float[][] verts) {
|
||||
setPath(vcount, verts, 0, null);
|
||||
}
|
||||
|
||||
|
||||
public void setPath(float[][] coords, int[] codes) {
|
||||
if (coords == null || coords.length == 0) return;
|
||||
|
||||
if (codes == null || codes.length == 0) {
|
||||
vertexCodeCount = 0;
|
||||
} else {
|
||||
if (codes.length != coords.length) {
|
||||
PGraphics.showWarning("Wrong number of vertex codes");
|
||||
return;
|
||||
}
|
||||
vertexCodeCount = codes.length;
|
||||
}
|
||||
public void setPath(int vcount, float[][] verts, int ccount, int[] codes) {
|
||||
if (verts == null || verts.length < vcount) return;
|
||||
if (0 < ccount && (codes == null || codes.length < ccount)) return;
|
||||
|
||||
int ncoords = coords[0].length;
|
||||
|
||||
if (vertices == null ||
|
||||
vertices.length != coords.length ||
|
||||
vertices[0].length != ncoords) {
|
||||
vertices = new float[coords.length][ncoords];
|
||||
}
|
||||
|
||||
for (int i = 0; i < coords.length; i++) {
|
||||
PApplet.arrayCopy(coords[i], vertices[i]);
|
||||
}
|
||||
|
||||
int ndim = verts[0].length;
|
||||
vertexCount = vcount;
|
||||
vertices = new float[vertexCount][ndim];
|
||||
for (int i = 0; i < vertexCount; i++) {
|
||||
PApplet.arrayCopy(verts[i], vertices[i]);
|
||||
}
|
||||
|
||||
vertexCodeCount = ccount;
|
||||
if (0 < vertexCodeCount) {
|
||||
if (vertexCodes == null || vertexCodes.length != vertexCodeCount) {
|
||||
vertexCodes = new int[vertexCodeCount];
|
||||
}
|
||||
PApplet.arrayCopy(codes, vertexCodes);
|
||||
}
|
||||
vertexCodes = new int[vertexCodeCount];
|
||||
PApplet.arrayCopy(codes, vertexCodes, vertexCodeCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,7 +27,23 @@ public class PGraphics2D extends PGraphicsOpenGL {
|
||||
|
||||
public PGraphics2D() {
|
||||
super();
|
||||
hints[ENABLE_ACCURATE_2D] = true;
|
||||
//hints[ENABLE_ACCURATE_2D] = true;
|
||||
hints[ENABLE_PERSPECTIVE_CORRECTED_LINES] = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this renderer supports 2D drawing. Defaults to true.
|
||||
*/
|
||||
public boolean is2D() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if this renderer supports 2D drawing. Defaults to false.
|
||||
*/
|
||||
public boolean is3D() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import java.nio.*;
|
||||
import java.util.*;
|
||||
|
||||
import processing.core.*;
|
||||
import processing.opengl.geom.LinePath;
|
||||
|
||||
|
||||
// drawPixels is missing...calls to glDrawPixels are commented out
|
||||
@@ -361,10 +362,15 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
protected boolean defaultEdges = false;
|
||||
protected PImage textureImage0;
|
||||
|
||||
static protected final int EDGE_MIDDLE = 0;
|
||||
static protected final int EDGE_START = 1;
|
||||
static protected final int EDGE_STOP = 2;
|
||||
static protected final int EDGE_SINGLE = 3;
|
||||
|
||||
protected boolean perspectiveCorrectedLines = false;
|
||||
|
||||
/** Used in point tessellation. */
|
||||
final static protected int MIN_POINT_ACCURACY = 6;
|
||||
final static protected int MIN_POINT_ACCURACY = 20;
|
||||
final protected float[][] QUAD_POINT_SIGNS = { {-1, +1}, {-1, -1}, {+1, -1}, {+1, +1} };
|
||||
|
||||
|
||||
@@ -1937,6 +1943,8 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
PShape3D shape = null;
|
||||
if (type == PShape.GROUP) {
|
||||
shape = new PShape3D(parent, PShape.GROUP);
|
||||
} else if (type == PShape.PATH) {
|
||||
shape = new PShape3D(parent, PShape.PATH);
|
||||
} else if (type == POINTS) {
|
||||
shape = new PShape3D(parent, PShape.GEOMETRY);
|
||||
shape.setKind(POINTS);
|
||||
@@ -4661,6 +4669,12 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
// Initializes the pixels array, copying the current contents of the
|
||||
// color buffer into it.
|
||||
public void loadPixels() {
|
||||
boolean needEndDraw = false;
|
||||
if (!drawing) {
|
||||
beginDraw();
|
||||
needEndDraw = true;
|
||||
}
|
||||
|
||||
if (!setgetPixels) {
|
||||
// Draws any remaining geometry in case the user is still not
|
||||
// setting/getting new pixels.
|
||||
@@ -4677,6 +4691,10 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
pixelsToTexture();
|
||||
}
|
||||
}
|
||||
|
||||
if (needEndDraw) {
|
||||
endDraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7627,6 +7645,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
begin = true;
|
||||
} else if (!breaks[i1]) {
|
||||
addEdge(i0, i1, begin, false);
|
||||
begin = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7972,10 +7991,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
float sx2 = screenX(x + w, y + h);
|
||||
float sy2 = screenY(x + w, y + h);
|
||||
|
||||
int accuracy = (int) (TWO_PI * PApplet.dist(sx1, sy1, sx2, sy2) / 20);
|
||||
if (accuracy < 6) {
|
||||
accuracy = 6;
|
||||
}
|
||||
int accuracy = PApplet.max(MIN_POINT_ACCURACY, (int) (TWO_PI * PApplet.dist(sx1, sy1, sx2, sy2) / 20));
|
||||
float inc = (float) PGraphicsOpenGL.SINCOS_LENGTH / accuracy;
|
||||
|
||||
if (fill) {
|
||||
@@ -8550,18 +8566,18 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
void getLineVertexMin(PVector v, int first, int last) {
|
||||
for (int i = first; i <= last; i++) {
|
||||
int index = 4 * i;
|
||||
v.x += PApplet.min(v.x, lineVertices[index++]);
|
||||
v.y += PApplet.min(v.y, lineVertices[index++]);
|
||||
v.z += PApplet.min(v.z, lineVertices[index ]);
|
||||
v.x = PApplet.min(v.x, lineVertices[index++]);
|
||||
v.y = PApplet.min(v.y, lineVertices[index++]);
|
||||
v.z = PApplet.min(v.z, lineVertices[index ]);
|
||||
}
|
||||
}
|
||||
|
||||
void getPointVertexMin(PVector v, int first, int last) {
|
||||
for (int i = first; i <= last; i++) {
|
||||
int index = 4 * i;
|
||||
v.x += PApplet.min(v.x, pointVertices[index++]);
|
||||
v.y += PApplet.min(v.y, pointVertices[index++]);
|
||||
v.z += PApplet.min(v.z, pointVertices[index ]);
|
||||
v.x = PApplet.min(v.x, pointVertices[index++]);
|
||||
v.y = PApplet.min(v.y, pointVertices[index++]);
|
||||
v.z = PApplet.min(v.z, pointVertices[index ]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8577,18 +8593,18 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
void getLineVertexMax(PVector v, int first, int last) {
|
||||
for (int i = first; i <= last; i++) {
|
||||
int index = 4 * i;
|
||||
v.x += PApplet.max(v.x, lineVertices[index++]);
|
||||
v.y += PApplet.max(v.y, lineVertices[index++]);
|
||||
v.z += PApplet.max(v.z, lineVertices[index ]);
|
||||
v.x = PApplet.max(v.x, lineVertices[index++]);
|
||||
v.y = PApplet.max(v.y, lineVertices[index++]);
|
||||
v.z = PApplet.max(v.z, lineVertices[index ]);
|
||||
}
|
||||
}
|
||||
|
||||
void getPointVertexMax(PVector v, int first, int last) {
|
||||
for (int i = first; i <= last; i++) {
|
||||
int index = 4 * i;
|
||||
v.x += PApplet.max(v.x, pointVertices[index++]);
|
||||
v.y += PApplet.max(v.y, pointVertices[index++]);
|
||||
v.z += PApplet.max(v.z, pointVertices[index ]);
|
||||
v.x = PApplet.max(v.x, pointVertices[index++]);
|
||||
v.y = PApplet.max(v.y, pointVertices[index++]);
|
||||
v.z = PApplet.max(v.z, pointVertices[index ]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9548,6 +9564,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
}
|
||||
lastPointIndexCache = index;
|
||||
|
||||
// NEW TESSMAP API
|
||||
// if (tess.renderMode == RETAINED) {
|
||||
// in.addPointMapping(in.firstVertex, in.lastVertex, tess.firstPointVertex, nPtVert);
|
||||
// }
|
||||
@@ -9620,6 +9637,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
}
|
||||
lastPointIndexCache = index;
|
||||
|
||||
// NEW TESSMAP API
|
||||
// if (tess.renderMode == RETAINED) {
|
||||
// in.addPointMapping(in.firstVertex, in.lastVertex, tess.firstPointVertex, 5);
|
||||
// }
|
||||
@@ -9632,57 +9650,82 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
|
||||
void tessellateLines() {
|
||||
int nInVert = in.lastVertex - in.firstVertex + 1;
|
||||
|
||||
|
||||
if (stroke && 2 <= nInVert) {
|
||||
int lineCount = nInVert / 2;
|
||||
int first = in.firstVertex;
|
||||
|
||||
// Lines are made up of 4 vertices defining the quad.
|
||||
// Each vertex has its own offset representing the stroke weight.
|
||||
int nvert = lineCount * 4;
|
||||
// Each stroke line has 4 vertices, defining 2 triangles, which
|
||||
// require 3 indices to specify their connectivities.
|
||||
int nind = lineCount * 2 * 3;
|
||||
|
||||
tess.lineVertexCheck(nvert);
|
||||
tess.lineIndexCheck(nind);
|
||||
int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : tess.lineIndexCache.getLast();
|
||||
firstLineIndexCache = index;
|
||||
for (int ln = 0; ln < lineCount; ln++) {
|
||||
int i0 = first + 2 * ln + 0;
|
||||
int i1 = first + 2 * ln + 1;
|
||||
index = addLine(i0, i1, index, false);
|
||||
}
|
||||
lastLineIndexCache = index;
|
||||
|
||||
if (is3D()) {
|
||||
// Lines are made up of 4 vertices defining the quad.
|
||||
// Each vertex has its own offset representing the stroke weight.
|
||||
int nvert = lineCount * 4;
|
||||
// Each stroke line has 4 vertices, defining 2 triangles, which
|
||||
// require 3 indices to specify their connectivities.
|
||||
int nind = lineCount * 2 * 3;
|
||||
|
||||
tess.lineVertexCheck(nvert);
|
||||
tess.lineIndexCheck(nind);
|
||||
int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : tess.lineIndexCache.getLast();
|
||||
firstLineIndexCache = index;
|
||||
for (int ln = 0; ln < lineCount; ln++) {
|
||||
int i0 = first + 2 * ln + 0;
|
||||
int i1 = first + 2 * ln + 1;
|
||||
index = addLine(i0, i1, index, false);
|
||||
}
|
||||
lastLineIndexCache = index;
|
||||
|
||||
// NEW TESSMAP API
|
||||
// if (tess.renderMode == RETAINED) {
|
||||
// addLineMapping(in.firstVertex, in.lastVertex);
|
||||
// }
|
||||
} else {
|
||||
// 2D renderer, the stroke geometry is stored in the fill array for accurate depth sorting
|
||||
LinePath path = new LinePath(LinePath.WIND_NON_ZERO);
|
||||
for (int ln = 0; ln < lineCount; ln++) {
|
||||
int i0 = first + 2 * ln + 0;
|
||||
int i1 = first + 2 * ln + 1;
|
||||
path.moveTo(inGeo.vertices[4 * i0 + 0], inGeo.vertices[4 * i0 + 1]);
|
||||
path.lineTo(inGeo.vertices[4 * i1 + 0], inGeo.vertices[4 * i1 + 1]);
|
||||
}
|
||||
tessellateLinePath(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tessellateLineStrip() {
|
||||
int nInVert = in.lastVertex - in.firstVertex + 1;
|
||||
|
||||
int lineCount = nInVert - 1;
|
||||
|
||||
if (stroke && 2 <= nInVert) {
|
||||
int lineCount = nInVert - 1;
|
||||
int nvert = lineCount * 4;
|
||||
int nind = lineCount * 2 * 3;
|
||||
tess.lineVertexCheck(nvert);
|
||||
tess.lineIndexCheck(nind);
|
||||
int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : tess.lineIndexCache.getLast();
|
||||
firstLineIndexCache = index;
|
||||
int i0 = in.firstVertex;
|
||||
for (int ln = 0; ln < lineCount; ln++) {
|
||||
int i1 = in.firstVertex + ln + 1;
|
||||
index = addLine(i0, i1, index, false);
|
||||
i0 = i1;
|
||||
}
|
||||
lastLineIndexCache = index;
|
||||
|
||||
// if (tess.renderMode == RETAINED) {
|
||||
// addLineMapping(in.firstVertex, in.lastVertex);
|
||||
// }
|
||||
if (is3D()) {
|
||||
int nvert = lineCount * 4;
|
||||
int nind = lineCount * 2 * 3;
|
||||
tess.lineVertexCheck(nvert);
|
||||
tess.lineIndexCheck(nind);
|
||||
int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : tess.lineIndexCache.getLast();
|
||||
firstLineIndexCache = index;
|
||||
int i0 = in.firstVertex;
|
||||
for (int ln = 0; ln < lineCount; ln++) {
|
||||
int i1 = in.firstVertex + ln + 1;
|
||||
index = addLine(i0, i1, index, false);
|
||||
i0 = i1;
|
||||
}
|
||||
lastLineIndexCache = index;
|
||||
|
||||
// NEW TESSMAP API
|
||||
// if (tess.renderMode == RETAINED) {
|
||||
// addLineMapping(in.firstVertex, in.lastVertex);
|
||||
// }
|
||||
} else {
|
||||
// 2D renderer, the stroke geometry is stored in the fill array for accurate depth sorting
|
||||
int first = in.firstVertex;
|
||||
LinePath path = new LinePath(LinePath.WIND_NON_ZERO);
|
||||
path.moveTo(inGeo.vertices[4 * first + 0], inGeo.vertices[4 * first + 1]);
|
||||
for (int ln = 0; ln < lineCount; ln++) {
|
||||
int i1 = first + ln + 1;
|
||||
path.lineTo(inGeo.vertices[4 * i1 + 0], inGeo.vertices[4 * i1 + 1]);
|
||||
}
|
||||
tessellateLinePath(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9691,47 +9734,119 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
|
||||
if (stroke && 2 <= nInVert) {
|
||||
int lineCount = nInVert;
|
||||
int nvert = lineCount * 4;
|
||||
int nind = lineCount * 2 * 3;
|
||||
tess.lineVertexCheck(nvert);
|
||||
tess.lineIndexCheck(nind);
|
||||
int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : tess.lineIndexCache.getLast();
|
||||
firstLineIndexCache = index;
|
||||
int i0 = in.firstVertex;
|
||||
for (int ln = 0; ln < lineCount - 1; ln++) {
|
||||
int i1 = in.firstVertex + ln + 1;
|
||||
index = addLine(i0, i1, index, false);
|
||||
i0 = i1;
|
||||
if (is3D()) {
|
||||
int nvert = lineCount * 4;
|
||||
int nind = lineCount * 2 * 3;
|
||||
tess.lineVertexCheck(nvert);
|
||||
tess.lineIndexCheck(nind);
|
||||
int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : tess.lineIndexCache.getLast();
|
||||
firstLineIndexCache = index;
|
||||
int i0 = in.firstVertex;
|
||||
for (int ln = 0; ln < lineCount - 1; ln++) {
|
||||
int i1 = in.firstVertex + ln + 1;
|
||||
index = addLine(i0, i1, index, false);
|
||||
i0 = i1;
|
||||
}
|
||||
index = addLine(in.lastVertex, in.firstVertex, index, false);
|
||||
lastLineIndexCache = index;
|
||||
|
||||
// NEW TESSMAP API
|
||||
// if (tess.renderMode == RETAINED) {
|
||||
// addLineMapping(in.firstVertex, in.lastVertex);
|
||||
// }
|
||||
} else {
|
||||
// 2D renderer, the stroke geometry is stored in the fill array for accurate depth sorting
|
||||
int first = in.firstVertex;
|
||||
LinePath path = new LinePath(LinePath.WIND_NON_ZERO);
|
||||
path.moveTo(inGeo.vertices[4 * first + 0], inGeo.vertices[4 * first + 1]);
|
||||
for (int ln = 0; ln < lineCount - 1; ln++) {
|
||||
int i1 = first + ln + 1;
|
||||
path.lineTo(inGeo.vertices[4 * i1 + 0], inGeo.vertices[4 * i1 + 1]);
|
||||
}
|
||||
path.closePath();
|
||||
tessellateLinePath(path);
|
||||
}
|
||||
index = addLine(in.lastVertex, in.firstVertex, index, false);
|
||||
lastLineIndexCache = index;
|
||||
|
||||
// if (tess.renderMode == RETAINED) {
|
||||
// addLineMapping(in.firstVertex, in.lastVertex);
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void tessellateEdges() {
|
||||
if (stroke) {
|
||||
int nInVert = in.getNumLineVertices();
|
||||
int nInInd = in.getNumLineIndices();
|
||||
if (is3D()) {
|
||||
int nInVert = in.getNumLineVertices();
|
||||
int nInInd = in.getNumLineIndices();
|
||||
|
||||
tess.lineVertexCheck(nInVert);
|
||||
tess.lineIndexCheck(nInInd);
|
||||
int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : tess.lineIndexCache.getLast();
|
||||
firstLineIndexCache = index;
|
||||
for (int i = in.firstEdge; i <= in.lastEdge; i++) {
|
||||
int[] edge = in.edges[i];
|
||||
index = addLine(edge[0], edge[1], index, true);
|
||||
tess.lineVertexCheck(nInVert);
|
||||
tess.lineIndexCheck(nInInd);
|
||||
int index = in.renderMode == RETAINED ? tess.lineIndexCache.addNew() : tess.lineIndexCache.getLast();
|
||||
firstLineIndexCache = index;
|
||||
for (int i = in.firstEdge; i <= in.lastEdge; i++) {
|
||||
int[] edge = in.edges[i];
|
||||
index = addLine(edge[0], edge[1], index, true);
|
||||
}
|
||||
lastLineIndexCache = index;
|
||||
|
||||
// NEW TESSMAP API
|
||||
// if (tess.renderMode == RETAINED) {
|
||||
// addLineMapping(in.firstVertex, in.lastVertex);
|
||||
// }
|
||||
} else {
|
||||
// 2D renderer, the stroke geometry is stored in the fill array for accurate depth sorting
|
||||
LinePath path = new LinePath(LinePath.WIND_NON_ZERO);
|
||||
for (int i = in.firstEdge; i <= in.lastEdge; i++) {
|
||||
int[] edge = in.edges[i];
|
||||
int i0 = edge[0];
|
||||
int i1 = edge[1];
|
||||
switch (edge[2]) {
|
||||
case EDGE_MIDDLE:
|
||||
path.lineTo(inGeo.vertices[4 * i1 + 0], inGeo.vertices[4 * i1 + 1]);
|
||||
break;
|
||||
case EDGE_START:
|
||||
path.moveTo(inGeo.vertices[4 * i0 + 0], inGeo.vertices[4 * i0 + 1]);
|
||||
path.lineTo(inGeo.vertices[4 * i1 + 0], inGeo.vertices[4 * i1 + 1]);
|
||||
break;
|
||||
case EDGE_STOP:
|
||||
path.lineTo(inGeo.vertices[4 * i1 + 0], inGeo.vertices[4 * i1 + 1]);
|
||||
path.closePath();
|
||||
break;
|
||||
case EDGE_SINGLE:
|
||||
path.moveTo(inGeo.vertices[4 * i0 + 0], inGeo.vertices[4 * i0 + 1]);
|
||||
path.lineTo(inGeo.vertices[4 * i1 + 0], inGeo.vertices[4 * i1 + 1]);
|
||||
path.closePath();
|
||||
break;
|
||||
}
|
||||
}
|
||||
tessellateLinePath(path);
|
||||
}
|
||||
lastLineIndexCache = index;
|
||||
|
||||
// if (tess.renderMode == RETAINED) {
|
||||
// addLineMapping(in.firstVertex, in.lastVertex);
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
// tessGeo.firstLineIndex = tessGeo.fillIndexCount;
|
||||
// tessGeo.addFillVertices(inGeo.getNumLineVertices());
|
||||
// tessGeo.addFillIndices(inGeo.getNumLineIndices());
|
||||
// tessGeo.lastLineIndex = tessGeo.fillIndexCount - 1;
|
||||
// int vcount = tessGeo.firstFillVertex;
|
||||
// int icount = tessGeo.firstFillIndex;
|
||||
// for (int i = inGeo.firstEdge; i <= inGeo.lastEdge; i++) {
|
||||
// int[] edge = inGeo.edges[i];
|
||||
// addLineToFill(edge[0], edge[1], vcount, icount); vcount += 4; icount += 6;
|
||||
// }
|
||||
|
||||
// Not using the fancy path tessellation in 2D because it slows down things
|
||||
// significantly (it also calls the GLU tessellator).
|
||||
// It generates the right caps and joins, though.
|
||||
|
||||
// GeneralPath path = new GeneralPath(GeneralPath.WIND_NON_ZERO);
|
||||
// for (int i = inGeo.firstEdge; i <= inGeo.lastEdge; i++) {
|
||||
// int[] edge = inGeo.edges[i];
|
||||
// if (startEdge(edge[2])) path.moveTo(inGeo.getVertexX(edge[0]), inGeo.getVertexY(edge[0]));
|
||||
// path.lineTo(inGeo.getVertexX(edge[1]), inGeo.getVertexY(edge[1]));
|
||||
// if (endEdge(edge[2])) path.closePath();
|
||||
// }
|
||||
// tessGeo.firstLineIndex = tessGeo.fillIndexCount;
|
||||
// tessellatePath(path);
|
||||
// tessGeo.lastLineIndex = tessGeo.fillIndexCount - 1;
|
||||
}
|
||||
|
||||
// Adding the data that defines a quad starting at vertex i0 and
|
||||
@@ -9774,6 +9889,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
tess.putLineVertex(in, i1, i0, vidx, color, +weight/2);
|
||||
tess.lineIndices[iidx++] = (short) (count + 3);
|
||||
|
||||
// NEW TESSMAP API
|
||||
// if (tess.renderMode == RETAINED) {
|
||||
// in.setLineMapping(i0, i1, vidx - 4);
|
||||
// }
|
||||
@@ -10031,6 +10147,7 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
void tessellatePolygon(boolean solid, boolean closed, boolean calcNormals) {
|
||||
int nInVert = in.lastVertex - in.firstVertex + 1;
|
||||
|
||||
// NEW TESSMAP API
|
||||
// if (tess.renderMode == RETAINED) {
|
||||
// in.addWeightedMapping(in.firstVertex, in.lastVertex);
|
||||
// }
|
||||
@@ -10097,8 +10214,91 @@ public class PGraphicsOpenGL extends PGraphics {
|
||||
}
|
||||
|
||||
tessellateEdges();
|
||||
}
|
||||
|
||||
// Tessellates the path given as parameter. This will work only in 2D.
|
||||
// Based on the opengl stroke hack described here:
|
||||
// http://wiki.processing.org/w/Stroke_attributes_in_OpenGL
|
||||
public void tessellateLinePath(LinePath path) {
|
||||
firstFillIndexCache = Integer.MAX_VALUE;
|
||||
callback.calcNormals = true;
|
||||
|
||||
int cap = strokeCap == ROUND ? LinePath.CAP_ROUND :
|
||||
strokeCap == PROJECT ? LinePath.CAP_SQUARE :
|
||||
LinePath.CAP_BUTT;
|
||||
int join = strokeJoin == ROUND ? LinePath.JOIN_ROUND :
|
||||
strokeJoin == BEVEL ? LinePath.JOIN_BEVEL :
|
||||
LinePath.JOIN_MITER;
|
||||
|
||||
// Make the outline of the stroke from the path
|
||||
LinePath strokedPath = LinePath.createStrokedPath(path, strokeWeight, cap, join);
|
||||
|
||||
gluTess.beginPolygon();
|
||||
|
||||
double[] vertex;
|
||||
float[] coords = new float[6];
|
||||
|
||||
LinePath.PathIterator iter = strokedPath.getPathIterator();
|
||||
int rule = iter.getWindingRule();
|
||||
switch(rule) {
|
||||
case LinePath.WIND_EVEN_ODD:
|
||||
gluTess.setWindingRule(PGL.GLU_TESS_WINDING_ODD);
|
||||
break;
|
||||
case LinePath.WIND_NON_ZERO:
|
||||
gluTess.setWindingRule(PGL.GLU_TESS_WINDING_NONZERO);
|
||||
break;
|
||||
}
|
||||
|
||||
while (!iter.isDone()) {
|
||||
float sr = 0;
|
||||
float sg = 0;
|
||||
float sb = 0;
|
||||
float sa = 0;
|
||||
|
||||
switch (iter.currentSegment(coords)) {
|
||||
|
||||
case LinePath.SEG_MOVETO:
|
||||
gluTess.beginContour();
|
||||
|
||||
case LinePath.SEG_LINETO:
|
||||
sa = (strokeColor >> 24) & 0xFF;
|
||||
sr = (strokeColor >> 16) & 0xFF;
|
||||
sg = (strokeColor >> 8) & 0xFF;
|
||||
sb = (strokeColor >> 0) & 0xFF;
|
||||
|
||||
// Vertex data includes coordinates, colors, normals, texture coordinates, and material properties.
|
||||
vertex = new double[] { coords[0], coords[1], 0,
|
||||
sa, sr, sg, sb,
|
||||
0, 0, 1,
|
||||
0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 1.0 }; // what about i!!!!!!!!!!!
|
||||
|
||||
gluTess.addVertex(vertex);
|
||||
|
||||
break;
|
||||
case LinePath.SEG_CLOSE:
|
||||
gluTess.endContour();
|
||||
break;
|
||||
}
|
||||
iter.next();
|
||||
}
|
||||
gluTess.endPolygon();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
|
||||
// Interenting notes about using the GLU tessellator to render thick polylines:
|
||||
// http://stackoverflow.com/questions/687173/how-do-i-render-thick-2d-lines-as-polygons
|
||||
//
|
||||
// "...Since I disliked the tesselator API I lifted the tesselation code from the free
|
||||
// SGI OpenGL reference implementation, rewrote the entire front-end and added memory
|
||||
// pools to get the number of allocations down. It took two days to do this, but it was
|
||||
// well worth it (like factor five performance improvement)..."
|
||||
//
|
||||
// This C implementation of GLU could be useful:
|
||||
// http://code.google.com/p/glues/
|
||||
// to eventually come up with an optimized GLU tessellator in native code.
|
||||
protected class TessellatorCallback implements PGL.TessellatorCallback {
|
||||
boolean calcNormals;
|
||||
IndexCache cache;
|
||||
|
||||
@@ -32,16 +32,6 @@ import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
|
||||
//Notes about geometry update in PShape3D.
|
||||
//1) When applying a transformation on a group shape
|
||||
// check if it is more efficient to apply as a gl
|
||||
// transformation on all the childs, instead of
|
||||
// propagating the transformation downwards in order
|
||||
// to calculate the transformation matrices.
|
||||
//2) Change the transformation logic, so the matrix is applied
|
||||
// on the values stored in the vertex cache and not on the
|
||||
// tessellated vertices.
|
||||
|
||||
/**
|
||||
* This class holds a 3D model composed of vertices, normals, colors (per vertex) and
|
||||
* texture coordinates (also per vertex). All this data is stored in Vertex Buffer Objects
|
||||
@@ -54,7 +44,7 @@ import java.util.HashSet;
|
||||
* Other formats to consider:
|
||||
* AMF: http://en.wikipedia.org/wiki/Additive_Manufacturing_File_Format
|
||||
* STL: http://en.wikipedia.org/wiki/STL_(file_format)
|
||||
* OFF: http://en.wikipedia.org/wiki/STL_(file_format)
|
||||
* OFF: http://people.sc.fsu.edu/~jburkardt/data/off/off.html(file_format)
|
||||
* DXF: http://en.wikipedia.org/wiki/AutoCAD_DXF
|
||||
*/
|
||||
public class PShape3D extends PShape {
|
||||
@@ -470,7 +460,7 @@ public class PShape3D extends PShape {
|
||||
PVector max = new PVector(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY);
|
||||
if (shapeEnded) {
|
||||
getVertexMin(min);
|
||||
getVertexMin(max);
|
||||
getVertexMax(max);
|
||||
}
|
||||
width = max.x - min.x;
|
||||
return width;
|
||||
@@ -482,9 +472,9 @@ public class PShape3D extends PShape {
|
||||
PVector max = new PVector(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY);
|
||||
if (shapeEnded) {
|
||||
getVertexMin(min);
|
||||
getVertexMin(max);
|
||||
getVertexMax(max);
|
||||
}
|
||||
width = max.y - min.y;
|
||||
height = max.y - min.y;
|
||||
return height;
|
||||
}
|
||||
|
||||
@@ -494,9 +484,9 @@ public class PShape3D extends PShape {
|
||||
PVector max = new PVector(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY);
|
||||
if (shapeEnded) {
|
||||
getVertexMin(min);
|
||||
getVertexMin(max);
|
||||
getVertexMax(max);
|
||||
}
|
||||
width = max.z - min.z;
|
||||
depth = max.z - min.z;
|
||||
return depth;
|
||||
}
|
||||
|
||||
@@ -517,59 +507,53 @@ public class PShape3D extends PShape {
|
||||
|
||||
|
||||
protected void getVertexMin(PVector min) {
|
||||
updateTessellation();
|
||||
|
||||
if (family == GROUP) {
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
PShape3D child = (PShape3D) children[i];
|
||||
child.getVertexMin(min);
|
||||
child.getVertexMin(min);
|
||||
}
|
||||
} else {
|
||||
if (tessellated) {
|
||||
if (haveFill) tessGeo.getFillVertexMin(min, firstFillVertex, lastFillVertex);
|
||||
if (haveLines) tessGeo.getLineVertexMin(min, firstLineVertex, lastLineVertex);
|
||||
if (havePoints) tessGeo.getPointVertexMin(min, firstPointVertex, lastPointVertex);
|
||||
} else {
|
||||
inGeo.getVertexMin(min);
|
||||
}
|
||||
if (haveFill) tessGeo.getFillVertexMin(min, firstFillVertex, lastFillVertex);
|
||||
if (haveLines) tessGeo.getLineVertexMin(min, firstLineVertex, lastLineVertex);
|
||||
if (havePoints) tessGeo.getPointVertexMin(min, firstPointVertex, lastPointVertex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void getVertexMax(PVector max) {
|
||||
updateTessellation();
|
||||
|
||||
if (family == GROUP) {
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
PShape3D child = (PShape3D) children[i];
|
||||
child.getVertexMax(max);
|
||||
}
|
||||
} else {
|
||||
if (tessellated) {
|
||||
if (haveFill) tessGeo.getFillVertexMax(max, firstFillVertex, lastFillVertex);
|
||||
if (haveLines) tessGeo.getLineVertexMax(max, firstLineVertex, lastLineVertex);
|
||||
if (havePoints) tessGeo.getPointVertexMax(max, firstPointVertex, lastPointVertex);
|
||||
} else {
|
||||
inGeo.getVertexMax(max);
|
||||
}
|
||||
if (haveFill) tessGeo.getFillVertexMax(max, firstFillVertex, lastFillVertex);
|
||||
if (haveLines) tessGeo.getLineVertexMax(max, firstLineVertex, lastLineVertex);
|
||||
if (havePoints) tessGeo.getPointVertexMax(max, firstPointVertex, lastPointVertex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected int getVertexSum(PVector sum, int count) {
|
||||
updateTessellation();
|
||||
|
||||
if (family == GROUP) {
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
PShape3D child = (PShape3D) children[i];
|
||||
count += child.getVertexSum(sum, count);
|
||||
}
|
||||
} else {
|
||||
if (tessellated) {
|
||||
if (haveFill) count += tessGeo.getFillVertexSum(sum, firstFillVertex, lastFillVertex);
|
||||
if (haveLines) count += tessGeo.getLineVertexSum(sum, firstLineVertex, lastLineVertex);
|
||||
if (havePoints) count += tessGeo.getPointVertexSum(sum, firstPointVertex, lastPointVertex);
|
||||
} else {
|
||||
count += inGeo.getVertexSum(sum);
|
||||
}
|
||||
if (haveFill) count += tessGeo.getFillVertexSum(sum, firstFillVertex, lastFillVertex);
|
||||
if (haveLines) count += tessGeo.getLineVertexSum(sum, firstLineVertex, lastLineVertex);
|
||||
if (havePoints) count += tessGeo.getPointVertexSum(sum, firstPointVertex, lastPointVertex);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
@@ -840,29 +824,13 @@ public class PShape3D extends PShape {
|
||||
}
|
||||
|
||||
|
||||
public void setPath(float[][] coords) {
|
||||
setPath(coords, null, OPEN);
|
||||
}
|
||||
|
||||
|
||||
public void setPath(float[][] coords, int mode) {
|
||||
setPath(coords, null, mode);
|
||||
}
|
||||
|
||||
|
||||
public void setPath(float[][] coords, int[] codes) {
|
||||
setPath(coords, codes, OPEN);
|
||||
}
|
||||
|
||||
|
||||
public void setPath(float[][] coords, int[] codes, int mode) {
|
||||
public void setPath(int vcount, float[][] verts, int ccount, int[] codes) {
|
||||
if (family != PATH) {
|
||||
PGraphics.showWarning("Vertex coordinates and codes can only be set to PATH shapes");
|
||||
return;
|
||||
}
|
||||
|
||||
super.setPath(coords, codes);
|
||||
isClosed = mode == CLOSE;
|
||||
super.setPath(vcount, verts, ccount, codes);
|
||||
root.tessellated = false;
|
||||
tessellated = false;
|
||||
shapeEnded = true;
|
||||
@@ -1043,7 +1011,7 @@ public class PShape3D extends PShape {
|
||||
protected void updateFillColor() {
|
||||
if (shapeEnded && tessellated && haveFill && texture == null) {
|
||||
Arrays.fill(inGeo.colors, 0, inGeo.vertexCount, PGL.javaToNativeARGB(fillColor));
|
||||
Arrays.fill(tessGeo.fillColors, firstFillVertex, lastFillVertex, PGL.javaToNativeARGB(fillColor));
|
||||
Arrays.fill(tessGeo.fillColors, firstFillVertex, lastFillVertex + 1, PGL.javaToNativeARGB(fillColor));
|
||||
root.setModifiedFillColors(firstFillVertex, lastFillVertex);
|
||||
}
|
||||
}
|
||||
@@ -1157,11 +1125,11 @@ public class PShape3D extends PShape {
|
||||
if (shapeEnded && tessellated && (haveLines || havePoints)) {
|
||||
Arrays.fill(inGeo.scolors, 0, inGeo.vertexCount, PGL.javaToNativeARGB(strokeColor));
|
||||
if (haveLines) {
|
||||
Arrays.fill(tessGeo.lineColors, firstLineVertex, lastLineVertex, PGL.javaToNativeARGB(strokeColor));
|
||||
Arrays.fill(tessGeo.lineColors, firstLineVertex, lastLineVertex + 1, PGL.javaToNativeARGB(strokeColor));
|
||||
root.setModifiedLineColors(firstLineVertex, lastLineVertex);
|
||||
}
|
||||
if (havePoints) {
|
||||
Arrays.fill(tessGeo.pointColors, firstPointVertex, lastPointVertex, PGL.javaToNativeARGB(strokeColor));
|
||||
Arrays.fill(tessGeo.pointColors, firstPointVertex, lastPointVertex + 1, PGL.javaToNativeARGB(strokeColor));
|
||||
root.setModifiedPointColors(firstPointVertex, lastPointVertex);
|
||||
}
|
||||
}
|
||||
@@ -1275,7 +1243,7 @@ public class PShape3D extends PShape {
|
||||
protected void updateTintColor() {
|
||||
if (shapeEnded && tessellated && haveFill && texture != null) {
|
||||
Arrays.fill(inGeo.colors, 0, inGeo.vertexCount, PGL.javaToNativeARGB(tintColor));
|
||||
Arrays.fill(tessGeo.fillColors, firstFillVertex, lastFillVertex, PGL.javaToNativeARGB(tintColor));
|
||||
Arrays.fill(tessGeo.fillColors, firstFillVertex, lastFillVertex + 1, PGL.javaToNativeARGB(tintColor));
|
||||
root.setModifiedFillColors(firstFillVertex, lastFillVertex);
|
||||
}
|
||||
}
|
||||
@@ -1334,7 +1302,7 @@ public class PShape3D extends PShape {
|
||||
protected void updateAmbientColor() {
|
||||
if (shapeEnded && tessellated && haveFill) {
|
||||
Arrays.fill(inGeo.ambient, 0, inGeo.vertexCount, PGL.javaToNativeARGB(ambientColor));
|
||||
Arrays.fill(tessGeo.fillAmbient, firstFillVertex, lastFillVertex, PGL.javaToNativeARGB(ambientColor));
|
||||
Arrays.fill(tessGeo.fillAmbient, firstFillVertex, lastFillVertex = 1, PGL.javaToNativeARGB(ambientColor));
|
||||
root.setModifiedFillAmbient(firstFillVertex, lastFillVertex);
|
||||
}
|
||||
}
|
||||
@@ -1393,7 +1361,7 @@ public class PShape3D extends PShape {
|
||||
protected void updateSpecularColor() {
|
||||
if (shapeEnded && tessellated && haveFill) {
|
||||
Arrays.fill(inGeo.specular, 0, inGeo.vertexCount, PGL.javaToNativeARGB(specularColor));
|
||||
Arrays.fill(tessGeo.fillSpecular, firstFillVertex, lastFillVertex, PGL.javaToNativeARGB(specularColor));
|
||||
Arrays.fill(tessGeo.fillSpecular, firstFillVertex, lastFillVertex + 1, PGL.javaToNativeARGB(specularColor));
|
||||
root.setModifiedFillSpecular(firstFillVertex, lastFillVertex);
|
||||
}
|
||||
}
|
||||
@@ -1452,7 +1420,7 @@ public class PShape3D extends PShape {
|
||||
protected void updateEmissiveColor() {
|
||||
if (shapeEnded && tessellated && 0 < tessGeo.fillVertexCount) {
|
||||
Arrays.fill(inGeo.emissive, 0, inGeo.vertexCount, PGL.javaToNativeARGB(emissiveColor));
|
||||
Arrays.fill(tessGeo.fillEmissive, firstFillVertex, lastFillVertex, PGL.javaToNativeARGB(emissiveColor));
|
||||
Arrays.fill(tessGeo.fillEmissive, firstFillVertex, lastFillVertex + 1, PGL.javaToNativeARGB(emissiveColor));
|
||||
root.setModifiedFillEmissive(firstFillVertex, lastFillVertex);
|
||||
}
|
||||
}
|
||||
@@ -1479,7 +1447,7 @@ public class PShape3D extends PShape {
|
||||
protected void updateShininessFactor() {
|
||||
if (shapeEnded && tessellated && haveFill) {
|
||||
Arrays.fill(inGeo.shininess, 0, inGeo.vertexCount, shininess);
|
||||
Arrays.fill(tessGeo.fillShininess, firstFillVertex, lastFillVertex, shininess);
|
||||
Arrays.fill(tessGeo.fillShininess, firstFillVertex, lastFillVertex + 1, shininess);
|
||||
root.setModifiedFillShininess(firstFillVertex, lastFillVertex);
|
||||
}
|
||||
}
|
||||
@@ -2399,7 +2367,7 @@ public class PShape3D extends PShape {
|
||||
|
||||
return tess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
@@ -2736,6 +2704,7 @@ public class PShape3D extends PShape {
|
||||
rounded = true;
|
||||
}
|
||||
|
||||
rectMode = CORNER;
|
||||
inGeo.setMaterial(fillColor, strokeColor, strokeWeight,
|
||||
ambientColor, specularColor, emissiveColor, shininess);
|
||||
inGeo.setNormal(normalX, normalY, normalZ);
|
||||
@@ -2762,7 +2731,8 @@ public class PShape3D extends PShape {
|
||||
c = params[2];
|
||||
d = params[3];
|
||||
}
|
||||
|
||||
|
||||
ellipseMode = CORNER;
|
||||
inGeo.setMaterial(fillColor, strokeColor, strokeWeight,
|
||||
ambientColor, specularColor, emissiveColor, shininess);
|
||||
inGeo.setNormal(normalX, normalY, normalZ);
|
||||
@@ -2784,6 +2754,7 @@ public class PShape3D extends PShape {
|
||||
stop = params[5];
|
||||
}
|
||||
|
||||
ellipseMode = CORNER;
|
||||
inGeo.setMaterial(fillColor, strokeColor, strokeWeight,
|
||||
ambientColor, specularColor, emissiveColor, shininess);
|
||||
inGeo.setNormal(normalX, normalY, normalZ);
|
||||
@@ -2851,39 +2822,43 @@ public class PShape3D extends PShape {
|
||||
int code = VERTEX;
|
||||
|
||||
if (vertices[0].length == 2) { // tessellating a 2D path
|
||||
|
||||
for (int j = 0; j < vertexCodeCount; j++) {
|
||||
switch (vertexCodes[j]) {
|
||||
|
||||
case VERTEX:
|
||||
inGeo.addVertex(vertices[index][X], vertices[index][Y], code);
|
||||
code = VERTEX;
|
||||
index++;
|
||||
break;
|
||||
|
||||
case QUAD_BEZIER_VERTEX:
|
||||
inGeo.addQuadraticVertex(vertices[index+0][X], vertices[index+0][Y], 0,
|
||||
vertices[index+1][X], vertices[index+1][Y], 0,
|
||||
fill, stroke, bezierDetail, code);
|
||||
vertices[index+1][X], vertices[index+1][Y], 0,
|
||||
fill, stroke, bezierDetail, code);
|
||||
code = VERTEX;
|
||||
index += 2;
|
||||
break;
|
||||
|
||||
case BEZIER_VERTEX:
|
||||
inGeo.addBezierVertex(vertices[index+0][X], vertices[index+0][Y], 0,
|
||||
vertices[index+1][X], vertices[index+1][Y], 0,
|
||||
vertices[index+2][X], vertices[index+2][Y], 0,
|
||||
fill, stroke, bezierDetail, code);
|
||||
vertices[index+1][X], vertices[index+1][Y], 0,
|
||||
vertices[index+2][X], vertices[index+2][Y], 0,
|
||||
fill, stroke, bezierDetail, code);
|
||||
code = VERTEX;
|
||||
index += 3;
|
||||
break;
|
||||
|
||||
case CURVE_VERTEX:
|
||||
inGeo.addCurveVertex(vertices[index][X], vertices[index][Y], 0,
|
||||
fill, stroke, curveDetail, code);
|
||||
fill, stroke, curveDetail, code);
|
||||
code = VERTEX;
|
||||
index++;
|
||||
|
||||
case BREAK:
|
||||
if (insideContour) {
|
||||
code = VERTEX;
|
||||
}
|
||||
code = BREAK;
|
||||
code = BREAK;
|
||||
}
|
||||
insideContour = true;
|
||||
}
|
||||
}
|
||||
@@ -2893,35 +2868,38 @@ public class PShape3D extends PShape {
|
||||
|
||||
case VERTEX:
|
||||
inGeo.addVertex(vertices[index][X], vertices[index][Y], vertices[index][Z], code);
|
||||
code = VERTEX;
|
||||
index++;
|
||||
break;
|
||||
|
||||
case QUAD_BEZIER_VERTEX:
|
||||
inGeo.addQuadraticVertex(vertices[index+0][X], vertices[index+0][Y], vertices[index+0][Z],
|
||||
vertices[index+1][X], vertices[index+1][Y], vertices[index+0][Z],
|
||||
fill, stroke, bezierDetail, code);
|
||||
vertices[index+1][X], vertices[index+1][Y], vertices[index+0][Z],
|
||||
fill, stroke, bezierDetail, code);
|
||||
code = VERTEX;
|
||||
index += 2;
|
||||
break;
|
||||
|
||||
|
||||
case BEZIER_VERTEX:
|
||||
inGeo.addBezierVertex(vertices[index+0][X], vertices[index+0][Y], vertices[index+0][Z],
|
||||
vertices[index+1][X], vertices[index+1][Y], vertices[index+1][Z],
|
||||
vertices[index+2][X], vertices[index+2][Y], vertices[index+2][Z],
|
||||
fill, stroke, bezierDetail, code);
|
||||
vertices[index+1][X], vertices[index+1][Y], vertices[index+1][Z],
|
||||
vertices[index+2][X], vertices[index+2][Y], vertices[index+2][Z],
|
||||
fill, stroke, bezierDetail, code);
|
||||
code = VERTEX;
|
||||
index += 3;
|
||||
break;
|
||||
|
||||
case CURVE_VERTEX:
|
||||
inGeo.addCurveVertex(vertices[index][X], vertices[index][Y], vertices[index][Z],
|
||||
fill, stroke, curveDetail, code);
|
||||
fill, stroke, curveDetail, code);
|
||||
code = VERTEX;
|
||||
index++;
|
||||
|
||||
case BREAK:
|
||||
if (insideContour) {
|
||||
code = VERTEX;
|
||||
}
|
||||
code = BREAK;
|
||||
code = BREAK;
|
||||
}
|
||||
insideContour = true;
|
||||
}
|
||||
}
|
||||
@@ -3878,6 +3856,43 @@ public class PShape3D extends PShape {
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
|
||||
// Style handling
|
||||
|
||||
|
||||
// Applies the styles of g.
|
||||
protected void styles(PGraphics g) {
|
||||
if (stroke) {
|
||||
stroke(g.strokeColor);
|
||||
strokeWeight(g.strokeWeight);
|
||||
|
||||
// These two don't to nothing probably:
|
||||
strokeCap(g.strokeCap);
|
||||
strokeJoin(g.strokeJoin);
|
||||
} else {
|
||||
noStroke();
|
||||
}
|
||||
|
||||
if (fill) {
|
||||
fill(g.fillColor);
|
||||
} else {
|
||||
noFill();
|
||||
}
|
||||
|
||||
ambient(g.ambientColor);
|
||||
specular(g.specularColor);
|
||||
emissive(g.emissiveColor);
|
||||
shininess(g.shininess);
|
||||
|
||||
// What about other style parameters, such as rectMode, etc?
|
||||
// These should force a tessellation update, same as stroke
|
||||
// cap and weight... right?
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
@@ -3892,25 +3907,23 @@ public class PShape3D extends PShape {
|
||||
|
||||
public void draw(PGraphics g) {
|
||||
if (visible) {
|
||||
pre(g);
|
||||
|
||||
updateTessellation();
|
||||
updateGeometry();
|
||||
|
||||
|
||||
if (family == GROUP) {
|
||||
if (textures != null && 1 < textures.size()) {
|
||||
// Some child shape below this group has a non-null matrix
|
||||
// transformation assigned to it, so the group cannot
|
||||
// be drawn in a single render call.
|
||||
// Or, some child shapes below this group use different
|
||||
if ((textures != null && 1 < textures.size()) ||
|
||||
pg.hintEnabled(ENABLE_ACCURATE_2D)) {
|
||||
// Some child shapes below this group use different
|
||||
// texture maps, so they cannot rendered in a single call
|
||||
// either.
|
||||
// either.
|
||||
// Or accurate 2D mode is enabled, which forces each
|
||||
// shape to be rendered separately.
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
((PShape3D) children[i]).draw(g);
|
||||
}
|
||||
} else {
|
||||
// None of the child shapes below this group has a matrix
|
||||
// transformation applied to them, so we can render everything
|
||||
// in a single block.
|
||||
// And all have the same texture applied to them.
|
||||
} else {
|
||||
PImage tex = null;
|
||||
if (textures != null && textures.size() == 1) {
|
||||
tex = (PImage)textures.toArray()[0];
|
||||
@@ -3921,10 +3934,23 @@ public class PShape3D extends PShape {
|
||||
} else {
|
||||
render((PGraphicsOpenGL)g, texture);
|
||||
}
|
||||
|
||||
post(g);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void pre(PGraphics g) {
|
||||
if (!style) {
|
||||
styles(g);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void post(PGraphics g) {
|
||||
}
|
||||
|
||||
|
||||
// Render the geometry stored in the root shape as VBOs, for the vertices
|
||||
// corresponding to this shape. Sometimes we can have root == this.
|
||||
protected void render(PGraphicsOpenGL g, PImage texture) {
|
||||
|
||||
@@ -734,7 +734,9 @@ public class PShape implements PConstants {
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The new copy methods to put an SVG into a PShape3D, for example
|
||||
|
||||
public PShape copy(PGraphics g) {
|
||||
PShape res = null;
|
||||
@@ -844,6 +846,7 @@ public class PShape implements PConstants {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user