Докуметация Cтарт Статьи Форум Лента Вход
Не официальное русскоязычное сообщество
Главная
    Статьи
        Основы
            Bounding Box

Bounding Box

Опубликованно: 15.08.2015, 13:33
Последняя редакция, AdiDOS: 07.05.2017 9:15

Bounding Box (Ограничивающая Коробка) мы знаем что любая геометрическая модель в  современной 3d графике состоит из вершин а вершины таким образом составляют полигоны ну и естественно с полигонов строится модель и некоторые модели могут состоять из тысячи вершин ну и как я уже писал чем больше вершин тем сложней видеокарте рисовать , вот и разработчики придумывали разные способы оптимизации моделей , вот по сути Bounding Box и есть один из способов оптимизации.

В некоторых случаях нам нужно определить нашу модель ну допустим нам нужно выделить её мышью , давайте представим что у нас 100 моделей на сцене и каждая состоит из 1000 вершин , теоретически все просто проходим циклом все модели и вычисляем координаты с каждой вершиной на пересечение если наша мышь попадает с конкретной модели то вот и выделяем его.

Итого 100*1000 =100000 и тут мы видим что  наша игра или редактор ну неважно короче тормозит из за длительных вычислений  , вот тут и приходит на помощь Bounding Box.

Строится Bounding Box по максимальным вершинам модели имеет 8 вершин , я веду к тому что не проще пройтись по коробкам вычислить с какой коробкой мышь пересекается 8*100 = 800 а потом в этой модели посчитать точку пересечения , да по моему в 100 раз быстрее ну далее приведу пример коробки в jme3.

package test;

import com.jme3.app.SimpleApplication;
import com.jme3.bounding.BoundingBox;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer;
import com.jme3.scene.shape.Box;

public class BoundingBoxTest extends SimpleApplication {

 public static void main(String[] args) {
   new BoundingBoxTest().start();

 }

