diff options
Diffstat (limited to 'Source/Graphics/lightprobecollection.cpp')
-rw-r--r-- | Source/Graphics/lightprobecollection.cpp | 904 |
1 files changed, 445 insertions, 459 deletions
diff --git a/Source/Graphics/lightprobecollection.cpp b/Source/Graphics/lightprobecollection.cpp index b255ad87..f3037fa3 100644 --- a/Source/Graphics/lightprobecollection.cpp +++ b/Source/Graphics/lightprobecollection.cpp @@ -1,7 +1,7 @@ //----------------------------------------------------------------------------- // Name: lightprobecollection.cpp // Developer: Wolfire Games LLC -// Description: +// Description: // License: Read below //----------------------------------------------------------------------------- // @@ -47,14 +47,12 @@ const float kQuantize = 10.0f; -LightProbeCollection::LightProbeCollection(): - tet_mesh_viz_enabled(false), - show_probes(false), - show_probes_through_walls(false), - probe_lighting_enabled(true), - light_volume_enabled(true), - probe_model_id(-1) -{ +LightProbeCollection::LightProbeCollection() : tet_mesh_viz_enabled(false), + show_probes(false), + show_probes_through_walls(false), + probe_lighting_enabled(true), + light_volume_enabled(true), + probe_model_id(-1) { cube_map_fbo = INVALID_FRAMEBUFFER; next_id = 0; tet_mesh.display_id = -1; @@ -70,13 +68,13 @@ LightProbeCollection::~LightProbeCollection() { LOG_ASSERT(cube_map_fbo == INVALID_FRAMEBUFFER); } -int LightProbeCollection::AddProbe(const vec3& pos, bool negative, const float *coeff) { - light_probes.resize(light_probes.size()+1); - LightProbe &probe = light_probes.back(); +int LightProbeCollection::AddProbe(const vec3& pos, bool negative, const float* coeff) { + light_probes.resize(light_probes.size() + 1); + LightProbe& probe = light_probes.back(); probe.pos = pos; probe.negative = negative; probe.id = next_id++; - if(!negative && !coeff){ + if (!negative && !coeff) { LightProbeUpdateEntry entry; entry.id = probe.id; entry.pass = 0; @@ -94,7 +92,7 @@ int LightProbeCollection::AddProbe(const vec3& pos, bool negative, const float * bool LightProbeCollection::MoveProbe(int id, const vec3& pos) { LightProbe* probe = GetProbeFromID(id); - if(probe){ + if (probe) { probe->pos = pos; LightProbeUpdateEntry entry; entry.id = id; @@ -109,7 +107,7 @@ bool LightProbeCollection::MoveProbe(int id, const vec3& pos) { bool LightProbeCollection::SetNegative(int id, bool negative) { LightProbe* probe = GetProbeFromID(id); - if(probe){ + if (probe) { probe->negative = negative; LightProbeUpdateEntry entry; entry.id = id; @@ -123,8 +121,8 @@ bool LightProbeCollection::SetNegative(int id, bool negative) { } bool LightProbeCollection::DeleteProbe(int id) { - for(int i=0, len=light_probes.size(); i<len; ++i){ - if(light_probes[i].id == id) { + for (int i = 0, len = light_probes.size(); i < len; ++i) { + if (light_probes[i].id == id) { light_probes.erase(light_probes.begin() + i); tet_mesh_needs_update = true; return true; @@ -134,15 +132,15 @@ bool LightProbeCollection::DeleteProbe(int id) { } void LightProbeCollection::Init() { - if(cube_map_fbo == INVALID_FRAMEBUFFER){ - Graphics::Instance()->genFramebuffers(&cube_map_fbo, "light_probe_cube_map"); - } - if(!cube_map.valid()){ - cube_map = Textures::Instance()->makeCubemapTexture(128, 128, GL_RGBA16F, GL_RGBA, Textures::MIPMAPS); - } - Textures::Instance()->SetTextureName(cube_map, "Light Probe Collection Cubemap"); - probe_model_id = Models::Instance()->loadModel(HardcodedPaths::paths[HardcodedPaths::kLightProbe]); - if(!light_probes.empty()){ + if (cube_map_fbo == INVALID_FRAMEBUFFER) { + Graphics::Instance()->genFramebuffers(&cube_map_fbo, "light_probe_cube_map"); + } + if (!cube_map.valid()) { + cube_map = Textures::Instance()->makeCubemapTexture(128, 128, GL_RGBA16F, GL_RGBA, Textures::MIPMAPS); + } + Textures::Instance()->SetTextureName(cube_map, "Light Probe Collection Cubemap"); + probe_model_id = Models::Instance()->loadModel(HardcodedPaths::paths[HardcodedPaths::kLightProbe]); + if (!light_probes.empty()) { tet_mesh_needs_update = true; } light_probe_texture_buffer_id = -1; @@ -159,23 +157,21 @@ void LightProbeCollection::Dispose() { light_probes.clear(); } -int LightProbeCollection::ShaderNumLightProbes() -{ +int LightProbeCollection::ShaderNumLightProbes() { return probe_lighting_enabled ? light_probes.size() : 0; } -int LightProbeCollection::ShaderNumTetrahedra() -{ - return probe_lighting_enabled ? tet_mesh.points.size()/4 : 0; +int LightProbeCollection::ShaderNumTetrahedra() { + return probe_lighting_enabled ? tet_mesh.points.size() / 4 : 0; } LightProbe* LightProbeCollection::GetNextProbeToProcess() { - if(!to_process.empty()){ + if (!to_process.empty()) { LightProbeUpdateEntry entry = to_process.front(); int id = entry.id; to_process.pop(); LightProbe* probe = GetProbeFromID(id); - if(probe){ + if (probe) { return probe; } } @@ -183,17 +179,17 @@ LightProbe* LightProbeCollection::GetNextProbeToProcess() { } LightProbe* LightProbeCollection::GetProbeFromID(int id) { - for(auto & light_probe : light_probes){ - if(light_probe.id == id) { + for (auto& light_probe : light_probes) { + if (light_probe.id == id) { return &light_probe; } } return NULL; } -float GetTetrahedronVolume(vec3 points[4]){ +float GetTetrahedronVolume(vec3 points[4]) { glm::mat4 tet_volume_mat; - for(int column=0; column<4; ++column){ + for (int column = 0; column < 4; ++column) { tet_volume_mat[column] = glm::vec4(points[column][0], points[column][1], points[column][2], 1.0f); } float volume = fabs(glm::determinant(tet_volume_mat) / 6.0f); @@ -206,250 +202,250 @@ void LightProbeCollection::UpdateTetMesh(BulletWorld& bw) { // Clear existing tet mesh tet_mesh.points.clear(); tet_mesh.point_id.clear(); - if(tet_mesh.display_id != -1){ + if (tet_mesh.display_id != -1) { DebugDraw::Instance()->Remove(tet_mesh.display_id); } // Don't bother if we don't even have four probes - if(light_probes.size() < 4) { + if (light_probes.size() < 4) { return; } - //Following block is commented out, disabling light probes, to disconnect tetgen from the project -// // Prepare tetgen -// tetgenio in, out; -// std::vector<REAL> points; -// std::vector<REAL> point_attributes; -// points.resize(light_probes.size()*3); -// for(int tet=0, index=0, len=light_probes.size(); tet<len; ++tet, index+=3){ -// // Quantize points how they will be bit-packed later for shaders -// for(int j=0; j<3; ++j){ -// unsigned encoded = (unsigned)(light_probes[tet].pos[j] * kQuantize + 32767.5f); -// float decoded = (encoded - 32767.5f) / kQuantize; -// points[index+j] = (REAL)decoded; -// } -// // Add point id -// point_attributes.push_back((REAL)((float)tet+0.5f)); -// } -// in.pointlist = &points[0]; -// in.numberofpoints = light_probes.size(); -// in.numberofpointattributes = 1; -// in.pointattributelist = &point_attributes[0]; -// -// bool success = true; -// tetgenbehavior behavior; -// behavior.quiet = true; -// behavior.neighout = true; // We want to preserve neighbor info so we don't have to recalculate that -// try { -// tetrahedralize(&behavior, &in, &out); -// } catch(int) { -// success = false; -// } -// in.initialize(); -// if(success && out.numberofpoints > 0){ -// tet_mesh.points.resize(out.numberofpoints); -// tet_mesh.tet_points.resize(out.numberoftetrahedra*4); -// tet_mesh.neighbors.resize(out.numberoftetrahedra*4); -// -// for(int i=0, index=0, len=out.numberofpoints; -// i<len; -// ++i, index+=3) -// { -// for(int j=0; j<3; ++j){ -// tet_mesh.points[i][j] = (float)out.pointlist[index+j]; -// } -// tet_mesh.point_id.push_back((int)out.pointattributelist[i]); -// } -// -// for(int i=0, len=out.numberoftetrahedra*4; i<len; ++i) { -// tet_mesh.tet_points[i] = out.tetrahedronlist[i]; -// } -// -// for(int i=0, len=out.numberoftetrahedra*4; i<len; ++i) { -// tet_mesh.neighbors[i] = out.neighborlist[i]; -// } -// -// if(tet_mesh_viz_enabled) { -// std::vector<GLfloat> line_verts; -// std::vector<GLuint> line_indices; -// -// for(int i=0, index=0, len=tet_mesh.tet_points.size()/4; -// i<len; -// ++i, index+=4) -// { -// for(int j=0; j<6; ++j){ -// int points[2]; -// const int *tet_points = &tet_mesh.tet_points[index]; -// switch(j){ -// case 0: points[0] = tet_points[0]; points[1] = tet_points[1]; break; -// case 1: points[0] = tet_points[0]; points[1] = tet_points[2]; break; -// case 2: points[0] = tet_points[0]; points[1] = tet_points[3]; break; -// case 3: points[0] = tet_points[1]; points[1] = tet_points[2]; break; -// case 4: points[0] = tet_points[1]; points[1] = tet_points[3]; break; -// case 5: points[0] = tet_points[2]; points[1] = tet_points[3]; break; -// } -// //if(!light_probes[tet_mesh.point_id[points[0]]].negative && -// // !light_probes[tet_mesh.point_id[points[1]]].negative) -// //{ -// for(int i=0; i<2; ++i){ -// vec3 pos = light_probes[tet_mesh.point_id[points[i]]].pos; -// line_indices.push_back(line_verts.size()/3); -// for(int j=0; j<3; ++j){ -// unsigned encoded = (unsigned)(pos[j] * kQuantize + 32767.5f); -// float decoded = (encoded - 32767.5f) / kQuantize; -// line_verts.push_back(decoded); -// } -// } -// //} -// } -// } -// tet_mesh.display_id = DebugDraw::Instance()->AddLines(line_verts, line_indices, vec4(vec3(1.0f), 0.2f), _persistent, _DD_NO_FLAG); -// } -// } -// -// // Update grid lookup -// grid_lookup.bounds[0] = vec3(FLT_MAX); -// grid_lookup.bounds[1] = vec3(-FLT_MAX); -// for(int tet=0, len=tet_mesh.points.size(); tet<len; ++tet){ -// for(int j=0; j<3; ++j){ -// grid_lookup.bounds[0][j] = min(grid_lookup.bounds[0][j], tet_mesh.points[tet][j]); -// grid_lookup.bounds[1][j] = max(grid_lookup.bounds[1][j], tet_mesh.points[tet][j]); -// } -// } -// static const float kCellSize = 4.0f; // Target dimensions of each grid cell -// for(int tet=0; tet<3; ++tet){ -// grid_lookup.subdivisions[tet] = (int)ceilf((grid_lookup.bounds[1][tet] - grid_lookup.bounds[0][tet]) / kCellSize); -// } -// int total_cells = grid_lookup.subdivisions[0] * grid_lookup.subdivisions[1] * grid_lookup.subdivisions[2]; -// if(total_cells > GridLookup::kMaxGridCells){ -// float scale = 0.99f; -// while((int)ceilf(grid_lookup.subdivisions[0]*scale) * -// (int)ceilf(grid_lookup.subdivisions[1]*scale) * -// (int)ceilf(grid_lookup.subdivisions[2]*scale) > GridLookup::kMaxGridCells) -// { -// scale -= 0.01f; -// } -// for(int i=0; i<3; ++i){ -// grid_lookup.subdivisions[i] = (int)ceilf(grid_lookup.subdivisions[i]*scale); -// } -// } -// const bool kDebugGridInfo = false; -// if(kDebugGridInfo){ -// LOGI << "Grid bounds: " << "(" << grid_lookup.bounds[0][0] << " " << grid_lookup.bounds[0][1] << " " << grid_lookup.bounds[0][2] << ")" -// << " (" << grid_lookup.bounds[1][0] << " " << grid_lookup.bounds[1][1] << " " << grid_lookup.bounds[1][2] << ")" << std::endl; -// LOGI << "Grid subdivisions: (" << grid_lookup.subdivisions[0] << " " << grid_lookup.subdivisions[1] << " " << grid_lookup.subdivisions[2] << ")" << std::endl; -// } -// grid_lookup.cell_tet.resize(grid_lookup.subdivisions[0] * grid_lookup.subdivisions[1] * grid_lookup.subdivisions[2], UINT_MAX); -// // Go through each tetrahedron and tag overlapping cells -// for(int tet=0, index=0, len=tet_mesh.tet_points.size()/4; -// tet<len; -// ++tet, index+=4) -// { -// const int *tet_points = &tet_mesh.tet_points[index]; -// // Get world-space bounds of tetrahedron -// vec3 ws_bounds[2] = {vec3(FLT_MAX), vec3(-FLT_MAX)}; -// for(int vert=0; vert<4; ++vert){ -// for(int axis=0; axis<3; ++axis){ -// ws_bounds[0][axis] = min(ws_bounds[0][axis], tet_mesh.points[tet_points[vert]][axis]); -// ws_bounds[1][axis] = max(ws_bounds[1][axis], tet_mesh.points[tet_points[vert]][axis]); -// } -// } -// // Get grid-space bounds -// int gs_bounds[2][3]; -// for(int corner=0; corner<2; ++corner){ -// for(int axis=0; axis<3; ++axis){ -// gs_bounds[corner][axis] = (int)((ws_bounds[corner][axis] - grid_lookup.bounds[0][axis]) / (grid_lookup.bounds[1][axis] - grid_lookup.bounds[0][axis]) * (float)grid_lookup.subdivisions[axis]); -// gs_bounds[corner][axis] = min(gs_bounds[corner][axis], grid_lookup.subdivisions[axis]-1); -// } -// } -// // Get tetrahedron planes for later use -// vec4 tet_planes[4]; -// for(int face=0; face<4; ++face){ -// int vert_ids[3]; -// switch(face) { -// case 0: vert_ids[0] = 0; vert_ids[1] = 1; vert_ids[2] = 2; break; -// case 1: vert_ids[0] = 0; vert_ids[1] = 2; vert_ids[2] = 3; break; -// case 2: vert_ids[0] = 0; vert_ids[1] = 3; vert_ids[2] = 1; break; -// case 3: vert_ids[0] = 1; vert_ids[1] = 3; vert_ids[2] = 2; break; -// } -// vec3 verts[3]; -// for(int i=0; i<3; ++i){ -// verts[i] = tet_mesh.points[tet_points[vert_ids[i]]]; -// } -// vec3 normal = normalize(cross(verts[1] - verts[0], verts[2] - verts[0])); -// float d = dot(normal, verts[0]); -// tet_planes[face] = vec4(normal, d); -// } -// // TODO: use the tetrahedron info to calculate the volume that overlaps each grid cell -// vec3 tet_verts[4]; -// for(int vert=0; vert<4; ++vert){ -// tet_verts[vert] = tet_mesh.points[tet_points[vert]]; -// } -// //float volume = GetTetrahedronVolume(tet_verts); -// -// const bool kCheckMidpointIsInTet = true; -// if(kCheckMidpointIsInTet){ // This is a sanity check -- if the midpoint of the tet is not inside all the planes, something is weird -// vec3 mid_point(0.0f); -// for(int vert=0; vert<4; ++vert){ -// mid_point += tet_mesh.points[tet_points[vert]] * 0.25f; -// } -// for(int face=0; face<4; ++face){ -// float dot_val = dot(mid_point, tet_planes[face].xyz()); -// LOG_ASSERT(dot_val > tet_planes[face][3]); -// } -// } -// -// vec3 grid_dims = grid_lookup.bounds[1] - grid_lookup.bounds[0]; -// vec3 grid_cell_dims; -// for(int axis=0; axis<3; ++axis){ -// grid_cell_dims[axis] = grid_dims[axis] / (float)grid_lookup.subdivisions[axis]; -// } -// btBoxShape* box_shape = new btBoxShape(btVector3(grid_cell_dims[0]*0.5f, -// grid_cell_dims[1]*0.5f, -// grid_cell_dims[2]*0.5f)); -// btCollisionObject aabb_col_obj; -// aabb_col_obj.setCollisionShape(box_shape); -// btTransform aabb_transform; -// aabb_transform.setIdentity(); -// -// btCollisionObject tet_col_obj; -// -// // Tag each of these grid cells with the current tetrahedron -// for(int x_cell = gs_bounds[0][0]; x_cell <= gs_bounds[1][0]; ++x_cell){ -// for(int y_cell = gs_bounds[0][1]; y_cell <= gs_bounds[1][1]; ++y_cell){ -// for(int z_cell = gs_bounds[0][2]; z_cell <= gs_bounds[1][2]; ++z_cell){ -// /*aabb_transform.setOrigin(btVector3( -// grid_lookup.bounds[0][0] + (x_cell + 0.5f) * grid_cell_dims[0], -// grid_lookup.bounds[0][1] + (y_cell + 0.5f) * grid_cell_dims[1], -// grid_lookup.bounds[0][2] + (z_cell + 0.5f) * grid_cell_dims[2])); -// aabb_col_obj.setWorldTransform(aabb_transform); -// -// btConvexHullShape* tet_shape = new btConvexHullShape(); -// for(int i=0; i<4; ++i){ -// tet_shape->addPoint(btVector3(tet_verts[i][0],tet_verts[i][1],tet_verts[i][2])); -// } -// tet_col_obj.setCollisionShape(tet_shape); -// -// ContactInfoCallback cb; -// bw.GetPairCollisions(aabb_col_obj, tet_col_obj, cb); -// -// delete tet_shape; -// -// if(cb.contact_info.size() != 0){*/ -// // TODO: eventually only label the tet with most volume in cell -// int cell_id = ((x_cell * grid_lookup.subdivisions[1]) + y_cell)*grid_lookup.subdivisions[2] + z_cell; -// grid_lookup.cell_tet[cell_id] = tet; -// //} -// } -// } -// } -// -// delete box_shape; -// } + // Following block is commented out, disabling light probes, to disconnect tetgen from the project + // // Prepare tetgen + // tetgenio in, out; + // std::vector<REAL> points; + // std::vector<REAL> point_attributes; + // points.resize(light_probes.size()*3); + // for(int tet=0, index=0, len=light_probes.size(); tet<len; ++tet, index+=3){ + // // Quantize points how they will be bit-packed later for shaders + // for(int j=0; j<3; ++j){ + // unsigned encoded = (unsigned)(light_probes[tet].pos[j] * kQuantize + 32767.5f); + // float decoded = (encoded - 32767.5f) / kQuantize; + // points[index+j] = (REAL)decoded; + // } + // // Add point id + // point_attributes.push_back((REAL)((float)tet+0.5f)); + // } + // in.pointlist = &points[0]; + // in.numberofpoints = light_probes.size(); + // in.numberofpointattributes = 1; + // in.pointattributelist = &point_attributes[0]; + // + // bool success = true; + // tetgenbehavior behavior; + // behavior.quiet = true; + // behavior.neighout = true; // We want to preserve neighbor info so we don't have to recalculate that + // try { + // tetrahedralize(&behavior, &in, &out); + // } catch(int) { + // success = false; + // } + // in.initialize(); + // if(success && out.numberofpoints > 0){ + // tet_mesh.points.resize(out.numberofpoints); + // tet_mesh.tet_points.resize(out.numberoftetrahedra*4); + // tet_mesh.neighbors.resize(out.numberoftetrahedra*4); + // + // for(int i=0, index=0, len=out.numberofpoints; + // i<len; + // ++i, index+=3) + // { + // for(int j=0; j<3; ++j){ + // tet_mesh.points[i][j] = (float)out.pointlist[index+j]; + // } + // tet_mesh.point_id.push_back((int)out.pointattributelist[i]); + // } + // + // for(int i=0, len=out.numberoftetrahedra*4; i<len; ++i) { + // tet_mesh.tet_points[i] = out.tetrahedronlist[i]; + // } + // + // for(int i=0, len=out.numberoftetrahedra*4; i<len; ++i) { + // tet_mesh.neighbors[i] = out.neighborlist[i]; + // } + // + // if(tet_mesh_viz_enabled) { + // std::vector<GLfloat> line_verts; + // std::vector<GLuint> line_indices; + // + // for(int i=0, index=0, len=tet_mesh.tet_points.size()/4; + // i<len; + // ++i, index+=4) + // { + // for(int j=0; j<6; ++j){ + // int points[2]; + // const int *tet_points = &tet_mesh.tet_points[index]; + // switch(j){ + // case 0: points[0] = tet_points[0]; points[1] = tet_points[1]; break; + // case 1: points[0] = tet_points[0]; points[1] = tet_points[2]; break; + // case 2: points[0] = tet_points[0]; points[1] = tet_points[3]; break; + // case 3: points[0] = tet_points[1]; points[1] = tet_points[2]; break; + // case 4: points[0] = tet_points[1]; points[1] = tet_points[3]; break; + // case 5: points[0] = tet_points[2]; points[1] = tet_points[3]; break; + // } + // //if(!light_probes[tet_mesh.point_id[points[0]]].negative && + // // !light_probes[tet_mesh.point_id[points[1]]].negative) + // //{ + // for(int i=0; i<2; ++i){ + // vec3 pos = light_probes[tet_mesh.point_id[points[i]]].pos; + // line_indices.push_back(line_verts.size()/3); + // for(int j=0; j<3; ++j){ + // unsigned encoded = (unsigned)(pos[j] * kQuantize + 32767.5f); + // float decoded = (encoded - 32767.5f) / kQuantize; + // line_verts.push_back(decoded); + // } + // } + // //} + // } + // } + // tet_mesh.display_id = DebugDraw::Instance()->AddLines(line_verts, line_indices, vec4(vec3(1.0f), 0.2f), _persistent, _DD_NO_FLAG); + // } + // } + // + // // Update grid lookup + // grid_lookup.bounds[0] = vec3(FLT_MAX); + // grid_lookup.bounds[1] = vec3(-FLT_MAX); + // for(int tet=0, len=tet_mesh.points.size(); tet<len; ++tet){ + // for(int j=0; j<3; ++j){ + // grid_lookup.bounds[0][j] = min(grid_lookup.bounds[0][j], tet_mesh.points[tet][j]); + // grid_lookup.bounds[1][j] = max(grid_lookup.bounds[1][j], tet_mesh.points[tet][j]); + // } + // } + // static const float kCellSize = 4.0f; // Target dimensions of each grid cell + // for(int tet=0; tet<3; ++tet){ + // grid_lookup.subdivisions[tet] = (int)ceilf((grid_lookup.bounds[1][tet] - grid_lookup.bounds[0][tet]) / kCellSize); + // } + // int total_cells = grid_lookup.subdivisions[0] * grid_lookup.subdivisions[1] * grid_lookup.subdivisions[2]; + // if(total_cells > GridLookup::kMaxGridCells){ + // float scale = 0.99f; + // while((int)ceilf(grid_lookup.subdivisions[0]*scale) * + // (int)ceilf(grid_lookup.subdivisions[1]*scale) * + // (int)ceilf(grid_lookup.subdivisions[2]*scale) > GridLookup::kMaxGridCells) + // { + // scale -= 0.01f; + // } + // for(int i=0; i<3; ++i){ + // grid_lookup.subdivisions[i] = (int)ceilf(grid_lookup.subdivisions[i]*scale); + // } + // } + // const bool kDebugGridInfo = false; + // if(kDebugGridInfo){ + // LOGI << "Grid bounds: " << "(" << grid_lookup.bounds[0][0] << " " << grid_lookup.bounds[0][1] << " " << grid_lookup.bounds[0][2] << ")" + // << " (" << grid_lookup.bounds[1][0] << " " << grid_lookup.bounds[1][1] << " " << grid_lookup.bounds[1][2] << ")" << std::endl; + // LOGI << "Grid subdivisions: (" << grid_lookup.subdivisions[0] << " " << grid_lookup.subdivisions[1] << " " << grid_lookup.subdivisions[2] << ")" << std::endl; + // } + // grid_lookup.cell_tet.resize(grid_lookup.subdivisions[0] * grid_lookup.subdivisions[1] * grid_lookup.subdivisions[2], UINT_MAX); + // // Go through each tetrahedron and tag overlapping cells + // for(int tet=0, index=0, len=tet_mesh.tet_points.size()/4; + // tet<len; + // ++tet, index+=4) + // { + // const int *tet_points = &tet_mesh.tet_points[index]; + // // Get world-space bounds of tetrahedron + // vec3 ws_bounds[2] = {vec3(FLT_MAX), vec3(-FLT_MAX)}; + // for(int vert=0; vert<4; ++vert){ + // for(int axis=0; axis<3; ++axis){ + // ws_bounds[0][axis] = min(ws_bounds[0][axis], tet_mesh.points[tet_points[vert]][axis]); + // ws_bounds[1][axis] = max(ws_bounds[1][axis], tet_mesh.points[tet_points[vert]][axis]); + // } + // } + // // Get grid-space bounds + // int gs_bounds[2][3]; + // for(int corner=0; corner<2; ++corner){ + // for(int axis=0; axis<3; ++axis){ + // gs_bounds[corner][axis] = (int)((ws_bounds[corner][axis] - grid_lookup.bounds[0][axis]) / (grid_lookup.bounds[1][axis] - grid_lookup.bounds[0][axis]) * (float)grid_lookup.subdivisions[axis]); + // gs_bounds[corner][axis] = min(gs_bounds[corner][axis], grid_lookup.subdivisions[axis]-1); + // } + // } + // // Get tetrahedron planes for later use + // vec4 tet_planes[4]; + // for(int face=0; face<4; ++face){ + // int vert_ids[3]; + // switch(face) { + // case 0: vert_ids[0] = 0; vert_ids[1] = 1; vert_ids[2] = 2; break; + // case 1: vert_ids[0] = 0; vert_ids[1] = 2; vert_ids[2] = 3; break; + // case 2: vert_ids[0] = 0; vert_ids[1] = 3; vert_ids[2] = 1; break; + // case 3: vert_ids[0] = 1; vert_ids[1] = 3; vert_ids[2] = 2; break; + // } + // vec3 verts[3]; + // for(int i=0; i<3; ++i){ + // verts[i] = tet_mesh.points[tet_points[vert_ids[i]]]; + // } + // vec3 normal = normalize(cross(verts[1] - verts[0], verts[2] - verts[0])); + // float d = dot(normal, verts[0]); + // tet_planes[face] = vec4(normal, d); + // } + // // TODO: use the tetrahedron info to calculate the volume that overlaps each grid cell + // vec3 tet_verts[4]; + // for(int vert=0; vert<4; ++vert){ + // tet_verts[vert] = tet_mesh.points[tet_points[vert]]; + // } + // //float volume = GetTetrahedronVolume(tet_verts); + // + // const bool kCheckMidpointIsInTet = true; + // if(kCheckMidpointIsInTet){ // This is a sanity check -- if the midpoint of the tet is not inside all the planes, something is weird + // vec3 mid_point(0.0f); + // for(int vert=0; vert<4; ++vert){ + // mid_point += tet_mesh.points[tet_points[vert]] * 0.25f; + // } + // for(int face=0; face<4; ++face){ + // float dot_val = dot(mid_point, tet_planes[face].xyz()); + // LOG_ASSERT(dot_val > tet_planes[face][3]); + // } + // } + // + // vec3 grid_dims = grid_lookup.bounds[1] - grid_lookup.bounds[0]; + // vec3 grid_cell_dims; + // for(int axis=0; axis<3; ++axis){ + // grid_cell_dims[axis] = grid_dims[axis] / (float)grid_lookup.subdivisions[axis]; + // } + // btBoxShape* box_shape = new btBoxShape(btVector3(grid_cell_dims[0]*0.5f, + // grid_cell_dims[1]*0.5f, + // grid_cell_dims[2]*0.5f)); + // btCollisionObject aabb_col_obj; + // aabb_col_obj.setCollisionShape(box_shape); + // btTransform aabb_transform; + // aabb_transform.setIdentity(); + // + // btCollisionObject tet_col_obj; + // + // // Tag each of these grid cells with the current tetrahedron + // for(int x_cell = gs_bounds[0][0]; x_cell <= gs_bounds[1][0]; ++x_cell){ + // for(int y_cell = gs_bounds[0][1]; y_cell <= gs_bounds[1][1]; ++y_cell){ + // for(int z_cell = gs_bounds[0][2]; z_cell <= gs_bounds[1][2]; ++z_cell){ + // /*aabb_transform.setOrigin(btVector3( + // grid_lookup.bounds[0][0] + (x_cell + 0.5f) * grid_cell_dims[0], + // grid_lookup.bounds[0][1] + (y_cell + 0.5f) * grid_cell_dims[1], + // grid_lookup.bounds[0][2] + (z_cell + 0.5f) * grid_cell_dims[2])); + // aabb_col_obj.setWorldTransform(aabb_transform); + // + // btConvexHullShape* tet_shape = new btConvexHullShape(); + // for(int i=0; i<4; ++i){ + // tet_shape->addPoint(btVector3(tet_verts[i][0],tet_verts[i][1],tet_verts[i][2])); + // } + // tet_col_obj.setCollisionShape(tet_shape); + // + // ContactInfoCallback cb; + // bw.GetPairCollisions(aabb_col_obj, tet_col_obj, cb); + // + // delete tet_shape; + // + // if(cb.contact_info.size() != 0){*/ + // // TODO: eventually only label the tet with most volume in cell + // int cell_id = ((x_cell * grid_lookup.subdivisions[1]) + y_cell)*grid_lookup.subdivisions[2] + z_cell; + // grid_lookup.cell_tet[cell_id] = tet; + // //} + // } + // } + // } + // + // delete box_shape; + // } } -//The following is adapted from http://dennis2society.de/main/painless-tetrahedral-barycentric-mapping +// The following is adapted from http://dennis2society.de/main/painless-tetrahedral-barycentric-mapping namespace { - + /** * Calculate the determinant for a 4x4 matrix based on this example: * http://www.euclideanspace.com/maths/algebra/matrix/functions/determinant/fourD/index.htm @@ -457,41 +453,39 @@ namespace { * using the Laplace expansion. * */ -const float Determinant4x4( const vec4& v0, - const vec4& v1, - const vec4& v2, - const vec4& v3 ) -{ - float det = v0[3]*v1[2]*v2[1]*v3[0] - v0[2]*v1[3]*v2[1]*v3[0] - - v0[3]*v1[1]*v2[2]*v3[0] + v0[1]*v1[3]*v2[2]*v3[0] + +const float Determinant4x4(const vec4& v0, + const vec4& v1, + const vec4& v2, + const vec4& v3) { + float det = v0[3] * v1[2] * v2[1] * v3[0] - v0[2] * v1[3] * v2[1] * v3[0] - + v0[3] * v1[1] * v2[2] * v3[0] + v0[1] * v1[3] * v2[2] * v3[0] + - v0[2]*v1[1]*v2[3]*v3[0] - v0[1]*v1[2]*v2[3]*v3[0] - - v0[3]*v1[2]*v2[0]*v3[1] + v0[2]*v1[3]*v2[0]*v3[1] + + v0[2] * v1[1] * v2[3] * v3[0] - v0[1] * v1[2] * v2[3] * v3[0] - + v0[3] * v1[2] * v2[0] * v3[1] + v0[2] * v1[3] * v2[0] * v3[1] + - v0[3]*v1[0]*v2[2]*v3[1] - v0[0]*v1[3]*v2[2]*v3[1] - - v0[2]*v1[0]*v2[3]*v3[1] + v0[0]*v1[2]*v2[3]*v3[1] + + v0[3] * v1[0] * v2[2] * v3[1] - v0[0] * v1[3] * v2[2] * v3[1] - + v0[2] * v1[0] * v2[3] * v3[1] + v0[0] * v1[2] * v2[3] * v3[1] + - v0[3]*v1[1]*v2[0]*v3[2] - v0[1]*v1[3]*v2[0]*v3[2] - - v0[3]*v1[0]*v2[1]*v3[2] + v0[0]*v1[3]*v2[1]*v3[2] + + v0[3] * v1[1] * v2[0] * v3[2] - v0[1] * v1[3] * v2[0] * v3[2] - + v0[3] * v1[0] * v2[1] * v3[2] + v0[0] * v1[3] * v2[1] * v3[2] + - v0[1]*v1[0]*v2[3]*v3[2] - v0[0]*v1[1]*v2[3]*v3[2] - - v0[2]*v1[1]*v2[0]*v3[3] + v0[1]*v1[2]*v2[0]*v3[3] + + v0[1] * v1[0] * v2[3] * v3[2] - v0[0] * v1[1] * v2[3] * v3[2] - + v0[2] * v1[1] * v2[0] * v3[3] + v0[1] * v1[2] * v2[0] * v3[3] + - v0[2]*v1[0]*v2[1]*v3[3] - v0[0]*v1[2]*v2[1]*v3[3] - - v0[1]*v1[0]*v2[2]*v3[3] + v0[0]*v1[1]*v2[2]*v3[3]; + v0[2] * v1[0] * v2[1] * v3[3] - v0[0] * v1[2] * v2[1] * v3[3] - + v0[1] * v1[0] * v2[2] * v3[3] + v0[0] * v1[1] * v2[2] * v3[3]; return det; } - + /** - * Calculate the actual barycentric coordinate from a point p0_ and the four + * Calculate the actual barycentric coordinate from a point p0_ and the four * vertices v0_ .. v3_ from a tetrahedron. */ -const vec4 GetBarycentricCoordinate( const vec3& v0_, - const vec3& v1_, - const vec3& v2_, - const vec3& v3_, - const vec3& p0_) -{ +const vec4 GetBarycentricCoordinate(const vec3& v0_, + const vec3& v1_, + const vec3& v2_, + const vec3& v3_, + const vec3& p0_) { vec4 v0(v0_, 1.0f); vec4 v1(v1_, 1.0f); vec4 v2(v2_, 1.0f); @@ -503,19 +497,19 @@ const vec4 GetBarycentricCoordinate( const vec3& v0_, const float det2 = Determinant4x4(v0, p0, v2, v3); const float det3 = Determinant4x4(v0, v1, p0, v3); const float det4 = Determinant4x4(v0, v1, v2, p0); - barycentricCoord[0] = (det1/det0); - barycentricCoord[1] = (det2/det0); - barycentricCoord[2] = (det3/det0); - barycentricCoord[3] = (det4/det0); + barycentricCoord[0] = (det1 / det0); + barycentricCoord[1] = (det2 / det0); + barycentricCoord[2] = (det3 / det0); + barycentricCoord[3] = (det4 / det0); return barycentricCoord; } -} // namespace "" +} // namespace static unsigned LeftShift(unsigned val, int amount) { - if(amount >-32 && amount < 32){ - if(amount >= 0){ - return val << amount; + if (amount > -32 && amount < 32) { + if (amount >= 0) { + return val << amount; } else { return val >> -amount; } @@ -526,13 +520,13 @@ static unsigned LeftShift(unsigned val, int amount) { void LightProbeCollection::UpdateTextureBuffer(BulletWorld& bw) { PROFILER_ZONE(g_profiler_ctx, "LightProbeCollection::UpdateTextureBuffer"); - if(tet_mesh_needs_update){ + if (tet_mesh_needs_update) { UpdateTetMesh(bw); } const int kMaxTextureBufferSize = 4 * 1024 * 1024; // Create texture buffer object if it is not already created - if(light_probe_texture_buffer_id == -1){ + if (light_probe_texture_buffer_id == -1) { PROFILER_ZONE(g_profiler_ctx, "Create light probe texture buffer"); int max_size; glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &max_size); @@ -542,9 +536,9 @@ void LightProbeCollection::UpdateTextureBuffer(BulletWorld& bw) { light_probe_buffer_object_id = buffer_object; glBindBuffer(GL_TEXTURE_BUFFER, light_probe_buffer_object_id); char* buf = new char[kMaxTextureBufferSize]; - float *buf_f = (float*)buf; + float* buf_f = (float*)buf; // Start by filling buffer with noise - for(int i=0, len=kMaxTextureBufferSize/sizeof(float); i<len; ++i){ + for (int i = 0, len = kMaxTextureBufferSize / sizeof(float); i < len; ++i) { buf_f[i] = RangedRandomFloat(0.0f, 1.0f); } glBufferData(GL_TEXTURE_BUFFER, kMaxTextureBufferSize, buf, GL_DYNAMIC_DRAW); @@ -557,26 +551,25 @@ void LightProbeCollection::UpdateTextureBuffer(BulletWorld& bw) { glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, light_probe_buffer_object_id); } LOG_ASSERT(light_probe_texture_buffer_id != -1); - if(tet_mesh.point_id.size() >= 4){ + if (tet_mesh.point_id.size() >= 4) { // Calculate colors of tet corners, flood-filling from positive probes to negative probes // TODO: allocate this using stack allocator for speed std::vector<unsigned char> tet_colors(tet_mesh.tet_points.size() * 6 * 3); { PROFILER_ZONE(g_profiler_ctx, "Flood fill tet mesh corners"); // Start by filling in positive probes - for(int i=0, len=tet_mesh.tet_points.size(); - i<len; - i+=4) - { + for (int i = 0, len = tet_mesh.tet_points.size(); + i < len; + i += 4) { int point_id[4]; - for(int j=0; j<4; ++j){ - point_id[j] = tet_mesh.point_id[tet_mesh.tet_points[i+j]]; + for (int j = 0; j < 4; ++j) { + point_id[j] = tet_mesh.point_id[tet_mesh.tet_points[i + j]]; } - for(int point=0; point<4; ++point){ - int index = (i+point)*18; + for (int point = 0; point < 4; ++point) { + int index = (i + point) * 18; LightProbe& probe = light_probes[point_id[point]]; - if(probe.negative){ - for(int face=0; face<6; ++face){ + if (probe.negative) { + for (int face = 0; face < 6; ++face) { tet_colors[index] = 255; ++index; tet_colors[index] = 0; @@ -585,10 +578,10 @@ void LightProbeCollection::UpdateTextureBuffer(BulletWorld& bw) { ++index; } } else { - for(auto & face : probe.ambient_cube_color){ - for(int channel=0; channel<3; ++channel){ + for (auto& face : probe.ambient_cube_color) { + for (int channel = 0; channel < 3; ++channel) { unsigned val = (unsigned)(face[channel] * 255.0f / 4.0f); - tet_colors[index] = (val > 255)?255:val; + tet_colors[index] = (val > 255) ? 255 : val; ++index; } } @@ -596,44 +589,43 @@ void LightProbeCollection::UpdateTextureBuffer(BulletWorld& bw) { } } // Next fill in negatives that share tet with positives - for(int i=0, len=tet_mesh.tet_points.size(); - i<len; - i+=4) - { + for (int i = 0, len = tet_mesh.tet_points.size(); + i < len; + i += 4) { int num_negative = 0; int num_positive = 0; int point_id[4]; - for(int j=0; j<4; ++j){ - point_id[j] = tet_mesh.point_id[tet_mesh.tet_points[i+j]]; + for (int j = 0; j < 4; ++j) { + point_id[j] = tet_mesh.point_id[tet_mesh.tet_points[i + j]]; LightProbe& probe = light_probes[point_id[j]]; - if(probe.negative){ + if (probe.negative) { ++num_negative; } else { ++num_positive; } } - if(num_negative && num_positive){ + if (num_negative && num_positive) { // Find average color of positive probes in this tet int avg_col[18] = {0}; - for(int point=0; point<4; ++point){ - int index = (i+point)*18; + for (int point = 0; point < 4; ++point) { + int index = (i + point) * 18; LightProbe& probe = light_probes[point_id[point]]; - if(!probe.negative){ - for(int avg_index=0; avg_index<18; ++avg_index){ - avg_col[avg_index] += tet_colors[index+avg_index]; + if (!probe.negative) { + for (int avg_index = 0; avg_index < 18; ++avg_index) { + avg_col[avg_index] += tet_colors[index + avg_index]; } } } - for(int & avg_index : avg_col){ + for (int& avg_index : avg_col) { avg_index /= num_positive; } // Assign average color to negative probes in this tet - for(int point=0; point<4; ++point){ - int index = (i+point)*18; + for (int point = 0; point < 4; ++point) { + int index = (i + point) * 18; LightProbe& probe = light_probes[point_id[point]]; - if(probe.negative){ - for(int avg_index=0; avg_index<18; ++avg_index){ - tet_colors[index+avg_index] = avg_col[avg_index]; + if (probe.negative) { + for (int avg_index = 0; avg_index < 18; ++avg_index) { + tet_colors[index + avg_index] = avg_col[avg_index]; } } } @@ -650,59 +642,57 @@ void LightProbeCollection::UpdateTextureBuffer(BulletWorld& bw) { glBindBuffer(GL_TEXTURE_BUFFER, light_probe_buffer_object_id); int space = 16 * tet_mesh.tet_points.size() * 8; char* buf = new char[space]; - unsigned *buf_u = (unsigned*)buf; + unsigned* buf_u = (unsigned*)buf; int buf_index = 0; - for(int i=0, len=tet_mesh.tet_points.size(); - i<len; - i+=4) - { + for (int i = 0, len = tet_mesh.tet_points.size(); + i < len; + i += 4) { int point_id[4]; - for(int j=0; j<4; ++j){ - point_id[j] = tet_mesh.point_id[tet_mesh.tet_points[i+j]]; + for (int j = 0; j < 4; ++j) { + point_id[j] = tet_mesh.point_id[tet_mesh.tet_points[i + j]]; } vec3 pos[4]; - for(int j=0; j<4; ++j){ + for (int j = 0; j < 4; ++j) { pos[j] = light_probes[point_id[j]].pos; } // Store coordinates of each point as 16-bit unsigned ints unsigned points[12]; - for(int j=0; j<12; ++j){ - int axis = j%3; - int point = j/3; + for (int j = 0; j < 12; ++j) { + int axis = j % 3; + int point = j / 3; points[j] = (unsigned)(pos[point][axis] * kQuantize + 32767.5f); - LOG_ASSERT(points[j] == (points[j] & 0xFFFF)); // Make sure coord fits in 16 bits + LOG_ASSERT(points[j] == (points[j] & 0xFFFF)); // Make sure coord fits in 16 bits } // Pack point values together unsigned point_coord_u[6]; - for(int j=0; j<6; ++j){ - point_coord_u[j] = (points[j*2] << 16) + points[j*2+1]; + for (int j = 0; j < 6; ++j) { + point_coord_u[j] = (points[j * 2] << 16) + points[j * 2 + 1]; } // Pack neighbors unsigned neighbors_u[4]; - for(int j=0; j<4; ++j) { - neighbors_u[j] = (unsigned)(tet_mesh.neighbors[i+j]); + for (int j = 0; j < 4; ++j) { + neighbors_u[j] = (unsigned)(tet_mesh.neighbors[i + j]); } // Store negative info unsigned negative = 0; - for(int j=0; j<4; ++j){ - negative += (light_probes[point_id[j]].negative?0:1) << j; + for (int j = 0; j < 4; ++j) { + negative += (light_probes[point_id[j]].negative ? 0 : 1) << j; } // Pack colors unsigned colors_u[18] = {0}; int offset = 0; - for(int point=0; point<4; ++point){ - int index = (i+point)*18; - for(int face=0; face<6; ++face){ - for(int channel=0; channel<3; ++channel){ + for (int point = 0; point < 4; ++point) { + int index = (i + point) * 18; + for (int face = 0; face < 6; ++face) { + for (int channel = 0; channel < 3; ++channel) { unsigned val = tet_colors[index]; - colors_u[offset/32] |= LeftShift(val, (24-offset%32)); + colors_u[offset / 32] |= LeftShift(val, (24 - offset % 32)); offset += 8; ++index; } - } } buf_u[buf_index++] = point_coord_u[0]; @@ -720,22 +710,22 @@ void LightProbeCollection::UpdateTextureBuffer(BulletWorld& bw) { buf_u[buf_index++] = neighbors_u[2]; buf_u[buf_index++] = neighbors_u[3]; - for(unsigned int i : colors_u){ + for (unsigned int i : colors_u) { buf_u[buf_index++] = i; } buf_u[buf_index++] = 0; buf_u[buf_index++] = 0; } - glBufferData(GL_TEXTURE_BUFFER, kMaxTextureBufferSize, NULL, GL_DYNAMIC_DRAW); // Orphan buffer? + glBufferData(GL_TEXTURE_BUFFER, kMaxTextureBufferSize, NULL, GL_DYNAMIC_DRAW); // Orphan buffer? - void* mapped = glMapBufferRange(GL_TEXTURE_BUFFER, 0, space, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT ); + void* mapped = glMapBufferRange(GL_TEXTURE_BUFFER, 0, space, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); memcpy(mapped, buf, space); glUnmapBuffer(GL_TEXTURE_BUFFER); delete[] buf; } - if(grid_texture_buffer_id == -1 && !grid_lookup.cell_tet.empty()){ + if (grid_texture_buffer_id == -1 && !grid_lookup.cell_tet.empty()) { PROFILER_ZONE(g_profiler_ctx, "Generate grid texture buffer"); int max_size; glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &max_size); @@ -745,8 +735,8 @@ void LightProbeCollection::UpdateTextureBuffer(BulletWorld& bw) { grid_buffer_object_id = buffer_object; glBindBuffer(GL_TEXTURE_BUFFER, grid_buffer_object_id); char* buf = new char[kMaxTextureBufferSize]; - float *buf_f = (float*)buf; - for(int i=0, len=kMaxTextureBufferSize/sizeof(float); i<len; ++i){ + float* buf_f = (float*)buf; + for (int i = 0, len = kMaxTextureBufferSize / sizeof(float); i < len; ++i) { buf_f[i] = RangedRandomFloat(0.0f, 1.0f); } glBufferData(GL_TEXTURE_BUFFER, kMaxTextureBufferSize, buf, GL_DYNAMIC_DRAW); @@ -758,24 +748,23 @@ void LightProbeCollection::UpdateTextureBuffer(BulletWorld& bw) { glBindTexture(GL_TEXTURE_BUFFER, grid_texture_buffer_id); glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32UI, grid_buffer_object_id); } - if(grid_texture_buffer_id != -1 && !grid_lookup.cell_tet.empty()){ + if (grid_texture_buffer_id != -1 && !grid_lookup.cell_tet.empty()) { PROFILER_ZONE(g_profiler_ctx, "Update grid texture buffer"); glBindBuffer(GL_TEXTURE_BUFFER, grid_buffer_object_id); int space = 4 * grid_lookup.cell_tet.size(); char* buf = new char[space]; - unsigned *buf_u = (unsigned*)buf; - //int buf_index = 0; + unsigned* buf_u = (unsigned*)buf; + // int buf_index = 0; - for(int i=0, len=grid_lookup.cell_tet.size(); - i<len; - ++i) - { + for (int i = 0, len = grid_lookup.cell_tet.size(); + i < len; + ++i) { buf_u[i] = grid_lookup.cell_tet[i]; } - glBufferData(GL_TEXTURE_BUFFER, kMaxTextureBufferSize, NULL, GL_DYNAMIC_DRAW); // Orphan buffer? + glBufferData(GL_TEXTURE_BUFFER, kMaxTextureBufferSize, NULL, GL_DYNAMIC_DRAW); // Orphan buffer? - void* mapped = glMapBufferRange(GL_TEXTURE_BUFFER, 0, space, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT ); + void* mapped = glMapBufferRange(GL_TEXTURE_BUFFER, 0, space, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); memcpy(mapped, buf, space); glUnmapBuffer(GL_TEXTURE_BUFFER); @@ -785,26 +774,25 @@ void LightProbeCollection::UpdateTextureBuffer(BulletWorld& bw) { int LightProbeCollection::GetTetrahedron(const vec3& position, vec3 ambient_cube_color[], int best_guess) { std::set<int> visited_nodes; - if(!tet_mesh.points.empty()){ + if (!tet_mesh.points.empty()) { int prev_to_check = -1; int prev_prev_to_check = -1; int to_check = best_guess; - if(to_check == -1){ - if(position[0] > grid_lookup.bounds[0][0] && - position[1] > grid_lookup.bounds[0][1] && - position[2] > grid_lookup.bounds[0][2] && - position[0] < grid_lookup.bounds[1][0] && - position[1] < grid_lookup.bounds[1][1] && - position[2] < grid_lookup.bounds[1][2]) - { + if (to_check == -1) { + if (position[0] > grid_lookup.bounds[0][0] && + position[1] > grid_lookup.bounds[0][1] && + position[2] > grid_lookup.bounds[0][2] && + position[0] < grid_lookup.bounds[1][0] && + position[1] < grid_lookup.bounds[1][1] && + position[2] < grid_lookup.bounds[1][2]) { vec3 grid_coord; - grid_coord[0] = (float) int((position[0] - grid_lookup.bounds[0][0]) / (grid_lookup.bounds[1][0] - grid_lookup.bounds[0][0]) * float(grid_lookup.subdivisions[0])); - grid_coord[1] = (float) int((position[1] - grid_lookup.bounds[0][1]) / (grid_lookup.bounds[1][1] - grid_lookup.bounds[0][1]) * float(grid_lookup.subdivisions[1])); - grid_coord[2] = (float) int((position[2] - grid_lookup.bounds[0][2]) / (grid_lookup.bounds[1][2] - grid_lookup.bounds[0][2]) * float(grid_lookup.subdivisions[2])); - int cell_id = (int) (((grid_coord[0] * grid_lookup.subdivisions[1]) + grid_coord[1])*grid_lookup.subdivisions[2] + grid_coord[2]); + grid_coord[0] = (float)int((position[0] - grid_lookup.bounds[0][0]) / (grid_lookup.bounds[1][0] - grid_lookup.bounds[0][0]) * float(grid_lookup.subdivisions[0])); + grid_coord[1] = (float)int((position[1] - grid_lookup.bounds[0][1]) / (grid_lookup.bounds[1][1] - grid_lookup.bounds[0][1]) * float(grid_lookup.subdivisions[1])); + grid_coord[2] = (float)int((position[2] - grid_lookup.bounds[0][2]) / (grid_lookup.bounds[1][2] - grid_lookup.bounds[0][2]) * float(grid_lookup.subdivisions[2])); + int cell_id = (int)(((grid_coord[0] * grid_lookup.subdivisions[1]) + grid_coord[1]) * grid_lookup.subdivisions[2] + grid_coord[2]); to_check = grid_lookup.cell_tet[cell_id]; - if(to_check == -1){ + if (to_check == -1) { to_check = 0; } } else { @@ -813,65 +801,64 @@ int LightProbeCollection::GetTetrahedron(const vec3& position, vec3 ambient_cube } bool success = false; - while(!success){ - vec3 points[4]; - for(int j=0, index = to_check*4; j<4; ++j){ - points[j] = tet_mesh.points[tet_mesh.tet_points[index+j]]; + while (!success) { + vec3 points[4]; + for (int j = 0, index = to_check * 4; j < 4; ++j) { + points[j] = tet_mesh.points[tet_mesh.tet_points[index + j]]; } vec4 bary_coords = GetBarycentricCoordinate(points[0], points[1], points[2], points[3], position); float lowest_val = FLT_MAX; int lowest_id = -1; - for(int i=0; i<4; ++i){ - if(bary_coords[i] < lowest_val){ + for (int i = 0; i < 4; ++i) { + if (bary_coords[i] < lowest_val) { lowest_val = bary_coords[i]; lowest_id = i; } } - if(lowest_val >= 0.0f){ + if (lowest_val >= 0.0f) { success = true; } else { visited_nodes.insert(to_check); - to_check = tet_mesh.neighbors[to_check*4+lowest_id]; - - //We've already been here before. - if( visited_nodes.find(to_check) != visited_nodes.end() ) - { + to_check = tet_mesh.neighbors[to_check * 4 + lowest_id]; + + // We've already been here before. + if (visited_nodes.find(to_check) != visited_nodes.end()) { return to_check; - //LOGE << "Returned to node we have already visited, exit execution" << std::endl; - //return -1; + // LOGE << "Returned to node we have already visited, exit execution" << std::endl; + // return -1; } } - if(to_check == -1){ + if (to_check == -1) { return -1; } - if(success || prev_to_check == to_check || prev_prev_to_check == to_check){ + if (success || prev_to_check == to_check || prev_prev_to_check == to_check) { vec3 ambient_cube[24]; vec4 modified_bary_coords = bary_coords; float total_modified_bary_coords = FLT_MIN; - for(int j=0, index=0; j<4; ++j, index+=6){ - LightProbe* probe = &light_probes[tet_mesh.point_id[tet_mesh.tet_points[to_check*4+j]]]; - if(probe) { - for(int k=0; k<6; ++k){ - ambient_cube[index+k] = probe->ambient_cube_color[k]; + for (int j = 0, index = 0; j < 4; ++j, index += 6) { + LightProbe* probe = &light_probes[tet_mesh.point_id[tet_mesh.tet_points[to_check * 4 + j]]]; + if (probe) { + for (int k = 0; k < 6; ++k) { + ambient_cube[index + k] = probe->ambient_cube_color[k]; } - if(probe->negative){ + if (probe->negative) { modified_bary_coords[j] = min(modified_bary_coords[j], FLT_MIN); } total_modified_bary_coords += modified_bary_coords[j]; } } - for(int j=0; j<4; ++j){ + for (int j = 0; j < 4; ++j) { modified_bary_coords[j] /= total_modified_bary_coords; } - for(int j=0; j<6; ++j){ - ambient_cube_color[j] = ambient_cube[0+j] * modified_bary_coords[0] + - ambient_cube[6+j] * modified_bary_coords[1] + - ambient_cube[12+j] * modified_bary_coords[2] + - ambient_cube[18+j] * modified_bary_coords[3]; + for (int j = 0; j < 6; ++j) { + ambient_cube_color[j] = ambient_cube[0 + j] * modified_bary_coords[0] + + ambient_cube[6 + j] * modified_bary_coords[1] + + ambient_cube[12 + j] * modified_bary_coords[2] + + ambient_cube[18 + j] * modified_bary_coords[3]; } return to_check; } @@ -888,18 +875,18 @@ void LightProbeCollection::Draw(BulletWorld& bw) { Shaders* shaders = Shaders::Instance(); Graphics* graphics = Graphics::Instance(); - if(show_probes){ - for(int i=0; i<2; ++i){ + if (show_probes) { + for (int i = 0; i < 2; ++i) { GLState gl_state; gl_state.blend = false; gl_state.cull_face = true; gl_state.depth_test = true; gl_state.depth_write = true; - if(i==0 && !show_probes_through_walls){ + if (i == 0 && !show_probes_through_walls) { continue; } - if(i==0 && show_probes_through_walls){ + if (i == 0 && show_probes_through_walls) { gl_state.depth_test = false; gl_state.depth_write = false; } @@ -907,7 +894,7 @@ void LightProbeCollection::Draw(BulletWorld& bw) { graphics->setGLState(gl_state); int shader_id = shaders->returnProgram("lightprobe"); - if(i==0 && show_probes_through_walls){ + if (i == 0 && show_probes_through_walls) { shader_id = shaders->returnProgram("lightprobe #STIPPLE"); } shaders->setProgram(shader_id); @@ -915,7 +902,7 @@ void LightProbeCollection::Draw(BulletWorld& bw) { int programHandle = shaders->programs[shader_id].gl_program; GLuint blockIndex = glGetUniformBlockIndex(programHandle, "LightProbeInfo"); - const GLchar *names[] = { + const GLchar* names[] = { "center[0]", "view_mat", "proj_mat", @@ -926,23 +913,22 @@ void LightProbeCollection::Draw(BulletWorld& bw) { "LightProbeInfo.view_mat", "LightProbeInfo.proj_mat", "LightProbeInfo.cam_pos", - "LightProbeInfo.ambient_cube_color[0]" - }; + "LightProbeInfo.ambient_cube_color[0]"}; GLuint indices[5] = {0}; glGetUniformIndices(programHandle, 5, names, indices); CHECK_GL_ERROR(); // Check long name if short name is not found - for(unsigned int index : indices){ - if(index == GL_INVALID_INDEX){ + for (unsigned int index : indices) { + if (index == GL_INVALID_INDEX) { glGetUniformIndices(programHandle, 5, &names[5], indices); break; } } - for(unsigned int index : indices){ - if(index == GL_INVALID_INDEX){ + for (unsigned int index : indices) { + if (index == GL_INVALID_INDEX) { return; } } @@ -952,7 +938,7 @@ void LightProbeCollection::Draw(BulletWorld& bw) { GLint blockSize; glGetActiveUniformBlockiv(programHandle, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize); - GLubyte * blockBuffer= (GLubyte *)OG_MALLOC(blockSize); + GLubyte* blockBuffer = (GLubyte*)OG_MALLOC(blockSize); vec4* center = (vec4*)((uintptr_t)blockBuffer + offset[0]); mat4* view_mat = (mat4*)((uintptr_t)blockBuffer + offset[1]); @@ -960,15 +946,15 @@ void LightProbeCollection::Draw(BulletWorld& bw) { vec3* cam_pos = (vec3*)((uintptr_t)blockBuffer + offset[3]); vec4* ambient_cube_color_vec = (vec4*)((uintptr_t)blockBuffer + offset[4]); static int ubo_id = -1; - if(ubo_id == -1){ + if (ubo_id == -1) { GLuint uboHandle; - glGenBuffers( 1, &uboHandle ); + glGenBuffers(1, &uboHandle); ubo_id = uboHandle; - glBindBuffer( GL_UNIFORM_BUFFER, ubo_id ); - glBufferData( GL_UNIFORM_BUFFER, blockSize, blockBuffer, GL_DYNAMIC_DRAW ); + glBindBuffer(GL_UNIFORM_BUFFER, ubo_id); + glBufferData(GL_UNIFORM_BUFFER, blockSize, blockBuffer, GL_DYNAMIC_DRAW); } - glBindBuffer( GL_UNIFORM_BUFFER, ubo_id ); - glBindBufferBase( GL_UNIFORM_BUFFER, blockIndex, ubo_id ); + glBindBuffer(GL_UNIFORM_BUFFER, ubo_id); + glBindBufferBase(GL_UNIFORM_BUFFER, blockIndex, ubo_id); Camera* camera = ActiveCameras::Get(); *cam_pos = camera->GetPos(); @@ -976,33 +962,33 @@ void LightProbeCollection::Draw(BulletWorld& bw) { *proj_mat = camera->GetProjMatrix(); int vert_attrib_id = shaders->returnShaderAttrib("vertex", shader_id); - Model* probe_model = &Models::Instance()->GetModel(probe_model_id); - if(!probe_model->vbo_loaded){ - probe_model->createVBO(); - } + Model* probe_model = &Models::Instance()->GetModel(probe_model_id); + if (!probe_model->vbo_loaded) { + probe_model->createVBO(); + } probe_model->VBO_vertices.Bind(); probe_model->VBO_faces.Bind(); graphics->EnableVertexAttribArray(vert_attrib_id); glVertexAttribPointer(vert_attrib_id, 3, GL_FLOAT, false, 3 * sizeof(GL_FLOAT), 0); - const int kBatchSize = 128; // Max that fits into 16k UBO - for(int i=0, len=light_probes.size(); i<len; i+=kBatchSize){ + const int kBatchSize = 128; // Max that fits into 16k UBO + for (int i = 0, len = light_probes.size(); i < len; i += kBatchSize) { int num_to_render = std::min(kBatchSize, (int)light_probes.size() - i); - for(int j=0; j<num_to_render; ++j){ - center[j] = vec4(light_probes[i+j].pos, 0.0f); - if(light_probes[i+j].negative){ - for(int k=0; k<6; ++k){ - ambient_cube_color_vec[j*6+k] = vec3(0.0f, 0.0f, 1.0f); + for (int j = 0; j < num_to_render; ++j) { + center[j] = vec4(light_probes[i + j].pos, 0.0f); + if (light_probes[i + j].negative) { + for (int k = 0; k < 6; ++k) { + ambient_cube_color_vec[j * 6 + k] = vec3(0.0f, 0.0f, 1.0f); } } else { - for(int k=0; k<6; ++k){ - ambient_cube_color_vec[j*6+k] = light_probes[i+j].ambient_cube_color[k]; + for (int k = 0; k < 6; ++k) { + ambient_cube_color_vec[j * 6 + k] = light_probes[i + j].ambient_cube_color[k]; } } } - glBindBuffer( GL_UNIFORM_BUFFER, ubo_id ); - glBufferData( GL_UNIFORM_BUFFER, blockSize, NULL, GL_DYNAMIC_DRAW ); // orphan buffer + glBindBuffer(GL_UNIFORM_BUFFER, ubo_id); + glBufferData(GL_UNIFORM_BUFFER, blockSize, NULL, GL_DYNAMIC_DRAW); // orphan buffer - void* mapped = glMapBufferRange(GL_UNIFORM_BUFFER, 0, blockSize, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT ); + void* mapped = glMapBufferRange(GL_UNIFORM_BUFFER, 0, blockSize, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_UNSYNCHRONIZED_BIT); memcpy(mapped, blockBuffer, blockSize); glUnmapBuffer(GL_UNIFORM_BUFFER); @@ -1014,7 +1000,7 @@ void LightProbeCollection::Draw(BulletWorld& bw) { } } - if(tet_mesh_needs_update){ + if (tet_mesh_needs_update) { UpdateTetMesh(bw); } } |