computeBoundingSphere method
void
computeBoundingSphere()
inherited
Computes the bounding sphere of the geometry, and updates the boundingSphere
attribute.
The engine automatically computes the bounding sphere when it is needed, e.g., for ray casting or view frustum culling. You may need to recompute the bounding sphere if the geometry vertices are modified.
Implementation
void computeBoundingSphere() {
boundingSphere ??= BoundingSphere();
final position = attributes["position"];
final morphAttributesPosition = morphAttributes["position"];
if (position != null && position is GLBufferAttribute) {
boundingSphere!.set(Vector3.zero(), 99999999999);
return;
}
if (position != null) {
// first, find the center of the bounding sphere
final center = boundingSphere!.center;
_bufferGeometrybox.setFromBuffer(position);
// process morph attributes if present
if (morphAttributesPosition != null) {
for (int i = 0, il = morphAttributesPosition.length; i < il; i++) {
final morphAttribute = morphAttributesPosition[i];
_bufferGeometryboxMorphTargets.setFromBuffer(morphAttribute);
if (morphTargetsRelative) {
_bufferGeometryvector.add2(_bufferGeometrybox.min, _bufferGeometryboxMorphTargets.min);
_bufferGeometrybox.expandByPoint(_bufferGeometryvector);
_bufferGeometryvector.add2(_bufferGeometrybox.max, _bufferGeometryboxMorphTargets.max);
_bufferGeometrybox.expandByPoint(_bufferGeometryvector);
} else {
_bufferGeometrybox.expandByPoint(_bufferGeometryboxMorphTargets.min);
_bufferGeometrybox.expandByPoint(_bufferGeometryboxMorphTargets.max);
}
}
}
_bufferGeometrybox.getCenter(center);
// second, try to find a boundingSphere with a radius smaller than the
// boundingSphere of the boundingBox: sqrt(3) smaller in the best case
double maxRadiusSq = 0;
for (int i = 0, il = position.count; i < il; i++) {
_bufferGeometryvector.fromBuffer(position, i);
maxRadiusSq = math.max(
maxRadiusSq,
center.distanceToSquared(_bufferGeometryvector),
);
}
// process morph attributes if present
if (morphAttributesPosition != null) {
for (int i = 0, il = morphAttributesPosition.length; i < il; i++) {
final morphAttribute = morphAttributesPosition[i];
final morphTargetsRelative = this.morphTargetsRelative;
for (int j = 0, jl = morphAttribute.count; j < jl; j++) {
_bufferGeometryvector.fromBuffer(morphAttribute, j);
if (morphTargetsRelative) {
_bufferGeometryoffset.fromBuffer(position, j);
_bufferGeometryvector.add(_bufferGeometryoffset);
}
maxRadiusSq = math.max(
maxRadiusSq,
center.distanceToSquared(_bufferGeometryvector),
);
}
}
}
boundingSphere!.radius = math.sqrt(maxRadiusSq);
if (boundingSphere?.radius == null) {
console.warning('BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values. $this');
}
}
}