diff options
Diffstat (limited to 'scene/3d/baked_lightmap.cpp')
-rw-r--r-- | scene/3d/baked_lightmap.cpp | 70 |
1 files changed, 58 insertions, 12 deletions
diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp index 7afac94e71..ae9834d95f 100644 --- a/scene/3d/baked_lightmap.cpp +++ b/scene/3d/baked_lightmap.cpp @@ -55,12 +55,13 @@ float BakedLightmapData::get_energy() const { return energy; } -void BakedLightmapData::add_user(const NodePath &p_path, const Ref<Texture> &p_lightmap) { +void BakedLightmapData::add_user(const NodePath &p_path, const Ref<Texture> &p_lightmap, int p_instance) { ERR_FAIL_COND(p_lightmap.is_null()); User user; user.path = p_path; user.lightmap = p_lightmap; + user.instance_index = p_instance; users.push_back(user); } @@ -79,16 +80,22 @@ Ref<Texture> BakedLightmapData::get_user_lightmap(int p_user) const { return users[p_user].lightmap; } +int BakedLightmapData::get_user_instance(int p_user) const { + + ERR_FAIL_INDEX_V(p_user, users.size(), -1); + return users[p_user].instance_index; +} + void BakedLightmapData::clear_users() { users.clear(); } void BakedLightmapData::_set_user_data(const Array &p_data) { - ERR_FAIL_COND(p_data.size() & 1); + ERR_FAIL_COND((p_data.size() % 3) != 0); - for (int i = 0; i < p_data.size(); i += 2) { - add_user(p_data[i], p_data[i + 1]); + for (int i = 0; i < p_data.size(); i += 3) { + add_user(p_data[i], p_data[i + 1], p_data[i + 2]); } } @@ -98,6 +105,7 @@ Array BakedLightmapData::_get_user_data() const { for (int i = 0; i < users.size(); i++) { ret.push_back(users[i].path); ret.push_back(users[i].lightmap); + ret.push_back(users[i].instance_index); } return ret; } @@ -209,6 +217,7 @@ void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, List<PlotMesh> &plo pm.local_xform = xf; pm.mesh = mesh; pm.path = get_path_to(mi); + pm.instance_idx = -1; for (int i = 0; i < mesh->get_surface_count(); i++) { pm.instance_materials.push_back(mi->get_surface_material(i)); } @@ -219,6 +228,26 @@ void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, List<PlotMesh> &plo } } + Spatial *s = Object::cast_to<Spatial>(p_at_node); + + if (!mi && s) { + Array meshes = p_at_node->call("get_bake_meshes"); + if (meshes.size() && (meshes.size() & 1) == 0) { + Transform xf = get_global_transform().affine_inverse() * s->get_global_transform(); + for (int i = 0; i < meshes.size(); i += 2) { + PlotMesh pm; + Transform mesh_xf = meshes[i + 1]; + pm.local_xform = xf * mesh_xf; + pm.mesh = meshes[i]; + pm.instance_idx = i / 2; + if (!pm.mesh.is_valid()) + continue; + pm.path = get_path_to(s); + plot_meshes.push_back(pm); + } + } + } + Light *light = Object::cast_to<Light>(p_at_node); if (light && light->get_bake_mode() != Light::BAKE_DISABLED) { @@ -477,7 +506,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi if (set_path) { tex->set_path(image_path); } - new_light_data->add_user(E->get().path, tex); + new_light_data->add_user(E->get().path, tex, E->get().instance_idx); } } @@ -547,12 +576,21 @@ void BakedLightmap::_assign_lightmaps() { ERR_FAIL_COND(!light_data.is_valid()); for (int i = 0; i < light_data->get_user_count(); i++) { - Node *node = get_node(light_data->get_user_path(i)); - VisualInstance *vi = Object::cast_to<VisualInstance>(node); - ERR_CONTINUE(!vi); Ref<Texture> lightmap = light_data->get_user_lightmap(i); ERR_CONTINUE(!lightmap.is_valid()); - VS::get_singleton()->instance_set_use_lightmap(vi->get_instance(), get_instance(), lightmap->get_rid()); + + Node *node = get_node(light_data->get_user_path(i)); + int instance_idx = light_data->get_user_instance(i); + if (instance_idx >= 0) { + RID instance = node->call("get_bake_mesh_instance", instance_idx); + if (instance.is_valid()) { + VS::get_singleton()->instance_set_use_lightmap(instance, get_instance(), lightmap->get_rid()); + } + } else { + VisualInstance *vi = Object::cast_to<VisualInstance>(node); + ERR_CONTINUE(!vi); + VS::get_singleton()->instance_set_use_lightmap(vi->get_instance(), get_instance(), lightmap->get_rid()); + } } } @@ -560,9 +598,17 @@ void BakedLightmap::_clear_lightmaps() { ERR_FAIL_COND(!light_data.is_valid()); for (int i = 0; i < light_data->get_user_count(); i++) { Node *node = get_node(light_data->get_user_path(i)); - VisualInstance *vi = Object::cast_to<VisualInstance>(node); - ERR_CONTINUE(!vi); - VS::get_singleton()->instance_set_use_lightmap(vi->get_instance(), RID(), RID()); + int instance_idx = light_data->get_user_instance(i); + if (instance_idx >= 0) { + RID instance = node->call("get_bake_mesh_instance", instance_idx); + if (instance.is_valid()) { + VS::get_singleton()->instance_set_use_lightmap(instance, get_instance(), RID()); + } + } else { + VisualInstance *vi = Object::cast_to<VisualInstance>(node); + ERR_CONTINUE(!vi); + VS::get_singleton()->instance_set_use_lightmap(vi->get_instance(), get_instance(), RID()); + } } } |