главная страница статьи файлы о сайте ссылки |
Георгий Мошкин файлы по теме: blender2006.zip
(546 kb) - 3d модель, исходники экспортера для Blender и загрузчика
на Delphi + exe Займёмся экспортом нашей модели. Для этого нужно написать простенький скрипт на языке Python, который записывает модель в текстовый файл по нашим правилам. Для написания скрипта вы можете использовать встроенный в Blender текстовый редактор. Для этого создайте окно (как создавать окго см. часть 1, шаг 12) и установите его тип (как установить нужный "Window type" см. часть 1, шаг 13) на "Text Editor". 1. Скрипт для Blender необходимо начинать с заголовочной части: #!BPY """ В смомом начале следует обязательная строчка
#!BPY, которая даёт Blender-у понять, что это скрипт в правильном
формате (Blender Python script). Обратите внимание на строчки с трёмя двойными кавычками (""") - их добавлять обязательно, как это показано выше.
2. После заголовка файла следует установить "описательные" переменные, которые дадут пользователям больше информации об авторе скрипта, а также краткую инструкцию по использованию. __author__
= ["Georgy Moshkin"] Etot skript zapisivaet scenu v nash format. Prosto zapustite skript. """ __author__ - список авторов скрипта.
Авторы записываются в кавычках через запятую (например: ["автор1","автор2","автор3"]).
3. Теперь следует подключить необходимые модули. import Blender После команды import стоит список из подключаемых модулей. Мы подключили только один модуль - Blender.
4. Создадим диалог, который позволит пользователю выбрать имя файла для записи. Эту строчку нужно добавить в самый конец исходника скрипта: Blender.Window.FileSelector(my_export, "Export v nash format") my_export - это название функции,
которой будет передано выбранное пользователем имя файла.
5. Приступим к написанию функции, отвечающий за экспорт сцены в файл. Это функция my_export: def
my_export(filename): Мы сделали заготовку функции.
6. Перед началом экспорта необходимо получить
доступ к объектам сцены. MYOBJECTS
= Blender.Scene.GetCurrent().getChildren()
7. Теперь мы должны просмотреть все объекты и распознать их тип. Например, для мешей: for object in MYOBJECTS: Это цикл с for, который перебирает все объекты object из массива MYOBJECTS. Если тип объекта отличен от Mesh, то вызывается команда continue, которая переходит к следующему элементу массива. Если же мы нашли объект типа "меш", то выведем его имя в окно консоли командой print. Команду print удобно использовать при отладке скриптов: в любом месте вашего скрипта вы можете добавить вывод отладочной информации в консоль.
8. Раззмотрим простейший скрипт, который выведет имена мешей, ламп и камер, которые имеются в нашей сцене: - - - НАЧАЛО КОДА - - -
#!BPY # -------------------------------------------------- # Peremennie dlya dobavlenia knopki v menu Blender-a # ================================================== """ Name: 'Nash format...' Blender: 241 Group: 'Export' Tooltip: 'Nash format...' """ # ------------------------------------ # Informacia dlya polzovateley skripta # ==================================== __author__ = ["Georgy Moshkin"] __url__ = ("http://www.tmtlib.narod.ru") __version__ = "1.0" __bpydoc__ = """\ Etot skript zapisivaet scenu v nash format. Prosto zapustite skript. """ # ----------------------- # Dobavlyaem nujnie uniti # ======================= import Blender # -------------------------- # Glavnaya procedura exporta # ========================== def my_export(filename): # -=((( Otrkoem file dlya zapisi )))=- myfile = open(filename, 'w') # -=((( Poluchim spisok obyektov tekushey sceni )))=- MYOBJECTS = Blender.Scene.GetCurrent().getChildren() # -=((( Proydemsa po vsem objektam )))=- # export Meshey for object in MYOBJECTS: if object.getType() != 'Mesh': continue print 'mesh:' + object.name # export Lamp for object in MYOBJECTS: if object.getType() != 'Lamp': continue print 'lamp:' + object.name # export Camer for object in MYOBJECTS: if object.getType() != 'Camera': continue print 'camera:' + object.name myfile.close() # -------------------------------------------- # Vizivaem okno vibora imeni faila dlya zapisi # ============================================ Blender.Window.FileSelector(my_export, "Export v nash format") - - - КОНЕЦ КОДА - - - скачать
исходный код Теперь осталось дописать код для экспорта мешей, ламп и камер - как раз в те места, где сейчас стоит команда print. Для объектов типа "Mesh" мы будем экспортировать треугольники, текстурные координаты и т.п.. Для объектов типа "Lamp" мы будем экспортировать положение, яркость, направление излучения. Для камеры - координаты и направление взгляда. Распознание типа объектов сделано с той целью, чтобы не возникало случаев экспорта треугольников из камеры или лампы.
9. Допишем процедуру экспорта мешей. Ниже приведён скриншот из встроенного текстового редактора Blender. Это исходный код по записи вершин, нормалей и текстурных координат:
В начале обозначен цикл for object in MYOBJECTS. Обратите внимание, что следующие строки сдвинуты вправо на один "TAB". В Delphi мы написали бы так: for i:=0 to length(myobjects)
-1 do А здесь никаких begin-ов и end-ов нет! Вместо этого важно соблюдать положение текста программы в пространстве и выравнивать его в соответствии с алгоритмом. Например, начиная со строчки for face in faces и до самого конца весь текст смещён вправо - это большой цикл! Внутри этого цикла есть маленький цикл while (vertidx<len(face.uv)), а так как этот цикл вложенный то его текстовое "тело" сдвинуто ещё правее. Как всё это работает? Переменные создаются прямо по ходу выполнения скрипта. Например, в строчке vertidx = 0 я задал значение переменной для цикла с while. Переменную vertidx компилятор скриптов создаст автоматически! Весьма оригинально реализованы циклы: например, что делает for object in MYOBJECTS? А делает эта строчка следующее: компилятор сам (!!!) создаст переменную object, которая будет являтся элементом массива MYOBJECTS. И сделает примерно следующее (весьма условный псевдоэквивалент на pascal): for i:=0 to length(MYOBJECTS)-1
do Вернёмся к рассмотрению приведённой выше части скрипта. Как только мы нашли объект типа Mesh, то выводим в консольное окно отладочную информацию - в данном случае это просто назывние объекта object.name. Далее идёт цикл, который перебирает все полигоны - этот цикл задаётся строчкой for face in faces. Внутри цикла мы сразу же делаем запись в файл myfile.write("face \n"). Здесь \n служит для перевода строки в файле (аналог нажатия Enter-а). Далее мы проверяем, есть ли у меша текстурные координаты. Если есть - срабатывает строчка if mesh.hasFaceUV: myfile.write("%s \n" % face.image.name). Далее в файл записывается количество вершин полигона - len(face.v). Полигоны могут иметь 3 или 4 вершины. Причём myfile.write("%i \n" % len(face.v)) означает следующее: в файл запишется всё, что находится в кавычках. Но при этом на место %i будет записан текст целого числа (integer, поэтому буква i перед процентами). Само число, из которого будет сделан текст, находится вне кавычек - после "вторых" процентов. При записи вершин мы используем не %i, а %f - что означает float (т.к. координаты вершин - это числа с точкой). %f преобразует в текст числа с точкой, а %i - целые числа. Для подстановки текстовых строк используется %s, что означает string. Здесь мы записываем координаты трёх вершин - v[0], v[1] и v[2] (в случае четырёхугольного полигона сработает проверка if len(face.v) == 4 и допишется четвёртая вершина). Соответствия с x,y,z следующие: .co[0] - это X, .co[1] - это Y, .co[2] - это Z. Например, face.v[1].co[2] - это координата первой (считая от нуля) вершины по оси Z. Потом мы записываем нормаль - всё аналогично вершинам, только вместо .co[ ] стоит .no[ ]. Здесь всё просто - .co обозначает координаты вершин (coordinates), а .no - нормали в этих вершинах. Ну и наконец, внизу, идёт цикл с while для записи текстурных координат. Приведу кусочек из файла, который будет создавать наш скрипт:
Скачать скрипт - blexp.zip (1kb) 10. Я написал скрипт, который уже готов к добавлению в Blender. Теперь полезно на скриншотах посмотреть пошаговую инструкцию по использованию своего скрипта. 10.1. Нужно скопировать наш скрипт в директорию со скриптами Blender-а: C:\Program Files\Blender Foundation\Blender\.blender\scripts\nashformat.py 10.2 Запустить Blender и сделать окно типа Text Editor (просто смените Window type у любого окна, кликнув на иконку в левом нижнем углу окна).
10.3 В появившемся пустом окне кликните правую кнопку мыши, выберите пункт Open... и откройте скрипт nashformat.py.
10.4 В окне появится исходный текст скрипта. Опять нажмите правую кнопку мыши и выберите пункт Execute script...
10.5 Наведите мышку на границу между верхним меню и основным окном. Потяните мышкой за эту границу вниз, чтобы вытянуть скрытые настройки из верхней части экрана. Выберите вкладку File Paths и нажмите на иконку "Re-evaluate scripts registration in menus":
11. Всё! Теперь в меню программы появится наш фирменный скрипт!
Для написания скриптов удобно использовать документацию по написанию Python-овских скриптов в Blender. Хотя написаннный мною скрипт не идеален, но он является отличной базой для понимания и написания собственных скриптов экспорта. Так как при экспорте из Blender-а очень легко обратиться ко всем данным сцены, то возникает возможность создания специального экспортера для создания уровней, учитывающий имена объектов (door_15, key_15, zomby_boss_txt), а также использовать различные параметры "не по назначению". Например, я использую Blender для разработки игры в стиле Resident Evil. Это означает, что двери, ключи, горшки с цветами и зомби и положения камер расстанавливаются при редактировании уровня, а на выходе из экспортера получается уже готовый для использования движком файл. Blender можно использовать не только для создания уровней и различных объектов, но и скелетной анимации. |