#include "rendering_light_culler.h"
#include "core/math/plane.h"
#include "core/math/projection.h"
#include "rendering_server_globals.h"
#ifdef RENDERING_LIGHT_CULLER_DEBUG_STRINGS
const char *RenderingLightCuller::Data::string_planes[] = {
"NEAR",
"FAR",
"LEFT",
"TOP",
"RIGHT",
"BOTTOM",
};
const char *RenderingLightCuller::Data::string_points[] = {
"FAR_LEFT_TOP",
"FAR_LEFT_BOTTOM",
"FAR_RIGHT_TOP",
"FAR_RIGHT_BOTTOM",
"NEAR_LEFT_TOP",
"NEAR_LEFT_BOTTOM",
"NEAR_RIGHT_TOP",
"NEAR_RIGHT_BOTTOM",
};
String RenderingLightCuller::Data::plane_bitfield_to_string(unsigned int BF) {
String sz;
for (int n = 0; n < 6; n++) {
unsigned int bit = 1 << n;
if (BF & bit) {
sz += String(string_planes[n]) + ", ";
}
}
return sz;
}
#endif
void RenderingLightCuller::prepare_directional_light(const RendererSceneCull::Instance *p_instance, int32_t p_directional_light_id) { … }
bool RenderingLightCuller::_prepare_light(const RendererSceneCull::Instance &p_instance, int32_t p_directional_light_id) { … }
bool RenderingLightCuller::cull_directional_light(const RendererSceneCull::InstanceBounds &p_bound, int32_t p_directional_light_id) { … }
void RenderingLightCuller::cull_regular_light(PagedArray<RendererSceneCull::Instance *> &r_instance_shadow_cull_result) { … }
void RenderingLightCuller::LightCullPlanes::add_cull_plane(const Plane &p) { … }
bool RenderingLightCuller::add_light_camera_planes_directional(LightCullPlanes &r_cull_planes, const LightSource &p_light_source) { … }
bool RenderingLightCuller::_add_light_camera_planes(LightCullPlanes &r_cull_planes, const LightSource &p_light_source) { … }
bool RenderingLightCuller::prepare_camera(const Transform3D &p_cam_transform, const Projection &p_cam_matrix) { … }
RenderingLightCuller::RenderingLightCuller() { … }
uint8_t RenderingLightCuller::Data::LUT_entry_sizes[LUT_SIZE] = …;
uint8_t RenderingLightCuller::Data::LUT_entries[LUT_SIZE][8] = …;
#ifdef RENDERING_LIGHT_CULLER_CALCULATE_LUT
void RenderingLightCuller::create_LUT() {
for (int plane_0 = 0; plane_0 < PLANE_TOTAL; plane_0++) {
PlaneOrder neighs[4];
get_neighbouring_planes((PlaneOrder)plane_0, neighs);
for (int n = 0; n < 4; n++) {
int plane_1 = neighs[n];
PointOrder pts[2];
get_corners_of_planes((PlaneOrder)plane_0, (PlaneOrder)plane_1, pts);
add_LUT(plane_0, plane_1, pts);
}
}
for (uint32_t n = 0; n < LUT_SIZE; n++) {
compact_LUT_entry(n);
}
debug_print_LUT();
debug_print_LUT_as_table();
}
void RenderingLightCuller::debug_print_LUT_as_table() {
print_line("\nLIGHT VOLUME TABLE BEGIN\n");
print_line("Copy this to LUT_entry_sizes:\n");
String sz = "{";
for (int n = 0; n < LUT_SIZE; n++) {
const LocalVector<uint8_t> &entry = _calculated_LUT[n];
sz += itos(entry.size()) + ", ";
}
sz += "}";
print_line(sz);
print_line("\nCopy this to LUT_entries:\n");
for (int n = 0; n < LUT_SIZE; n++) {
const LocalVector<uint8_t> &entry = _calculated_LUT[n];
String sz = "{";
int s = entry.size();
for (int p = 0; p < 8; p++) {
if (p < s)
sz += itos(entry[p]);
else
sz += "0";
sz += ", ";
}
sz += "},";
print_line(sz);
}
print_line("\nLIGHT VOLUME TABLE END\n");
}
void RenderingLightCuller::debug_print_LUT() {
for (int n = 0; n < LUT_SIZE; n++) {
String sz;
sz = "LUT" + itos(n) + ":\t";
sz += Data::plane_bitfield_to_string(n);
print_line(sz);
const LocalVector<uint8_t> &entry = _calculated_LUT[n];
sz = "\t" + string_LUT_entry(entry);
print_line(sz);
}
}
String RenderingLightCuller::string_LUT_entry(const LocalVector<uint8_t> &p_entry) {
String string;
for (uint32_t n = 0; n < p_entry.size(); n++) {
uint8_t val = p_entry[n];
DEV_ASSERT(val < 8);
const char *sz_point = Data::string_points[val];
string += sz_point;
string += ", ";
}
return string;
}
String RenderingLightCuller::debug_string_LUT_entry(const LocalVector<uint8_t> &p_entry, bool p_pair) {
String string;
for (uint32_t i = 0; i < p_entry.size(); i++) {
int pt_order = p_entry[i];
if (p_pair && ((i % 2) == 0)) {
string += itos(pt_order) + "-";
} else {
string += itos(pt_order) + ", ";
}
}
return string;
}
void RenderingLightCuller::add_LUT(int p_plane_0, int p_plane_1, PointOrder p_pts[2]) {
uint32_t bit0 = 1 << p_plane_0;
uint32_t bit1 = 1 << p_plane_1;
for (uint32_t n = 0; n < 64; n++) {
if (!(n & bit0))
continue;
if (n & bit1)
continue;
add_LUT_entry(n, p_pts);
}
}
void RenderingLightCuller::add_LUT_entry(uint32_t p_entry_id, PointOrder p_pts[2]) {
DEV_ASSERT(p_entry_id < LUT_SIZE);
LocalVector<uint8_t> &entry = _calculated_LUT[p_entry_id];
entry.push_back(p_pts[0]);
entry.push_back(p_pts[1]);
}
void RenderingLightCuller::compact_LUT_entry(uint32_t p_entry_id) {
DEV_ASSERT(p_entry_id < LUT_SIZE);
LocalVector<uint8_t> &entry = _calculated_LUT[p_entry_id];
int num_pairs = entry.size() / 2;
if (num_pairs == 0)
return;
LocalVector<uint8_t> temp;
String string;
string = "Compact LUT" + itos(p_entry_id) + ":\t";
string += debug_string_LUT_entry(entry, true);
print_line(string);
temp.push_back(entry[0]);
temp.push_back(entry[1]);
unsigned int BFpairs = 1;
string = debug_string_LUT_entry(temp) + " -> ";
print_line(string);
for (int done = 1; done < num_pairs; done++) {
string = "done " + itos(done) + ": ";
for (int p = 1; p < num_pairs; p++) {
unsigned int bit = 1 << p;
if (BFpairs & bit)
continue;
int a = entry[p * 2];
int b = entry[(p * 2) + 1];
string += "[" + itos(a) + "-" + itos(b) + "], ";
int found_a = temp.find(a);
int found_b = temp.find(b);
if ((found_a != -1) && (found_b != -1)) {
string += "foundAB link " + itos(found_a) + ", " + itos(found_b) + " ";
BFpairs |= bit;
goto found;
}
if (found_a != -1) {
string += "foundA " + itos(found_a) + " ";
temp.insert(found_a + 1, b);
BFpairs |= bit;
goto found;
}
if (found_b != -1) {
string += "foundB " + itos(found_b) + " ";
temp.insert(found_b, a);
BFpairs |= bit;
goto found;
}
}
print_line("\tINVALID");
entry.clear();
return;
found:;
print_line(string);
string = "\ttemp now : " + debug_string_LUT_entry(temp);
print_line(string);
}
entry.clear();
entry = temp;
}
void RenderingLightCuller::get_neighbouring_planes(PlaneOrder p_plane, PlaneOrder r_neigh_planes[4]) const {
static const PlaneOrder neigh_table[PLANE_TOTAL][4] = {
{
PLANE_LEFT,
PLANE_RIGHT,
PLANE_TOP,
PLANE_BOTTOM },
{
PLANE_LEFT,
PLANE_RIGHT,
PLANE_TOP,
PLANE_BOTTOM },
{
PLANE_TOP,
PLANE_BOTTOM,
PLANE_NEAR,
PLANE_FAR },
{
PLANE_LEFT,
PLANE_RIGHT,
PLANE_NEAR,
PLANE_FAR },
{
PLANE_TOP,
PLANE_BOTTOM,
PLANE_NEAR,
PLANE_FAR },
{
PLANE_LEFT,
PLANE_RIGHT,
PLANE_NEAR,
PLANE_FAR },
};
for (int n = 0; n < 4; n++) {
r_neigh_planes[n] = neigh_table[p_plane][n];
}
}
void RenderingLightCuller::get_corners_of_planes(PlaneOrder p_plane_a, PlaneOrder p_plane_b, PointOrder r_points[2]) const {
static const PointOrder fp_table[PLANE_TOTAL][PLANE_TOTAL][2] = {
{
{
PT_NEAR_LEFT_TOP, PT_NEAR_RIGHT_TOP,
},
{
PT_FAR_RIGHT_TOP, PT_FAR_LEFT_TOP,
},
{
PT_NEAR_LEFT_TOP,
PT_NEAR_LEFT_BOTTOM,
},
{
PT_NEAR_RIGHT_TOP,
PT_NEAR_LEFT_TOP,
},
{
PT_NEAR_RIGHT_BOTTOM,
PT_NEAR_RIGHT_TOP,
},
{
PT_NEAR_LEFT_BOTTOM,
PT_NEAR_RIGHT_BOTTOM,
},
},
{
{
PT_FAR_LEFT_TOP, PT_FAR_RIGHT_TOP,
},
{
PT_FAR_RIGHT_TOP, PT_FAR_LEFT_TOP,
},
{
PT_FAR_LEFT_BOTTOM,
PT_FAR_LEFT_TOP,
},
{
PT_FAR_LEFT_TOP,
PT_FAR_RIGHT_TOP,
},
{
PT_FAR_RIGHT_TOP,
PT_FAR_RIGHT_BOTTOM,
},
{
PT_FAR_RIGHT_BOTTOM,
PT_FAR_LEFT_BOTTOM,
},
},
{
{
PT_NEAR_LEFT_BOTTOM,
PT_NEAR_LEFT_TOP,
},
{
PT_FAR_LEFT_TOP,
PT_FAR_LEFT_BOTTOM,
},
{
PT_FAR_LEFT_BOTTOM, PT_FAR_LEFT_BOTTOM,
},
{
PT_NEAR_LEFT_TOP,
PT_FAR_LEFT_TOP,
},
{
PT_FAR_LEFT_BOTTOM, PT_FAR_LEFT_BOTTOM,
},
{
PT_FAR_LEFT_BOTTOM,
PT_NEAR_LEFT_BOTTOM,
},
},
{
{
PT_NEAR_LEFT_TOP,
PT_NEAR_RIGHT_TOP,
},
{
PT_FAR_RIGHT_TOP,
PT_FAR_LEFT_TOP,
},
{
PT_FAR_LEFT_TOP,
PT_NEAR_LEFT_TOP,
},
{
PT_NEAR_LEFT_TOP, PT_FAR_LEFT_TOP,
},
{
PT_NEAR_RIGHT_TOP,
PT_FAR_RIGHT_TOP,
},
{
PT_FAR_LEFT_BOTTOM, PT_NEAR_LEFT_BOTTOM,
},
},
{
{
PT_NEAR_RIGHT_TOP,
PT_NEAR_RIGHT_BOTTOM,
},
{
PT_FAR_RIGHT_BOTTOM,
PT_FAR_RIGHT_TOP,
},
{
PT_FAR_RIGHT_BOTTOM, PT_FAR_RIGHT_BOTTOM,
},
{
PT_FAR_RIGHT_TOP,
PT_NEAR_RIGHT_TOP,
},
{
PT_FAR_RIGHT_BOTTOM, PT_FAR_RIGHT_BOTTOM,
},
{
PT_NEAR_RIGHT_BOTTOM,
PT_FAR_RIGHT_BOTTOM,
},
},
{
{
PT_NEAR_RIGHT_BOTTOM,
PT_NEAR_LEFT_BOTTOM,
},
{
PT_FAR_LEFT_BOTTOM,
PT_FAR_RIGHT_BOTTOM,
},
{
PT_NEAR_LEFT_BOTTOM,
PT_FAR_LEFT_BOTTOM,
},
{
PT_NEAR_LEFT_BOTTOM, PT_FAR_LEFT_BOTTOM,
},
{
PT_FAR_RIGHT_BOTTOM,
PT_NEAR_RIGHT_BOTTOM,
},
{
PT_FAR_LEFT_BOTTOM, PT_NEAR_LEFT_BOTTOM,
},
},
};
r_points[0] = fp_table[p_plane_a][p_plane_b][0];
r_points[1] = fp_table[p_plane_a][p_plane_b][1];
}
#endif