summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2017-12-18 00:34:48 -0300
committerJuan Linietsky <reduzio@gmail.com>2017-12-18 00:35:20 -0300
commite96c40f94a87325a5838662800277577b95f558b (patch)
tree995787ac4925268d34ea8938cf3384a72bc43d92 /scene
parent4e442b0648332dd70751c7a9ee739c7c2bf9dfb5 (diff)
Added baked light support for gridmaps.
Diffstat (limited to 'scene')
-rw-r--r--scene/3d/baked_lightmap.cpp70
-rw-r--r--scene/3d/baked_lightmap.h5
-rw-r--r--scene/3d/voxel_light_baker.cpp36
3 files changed, 83 insertions, 28 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());
+ }
}
}
diff --git a/scene/3d/baked_lightmap.h b/scene/3d/baked_lightmap.h
index f63749a0b4..9e15f1bb10 100644
--- a/scene/3d/baked_lightmap.h
+++ b/scene/3d/baked_lightmap.h
@@ -18,6 +18,7 @@ class BakedLightmapData : public Resource {
NodePath path;
Ref<Texture> lightmap;
+ int instance_index;
};
Vector<User> users;
@@ -44,10 +45,11 @@ public:
void set_energy(float p_energy);
float get_energy() const;
- void add_user(const NodePath &p_path, const Ref<Texture> &p_lightmap);
+ void add_user(const NodePath &p_path, const Ref<Texture> &p_lightmap, int p_instance = -1);
int get_user_count() const;
NodePath get_user_path(int p_user) const;
Ref<Texture> get_user_lightmap(int p_user) const;
+ int get_user_instance(int p_user) const;
void clear_users();
virtual RID get_rid() const;
@@ -111,6 +113,7 @@ private:
Ref<Mesh> mesh;
Transform local_xform;
NodePath path;
+ int instance_idx;
};
struct PlotLight {
diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp
index 39ff6fa35e..96ac5e8a05 100644
--- a/scene/3d/voxel_light_baker.cpp
+++ b/scene/3d/voxel_light_baker.cpp
@@ -833,11 +833,13 @@ void VoxelLightBaker::plot_light_directional(const Vector3 &p_direction, const C
}
}
- for (int i = 0; i < 6; i++) {
- float s = MAX(0.0, aniso_normal[i].dot(-light_axis)); //light depending on normal for direct
- light->direct_accum[i][0] += light_energy.x * s;
- light->direct_accum[i][1] += light_energy.y * s;
- light->direct_accum[i][2] += light_energy.z * s;
+ if (p_direct) {
+ for (int i = 0; i < 6; i++) {
+ float s = MAX(0.0, aniso_normal[i].dot(-light_axis)); //light depending on normal for direct
+ light->direct_accum[i][0] += light_energy.x * s;
+ light->direct_accum[i][1] += light_energy.y * s;
+ light->direct_accum[i][2] += light_energy.z * s;
+ }
}
success_count++;
}
@@ -962,11 +964,13 @@ void VoxelLightBaker::plot_light_omni(const Vector3 &p_pos, const Color &p_color
}
}
- for (int i = 0; i < 6; i++) {
- float s = MAX(0.0, aniso_normal[i].dot(-light_axis)); //light depending on normal for direct
- light->direct_accum[i][0] += light_energy.x * s * att;
- light->direct_accum[i][1] += light_energy.y * s * att;
- light->direct_accum[i][2] += light_energy.z * s * att;
+ if (p_direct) {
+ for (int i = 0; i < 6; i++) {
+ float s = MAX(0.0, aniso_normal[i].dot(-light_axis)); //light depending on normal for direct
+ light->direct_accum[i][0] += light_energy.x * s * att;
+ light->direct_accum[i][1] += light_energy.y * s * att;
+ light->direct_accum[i][2] += light_energy.z * s * att;
+ }
}
}
@@ -1095,11 +1099,13 @@ void VoxelLightBaker::plot_light_spot(const Vector3 &p_pos, const Vector3 &p_axi
}
}
- for (int i = 0; i < 6; i++) {
- float s = MAX(0.0, aniso_normal[i].dot(-light_axis)); //light depending on normal for direct
- light->direct_accum[i][0] += light_energy.x * s * att;
- light->direct_accum[i][1] += light_energy.y * s * att;
- light->direct_accum[i][2] += light_energy.z * s * att;
+ if (p_direct) {
+ for (int i = 0; i < 6; i++) {
+ float s = MAX(0.0, aniso_normal[i].dot(-light_axis)); //light depending on normal for direct
+ light->direct_accum[i][0] += light_energy.x * s * att;
+ light->direct_accum[i][1] += light_energy.y * s * att;
+ light->direct_accum[i][2] += light_energy.z * s * att;
+ }
}
}