@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) {

      /* 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));
      }
    }
    private void drawContainer(Target<?> target, String trash, VectorXYZ pos) {

      if ("clothes".equals(trash)) {
        target.drawBox(
            new ImmutableMaterial(Lighting.FLAT, new Color(0.82f, 0.784f, 0.75f)),
            pos,
            faceVector,
            2,
            1,
            1);
      } else { // "paper" || "white_glass" || "coloured_glass"
        float width = 1.5f;
        float height = 1.6f;

        Material colourFront = null;
        Material colourBack = null;

        if ("paper".equals(trash)) {
          colourFront = new ImmutableMaterial(Lighting.FLAT, Color.BLUE);
          colourBack = new ImmutableMaterial(Lighting.FLAT, Color.BLUE);
        } else if ("white_glass".equals(trash)) {
          colourFront = new ImmutableMaterial(Lighting.FLAT, Color.WHITE);
          colourBack = new ImmutableMaterial(Lighting.FLAT, Color.WHITE);
        } else { // "coloured_glass"
          colourFront = new ImmutableMaterial(Lighting.FLAT, new Color(0.18f, 0.32f, 0.14f));
          colourBack = new ImmutableMaterial(Lighting.FLAT, new Color(0.39f, 0.15f, 0.11f));
        }

        target.drawBox(STEEL, pos, faceVector, height, width, width);
        target.drawBox(
            colourFront,
            pos.add(
                new VectorXYZ((width / 2 - 0.10), 0.1f, (width / 2 - 0.1)).rotateY(directionAngle)),
            faceVector,
            height - 0.2,
            0.202,
            0.202);
        target.drawBox(
            colourBack,
            pos.add(
                new VectorXYZ(-(width / 2 - 0.10), 0.1f, (width / 2 - 0.1))
                    .rotateY(directionAngle)),
            faceVector,
            height - 0.2,
            0.202,
            0.202);
        target.drawBox(
            colourFront,
            pos.add(
                new VectorXYZ((width / 2 - 0.10), 0.1f, -(width / 2 - 0.1))
                    .rotateY(directionAngle)),
            faceVector,
            height - 0.2,
            0.202,
            0.202);
        target.drawBox(
            colourBack,
            pos.add(
                new VectorXYZ(-(width / 2 - 0.10), 0.1f, -(width / 2 - 0.1))
                    .rotateY(directionAngle)),
            faceVector,
            height - 0.2,
            0.202,
            0.202);
      }
    }