Geometry._updateExtend & Mesh.refreshBoundingInfo can cause Minor GC

When adding meshes with ~50k vertices, this method shows up under Minor GC

From Chrome’s profiler:

From the implementation, we can see that its creating a new object instead of setting a ref:

    Geometry.prototype._updateExtend = function (data) {
        if (data === void 0) { data = null; }
        if (this.useBoundingInfoFromGeometry && this._boundingInfo) {
            this._extend = {
                minimum: this._boundingInfo.minimum.clone(),
                maximum: this._boundingInfo.maximum.clone()
            };
        }
        else {
            if (!data) {
                data = this.getVerticesData(VertexBuffer.PositionKind);
            }
            this._extend = extractMinAndMax(data, 0, this._totalVertices, this.boundingBias, 3);
        }
    };

Additionally, we can see that extractMinAndMax creates three objects:

  • 2x Vector3
  • 1x { }
export function extractMinAndMax(
  positions: FloatArray,
  start: number,
  count: number,
  bias: Nullable<Vector2> = null,
  stride?: number
): { minimum: Vector3; maximum: Vector3 } {
  var minimum = new Vector3(
    Number.MAX_VALUE,
    Number.MAX_VALUE,
    Number.MAX_VALUE
  );
  var maximum = new Vector3(
    -Number.MAX_VALUE,
    -Number.MAX_VALUE,
    -Number.MAX_VALUE
  );

  if (!stride) {
    stride = 3;
  }

  for (
    var index = start, offset = start * stride;
    index < start + count;
    index++, offset += stride
  ) {
    const x = positions[offset];
    const y = positions[offset + 1];
    const z = positions[offset + 2];
    minimum.minimizeInPlaceFromFloats(x, y, z);
    maximum.maximizeInPlaceFromFloats(x, y, z);
  }

  if (bias) {
    minimum.x -= minimum.x * bias.x + bias.y;
    minimum.y -= minimum.y * bias.x + bias.y;
    minimum.z -= minimum.z * bias.x + bias.y;
    maximum.x += maximum.x * bias.x + bias.y;
    maximum.y += maximum.y * bias.x + bias.y;
    maximum.z += maximum.z * bias.x + bias.y;
  }

  return {
    minimum: minimum,
    maximum: maximum,
  };
}

This could likely be reused from this._extend if this._extend is defined.

extractMinAndMax is also used in Mesh.refreshBoundingInfo, so this applies to that as well.

totally agree we could have a toRef equivalent. Would you like creating a PR for it ?