@Override public void renderTo(Target<?> target) { double directionAngle = parseDirection(node.getTags(), PI); VectorXZ faceVector = VectorXZ.fromAngle(directionAngle); Material boxMaterial = null; Material poleMaterial = null; Type type = null; // post boxes differ widely in appearance, hence we draw them only for known operators or // brands if (node.getTags() .containsAny(asList("operator", "brand"), asList("Deutsche Post AG", "Deutsche Post"))) { boxMaterial = POSTBOX_DEUTSCHEPOST; poleMaterial = STEEL; type = Type.WALL; } else if (node.getTags().contains("operator", "Royal Mail")) { boxMaterial = POSTBOX_ROYALMAIL; type = Type.PILLAR; } else { // no rendering, unknown operator or brand for post box //TODO log info return; } assert (type != Type.WALL || poleMaterial != null) : "post box of type wall requires a pole material"; // default dimensions will differ depending on the post box type float height = 0f; float width = 0f; switch (type) { case WALL: height = parseHeight(node.getTags(), 0.8f); width = parseWidth(node.getTags(), 0.3f); target.drawBox(poleMaterial, getBase(), faceVector, height, 0.08, 0.08); target.drawBox( boxMaterial, getBase().add(faceVector.mult(width / 2 - 0.08 / 2)).addY(height), faceVector, width, width, width); break; case PILLAR: height = parseHeight(node.getTags(), 2f); width = parseWidth(node.getTags(), 0.5f); target.drawColumn(boxMaterial, null, getBase(), height - 0.1, width, width, false, false); target.drawColumn( boxMaterial, null, getBase().addY(height - 0.1), 0.1, width + 0.1, 0, true, true); break; default: assert false : "unknown post box type"; } }
@Override public void renderTo(Target<?> target) { float height = parseHeight(node.getTags(), 3f); /* draw socket, poster and cap */ target.drawColumn(CONCRETE, null, getBase(), 0.15 * height, 0.5, 0.5, false, false); target.drawColumn( ADVERTISING_POSTER, null, getBase(), 0.98 * height, 0.48, 0.48, false, false); target.drawColumn( CONCRETE, null, getBase().add(0, 0.95 * height, 0), 0.05 * height, 0.5, 0.5, false, true); }
@Override public void renderTo(Target<?> target) { /* render fence */ List<VectorXYZ> pointsWithEle = line.getElevationProfile().getPointsWithEle(); List<VectorXYZ> vsFence = createVerticalTriangleStrip(pointsWithEle, 0, height); List<List<VectorXZ>> texCoordListsFence = wallTexCoordLists(vsFence, CHAIN_LINK_FENCE); target.drawTriangleStrip(CHAIN_LINK_FENCE, vsFence, texCoordListsFence); List<VectorXYZ> pointsWithEleBack = new ArrayList<VectorXYZ>(pointsWithEle); Collections.reverse(pointsWithEleBack); List<VectorXYZ> vsFenceBack = createVerticalTriangleStrip(pointsWithEleBack, 0, height); List<List<VectorXZ>> texCoordListsFenceBack = wallTexCoordLists(vsFenceBack, CHAIN_LINK_FENCE); target.drawTriangleStrip(CHAIN_LINK_FENCE, vsFenceBack, texCoordListsFenceBack); /* render poles */ List<VectorXZ> polePositions = GeometryUtil.equallyDistributePointsAlong( 2f, false, line.getStartNode().getPos(), line.getEndNode().getPos()); for (VectorXZ polePosition : polePositions) { VectorXYZ base = polePosition.xyz(line.getElevationProfile().getEleAt(polePosition)); target.drawColumn(CHAIN_LINK_FENCE_POST, null, base, height, width, width, false, true); } }
@Override public void renderTo(Target<?> target) { if (!isInHighway(node)) { float height = parseHeight(node.getTags(), 3f); float signHeight = 0.7f; float signWidth = 0.4f; Material poleMaterial = STEEL; double directionAngle = parseDirection(node.getTags(), PI); VectorXZ faceVector = VectorXZ.fromAngle(directionAngle); target.drawColumn( poleMaterial, null, getBase(), height - signHeight, 0.05, 0.05, true, true); /* draw sign */ target.drawBox( BUS_STOP_SIGN, getBase().addY(height - signHeight), faceVector, signHeight, signWidth, 0.02); /* draw timetable */ target.drawBox( poleMaterial, getBase().addY(1.2f).add(new VectorXYZ(0.055f, 0, 0f).rotateY(directionAngle)), faceVector, 0.31, 0.01, 0.43); // TODO Add Shelter and bench } }
@Override public void renderTo(Target<?> target) { float lampHeight = 0.8f; float lampHalfWidth = 0.4f; float poleHeight = parseHeight(node.getTags(), 5f) - lampHeight; /* determine material */ Material material = null; if (material == null) { material = Materials.getSurfaceMaterial(node.getTags().getValue("material")); } if (material == null) { material = Materials.getSurfaceMaterial(node.getTags().getValue("surface"), STEEL); } /* draw pole */ target.drawColumn(material, null, getBase(), 0.5, 0.16, 0.08, false, false); target.drawColumn(material, null, getBase().addY(0.5), poleHeight, 0.08, 0.08, false, false); /* draw lamp */ // lower part List<VectorXYZ> vs = new ArrayList<VectorXYZ>(); vs.add(getBase().addY(poleHeight)); vs.add(getBase().addY(poleHeight + lampHeight * 0.8).add(lampHalfWidth, 0, lampHalfWidth)); vs.add(getBase().addY(poleHeight + lampHeight * 0.8).add(lampHalfWidth, 0, -lampHalfWidth)); vs.add(getBase().addY(poleHeight + lampHeight * 0.8).add(-lampHalfWidth, 0, -lampHalfWidth)); vs.add(getBase().addY(poleHeight + lampHeight * 0.8).add(-lampHalfWidth, 0, lampHalfWidth)); vs.add(getBase().addY(poleHeight + lampHeight * 0.8).add(lampHalfWidth, 0, lampHalfWidth)); target.drawTriangleFan(material, vs, null); // upper part vs.clear(); vs.add(getBase().addY(poleHeight + lampHeight)); vs.add(getBase().addY(poleHeight + lampHeight * 0.8).add(lampHalfWidth, 0, lampHalfWidth)); vs.add(getBase().addY(poleHeight + lampHeight * 0.8).add(-lampHalfWidth, 0, lampHalfWidth)); vs.add(getBase().addY(poleHeight + lampHeight * 0.8).add(-lampHalfWidth, 0, -lampHalfWidth)); vs.add(getBase().addY(poleHeight + lampHeight * 0.8).add(lampHalfWidth, 0, -lampHalfWidth)); vs.add(getBase().addY(poleHeight + lampHeight * 0.8).add(lampHalfWidth, 0, lampHalfWidth)); target.drawTriangleFan(material, vs, null); }
@Override public void renderTo(Target<?> target) { double directionAngle = parseDirection(node.getTags(), PI); VectorXZ faceVector = VectorXZ.fromAngle(directionAngle); target.drawColumn(WOOD, null, getBase(), 1.5, 0.05, 0.05, false, true); target.drawBox(WOOD, getBase().addY(1.2), faceVector, 0.4, 0.4, 0.1); }
@Override public void renderTo(Target<?> target) { /* determine material */ Material material = null; // TODO parse color if (material == null) { material = Materials.getSurfaceMaterial(node.getTags().getValue("material")); } if (material == null) { material = Materials.getSurfaceMaterial(node.getTags().getValue("surface"), STEEL); } /* draw pole */ target.drawColumn(material, null, getBase(), 1.2, 0.06, 0.06, false, true); /* draw basket */ target.drawColumn( material, null, getBase().addY(0.5).add(0.25, 0f, 0f), 0.5, 0.2, 0.2, true, true); }
@Override public void renderTo(Target<?> target) { float height = parseHeight(node.getTags(), 1f); /* draw main pole */ target.drawColumn(FIREHYDRANT, null, getBase(), height, 0.15, 0.15, false, true); /* draw two small and one large valve */ VectorXYZ valveBaseVector = getBase().addY(height - 0.3); VectorXZ smallValveVector = VectorXZ.X_UNIT; VectorXZ largeValveVector = VectorXZ.Z_UNIT; target.drawBox(FIREHYDRANT, valveBaseVector, smallValveVector, 0.1f, 0.5f, 0.1f); target.drawBox( FIREHYDRANT, valveBaseVector.add(0.2f, -0.1f, 0f), largeValveVector, 0.15f, 0.15f, 0.15f); }
@Override public void renderTo(Target<?> target) { /* render bars */ List<VectorXYZ> vsLowFront = createVerticalTriangleStrip( line.getElevationProfile().getPointsWithEle(), 0.2f * height, 0.5f * height); List<VectorXYZ> vsLowBack = createVerticalTriangleStrip( line.getElevationProfile().getPointsWithEle(), 0.5f * height, 0.2f * height); target.drawTriangleStrip(material, vsLowFront, null); target.drawTriangleStrip(material, vsLowBack, null); List<VectorXYZ> vsHighFront = createVerticalTriangleStrip( line.getElevationProfile().getPointsWithEle(), 0.65f * height, 0.95f * height); List<VectorXYZ> vsHighBack = createVerticalTriangleStrip( line.getElevationProfile().getPointsWithEle(), 0.95f * height, 0.65f * height); target.drawTriangleStrip(material, vsHighFront, null); target.drawTriangleStrip(material, vsHighBack, null); /* render poles */ List<VectorXZ> polePositions = GeometryUtil.equallyDistributePointsAlong( 1f, false, line.getStartNode().getPos(), line.getEndNode().getPos()); for (VectorXZ polePosition : polePositions) { VectorXYZ base = polePosition.xyz(line.getElevationProfile().getEleAt(polePosition)); target.drawColumn(material, null, base, height, width, width, false, true); } }
@Override public void renderTo(Target<?> target) { VectorXYZ pos = node.getElevationProfile().getPointWithEle(); target.drawColumn(Materials.CONCRETE, null, pos, height, 0.15f, 0.15f, false, true); }
@Override public void renderTo(Target<?> target) { /* get basic parameters */ double height = parseHeight(node.getTags(), (float) types.get(0).defaultHeight); double postRadius = 0.05; double[] signHeights = new double[types.size()]; double[] signWidths = new double[types.size()]; for (int sign = 0; sign < types.size(); sign++) { TextureData textureData = null; if (types.get(sign).material.getNumTextureLayers() != 0) { textureData = types.get(sign).material.getTextureDataList().get(0); } if (textureData == null) { signHeights[sign] = 0.6; signWidths[sign] = 0.6; } else { signHeights[sign] = textureData.height; signWidths[sign] = textureData.width; } } /* position the post(s) */ int numPosts = types.get(0).numPosts; List<VectorXYZ> positions = new ArrayList<VectorXYZ>(numPosts); for (int i = 0; i < numPosts; i++) { double relativePosition = 0.5 - (i + 1) / (double) (numPosts + 1); positions.add(getBase().add(X_UNIT.mult(relativePosition * signWidths[0]))); } /* create the front and back side of the sign */ List<List<VectorXYZ>> signGeometries = new ArrayList<List<VectorXYZ>>(); double distanceBetweenSigns = 0.1; double upperHeight = height; for (int sign = 0; sign < types.size(); sign++) { double signHeight = signHeights[sign]; double signWidth = signWidths[sign]; List<VectorXYZ> vs = asList( getBase().add(+signWidth / 2, upperHeight, postRadius), getBase().add(+signWidth / 2, upperHeight - signHeight, postRadius), getBase().add(-signWidth / 2, upperHeight, postRadius), getBase().add(-signWidth / 2, upperHeight - signHeight, postRadius)); signGeometries.add(vs); upperHeight -= signHeight + distanceBetweenSigns; } /* rotate the sign around the base to match the direction tag */ double direction = parseDirection(node.getTags(), PI); for (List<VectorXYZ> vs : signGeometries) { for (int i = 0; i < vs.size(); i++) { VectorXYZ v = vs.get(i); v = v.rotateVec(direction, getBase(), VectorXYZ.Y_UNIT); vs.set(i, v); } } if (positions.size() > 1) { // if 1, the post is exactly on the base for (int i = 0; i < positions.size(); i++) { VectorXYZ v = positions.get(i); v = v.rotateVec(direction, getBase(), VectorXYZ.Y_UNIT); positions.set(i, v); } } /* render the post(s) */ for (VectorXYZ position : positions) { target.drawColumn(STEEL, null, position, height, postRadius, postRadius, false, true); } /* render the sign (front, then back) */ for (int sign = 0; sign < types.size(); sign++) { TrafficSignType type = types.get(sign); List<VectorXYZ> vs = signGeometries.get(sign); target.drawTriangleStrip(type.material, vs, texCoordLists(vs, type.material, STRIP_FIT)); vs = asList(vs.get(2), vs.get(3), vs.get(0), vs.get(1)); target.drawTriangleStrip(STEEL, vs, texCoordLists(vs, STEEL, STRIP_FIT)); } }
@Override public void renderTo(Target<?> target) { double ele = getBase().y; double directionAngle = parseDirection(node.getTags(), PI); Material boxMaterial = POSTBOX_DEUTSCHEPOST; Material otherMaterial = STEEL; VectorXZ faceVector = VectorXZ.fromAngle(directionAngle); VectorXZ rightVector = faceVector.rightNormal(); // shape depends on type if (node.getTags().contains("type", "Rondell")) { float height = parseHeight(node.getTags(), 2.2f); float width = parseWidth(node.getTags(), 3f); float rondelWidth = width * 2 / 3; float boxWidth = width * 1 / 3; float roofOverhang = 0.3f; /* draw rondel */ target.drawColumn( boxMaterial, null, getBase().add(rightVector.mult(-rondelWidth / 2)), height, rondelWidth / 2, rondelWidth / 2, false, true); /* draw box */ target.drawBox( boxMaterial, getBase().add(rightVector.mult(boxWidth / 2)).add(faceVector.mult(-boxWidth / 2)), faceVector, height, boxWidth, boxWidth); /* draw roof */ target.drawColumn( otherMaterial, null, getBase().addY(height), 0.1, rondelWidth / 2 + roofOverhang / 2, rondelWidth / 2 + roofOverhang / 2, true, true); } else if (node.getTags().contains("type", "Paketbox")) { float height = parseHeight(node.getTags(), 1.5f); float width = parseHeight(node.getTags(), 1.0f); float depth = width; target.drawBox(boxMaterial, getBase(), faceVector, height, width * 2, depth * 2); } else { // type=Schrank or type=24/7 Station (they look roughly the same) or no type // (fallback) float height = parseHeight(node.getTags(), 2.2f); float width = parseWidth(node.getTags(), 3.5f); float depth = width / 3; float roofOverhang = 0.3f; /* draw box */ target.drawBox(boxMaterial, getBase(), faceVector, height, width, depth); /* draw small roof */ target.drawBox( otherMaterial, node.getPos().add(faceVector.mult(roofOverhang)).xyz(ele + height), faceVector, 0.1, width, depth + roofOverhang * 2); } }
@Override public void renderTo(Target<?> target) { target.drawColumn( STEEL, null, getBase(), parseHeight(node.getTags(), 10f), 0.15, 0.15, false, true); }