Blend4Web+NPM
2018-01-29
Ни для кого не секрет, что на рынке труда наиболее востребована разработка приложений, так или иначе связанных с Интернет. Это всевозможные новостные и развлекательные сайты, торговые площадки, социальные сети, CRM-системы, различного рода сервисы, онлайн игры и т.д. С каждым днем появляется все больше и больше новейших технологий, о которых вчера мы рассуждали скептически, а сейчас широко используем. А чтобы получить доступ к этим технологиям, нам нужно всего лишь установить веб-браузер. К такой технологии в том числе относится и WebGL, о которой, я думаю, мы еще поговорим. А для начала, самую малость окунемся в историю.
Немного истории
В 2009 году, после нескольких лет исследований, появилась новая программная платформа, основой которой стал движок V8 из браузера Chrome. NodeJS, по своей сути, является средой выполнения JavaScript-программ, которая превратила JavaScript из чисто браузерного в язык общего назначения. Наибольшую популярность NodeJS приобрел в сфере разработки серверных приложений.
В дальнейшем была создана мощная инфраструктура для разработки приложений на JavaScript — пакетный менеджер NPM, назначением которого является установка библиотек и их зависимостей.
Вскоре некоторые библиотеки из NPM стали использовать и при разработке Web-страниц. Сейчас NPM — это огромный репозиторий, содержащий невероятное количество различных серверных и браузерных библиотек, фреймворков, утилит.
Теперь и Blend4Web доступен для загрузки из репозитория NPM.
Установка NodeJS
Способов установки NodeJS на различные операционные системы несколько. Мы рассмотрим вариант, который автор считает наиболее приемлемым, так как он минимизирует вероятность возникновения каких-либо проблем в процессе разработки.
Суть этого способа в том, чтобы отказаться от установки NodeJS через инсталляционные пакеты (будь то .msi на Windows, .pkg на MacOS, .deb, .rpm и т.д. на Linux), а вместо этого использовать другой тип дистрибутива. Возможно, что вам в вашей работе могут понадобиться различные версии NodeJS и если использовать инсталляционные пакеты, то держать их на одной операционной системе может быть проблематично, либо вовсе невозможно.
Скачивать NodeJS мы будем с официального сайта. Нас интересуют дистрибутивы для соответствующих операционных систем, помеченные как Binaries: Linux Binaries (x86/x64), Windows Binary (.zip), macOS Binaries (.tar.gz).
Скачав дистрибутив для нашей операционной системы, мы понимаем, что это всего лишь архив, который нужно куда-нибудь распаковать и сделать исполняемые файлы node и npm доступными из командной строки. Другими словами, после распаковки необходимо настроить окружение (environment). Для этого во всех операционных системах существует переменная окружения PATH, которую необходимо дополнить путем к директории с исполняемыми файлами.
Для Linux и MacOS настройка окружения осуществляется одинаково.
Для настройки окружения я рекомендую использовать файл ~/.profile, поскольку он является с одной стороны локальной пользовательской настройкой, с другой стороны инициализирует окружение в том числе для графических утилит (в отличие например от файла конфигурации ~/.bashrc).
Итак, в конец ~/.profile добавляем строчку
PATH=/home/user/path/to/node/binaries:$PATH
Так как командный интерпретатор (в моем случае bash) вызывает первую найденную программу в процессе последовательного обхода путей из PATH, то путь мы добавляем именно в начало, перед содержимым переменной PATH, чтобы никакие другие программы с именами node или npm не встретились раньше чем те, которые мы в данный момент устанавливаем. У меня эта строчка выглядит так:
PATH=/home/dal/soft/node-v8.8.1-linux-x64/bin/:$PATH
Перезаходим в операционную систему и запускаем терминал. Проверяем, что node и npm доступны.
Начиная с этого момента, я буду использовать команды *nix-систем. Пользователи Windows должны добавлять расширение .exe, например node.exe или npm.exe.
node --version
npm --version
Если терминал сообщил вам, что программа не найдена, значит вы где-то совершили ошибку. Используйте команду env (в *nix-системах), чтобы вывести все переменные окружения. Найдите там PATH и проверьте вручную доступность исполняемых файлов по указанному пути.
env | grep ^PATH=
Как настроить переменные окружения для Windows можно посмотреть, например, тут.
NodeJS установлен и это все, что нам необходимо! Поэтому...
Приступим к работе
1. Создайте где-нибудь в директории со своими проектами новую директорию, например b4w_test.
2. Перейдите в нее и создайте новый пакет (в некотором роде проект в терминах npm):
cd b4w_test
npm init
Эта команда задаст вам несколько вопросов. Вы не обязаны отвечать на них, а можете просто жать Enter.
После выполнения команды вы найдете в текущем каталоге файл package.json. В любое время вы можете исправить свои неверные ответы команде npm init, отредактировав этот файл.
3. Теперь мы подходим к самому интересному:
npm install blend4web
Эта команда установит в директорию node_modules пакет blend4web.
4. В описании пакета можно заметить информацию о том, что пакет содержит примеры приложений в директории projects. И в данный момент там находится один проект с названием my_project.
А давайте попробуем его!
a. Проект my_project имеет собственный package.json и он значительно отличается от нашего. Мы рассмотрим эти отличия в следующей статье, а сейчас просто скопируем все содержимое из node_modules/blend4web/projects/my_project/ в наш проект b4w_npm_test, в том числе заменив package.json.
b. Устанавливаем все зависимости скопированного приложения:
npm install
c. Запускаем скрипт start из package.json:
npm run start
Скрипт запускает сборщик webpack в режиме watch и webpack-dev-server, а также открывает наше приложение в браузере.
Далее вы можете изменять код приложения и проверять результат своих модификаций, обновляя страничку, как вы привыкли это делать. Сборщик webpack автоматически распознает измененные файлы и произведет необходимые действия по сборке.
Чтобы остановить сервер, в окне консоли с запущенной командой npm run start нажмите Ctrl+C.
А давайте попробуем сделать что-нибудь с нуля?
А что бы такое сделать...
Поиграв с кристаллами из предыдущего приложения, я заметил, что пользователь может взаимодействовать с кристаллами, а вот кристаллы друг с другом нет. И мне захотелось сделать приложение, в котором объекты взаимодействовали бы друг с другом физически.
Итак, начнем с того, что мы уже делали - создадим новый пакет с именем b4w_npm_test (пункт 1-3 из раздела "Приступим к работе").
Чтобы создать сцену нам необходим Blender с установленным аддоном Blend4Web. Допускаю, что с Blender вы в какой-то степени знакомы, и устанавливать аддоны вы умеете, а если нет, то у вас не возникнет трудностей прогуглить этот вопрос. Как я уже говорил, npm-пакет содержит все необходимое для создания своих собственных приложений, в том числе и аддон, который вы можете найти в директории dist/addons/.
После установки аддона в хэдере 3DView у рендеров Cycles и Blend4Web появится кнопка Fast Preview.
Нажав на нее, вы даете аддону команду произвести экспорт сцены в JSON во временную директорию и открыть результат в специальном приложении Scene Viewer, которое используется для отладки экспортированных сцен. Во Scene Viewer можно в том числе посмотреть, какая из частей вашей сцены наиболее тяжелая и визуализируется дольше всего. В то время как Scene Viewer является очень мощным инструментом отладки, о котором вы можете подробно прочитать в документации, для нас сейчас самым важным является его способность быстро показать нам нашу модель в браузере.
Уже сейчас вы можете поэкспериментировать c экспортом любых моделей и посмотреть, что выходит. Если что-то выглядит не так, как вы ожидаете, то возможно данная фича еще не реализована, либо вы нашли баг. Если вы столкнулись с какими-либо сложностями, непременно оставляйте отзыв на форуме Blend4Web, так вы поможете сделать Blend4Web еще лучше!
Сцена с нуля
Мы будем делать башню из кубиков, поэтому дефолтный кубик удалять не станем, а просто отредактируем некоторые его физические параметры.
На вкладке Physics необходимо включить галочку Object Physics и выставить Physics Type в Rigid Body. Установить галочку Collision Bounds с оставленным по-умолчанию значением Box для поля Bounds. Помимо этого, чтобы кубик не засыпал при низких значениях скоростей, необходимо включить опцию No Sleeping. Она позволит получить симуляцию падения нашей башни. |
Если нажать кнопку Fast Preview, то мы увидим падение нашего кубика вниз, ведь он теперь динамический и на него действует гравитация. Давайте сохраним наш blend-файл. Я разместил его в поддиректории проекта с именем blender и назвал его main.blend.
Башня будет стоять на полу, который мы сделаем из объекта Plane. Объекты размещаем так, чтобы кубик не пересекался с Plane. Для Plane на вкладке Physics просто включаем галочку Object Physics, а необходимый нам тип физического объекта Static уже выставлен по-умолчанию. Теперь кубик уверенно стоит на полу и никуда не падает.
Башню сформируем прямо в Blender. Для этого продублируем наш кубик несколько раз:
1. Выбираем самый верхний кубик и дублируем его (Shift+D, Enter);
2. Смещаем кубик на самый верх (G, Z, 2, Enter).
Давайте сдвинем самый нижний кубик куда-нибудь в плоскости пола, чтобы создать неустойчивое состояние для башни, в котором она начнет падать. И вот как это выглядит у меня:
Вроде все работает, но если вращать колесико мышки, то наша сцена куда-то пропадает при отдалении. Поэтому поменяем настройки Clipping камеры. |
Теперь нам нужно экспортировать нашу сцену. Для этого в Blender выбираем File->Export->Blend4Web(.json) и сохраняем экспортированную сцену в поддиректории assets нашего проекта. Мы получаем два файла - это main.json и main.bin. Файл main.json содержит метаданные экспортированных сцен, а bin - данные вершин, текстурные координаты и другие атрибуты, в общем все, что связано с мешами моделей. Но что нам делать дальше с этими файлами?
Мы будем писать свое собственное приложение.
Перейдем к программированию
Вы уже могли слышать, что Blend4Web, начиная с версии 17.12, ввел поддержку модулей ES-6. В двух словах, это способ подключения JavaScript-библиотек, отличный от привычного. В обычном ES-5 стиле мы подключаем все используемые скрипты при помощи тега script с атрибутом type="text/javascript". В нотации ES-6 модулей при помощи тега script подключается корневой модуль с указанием атрибута type="module". А все зависимости в таком случае загружаются браузером автоматически. Система ES-6 модулей имеет еще один важный плюс - она позволяет уменьшить код результирующего приложения путем отбрасывания неиспользуемых функций подключаемых библиотек. Однако для того, чтобы ES-6 модули работали корректно, в большинстве случаев необходимо использовать сборщики модулей.
Рассмотренный пример, поставляемый в npm-пакете, написан с использованием ES6 и использует Webpack для сборки модулей. Замечу, что если вы использовали какие-либо конструкции ES6, помимо import/export (ключевые слова для ES6-модулей), то для того, чтобы ваш код работал во всех браузерах, вам может потребоваться сконвертировать его в ES5, например средствами babel. О сборщиках мы поговорим в следующий раз, а сейчас я опишу 100% работающий для всех современных браузеров подход: мы будем использовать уже собранную библиотеку blend4web, которая имеет нотацию ES5.
Собранные библиотеки находятся в директории dist. Это любой из файлов b4w.js, b4w.min.js, b4w.simple.min.js, b4w.whitespace.min.js. Отличие их лишь в уровне обфускации.
Чтобы открыть наше приложение можно воспользоваться статическим сервером. Я установил его командой npm install node-static. Для запуска в каталоге с проектом используется команда static. Приложение доступно по адресу: http://127.0.0.1:8080/index.html. Приведу здесь листинги основных файлов приложения с комментариями, которые вы можете использовать в своих проектах.
Итак - index.html:
<html>
<head>
<title>Blend4web Test</title>
<!--Собранный движок-->
<script src="b4w.min.js" type="text/javascript"></script>
<!--Наш код-->
<script src="b4w_npm_test.js" type="text/javascript"></script>
</head>
<body style="background-color: black;">
<div id="main_canvas_container" style="height: 100%; left: 0px; position: absolute; top: 0px; width: 100%;"></div></body>
</html>
А вот и основной код приложения b4w_npm_test.js:
"use strict"
b4w.register("b4w_npm_test", function(exports, require) {
// импортируем необходимые модули
var m_app = b4w.require("app");
var m_cfg = b4w.require("config");
var m_data = b4w.require("data");
var m_preloader = b4w.require("preloader");
var DEBUG = true;
// задаем путь к ассетам
var APP_ASSETS_PATH = "assets/";
// задаем путь к физическому движку
m_cfg.set("physics_uranium_path", "node_modules/blend4web/dist/uranium/")
/**
* экспортируем метод инициализации, который будет вызван в самом конце файла
*/
exports.init = init;
function init() {
m_app.init({
canvas_container_id: "main_canvas_container",
callback: init_cb,
show_fps: DEBUG,
console_verbose: DEBUG,
autoresize: true
});
}
/**
* коллбэк вызывается когда приложение инициализировалось
*/
function init_cb(canvas_elem, success) {
if (!success) {
console.log("b4w init failure");
return;
}
m_preloader.create_preloader();
// игнорируем клик правой кнопкой мыши на элементе canvas
canvas_elem.oncontextmenu = function(e) {
e.preventDefault();
e.stopPropagation();
return false;
};
load();
}
/**
* загрузка данных сцены
*/
function load() {
m_data.load(APP_ASSETS_PATH + "main.json", load_cb, preloader_cb);
}
/**
* обновление прелоадера
*/
function preloader_cb(percentage) {
m_preloader.update_preloader(percentage);
}
/**
* коллбэк вызывается когда сцена загружена
*/
function load_cb(data_id, success) {
if (!success) {
console.log("b4w load failure");
return;
}
m_app.enable_camera_controls();
// размещайте свой код здесь
}
})
b4w.require("b4w_npm_test").init();
На сегодня все! Надеюсь эта статья была полезна не только новичкам! По ссылкам ниже вы сможете найти исходники приложения. Всем удачи и интересных проектов!