 @Override
 public void simpleInitApp() {
   flyCam.setMoveSpeed(5);
   Box box = new Box(1, 1, 1);// Создаем куб и указываем размер по трем осям
   Geometry geomBox = new Geometry("Box", box); // Создание геометрического объекта
   Material matBox = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
   matBox.setTexture("ColorMap", assetManager.loadTexture("Interface/Logo/Monkey.jpg"));
   geomBox.setMaterial(matBox);
   rootNode.attachChild(geomBox);
   drawBoundingBox(geomBox, 0.1f, 0.3f);

 }
 //Метод прорисовывает грани модели
 //offset отступ линий от модели
 //lineLen длинна линий
 private void drawBoundingBox(Geometry geom, float offset, float lineLen){
   geom.updateModelBound(); //Пересчитывание коробки
   BoundingBox bb = (BoundingBox)geom.getModelBound();

   Vector3f cent = bb.getCenter(); //Координаты центра модели
   float xex = bb.getXExtent(); //Размер Модели по оси Х
   float xey = bb.getYExtent(); //Размер Модели по оси Y
   float xez = bb.getXExtent(); //Размер Модели по оси Z

   Mesh mesh = new Mesh();
   mesh.setMode(Mesh.Mode.Lines);

   float[] lines = new float[]{
                   //Передний правый верхний
                   cent.x+xex + offset, cent.y+xey+offset, cent.z+xez+offset
                   ,cent.x+xex + offset- lineLen, cent.y+xey+offset, cent.z+xez+offset
                   ,cent.x+xex + offset, cent.y+xey+offset- lineLen, cent.z+xez+offset
                   ,cent.x+xex + offset, cent.y+xey+offset, cent.z+xez+offset- lineLen
                   //Передний левый верхний
                   ,cent.x-xex - offset, cent.y+xey+offset, cent.z+xez+offset
                   ,cent.x-xex - offset+lineLen, cent.y+xey+offset, cent.z+xez+offset
                   ,cent.x-xex - offset, cent.y+xey+offset-lineLen, cent.z+xez+offset
                   ,cent.x-xex - offset, cent.y+xey+offset, cent.z+xez+offset-lineLen
                   //Передний правый нижний
                   ,cent.x+xex+offset, cent.y-xey-offset, cent.z+xez+offset
                   ,cent.x+xex+offset-lineLen, cent.y-xey-offset, cent.z+xez+offset
                   ,cent.x+xex+offset, cent.y-xey-offset+lineLen, cent.z+xez+offset
                   ,cent.x+xex+offset, cent.y-xey-offset, cent.z+xez+offset-lineLen
                   //Передний левый нижний
                   ,cent.x-xex-offset, cent.y-xey-offset, cent.z+xez+offset
                   ,cent.x-xex-offset+lineLen, cent.y-xey-offset, cent.z+xez+offset
                   ,cent.x-xex-offset, cent.y-xey-offset+lineLen, cent.z+xez+offset
                   ,cent.x-xex-offset, cent.y-xey-offset, cent.z+xez+offset-lineLen
                   //Задний правый верхний
                   ,cent.x+xex + offset, cent.y+xey+offset, cent.z-xez-offset
                   ,cent.x+xex + offset- lineLen, cent.y+xey+offset, cent.z-xez-offset
                   ,cent.x+xex + offset, cent.y+xey+offset- lineLen, cent.z-xez-offset
                   ,cent.x+xex + offset, cent.y+xey+offset, cent.z-xez-offset+lineLen
                   //Задний левый верхний
                   ,cent.x-xex - offset, cent.y+xey+offset, cent.z-xez-offset
                   ,cent.x-xex - offset+lineLen, cent.y+xey+offset, cent.z-xez-offset
                   ,cent.x-xex - offset, cent.y+xey+offset-lineLen, cent.z-xez-offset
                   ,cent.x-xex - offset, cent.y+xey+offset, cent.z-xez-offset+lineLen
                   //Задний правый нижний
                   ,cent.x+xex+offset, cent.y-xey-offset, cent.z-xez-offset
                   ,cent.x+xex+offset-lineLen, cent.y-xey-offset, cent.z-xez-offset
                   ,cent.x+xex+offset, cent.y-xey-offset+lineLen, cent.z-xez-offset
                   ,cent.x+xex+offset, cent.y-xey-offset, cent.z-xez-offset+lineLen
                   //Задний левый нижний
                   ,cent.x-xex-offset, cent.y-xey-offset, cent.z-xez-offset
                   ,cent.x-xex-offset+lineLen, cent.y-xey-offset, cent.z-xez-offset
                   ,cent.x-xex-offset, cent.y-xey-offset+lineLen, cent.z-xez-offset
                   ,cent.x-xex-offset, cent.y-xey-offset, cent.z-xez-offset+lineLen};

   //Установка вершинного буфера
   mesh.setBuffer(VertexBuffer.Type.Position, 3,lines);
   //Установка индексного буфера
   mesh.setBuffer(VertexBuffer.Type.Index, 2, new int[]{
                             0,1, 0,2, 0,3, 4,5 ,4,6 ,4,7
                             ,8,9 ,8,10 ,8,11 ,12,13 ,12,14 ,12,15
                             ,16,17 ,16,18 ,16,19 ,20,21 ,20,22 ,20,23
                             ,24,25 ,24,26 ,24,27 ,28,29 ,28,30 ,28,31});
   Geometry geomLines = new Geometry("lines", mesh);
   Material matlines = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
   matlines.setColor("Color", ColorRGBA.Red);
   geomLines.setMaterial(matlines);
   rootNode.attachChild(geomLines);

 }
}

1

2

Bounding Box можно используется не только в вычислениях мыши но и определения видимости камеры да и активно используется в физике.

Хочу добавить в коде я использовал функцию updateModelBound() она пересчитывает все вершины модели и заново строит коробку , если большая модель и функция вызывается в реал тайме то может привести к торможению вашего приложения, так что старайтесь вызывать её или при изменении ваших вершил или по надобности.

Спасибо за внимание!!

Добавить комментарий

jMonkeyEngine.ru © 2017. Все права сохранены.