convexHeightfield method

bool convexHeightfield(
  1. ConvexPolyhedron si,
  2. Heightfield sj,
  3. Vec3 xi,
  4. Vec3 xj,
  5. Quaternion qi,
  6. Quaternion qj,
  7. Body bi,
  8. Body bj, [
  9. Shape? rsi,
  10. Shape? rsj,
  11. bool justTest = false,
])

Implementation

bool convexHeightfield(
  ConvexPolyhedron si,
  Heightfield sj,
  Vec3 xi,
  Vec3 xj,
  Quaternion qi,
  Quaternion qj,
  Body bi,
  Body bj,
  [
    Shape? rsi,
    Shape? rsj,
    bool justTest = false
]){
  final data = sj.data;
  final w = sj.elementSize;
  final radius = si.boundingSphereRadius;
  final worldPillarOffset = _convexHeightfieldTmp2;
  final faceList = convexHeightfieldFaceList;

  // Get sphere position to heightfield local!
  final localConvexPos = _convexHeightfieldTmp1;
  Transform.pointToLocalFrame(xj, qj, xi, localConvexPos);

  // Get the index of the data points to test against
  int iMinX = ((localConvexPos.x - radius) / w).floor() - 1;

  int iMaxX = ((localConvexPos.x + radius) / w).ceil() + 1;
  int iMinY = ((localConvexPos.y - radius) / w).floor() - 1;
  int iMaxY = ((localConvexPos.y + radius) / w).ceil() + 1;

  // Bail out if we are out of the terrain
  if (iMaxX < 0 || iMaxY < 0 || iMinX > data.length || iMinY > data[0].length) {
    return false;
  }

  // Clamp index to edges
  if (iMinX < 0) {
    iMinX = 0;
  }
  if (iMaxX < 0) {
    iMaxX = 0;
  }
  if (iMinY < 0) {
    iMinY = 0;
  }
  if (iMaxY < 0) {
    iMaxY = 0;
  }
  if (iMinX >= data.length) {
    iMinX = data.length - 1;
  }
  if (iMaxX >= data.length) {
    iMaxX = data.length - 1;
  }
  if (iMaxY >= data[0].length) {
    iMaxY = data[0].length - 1;
  }
  if (iMinY >= data[0].length) {
    iMinY = data[0].length - 1;
  }

  final List<double> minMax = [0,0];
  sj.getRectMinMax(iMinX, iMinY, iMaxX, iMaxY, minMax);
  final min = minMax[0];
  final max = minMax[1];

  // Bail out if we're cant touch the bounding height box
  if (localConvexPos.z - radius > max || localConvexPos.z + radius < min) {
    return false;
  }

  for (int i = iMinX; i < iMaxX; i++) {
    for (int j = iMinY; j < iMaxY; j++) {
      bool? intersecting = false;

      // Lower triangle
      sj.getConvexTrianglePillar(i, j, false);
      Transform.pointToWorldFrame(xj, qj, sj.pillarOffset, worldPillarOffset);
      if (
        xi.distanceTo(worldPillarOffset) <
        sj.pillarConvex.boundingSphereRadius + si.boundingSphereRadius
      ) {
        intersecting = convexConvex(
          si,
          sj.pillarConvex,
          xi,
          worldPillarOffset,
          qi,
          qj,
          bi,
          bj,
          null,
          null,
          justTest,
          faceList,
          null
        );
      }

      if (justTest && intersecting) {
        return true;
      }

      // Upper triangle
      sj.getConvexTrianglePillar(i, j, true);
      Transform.pointToWorldFrame(xj, qj, sj.pillarOffset, worldPillarOffset);
      if (
        xi.distanceTo(worldPillarOffset) <
        sj.pillarConvex.boundingSphereRadius + si.boundingSphereRadius
      ) {
        intersecting = convexConvex(
          si,
          sj.pillarConvex,
          xi,
          worldPillarOffset,
          qi,
          qj,
          bi,
          bj,
          null,
          null,
          justTest,
          faceList,
          null
        );
      }

      if (justTest && intersecting) {
        return true;
      }
    }
  }

  return false;
}