Forum

User posts Ivan Lyubovnikov
23 October 2017 21:17
здравствуйте

1) Её можно использовать, только если объект obj_to (к которому хотим применить материал) уже содержит какой-то материал и при это надо именно указать его имя?
Да, только так.

2) Есть ли возможность программно создать какой-то пустой материал у объекта, чтобы потом применить к нему метод inherit_material?
Нет, процедурного создания материалов нет.

3) Если у объекта в блендере создано несколько материалов, можно ли их переключать?
Да, например, на скриншоте ниже материал "Material" изначально применен ко всему объекту, а остальные материалы просто "висят" мертвым грузом, но экспортируются (если включено "Dynamic Geometry & Materials") :


тогда можно переключать так:
var cube = m_scenes.get_object_by_name("Cube");

m_mat.inherit_material(cube, "Material.001", cube, "Material");
m_mat.inherit_material(cube, "Material.002", cube, "Material");
m_mat.inherit_material(cube, "Material.003", cube, "Material");


но материал "Material" после наследования затрется, и его восстановить не получится, поэтому стоит его рассматривать только в качестве пустышки, в которую будут помещаться остальные.

4) Есть ли возможность сохранять старый материал у объекта, чтобы потом его вернуть?
Т.к. он затирается, то только, если где-то его дополнительно хранить - на самом целевом объекте или на каком-нибудь объекте-контейнере для материалов

Если можно, расскажите в чём сложность манипулировать материалами, не привязанными к объекту (чтобы не использовать наследование материала, а просто назначение его из некой виртуальной библиотеки).
Зависит от того, как себе представлять эту виртуальную библиотеку:
1) Если говорить о полноценном API для материалов, то сложность в том, что в API сейчас нет объекта "материал" как такового, да и внутри движка он размыт. При наследовании используются сырые данные экспортированных из Блендера материалов, которые собственно висят на объектах. Чтобы была возможность использовать библиотеку материалов в виде списка вполне определенных объектов типа "материал", нужно продумывать интерфейс и API для этой категории объектов и рефакторить движок в сторону создания процедурных материалов. Тогда, можно было бы создавать материалы динамически или хранить уже созданные каким-то образом, например, в формате json и загружать их в приложение и т.д.
Это довольно затратно, а полумеры в виде некоего сырого объекта "материал", который только и можно будет, что подать в метод inherit_material, делать не хочется.
2) Если представлять библиотеку как "черный ящик", в который не придется лезть и не требовать ничего от материалов, то можно обойтись и тем, что есть сейчас, т.е. замоделить полигон в Блендере, на который сложить все материалы, и считать, что это и есть библиотека. Ну придется только его имя подавать, а так можно даже blend-файл с ним подгружать динамически при необходимости.
12 October 2017 16:45
Hi Spartan,
Thanks for the report! This bug appeared in 17.08, so you can still use 17.06 without getting that error. We'll fix it in the upcoming 17.10 release.
12 October 2017 15:25
Hi, you can create a special module for this purpose and execute it prior to the other app modules:

b4w.register("overwrite_b4w", function(exports, require) {

var m_anchors = require("anchors");
var m_anim = require("animation");
var m_ver = require("version");

exports.init = function() {
    m_anchors.append = function(){ console.log("hello world") };
    m_anim.append = function(){ console.log("hello world") };
}
});
// start application with overriding the original modules
b4w.require("overwrite_b4w").init();



// register and then execute the main app module
b4w.register("my_project_main", function(exports, require) {
    ....
});
b4w.require("my_project_main").init();
12 October 2017 14:49
Hi, how do you execute the code, which should perform switching? The error message is not a blend4web specific thing. It's a common js security measure to prevent such actions from happening without user participation.

This should work inside an event handler, e.g:
document.addEventListener("click", function(e) {
    // switch to fullscreen
})
12 October 2017 14:20
Hi, do you want a single preloader for multiple json files? You can try the solution described here: link
12 October 2017 11:14
Hi,
The camera keeps the orientation of its UP-axis, so if it's already flipped from a particular view, then it'll also be flipped after such transformation. You should use the correct_up method to strictly define the camera orientation:
m_cam.target_set_trans_pivot(...);
m_cam.correct_up(camera, m_util.AXIS_Z, true);
12 October 2017 10:56
Hi Daniel,

You can use "a_texcoord" and "a_color" for texture coordinates and vertex color respectively if an object has a non-node material.
For node materials it requires to specify an attribute name, which corresponds to a particular uv map or a vertex color. But it's inconvenient as for now, because these attribute names are the engine's internal identifiers like "param_GEOMETRY_UV_a_0", "param_GEOMETRY_UV_a_1" etc.
02 October 2017 10:18
yes, replace_image should work
29 September 2017 19:08
Можно воспользоваться методами set_render_callback/clear_render_callback, чтобы выставить колбек на ближайший кадр, а потом после отработки сразу удалить его:
var cam_obj = m_scenes.get_active_camera();
m_cam.rotate_camera(cam_obj, 0, 0, true);

m_main.set_render_callback(function() {
    var dataURL = $('#main_canvas_container canvas')[0].toDataURL();
    m_main.clear_render_callback();
});

- но он выполняется прямо перед отрисовкой, поэтому изменения, скорее всего, ещё не будут видны, только если делать его не на следующий, а через один кадр.

Также можно использовать метод canvas_data_url, который снимет ближайший кадр и вернет его, правда в виде урла Blob-объекта, а не dataURL. Пример использования есть во внешнем модуле screen.js в функции взятия скриншота: https://github.com/TriumphLLC/Blend4Web/blob/17.08/src/ext/screen.js#L434-L450
29 September 2017 12:19
Hi, do you mean that a mesh should always have a normal map applied on it even if it inherits a different material? In this case you're right - normal map is a part of a material and if it isn't presented in the inherited one, then it will be lost, because the inherit_material method overrides a material completely and doesn't combine them partially.

One possible solution is to create a dummy material with a normal map and swap the corresponding texture with the required one for a particular object immediately after inheriting.