Merge pull request #458 from Gustl22/buckets

Refactor ExtrusionBucket
This commit is contained in:
Emux 2017-12-19 14:09:30 +02:00 committed by GitHub
commit 641db3ade0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 29 deletions

View File

@ -159,8 +159,8 @@ public class BuildingLayer extends Layer implements TileLoaderThemeHook {
ExtrusionBuckets ebs = get(tile); ExtrusionBuckets ebs = get(tile);
for (ExtrusionBucket b = ebs.buckets; b != null; b = b.next()) { for (ExtrusionBucket b = ebs.buckets; b != null; b = b.next()) {
if (b.colors == extrusion.colors) { if (b.getColors() == extrusion.colors) {
b.add(element, height, minHeight); b.addPoly(element, height, minHeight);
return; return;
} }
} }
@ -173,7 +173,7 @@ public class BuildingLayer extends Layer implements TileLoaderThemeHook {
new ExtrusionBucket(0, groundScale, new ExtrusionBucket(0, groundScale,
extrusion.colors)); extrusion.colors));
ebs.buckets.add(element, height, minHeight); ebs.buckets.addPoly(element, height, minHeight);
} }
/** /**

View File

@ -139,15 +139,15 @@ class S3DBTileLoader extends TileLoader {
String roofShape = element.tags.getValue(Tag.KEY_ROOF_SHAPE); String roofShape = element.tags.getValue(Tag.KEY_ROOF_SHAPE);
if (isRoof && (roofShape == null || Tag.VALUE_FLAT.equals(roofShape))) if (isRoof && (roofShape == null || Tag.VALUE_FLAT.equals(roofShape)))
mRoofs.add(element); mRoofs.addMesh(element);
else else
mParts.add(element); mParts.addMesh(element);
return; return;
} }
for (ExtrusionBucket l = mParts; l != null; l = l.next()) { for (ExtrusionBucket l = mParts; l != null; l = l.next()) {
if (l.color == c) { if (l.getColor() == c) {
l.add(element); l.addMesh(element);
return; return;
} }
} }
@ -156,7 +156,7 @@ class S3DBTileLoader extends TileLoader {
l.next = mParts.next; l.next = mParts.next;
mParts.next = l; mParts.next = l;
l.add(element); l.addMesh(element);
} }
@Override @Override

View File

@ -95,7 +95,7 @@ public abstract class ExtrusionRenderer extends LayerRenderer {
@Override @Override
public void render(GLViewport v) { public void render(GLViewport v) {
float[] currentColor = null; float[] currentColors = null;
float currentAlpha = 0; float currentAlpha = 0;
gl.depthMask(true); gl.depthMask(true);
@ -171,11 +171,11 @@ public abstract class ExtrusionRenderer extends LayerRenderer {
for (; eb != null; eb = eb.next()) { for (; eb != null; eb = eb.next()) {
if (eb.colors != currentColor) { if (eb.getColors() != currentColors) {
currentColor = eb.colors; currentColors = eb.getColors();
GLUtils.glUniform4fv(s.uColor, GLUtils.glUniform4fv(s.uColor,
mMode == 0 ? 4 : 1, mMode == 0 ? 4 : 1,
eb.colors); currentColors);
} }
gl.vertexAttribPointer(s.aPos, 3, GL.SHORT, gl.vertexAttribPointer(s.aPos, 3, GL.SHORT,

View File

@ -1,5 +1,6 @@
/* /*
* Copyright 2012, 2013 Hannes Janetzek * Copyright 2012, 2013 Hannes Janetzek
* Copyright 2017 Gustl22
* *
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
* *
@ -18,8 +19,6 @@ package org.oscim.renderer.bucket;
import org.oscim.backend.canvas.Color; import org.oscim.backend.canvas.Color;
import org.oscim.core.GeometryBuffer; import org.oscim.core.GeometryBuffer;
import org.oscim.core.GeometryBuffer.GeometryType;
import org.oscim.core.MapElement;
import org.oscim.core.Tile; import org.oscim.core.Tile;
import org.oscim.utils.FastMath; import org.oscim.utils.FastMath;
import org.oscim.utils.KeyMap; import org.oscim.utils.KeyMap;
@ -43,13 +42,14 @@ public class ExtrusionBucket extends RenderBucket {
/** /**
* 16 floats rgba for top, even-side, odd-sides and outline * 16 floats rgba for top, even-side, odd-sides and outline
*/ */
public final float[] colors; private final float[] colors;
public final int color; private final int color;
/** /**
* indices for: 0. even sides, 1. odd sides, 2. roof, 3. roof outline * indices for: 0. even sides, 1. odd sides, 2. roof, 3. roof outline
*/ */
public int idx[] = {0, 0, 0, 0, 0}; public int idx[] = {0, 0, 0, 0, 0};
/** /**
* indices offsets in bytes * indices offsets in bytes
*/ */
@ -90,7 +90,7 @@ public class ExtrusionBucket extends RenderBucket {
} }
/** /**
* ExtrusionLayer for triangle geometries. * ExtrusionLayer for triangle geometries / meshes.
*/ */
public ExtrusionBucket(int level, float groundResolution, int color) { public ExtrusionBucket(int level, float groundResolution, int color) {
super(RenderBucket.EXTRUSION, true, false); super(RenderBucket.EXTRUSION, true, false);
@ -98,7 +98,7 @@ public class ExtrusionBucket extends RenderBucket {
this.color = color; this.color = color;
float a = Color.aToFloat(color); float a = Color.aToFloat(color);
colors = new float[4]; colors = new float[4]; // Why not 16?
colors[0] = a * Color.rToFloat(color); colors[0] = a * Color.rToFloat(color);
colors[1] = a * Color.gToFloat(color); colors[1] = a * Color.gToFloat(color);
colors[2] = a * Color.bToFloat(color); colors[2] = a * Color.bToFloat(color);
@ -152,8 +152,13 @@ public class ExtrusionBucket extends RenderBucket {
} }
} }
public void add(MapElement element) { /**
if (element.type != GeometryType.TRIS) * Add MapElement which provides meshes
*
* @param element the map element to add
*/
public void addMesh(GeometryBuffer element) {
if (!element.isTris())
return; return;
int[] index = element.index; int[] index = element.index;
@ -165,6 +170,7 @@ public class ExtrusionBucket extends RenderBucket {
Vertex key = vertexPool.get(); Vertex key = vertexPool.get();
double scale = COORD_SCALE * Tile.SIZE / 4096; double scale = COORD_SCALE * Tile.SIZE / 4096;
// n is introduced if length increases while processing
for (int k = 0, n = index.length; k < n; ) { for (int k = 0, n = index.length; k < n; ) {
if (index[k] < 0) if (index[k] < 0)
break; break;
@ -173,6 +179,7 @@ public class ExtrusionBucket extends RenderBucket {
if (vertexCnt >= 1 << 16) if (vertexCnt >= 1 << 16)
break; break;
// Get position of points for each polygon (which always has 3 points)
int vtx1 = index[k++] * 3; int vtx1 = index[k++] * 3;
int vtx2 = index[k++] * 3; int vtx2 = index[k++] * 3;
int vtx3 = index[k++] * 3; int vtx3 = index[k++] * 3;
@ -189,6 +196,7 @@ public class ExtrusionBucket extends RenderBucket {
float vy3 = points[vtx3 + 1]; float vy3 = points[vtx3 + 1];
float vz3 = points[vtx3 + 2]; float vz3 = points[vtx3 + 2];
// Calculate normal for color gradient
float ax = vx2 - vx1; float ax = vx2 - vx1;
float ay = vy2 - vy1; float ay = vy2 - vy1;
float az = vz2 - vz1; float az = vz2 - vz1;
@ -197,6 +205,7 @@ public class ExtrusionBucket extends RenderBucket {
float by = vy3 - vy1; float by = vy3 - vy1;
float bz = vz3 - vz1; float bz = vz3 - vz1;
// Vector product (c is at right angle to a and b)
float cx = ay * bz - az * by; float cx = ay * bz - az * by;
float cy = az * bx - ax * bz; float cy = az * bx - ax * bz;
float cz = ax * by - ay * bx; float cz = ax * by - ay * bx;
@ -225,11 +234,11 @@ public class ExtrusionBucket extends RenderBucket {
if (vertex == null) { if (vertex == null) {
key.id = vertexCnt++; key.id = vertexCnt++;
addIndex(key, true); addMeshIndex(key, true);
key = vertexPool.get(); key = vertexPool.get();
} else { } else {
//numIndexHits++; //numIndexHits++;
addIndex(vertex, false); addMeshIndex(vertex, false);
} }
key.set((short) (vx2 * scale), key.set((short) (vx2 * scale),
@ -241,11 +250,11 @@ public class ExtrusionBucket extends RenderBucket {
if (vertex == null) { if (vertex == null) {
key.id = vertexCnt++; key.id = vertexCnt++;
addIndex(key, true); addMeshIndex(key, true);
key = vertexPool.get(); key = vertexPool.get();
} else { } else {
//numIndexHits++; //numIndexHits++;
addIndex(vertex, false); addMeshIndex(vertex, false);
} }
key.set((short) (vx3 * scale), key.set((short) (vx3 * scale),
@ -256,11 +265,11 @@ public class ExtrusionBucket extends RenderBucket {
vertex = mVertexMap.put(key, false); vertex = mVertexMap.put(key, false);
if (vertex == null) { if (vertex == null) {
key.id = vertexCnt++; key.id = vertexCnt++;
addIndex(key, true); addMeshIndex(key, true);
key = vertexPool.get(); key = vertexPool.get();
} else { } else {
//numIndexHits++; //numIndexHits++;
addIndex(vertex, false); addMeshIndex(vertex, false);
} }
} }
@ -269,7 +278,7 @@ public class ExtrusionBucket extends RenderBucket {
numVertices = vertexCnt; numVertices = vertexCnt;
} }
private void addIndex(Vertex v, boolean addVertex) { private void addMeshIndex(Vertex v, boolean addVertex) {
if (addVertex) if (addVertex)
vertexItems.add(v.x, v.y, v.z, v.n); vertexItems.add(v.x, v.y, v.z, v.n);
@ -339,7 +348,14 @@ public class ExtrusionBucket extends RenderBucket {
// sumVertices += (vertexCnt / 3); // sumVertices += (vertexCnt / 3);
//} //}
public void add(MapElement element, float height, float minHeight) { /**
* Add MapElement which provides polygons
*
* @param element the map element to add
* @param height the maximum height of element
* @param minHeight the minimum height of element
*/
public void addPoly(GeometryBuffer element, float height, float minHeight) {
int[] index = element.index; int[] index = element.index;
float[] points = element.points; float[] points = element.points;
@ -383,7 +399,7 @@ public class ExtrusionBucket extends RenderBucket {
log.debug("explicit closed poly " + len); log.debug("explicit closed poly " + len);
} }
/* need at least three points */ /* need at least three points (x and y) */
if (len < 6) if (len < 6)
continue; continue;
@ -429,6 +445,7 @@ public class ExtrusionBucket extends RenderBucket {
int numRings = 0; int numRings = 0;
/* get sum of points in polygon */ /* get sum of points in polygon */
// n is introduced if length increases while processing
for (int i = ipos, n = index.length; i < n && index[i] > 0; i++) { for (int i = ipos, n = index.length; i < n && index[i] > 0; i++) {
numPoints += index[i]; numPoints += index[i];
numRings++; numRings++;
@ -615,6 +632,20 @@ public class ExtrusionBucket extends RenderBucket {
} }
} }
/**
* @return the polygon colors (top, side, side, line)
*/
public float[] getColors() {
return colors;
}
/**
* @return the mesh color
*/
public int getColor() {
return color;
}
@Override @Override
protected void prepare() { protected void prepare() {
mClipper = null; mClipper = null;