Maya. Еще одна статья про сотворение террейна — S.T.A.L.K.E.R. Inside Wiki

Maya. Еще одна статья про сотворение террейна

Материал из S.T.A.L.K.E.R. Inside Wiki

Перейти к: навигация, поиск
Еще одна статья, рассказывающая про сотворение террейна.

Дело было вечером, делать было нечего…

Что-то до боли знакомое чувство. Не правда ли?

Ну вот, решил заняться абсолютно новой локацией, посмотрел как «пыс» локи в майе стряпают – понравилось. Дай думаю, свою забубеним, чем мы то хуже.

Залез майку, создал плоскость с нужной тесселяцией, пора крутить – вертеть.

Гляжу на рисунок так называемой будущей локации. Что-то поплохело враз. Тут тебе и перепады высот, и красивый холмик и озерцо с береговой линией…

Хочется, чтоб береговая линия поточнее была, незатейливые изгибы, холмики чтоб как в жизни.… Поплохело на душе от такого в раз. Это если сие каждый полик руками двигать, потом применять sculpt geom., свихнуться можно, тем более что размер карты 1х1км.

Все. За кофе….

Говорили же мне умные люди, что Maya весьма заносчивая дама, дураков и лентяев не терпит… Блин, а я как раз и то и другое. Че делать???

Есть конечно, еще способ. По нашему рисунку строим карту высот и применим displace. Хорошо. Уперев зад в стул открываю фотошоп. После 2-2.5часов, что-то получилось.

Maya terrain 1.jpg

Едем далее, открываем нашу дамочку, майя зовут, определяемся с шагом сетки. Хочется подетальнее отобразить, хочется – делаем.

Допустим, шаг в 20см вполне устроит. Создаем плоскость, указываем шаг сетки 0,2м, применяем. Что-то комп повис. Пойду за кофе… Возвращаюсь… Чуть кофе не разлил.

Задумался. Шаг сетки 0.2м, габариты 1000х1000м. это что же получается?

Кому охота – посчитайте, мне лень, и так понятно, что перебор за пару миллионов точно шкалит, даже без trianguliate. В ручную строить все это лень, пойду по пиву с ребятами вдарю.

Нет, не пойдешь!!!! Это еще кто? Нет, ну что за дамочка. А? Ладно, не пойду. Будем думать. Гляжу на карту высот. Определяюсь, где хотел бы поточнее отобразить . Ага, давай для простоты еще порисуем. По верх карты высот белым малюю карту подробностей. Вот, уже что-то.

Maya terrain 2.jpg

В принципе можно ручками по этой штуке полигонов добавить, но как-то лень. А что если заставить нашу «даму» поработать, пускай она унюхает различия между черным и белым, и в нужных местах полигонов добавить. Как оно? Вроде не плохо. Лезем в хелп. Т.к. нет такого плагина соберем скрипт. (в нете наткнулся на подобный разбор проблемы, вот от туда и позаимствуем)

Команда colorAtPoint возвратит вес цвета в указанной точке UV пространства от 0 (черный.) до 1 (белый).

Команда polyInfo может возвратить список вертексов у выделенного фэйса, если использовать флаг -faceToVertex(-fv).

Команда polyEditUV с флагом-q возвращает U и V значения выделенного вертекса отселектированного фэйса.

Команда ls с флагом–selection (-sl) выдаст на гора весь список имен отселектированных объектов. Кстати флаг -flatten (-fl)организует поименный список элементов, а не «оптовый через тире от и до». Некстати, если есть желание загнать в переменную нечто, возвращаемое любой командой, пользуйтесь символом обратного апострофа (не путать с прямым), например: string $aw[] = `ls -sl`;

Команда select позволяет варьировать наборы из активного листа выделенных элементов в зависимости от используемого флага, например флаг –clear (-cl) снимет выделение со всех объектов, а флаг –replace (-r) позволяет переопределить заново элементы активного листа. Краткое напоминание о любой команде можно получить, набрав в командной строке help, аргументом которой является запрашиваемая команда. Вот что возвращает Script Editor, например в случае:

help select;

// Result:

Synopsis: select [flags] [String...]

Flags:

-add -

-adn -allDependencyNodes

-ado -allDagObjects

-af -addFirst

-all -

-cl -clear

-d -deselect

-hi -hierarchy

-ne -noExpand

-r -replace

-tgl -toggle

-vis -visible

//

Очень интересная команда tokenize, позволяющая разбить строку на список элементов, которые можно занести в массив.

Команда polySubdivideFacet разбивает выделенный фэйс на части.

Команда sort сортирует элементы массива по возрастанию, например.

Команда print с любой переменной или константой в виде аргумента помогает организовать тесты выполнения кода. Строковый аргумент "\n" означает перевод строки при отображении ряда данных.

Цикл while дает возможность закольцевать кусок кода до тех пор, пока не выполнится какое-то условие.

Условный оператор if-else инструктирует Maya на выполнение блока кода, если проверочное условие соблюдается, а в противном случае – на выполнение альтернативного блока кода.

Выстраивается следующая технологическая цепочка:

1. Выделяем фэйс.

2. Определяем имя фэйса с помощью команды ls с флагом –sl.

3. Получаем список вертексов из 4 элементов, подставив имя фэйса в команду polyInfo с флагом -fv.

4. Определяем uv-координаты каждого элемента из полученного выше списка вертексов с помощью команды polyEditUV с флагом -q.

5. Сканируем все UV-пространство внутри полученных 4-х пар uv-координат на наличие нечерного цвета, используя команду colorAtPoint с указанием текущей пары uv-координат.

