예제 #1
0
  /** 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;
  }
예제 #2
0
  //	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);
  }
예제 #3
0
  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;
  }