getConvexTrianglePillar method

void getConvexTrianglePillar(
  1. int xi,
  2. int yi,
  3. bool getUpperTriangle
)

Get a triangle in the terrain in the form of a triangular convex shape.

Implementation

void getConvexTrianglePillar(int xi, int yi, bool getUpperTriangle) {
  ConvexPolyhedron result = pillarConvex;
  Vec3 offsetResult = pillarOffset;

  if (cacheEnabled) {
    final data = getCachedConvexTrianglePillar(xi, yi, getUpperTriangle);

    if(data != null){
      pillarConvex = data.convex;
      pillarOffset = data.offset;
      return;
    }

    result = ConvexPolyhedron();
    offsetResult = Vec3();

    pillarConvex = result;
    pillarOffset = offsetResult;
  }

  final data = this.data;
  final elementSize = this.elementSize;

  // Reuse verts if possible
  if(result.vertices.isEmpty){
    for (int i = 0; i < 6; i++) {
      result.vertices.add(Vec3());
    }
  }

  // Reuse faces if possible
  bool wasEmpty = result.faces.isEmpty;
  result.faces = wasEmpty? List.filled(5, []):result.faces;
  if(wasEmpty){
    for (int i = 0; i < 5; i++) {
      if (result.faces[i].isEmpty) {
        int len = 4;
        if(i < 2){
          len = 3;
        }
        result.faces[i] = List.filled(len, 0);
      }
    }
  }

  final verts = result.vertices;
  final faces = result.faces;

  final h =(
    math.min(
      math.min(
        data[xi][yi],
        data[xi + 1][yi]
      ),
      math.min(
        data[xi][yi + 1],
        data[xi + 1][yi + 1]
      )
    ) - minValue!
  ) / 2 +minValue!;

  if (!getUpperTriangle) {
    // Center of the triangle pillar - all polygons are given relative to this one
    offsetResult.set(
      (xi + 0.25) * elementSize, // sort of center of a triangle
      (yi + 0.25) * elementSize,
      h // vertical center
    );

    // Top triangle verts
    verts[0].set(-0.25 * elementSize, -0.25 * elementSize, data[xi][yi] - h);
    verts[1].set(0.75 * elementSize, -0.25 * elementSize, data[xi + 1][yi] - h);
    verts[2].set(-0.25 * elementSize, 0.75 * elementSize, data[xi][yi + 1] - h);

    // bottom triangle verts
    verts[3].set(-0.25 * elementSize, -0.25 * elementSize, -h - 1);
    verts[4].set(0.75 * elementSize, -0.25 * elementSize, -h - 1);
    verts[5].set(-0.25 * elementSize, 0.75 * elementSize, -h - 1);

    // top triangle
    faces[0][0] = 0;
    faces[0][1] = 1;
    faces[0][2] = 2;

    // bottom triangle
    faces[1][0] = 5;
    faces[1][1] = 4;
    faces[1][2] = 3;

    // -x facing quad
    faces[2][0] = 0;
    faces[2][1] = 2;
    faces[2][2] = 5;
    faces[2][3] = 3;

    // -y facing quad
    faces[3][0] = 1;
    faces[3][1] = 0;
    faces[3][2] = 3;
    faces[3][3] = 4;

    // +xy facing quad
    faces[4][0] = 4;
    faces[4][1] = 5;
    faces[4][2] = 2;
    faces[4][3] = 1;
  } else {
    // Center of the triangle pillar - all polygons are given relative to this one
    offsetResult.set(
      (xi + 0.75) * elementSize, // sort of center of a triangle
      (yi + 0.75) * elementSize,
      h // vertical center
    );

    // Top triangle verts
    verts[0].set(0.25 * elementSize, 0.25 * elementSize, data[xi + 1][yi + 1] - h);
    verts[1].set(-0.75 * elementSize, 0.25 * elementSize, data[xi][yi + 1] - h);
    verts[2].set(0.25 * elementSize, -0.75 * elementSize, data[xi + 1][yi] - h);

    // bottom triangle verts
    verts[3].set(0.25 * elementSize, 0.25 * elementSize, -h - 1);
    verts[4].set(-0.75 * elementSize, 0.25 * elementSize, -h - 1);
    verts[5].set(0.25 * elementSize, -0.75 * elementSize, -h - 1);

    // Top triangle
    faces[0][0] = 0;
    faces[0][1] = 1;
    faces[0][2] = 2;

    // bottom triangle
    faces[1][0] = 5;
    faces[1][1] = 4;
    faces[1][2] = 3;

    // +x facing quad
    faces[2][0] = 2;
    faces[2][1] = 5;
    faces[2][2] = 3;
    faces[2][3] = 0;

    // +y facing quad
    faces[3][0] = 3;
    faces[3][1] = 4;
    faces[3][2] = 1;
    faces[3][3] = 0;

    // -xy facing quad
    faces[4][0] = 1;
    faces[4][1] = 4;
    faces[4][2] = 5;
    faces[4][3] = 2;
  }
  result.computeNormals();
  result.computeEdges();
  result.updateBoundingSphereRadius();
  setCachedConvexTrianglePillar(xi, yi, getUpperTriangle, result, offsetResult);
}