/** optimization for Line- and PolygonLayer: collect all pool items and add back in one go. */ private static int addLayerItems(ShortBuffer sbuf, RenderElement l, int type, int pos) { VertexItem last = null, items = null; int size = 0; for (; l != null; l = l.next) { if (l.type != type) continue; for (VertexItem it = l.vertexItems; it != null; it = it.next) { if (it.next == null) { size += it.used; sbuf.put(it.vertices, 0, it.used); } else { size += VertexItem.SIZE; sbuf.put(it.vertices, 0, VertexItem.SIZE); } last = it; } if (last == null) continue; l.offset = pos; pos += l.numVertices; last.next = items; items = l.vertexItems; last = null; l.vertexItems = null; } items = VertexItem.pool.releaseAll(items); return size; }
// private void encodeNormal(float v[], int offset) { // var p = Math.sqrt(cartesian.z * 8.0 + 8.0); // var result = new Cartesian2(); // result.x = cartesian.x / p + 0.5; // result.y = cartesian.y / p + 0.5; // return result; // } // public void addNoNormal(MapElement element) { if (element.type != GeometryType.TRIS) return; short[] index = element.index; float[] points = element.points; /* current vertex id */ int startVertex = sumVertices; /* roof indices for convex shapes */ int i = mCurIndices[IND_MESH].used; short[] indices = mCurIndices[IND_MESH].vertices; int first = startVertex; for (int k = 0, n = index.length; k < n; ) { if (index[k] < 0) break; if (i == VertexItem.SIZE) { mCurIndices[IND_MESH].used = VertexItem.SIZE; mCurIndices[IND_MESH].next = VertexItem.pool.get(); mCurIndices[IND_MESH] = mCurIndices[IND_MESH].next; indices = mCurIndices[IND_MESH].vertices; i = 0; } indices[i++] = (short) (first + index[k++]); indices[i++] = (short) (first + index[k++]); indices[i++] = (short) (first + index[k++]); } mCurIndices[IND_MESH].used = i; short[] vertices = mCurVertices.vertices; int v = mCurVertices.used; int vertexCnt = element.pointPos; for (int j = 0; j < vertexCnt; ) { /* add bottom and top vertex for each point */ if (v == VertexItem.SIZE) { mCurVertices.used = VertexItem.SIZE; mCurVertices.next = VertexItem.pool.get(); mCurVertices = mCurVertices.next; vertices = mCurVertices.vertices; v = 0; } /* set coordinate */ vertices[v++] = (short) (points[j++] * S); vertices[v++] = (short) (points[j++] * S); vertices[v++] = (short) (points[j++] * S); v++; } mCurVertices.used = v; sumVertices += (vertexCnt / 3); }
@Override public void layout() { int y = 2; int width = getWidth(); int itemCount = getItemCount(); for (int i = 0; i < itemCount; i++) { VertexItem item = getItem(i); int itemHeight = (item.isHairline()) ? 0 : 2; item.setBounds(0, y, width, itemHeight); y += itemHeight; } setHeight(y + 2); super.layout(); }
private void addVertex(Vertex vertex) { VertexItem vi = mCurVertices; if (vi.used == VertexItem.SIZE) { mCurVertices.used = VertexItem.SIZE; mCurVertices = VertexItem.pool.getNext(vi); vi = mCurVertices; } vi.vertices[vi.used++] = vertex.x; vi.vertices[vi.used++] = vertex.y; vi.vertices[vi.used++] = vertex.z; vi.vertices[vi.used++] = vertex.n; }
private boolean addOutline( float[] points, int pos, int len, float minHeight, float height, boolean convex) { /* add two vertices for last face to make zigzag indices work */ boolean addFace = (len % 4 != 0); int vertexCnt = len + (addFace ? 2 : 0); short h = (short) height; short mh = (short) minHeight; float cx = points[pos + len - 2]; float cy = points[pos + len - 1]; float nx = points[pos + 0]; float ny = points[pos + 1]; /* vector to next point */ float vx = nx - cx; float vy = ny - cy; /* vector from previous point */ float ux, uy; float a = (float) Math.sqrt(vx * vx + vy * vy); short color1 = (short) ((1 + vx / a) * 127); short fcolor = color1; short color2 = 0; int even = 0; int changeX = 0; int changeY = 0; int angleSign = 0; /* vertex offset for all vertices in layer */ int vOffset = sumVertices; short[] vertices = mCurVertices.vertices; int v = mCurVertices.used; mClipper.clipStart((int) nx, (int) ny); for (int i = 2, n = vertexCnt + 2; i < n; i += 2, v += 8) { cx = nx; cy = ny; ux = vx; uy = vy; /* add bottom and top vertex for each point */ if (v == VertexItem.SIZE) { mCurVertices.used = VertexItem.SIZE; mCurVertices.next = VertexItem.pool.get(); mCurVertices = mCurVertices.next; vertices = mCurVertices.vertices; v = 0; } /* set coordinate */ vertices[v + 0] = vertices[v + 4] = (short) (cx * S); vertices[v + 1] = vertices[v + 5] = (short) (cy * S); /* set height */ vertices[v + 2] = mh; vertices[v + 6] = h; /* get direction to next point */ if (i < len) { nx = points[pos + i + 0]; ny = points[pos + i + 1]; } else if (i == len) { nx = points[pos + 0]; ny = points[pos + 1]; } else { // if (addFace) short c = (short) (color1 | fcolor << 8); vertices[v + 3] = vertices[v + 7] = c; v += 8; break; } vx = nx - cx; vy = ny - cy; /* set lighting (by direction) */ a = (float) Math.sqrt(vx * vx + vy * vy); color2 = (short) ((1 + vx / a) * 127); short c; if (even == 0) c = (short) (color1 | color2 << 8); else c = (short) (color2 | color1 << 8); vertices[v + 3] = vertices[v + 7] = c; color1 = color2; /* check if polygon is convex */ if (convex) { /* TODO simple polys with only one concave arc * could be handled without special triangulation */ if ((ux < 0 ? 1 : -1) != (vx < 0 ? 1 : -1)) changeX++; if ((uy < 0 ? 1 : -1) != (vy < 0 ? 1 : -1)) changeY++; if (changeX > 2 || changeY > 2) convex = false; float cross = ux * vy - uy * vy; if (cross > 0) { if (angleSign == -1) convex = false; angleSign = 1; } else if (cross < 0) { if (angleSign == 1) convex = false; angleSign = -1; } } /* check if face is within tile */ if (mClipper.clipNext((int) nx, (int) ny) == 0) { even = ++even % 2; continue; } /* add ZigZagQuadIndices(tm) for sides */ short vert = (short) (vOffset + (i - 2)); short s0 = vert++; short s1 = vert++; short s2 = vert++; short s3 = vert++; /* connect last to first (when number of faces is even) */ if (!addFace && i == len) { s2 -= len; s3 -= len; } VertexItem it = mCurIndices[even]; if (it.used == VertexItem.SIZE) { it = VertexItem.pool.getNext(it); mCurIndices[even] = it; } int ind = it.used; short[] indices = it.vertices; indices[ind + 0] = s0; indices[ind + 1] = s2; indices[ind + 2] = s1; indices[ind + 3] = s1; indices[ind + 4] = s2; indices[ind + 5] = s3; it.used += 6; sumIndices += 6; /* flipp even-odd */ even = ++even % 2; /* add roof outline indices */ it = mCurIndices[IND_OUTLINE]; if (it.used == VertexItem.SIZE) { it = VertexItem.pool.getNext(it); mCurIndices[IND_OUTLINE] = it; } ind = it.used; indices = it.vertices; indices[ind + 0] = s1; indices[ind + 1] = s3; it.used += 2; sumIndices += 2; } mCurVertices.used = v; sumVertices += vertexCnt; return convex; }
public void paint( Graphics2D g2, TreePath treePath, CanvasRendererContext rendererContext, int graphY) { boolean selected = rendererContext.isSelected(treePath, this); int step = rendererContext.getStep(); int x0 = rendererContext.getGraphX() + getX() * step; int y0 = graphY + getY() * step; int width = getWidth() * step; int height = getHeight() * step; double tx = x0 + 0.5; double ty = y0 + 0.5; g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); g2.translate(tx, ty); RRectangle rrect = new RRectangle(0, 0, width, step * 2, step, step, 0.0, 0.0); g2.setPaint(Color.WHITE); int y = step * 2; int h = height - y; g2.fillRect(0, y, width, h); g2.setPaint( new TexturePaint(MapperStyle.GRADIENT_TEXTURE, new Rectangle(0, 0, width, step * 2))); g2.fill(rrect); Icon icon = getIcon(); int textX = step; if (icon != null) { double tx2 = step - 0.5; double ty2 = step - 0.5 - icon.getIconHeight() / 2 + 1; g2.translate(tx2, ty2); g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); icon.paintIcon(rendererContext.getCanvas(), g2, 0, 0); g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); g2.translate(-tx2, -ty2); textX += icon.getIconWidth() + 4; } g2.translate(-tx, -ty); g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); String name = getName(); if (name != null) { int labelWidth = width - textX - step - 1; if (labelWidth > 0) { int labelX = x0 + textX; int labelY = y0 + 1; int labelHeight = step * 2 - 1; JLabel label = rendererContext.getTextRenderer(); label.setBounds(0, 0, labelWidth, labelHeight); label.setForeground(MapperStyle.ICON_COLOR); label.setText(name); label.setHorizontalAlignment(JLabel.LEFT); label.setFont(label.getFont().deriveFont(Font.PLAIN)); g2.translate(labelX, labelY); label.paint(g2); g2.translate(-labelX, -labelY); } } g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); g2.translate(tx, ty); Stroke oldStroke = g2.getStroke(); g2.setPaint(MapperStyle.VERTEX_BORDER_COLOR); for (int i = 2; i < getHeight(); i += 2) { y = i * step; g2.drawLine(0, y, width - 1, y); } rrect.setBounds(0, 0, width, height); if (selected) { g2.setStroke(MapperStyle.SELECTION_STROKE); g2.setPaint(MapperStyle.SELECTION_COLOR); g2.draw(rrect); } else { g2.setPaint(MapperStyle.VERTEX_BORDER_COLOR); g2.draw(rrect); } g2.fill(new Triangle(width - step, height, width, height - step, width, height)); g2.setStroke(oldStroke); g2.translate(-tx, -ty); g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); for (int i = getItemCount() - 1; i >= 0; i--) { VertexItem item = getItem(i); item.paintTargetPin(g2, treePath, rendererContext, graphY); if (!item.isHairline()) { item.paint(g2, treePath, rendererContext, graphY); } } paintSourcePin(g2, treePath, rendererContext, graphY); String resultText = getResultText(); if (resultText != null) { JLabel label = rendererContext.getTextRenderer(); int labelWidth = width - 5 - step; if (labelWidth > 0) { int labelHeight = 2 * step - 1; int labelX = x0 + 3; int labelY = y0 + height - labelHeight; label.setHorizontalAlignment(JLabel.RIGHT); label.setText(resultText); label.setFont(label.getFont().deriveFont(Font.PLAIN)); label.setForeground(MapperStyle.FUNCTION_RESULT_TEXT_COLOR); label.setBounds(0, 0, labelWidth, labelHeight); g2.translate(labelX, labelY); label.paint(g2); g2.translate(-labelX, -labelY); } } }