Процедурний… будинок з генератором кімнат


74

Я розглядав деякі алгоритми та статті про процедурну генерацію підземелля. Проблема в тому, що я намагаюся створити будинок із кімнатами, і вони, здається, не відповідають моїм вимогам.

Для одного підземелля мають коридори, де в будинках є зали. І хоча спочатку вони можуть здатися однаковими, зал - це не що інше, як площа, яка не є кімнатою, тоді як коридор призначений спеціально для з'єднання однієї зони з іншою.

Ще одна важлива відмінність будинку - це те, що ти маєш конкретну ширину та висоту, і ти повинен заповнити всю річ приміщеннями та залами, тоді як у підземеллі - порожній простір.

Я думаю, що зали в будинку - це щось середнє між коридором підземелля (потрапляє в інші кімнати) і порожнім місцем у підземеллі (це чітко не визначено в коді).

Більш конкретно, вимоги:

  • Існує набір заздалегідь заданих кімнат, які
    я не можу створювати стіни та двері з льоту.
  • Кімнати можна повертати, але не змінювати їх
    знов, тому що у мене заздалегідь визначений набір кімнат, я можу лише повертати їх, а не змінювати їх розмір.
  • Розміри будинку встановлені і повинні бути повністю заповнені кімнатами (або залами),
    тобто я хочу заповнити будинок розміром 14х20 наявними кімнатами, упевнившись, що немає порожнього місця.

Ось кілька зображень, щоб зробити це трохи більш зрозумілим:

Типовий генератор підземелля Підземелля без коридорів Результат генератора будинку

Як бачите, в будинку "порожній простір" все ще проходить, і він переносить вас з однієї кімнати в іншу.

Отож, сказавши все це, можливо, будинок - це просто дійсно щільно забита підземелля з коридорами. Або це щось легше, ніж підземелля. Можливо, щось там є, і я цього не знайшов, бо я не знаю, що саме шукати.

Тут я хотів би отримати вашу допомогу: ви могли б дати мені вказівки, як створити цей алгоритм? Будь-які думки щодо того, які кроки він буде робити? Якщо ви створили генератор підземелля, як би ви змінили його, щоб він відповідав моїм вимогам? Ви можете бути настільки конкретними або такими ж загальними, як вам подобається. Я дуже хочу забрати твій мізок.


2
Незвичайна рекомендація: я настійно рекомендую перевірити книги Крістофера Олександра " Безчасний спосіб побудови" та "Шаблон мови" , книги архітектури, які сформували оригінальну основу для поняття (програмного) малюнка; вони по суті описують явну мову для будівель та житлових приміщень, які можна перетворити на процедурний метод побудови зверху вниз.
Стівен Стадницький