6. Если сканирование определяет наличие нечерного цвета – разбиваем выделенный фэйс.

Нет, майя издевается.

Вот же наглая сущность. Но обойдемся без словесной перепалки.

Вот кое-что и поконкретнее.


Тыкаем мышом в меш, переходим в режим выделения компонентов Face и селектируем нужный фэйс. После этого запускаем скрипт, часть кода которого приведена ниже. Код проверяет фэйс на «нечерность», то есть содержит ли фэйс светлые тона текстуры «карты подробностей».


//Заносим отселектированный фэйс в строковый массив $aw[]. Предварительно, разумеется, необходимо выделить этот фэйс.


string $aw[] = `ls -sl`;


//Получаем строку из имени, номера фэйса и списка номеров образующих вертексов, разделенных пробелами.


string $aw[] = `polyInfo -fv $aw`;


//Разбиваем полученную строку на список и заносим его в этот же массив. Номера всех 4-х вертексов теперь содержатся в массиве под индексами от 2-го до 5-го соответственно.


tokenize $aw[0] $aw;


//Для проверки распечатаем элементы массива


print $aw;


//Получаем uv-координаты 1-го вертекса по индексом 2 в массиве $aw[2]. Заносим в соответствующие массивы.


float $pNum[] = `polyEditUV -q ("pPlane1.map[" + $aw[2] + "]")` ;

$Ucoord[0] = $pNum[0]; $Vcoord[0] = $pNum[1];


//Получаем uv-координаты 2-го вертекса по индексом 3 в массиве $aw[3]. Заносим в соответствующие массивы.


float $pNum[] = `polyEditUV -q ("pPlane1.map[" + $aw[3] + "]")` ;

$Ucoord[1] = $pNum[0]; $Vcoord[1] = $pNum[1];


//Получаем uv-координаты 3-го вертекса по индексом 4 в массиве $aw[4]. Заносим в соответствующие массивы.


float $pNum[] = `polyEditUV -q ("pPlane1.map[" + $aw[4] + "]")` ;

$Ucoord[2] = $pNum[0]; $Vcoord[2] = $pNum[1];


//Получаем uv-координаты 4-го вертекса по индексом 5 в массиве $aw[5]. Заносим в соответствующие массивы.


float $pNum[] = `polyEditUV -q ("pPlane1.map[" + $aw[5] + "]")` ;

$Ucoord[3] = $pNum[0]; $Vcoord[3] = $pNum[1];


//Сортируем массивы с парами u-координат и v-координат по возрастанию. Минимальная имеет индекс 0 в массиве, Максимальная имеет индекс 1 в массиве.


$Ucoord = sort ($Ucoord); $Vcoord = sort ($Vcoord);


//Можно распечатать для контроля.


//print $Ucoord; print $Vcoord; print (" " + "\n");


//Зная информацию об этих парах можно организовать цикл сканирования участка в пределах UV-пространства, ограниченного значениями этих пар.


//Цикл сканирования UV-участка на наличие нечерного цвета


//Некий флаг-индикатор «нечерности». Если содержит 0, то фэйс «черный», если 1 – «нечерный».


$wFl = 0;

clear $cFl;


//Присваиваем цикловому шагу минимальное значение по u-координате.


float $uStep = $Ucoord[0];


//Присваиваем цикловому шагу минимальное значение по v-координате.


float $vStep = $Vcoord[0];


//Цикл по u-координате. Условие прекращения цикла $uStep <= $Ucoord[3].


while ($uStep <= $Ucoord[3])

{


//Цикл по u-координате. Условие прекращения цикла $vStep <= $Vcoord[3].


while ($vStep <= $Vcoord[3])

{

//print ("U= " + $uStep + " V= " + $vStep + "\n");


//Определяем цвет текстуры в указанных uv-координатах


$cFl = `colorAtPoint -u $uStep -v $vStep file1`;

if ($cFl[0] > 0)

{


//Если цвет нечерный, то есть >0, то в содержимое флага вносим 1, а цикл прерываем.


$wFl = 1;

break;

}

$vStep = $vStep + (($Vcoord[3] - $Vcoord[0])/$stepFl);

}

$vStep = $Vcoord[0];

if ($cFl[0] > 0)

{

break;

}

$uStep = $uStep + (($Ucoord[3] - $Ucoord[0])/$stepFl);

}

$uStep = $Ucoord[0];


Ну вот, кажись получилось. Ура!

Maya terrain 3.jpg

Теперь опробуем скрипт….

Maya terrain 4.jpg

Работает. Счетчик идет. В одном месте зудит…

Maya terrain 5.jpg

Вот как стал выглядеть наш меш после первого цикла. Еще 3-4 и все ок.

Maya terrain 6.jpg

Вот так то. Дамочка. Ты заносчива, а я настырнее. Вот что стало с мешем, теперь наглым образом проецируем карту высот на это безобразие, не забываем создать источник света , например ambiet, и пускаем дисплейс.

Maya terrain 7.jpg

Смотрим что получилось.

А вот наш террейн в полутонах, после применения дисплейса.

Maya terrain 8.jpg

Красота, не правда ли?

В чем прикол? Спросят многие, да в том, что дальше руками только поправить до финала высоты и группы сглаживания. Оттекстурить и все гут.

Что касается кол-ва полигонов, то всего 37000 с небольшим, до критического 150000 еще чапать и чапать.

Вот так то, даже такую заносчивую Дамочку как Майя, можно заставить работать.


Кого заинтересовал финальный вариант скрипта , в личку стучать.


Автор: ZVUKARb Великий лентяй Зоны.

Другие места
LANGUAGE