Box3, Sphere: ограничивающие объёмы

В библиотеке Three.js ограничивающие объёмы играют ключевую роль в оптимизации сцены и обработке столкновений. Наиболее часто используются Box3 и Sphere, представляющие собой осесимметричные ограничивающие коробки и сферы соответственно. Они позволяют быстро определять пересечения объектов, проверять видимость и управлять пространственными отношениями между элементами сцены.


Box3: ограничивающий прямоугольный параллелепипед

Box3 описывает трёхмерный прямоугольный параллелепипед с осями, параллельными осям координат. Основные свойства и методы:

const box = new THREE.Box3();
box.min.set(-1, -1, -1);
box.max.set(1, 1, 1);
  • min — вектор THREE.Vector3, представляющий минимальные координаты (x, y, z) коробки.
  • max — вектор THREE.Vector3, представляющий максимальные координаты коробки.

Основные методы Box3

  1. setFromObject(object) — вычисляет ограничивающий объём для объекта и всех его потомков:
const box = new THREE.Box3();
box.setFromObject(mesh);
  1. setFromCenterAndSize(center, size) — создаёт коробку по центру и размерам:
const center = new THREE.Vector3(0, 0, 0);
const size = new THREE.Vector3(2, 2, 2);
const box = new THREE.Box3().setFromCenterAndSize(center, size);
  1. getCenter(target) — возвращает центр коробки:
const center = new THREE.Vector3();
box.getCenter(center);
  1. getSize(target) — возвращает размеры по осям:
const size = new THREE.Vector3();
box.getSize(size);
  1. expandByPoint(point) — расширяет коробку, чтобы включить заданную точку:
box.expandByPoint(new THREE.Vector3(2, 3, 1));
  1. containsPoint(point) — проверяет, находится ли точка внутри коробки:
const inside = box.containsPoint(new THREE.Vector3(0.5, 0.5, 0.5));
  1. intersectsBox(box) — проверяет пересечение с другой коробкой:
const box2 = new THREE.Box3(new THREE.Vector3(-0.5, -0.5, -0.5), new THREE.Vector3(0.5, 0.5, 0.5));
const intersects = box.intersectsBox(box2);
  1. union(box) — объединяет текущую коробку с другой:
box.union(box2);

Box3 часто используется для:

  • Быстрой проверки столкновений между объектами.
  • Определения видимости объектов через фрустрационные проверки.
  • Расчёта центра сцены и размеров объектов для позиционирования камеры.

Sphere: ограничивающая сфера

Sphere описывает сферу с центром и радиусом, идеально подходящую для объектов с приблизительно сферической формой. Основные свойства:

const sphere = new THREE.Sphere();
sphere.center.set(0, 0, 0);
sphere.radius = 1;
  • center — вектор THREE.Vector3 центра сферы.
  • radius — радиус сферы.

Основные методы Sphere

  1. setFromPoints(points, optionalCenter) — вычисляет минимальную сферу, включающую массив точек:
const points = [new THREE.Vector3(1, 0, 0), new THREE.Vector3(0, 1, 0)];
const sphere = new THREE.Sphere().setFromPoints(points);
  1. containsPoint(point) — проверяет, лежит ли точка внутри сферы:
const inside = sphere.containsPoint(new THREE.Vector3(0.5, 0, 0));
  1. distanceToPoint(point) — вычисляет расстояние от поверхности сферы до точки:
const distance = sphere.distanceToPoint(new THREE.Vector3(2, 0, 0));
  1. intersectsSphere(sphere) — проверяет пересечение с другой сферой:
const sphere2 = new THREE.Sphere(new THREE.Vector3(1, 1, 1), 1);
const intersects = sphere.intersectsSphere(sphere2);
  1. expandByPoint(point) — расширяет сферу, чтобы включить новую точку:
sphere.expandByPoint(new THREE.Vector3(2, 0, 0));
  1. clampPoint(point, target) — возвращает ближайшую точку на поверхности сферы к заданной точке:
const closest = new THREE.Vector3();
sphere.clampPoint(new THREE.Vector3(2, 0, 0), closest);

Сравнение Box3 и Sphere

Свойство Box3 Sphere
Форма Ось-параллельный параллелепипед Сфера
Проверка точек Быстро через containsPoint Быстро через containsPoint
Проверка пересечений intersectsBox intersectsSphere
Применение Объекты с прямоугольной геометрией, сцена, фрустрация Сферические или округлые объекты, столкновения, радиусные зоны
Вычисление объёма Через getSize Через radius и формулы объёма

Практическое использование

Определение видимости камеры:

const frustum = new THREE.Frustum();
const cameraViewProjectionMatrix = new THREE.Matrix4();

camera.updateMatrixWorld();
camera.matrixWorldInverse.copy(camera.matrixWorld).invert();
cameraViewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
frustum.setFromProjectionMatrix(cameraViewProjectionMatrix);

if (frustum.intersectsBox(box)) {
    // объект видим
}

Столкновения объектов:

if (box1.intersectsBox(box2)) {
    // обработка столкновения
}

if (sphere1.intersectsSphere(sphere2)) {
    // обработка столкновения сфер
}

Оптимизация сцены:

Box3 и Sphere позволяют отсеивать объекты, находящиеся вне видимой области, и ускорять рендеринг при больших количествах объектов, комбинируя их с пространственными структурами вроде Octree или BVH.


Взаимодействие с Mesh и Geometry

Box3 и Sphere можно создавать напрямую из объектов:

const geometry = new THREE.BoxGeometry(1, 2, 3);
const mesh = new THREE.Mesh(geometry, material);

const boundingBox = new THREE.Box3().setFromObject(mesh);
const boundingSphere = new THREE.Sphere().setFromPoints(geometry.attributes.position.array.map((v, i) => new THREE.Vector3(
    geometry.attributes.position.array[i*3],
    geometry.attributes.position.array[i*3 + 1],
    geometry.attributes.position.array[i*3 + 2]
)));

Для геометрий BufferGeometry Three.js также предоставляет метод computeBoundingBox() и computeBoundingSphere(), которые автоматически вычисляют ограничения:

geometry.computeBoundingBox();
geometry.computeBoundingSphere();

Эти методы сохраняют результаты в свойствах geometry.boundingBox и geometry.boundingSphere, что удобно для быстрой проверки столкновений и оптимизации рендеринга.


Box3 и Sphere являются фундаментальными инструментами при работе с трехмерными сценами, обеспечивая эффективное управление пространственными отношениями объектов, ускоряя проверку столкновений и облегчая интеграцию с камерами и физическими системами. Они служат основой для создания более сложных алгоритмов пространственного анализа и оптимизации.