Схоже, ти хочеш дізнатися про Дерева!
І я серйозно кажу, якщо ви зараз перебираєте масив усіх своїх кубів, то вам дійсно слід заглянути в різні структури просторових даних. У цьому випадку найкращий спосіб уявити свій світ кубів - це дерево.
Перш ніж розібратися в причинах, чому, давайте подумаємо про нашу проблему. Ми шукаємо рішення, де за якомога менші витрати ми зможемо отримати список кубів поблизу, з якими може зіткнутися гравець. Цей список повинен бути максимально невеликим, але максимально точним.
Тепер, щоб визначити цю зону, нам потрібно віднести простір координат нашого гравця до координатного простору карти куба; тобто нам потрібно зіставити положення програвача з плаваючою комою на дискретний індекс багатовимірного масиву кубів (наприклад, нотація може бути world[31][31][31]
, тобто точна середина для багатовимірного масиву 64 * 64 * 64).
Ми можемо просто обчислити навколишні блоки за допомогою цього ж дискретного індексування, можливо, відбираємо лише куби, що знаходяться поблизу, але це все ще потребує постійного перерахунку і не допускає будь-яких об'єктів, які не дискретні в розміщенні (тобто не можуть відображатись на кубі карта).
Ідеальна ситуація - це набір відер, які містять наші набори кубів для окремих ділянок нашої кубкової карти, розділених порівну, тому замість того, щоб перераховувати навколишню територію, ми просто переміщуємось у ці зони та виходимо з них . Для будь-якого нетривіального обчислення, зберігання таких даних може усунути повторення всіх кубів, і лише ці окремі набори, які знаходяться поруч.
Питання: як ми це реалізуємо?
Для світу 64 * 64 * 64 уявіть, що він розбився на 8 * 8 * 8 зон . Це означає, що у вашому світі у вас буде 8 зон на вісь (X, Y, Z). Кожна з цих зон міститиме 8 кубів, які легко отримати за допомогою цього нового спрощеного індексу.
Якщо вам потрібно було виконати операцію на наборі кубів, що знаходяться поблизу, замість того, щоб повторювати кожен куб у вашому світі, ви можете просто повторити ці зони , розбивши максимальну кількість ітерацій від початкових 64 * 64 * 64 (262144) до всього 520 (8 * 8 * 8 + 8).
Тепер зменшіть масштаб із цього світу зон і розташуйте зони у великих суперзонах ; де кожна суперзона містить 2 * 2 * 2 регулярних зони . Оскільки ваш світ наразі містить 512 (8 * 8 * 8) зон , ми можемо розділити 8 * 8 * 8 зон на 64 (4 * 4 * 4) суперзони , розділивши 8 зон на 2 зони на суперзону . Застосовуючи ту саму логіку зверху, це дозволило б порушити максимальні ітерації від 512 до 8, щоб знайти суперзону ; а потім максимум 64, щоб знайти зону, що триває(всього макс. 72)! Ви можете бачити, як це економить уже багато ітерацій (262144: 72).
Я впевнений, що тепер ви можете бачити, наскільки корисні дерева. Кожна зона є гілкою на дереві, кожна суперзона є попередньою гілкою. Ви просто об’їжджаєте дерево, щоб знайти те, що вам потрібно; використання менших наборів даних для мінімізації загальної вартості.
Наведена нижче діаграма повинна допомогти вам уявити концепцію. (зображення з Вікіпедії: жовтені ):
Відмова:
В ідеальному режимі, як описано вище, де ваш світ вокселів вже розміщений у багатовимірному масиві фіксованого розміру, ви можете просто запитати позицію гравця, а потім індексувати навколишні блоки із вартістю O (1)! (Див. Пояснення Олховського) Але це стає складніше, коли ти починаєш враховувати, що твій світ рідко має фіксований розмір у воксельній грі; і може знадобитися ваша структура даних, щоб мати можливість завантажувати цілі суперзони з HDD в пам'ять. На відміну від багатовимірного масиву фіксованого розміру, дерева легко дозволяють це без зайвого часу, витраченого на комбінаційні алгоритми.