Особисто я б спробував скласти такий алгоритм, як відповідь egarcias. Почніть з генерування заповнювачів кімнат (великі площі, на які можна заповнити різну кількість кімнат. Кожен власник місця в кімнаті повинен мати між собою певний (або випадковий з нижчими межами) розрив між розмірами. Простір "пробіл" - це те, що було б вважається коридором , тобто простір , яке знаходиться в будинку , але не в кімнаті, а власники кімнати місця буде заповнені номерами випадкових розмірів , схожі на вашу "темницю без яких - або коридорів , наприклад.
Бенджамін Джонсон Danger

@pek Будь-ласка, створіть відповідь на своє рішення, не ставте цього питання.
MichaelHouse

@ Byte56 Готово. Щоб було зрозуміло, я це зробив, бо не хотів отримати кредит, оскільки робив лише те, що пропонували інші. Я розумію, хоча це не ідеально підходить для формату сайту, тому я додав свою відповідь.
пік

Дякую @pek Не турбуйтеся про отримання кредиту, це заслужено, і людям, які заходять на сайт, корисно бачити рішення (і найкраще бачити його там, де очікується).
MichaelHouse

Відповіді:


50

Я думаю, що це хороший випадок для використання або двійкового або потрійного простору.

На першому переході розділіть простір будинку на зали і {блоки кімнат}. Отримайте наступний великий шматок, розділіть його на {hall and chunk} або {2 шматки та зал між ними}. На кожному кроці обертайте напрямок нарізки на 90 градусів. Зупиніться, коли {більше не залишилося великих шматочків} або {загальна площа залу досягла межі}.

На другому переході розділіть залишилися шматки на кімнати. Отримайте наступний великий шматок і розділіть його. Пропустіть розбиття декількох не дуже великих шматочків навмання, щоб мати кілька великих кімнат.

Якщо будь-який зал стикається зі значно старшим залом, розмістіть там стіну (або стіну з дверима).

Підключіть кімнати із залами безпосередньо або через інші вже підключені кімнати.

Наприклад, ви можете побачити або мій результат, створений вручну, або C ++ - так само частково виконаний псевдо-код . Фінальний кадр:

фінальний знімок


Ось де моє дослідження призвело до розподілу простору. Ваш приклад з кодом дав мені дуже гарний початок. Зараз читаю на алгоритмах. Хоча одне питання: одна з моїх вимог - це те, що кімнати заздалегідь визначені (тобто є 2х2 кімнати з однією дверима, 1х1 з двома дверима, але не 2х2 з трьома дверима), тому я не можу розпочати перегородку, а потім вирішувати, де розміщуватиму двері . Я думаю, що я маю пам’ятати про свої обмеження, коли я розбиваю. Чи є у вас пропозиція, як я б пішов з цього приводу? У будь-якому випадку, дуже дякую за вашу відповідь та зусилля!
пік

@pek Я не впевнений, чи просто смертний може знайти академічне рішення для цієї проблеми. Ви можете спробувати встановити додаткові умови для кускового розбиття та розбивки коробки, а потім генерувати та скидати рівні, поки не знайдете такий, де всі умови можуть бути виконані.
Тіні під дощем

так, я сподівався, що я щось пропускаю. Першим моїм підходом було використання A *, щоб з'ясувати, як розмістити кімнати в заданому просторі, але для зали не вистачало логіки. Зараз я думаю, що я можу використовувати BSP для розміщення залів, а потім використовувати A * до блоків. Мене найбільше хвилює те, що це може бути занадто дорогим і не завжди дає результат. Але мені доведеться перевірити це спочатку. Може, це не буде так погано?
пік

2
@pek Я знайшов щось корисне, якщо ти все ще зацікавився. Подивіться на це , також google L-system.
Тіні під дощем

24

Ви можете скористатися тим, що бажаний дизайн обробляє кімнати у прямокутних приміщеннях, оточених коридорами. Маючи це на увазі, я би зробив це:

  1. Проектуйте коридори та «великі простори» для кімнат
  2. Заповніть кожен «великий простір» кімнатами

2 кроки

Заповнити великі простори кімнатами можна легко, якщо почати з кімнат на кордонах - вони мають певні обмеження, наприклад, кімнати, що виходять на коридор, можуть мати двері на цій стіні, але кімнати, звернені до "зовнішніх стін" не можуть (можливо, вони могли мати вікна). Кімнати, що знаходяться «всередині» великих блоків, потребуватимуть хоча б одного входу.


15

Отже, ось як я вирішив цю проблему. Але спочатку я хотів би подякувати @Shadows In Rain та @egarcia за їх відповіді. Вони дали мені гарне керівництво, що допомогло мені отримати певні результати.

Я використовував розділення простору Shadows In Rain, щоб створити основний будинок, а потім дотримувався порад egarcia, щоб заповнити територію кімнатами.

Розділення простору було досить простим, оскільки 90% коду було зроблено Shadows. Частина "заповнити кімнати" була дещо складнішою. Я вирішив використовувати систему планування псевдоінтерфейсів AI, яка використовує A * для належного розміщення кімнат. Хороша річ у використанні планування замість просто A * полягає в тому, що передумови допомагають значно скоротити простір пошуку.

Ось кілька скріншотів із результатами:

Фаза генерації плану поверху Фаза генерації плану поверху

Фаза розміщення кімнати Фаза розміщення кімнати

Тепер із з'єднувальними дверима!
Тепер із з'єднувальними дверима!


11

У Dahl & Rinde є дипломна робота про процедурну генерацію приміщень у приміщенні, в якій використовується підхід скелета та регіонів для заповнення інтер'єрів будівель кімнатами та передпокої. У статтю включені діаграми класів для їх прототипу. У їхній бібліографії також є кілька хороших посилань, включаючи згадану мову «Шаблон» .

Їх робота розроблена на основі спрощення припущень:

  • займається лише житловими будинками
  • відсутність розділених рівнів
  • обмеження форми будівель (конверт) повинно бути багатокутним
  • відсутність отворів у конверті
  • однакова або лінійно змінюється товщина конверта (IE немає форм пісочного годинника)
  • займаються лише будівлями, які потребують коридорів

Ось короткий огляд їх процесу:

  • Знайдіть скелет для конверта. Потім коридори розміщують уздовж каркаса на основі відстані від огортання, близькості до дверей або сходів і близькості до раніше розміщених коридорів.
  • Далі, залишився не коридорний простір розподіляється на максимально пов’язані ділянки, кожна з яких має єдину суцільну межу. У деяких випадках для цього знадобиться встановлення стіни.
  • Потім ці регіони діляться на квартири, намагаючись виділити принаймні одне вікно на одну квартиру. У деяких випадках менші підрозділи об'єднаються, щоб уникнути занадто малих квартир. Регіони без вікон просто ігноруються.
  • Нарешті, квартири поділяються на кімнати, використовуючи зважену схему, подібну до Вороного, як основу:

    • Насінні ваги використовуються для впливу на розміри приміщення. Насіння додають у двері та вікна. Додаються додаткові насіння, як правило, одне на бажане приміщення; хоча це прямо не вказано, схоже, що насіння розміщено уздовж зовнішніх стін квартири.
    • Починаючи з найдальшої точки, обчислюється лінія між даним насінням та усіма іншими точками, а потім ділиться відстань відносно відповідних ваг кінцевих точок (EG, якщо A&B мав ваги 1 & 4, то точка ділення буде 1/4 шляху від А до В). Колекція бісектних ліній разом із зовнішньою стінкою утворює клітинку для насіння.
    • Далі, скелет стіни S-Space (за Пепонісом та ін. 1997) створюється шляхом перегородки ділянки лініями, що виникають перпендикулярно від середніх точок між сусідніми парами зовнішніх стін (вікна чи двері).
    • Нарешті, стіни вибираються із скелета S-простору, які "максимально відповідають стінкам стінок Вороного".

3
Чи можете ви включити фотографії? Було б чудово. Я знімав папір, і створені ними кімнати виглядали добре з архітектурного POV.
congusbongus

Дуже цікавий метод, мені доведеться більш уважно його вивчити на предмет будь-яких ідей, які я можу від нього відібрати.
Draco18s

Я приїхав сюди, щоб відпочити від роботи ... Здивуйте, виходить моя тема досліджень. Мені лінь писати відповідь, грунтуючись на моєму власному дослідженні (я створив лише голі кістки альгоіртми, тому це все одно не варто) або описати підходи Даніла Наді до проблеми, тому я просто залишу це тут autodeskresearch.com/publications/…
Феліпе Гутьєррес
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.