Update Sky.h & LightEditor.h - Titi

Titi major work
EIntemporel minor implementation of LightViewWidget
This commit is contained in:
EIntemporel
2022-11-14 23:19:04 +01:00
parent 5f6ec82849
commit 1ded0d264e
4 changed files with 1414 additions and 189 deletions

View File

@@ -29,176 +29,326 @@ SkyFloatParam::SkyFloatParam(int t, float val)
{ {
} }
SkyParam::SkyParam(int paramId, Noggit::NoggitRenderContext context)
: _context(context)
{
Id = paramId;
if (paramId == 0)
return; // don't initialise entry
for (int i = 0; i < 36; ++i)
{
mmin[i] = -2;
}
for (int i = 0; i < 6; ++i)
{
mmin_float[i] = -2;
}
// int light_param_0 = data->getInt(LightDB::DataIDs);
int light_int_start = paramId * NUM_SkyColorNames - 17;
for (int i = 0; i < NUM_SkyColorNames; ++i)
{
try
{
DBCFile::Record rec = gLightIntBandDB.getByID(light_int_start + i);
int entries = rec.getInt(LightIntBandDB::Entries);
if (entries == 0)
{
mmin[i] = -1;
}
else
{
mmin[i] = rec.getInt(LightIntBandDB::Times);
for (int l = 0; l < entries; l++)
{
SkyColor sc(rec.getInt(LightIntBandDB::Times + l), rec.getInt(LightIntBandDB::Values + l));
colorRows[i].push_back(sc);
}
}
}
catch (...)
{
// LogError << "When trying to intialize sky " << data->getInt(LightDB::ID) << ", there was an error with getting an entry in a DBC (" << i << "). Sorry." << std::endl;
LogError << "When trying to intialize sky, there was an error with getting an entry in LightIntBand DBC (" << i << "). Sorry." << std::endl;
DBCFile::Record rec = gLightIntBandDB.getByID(i);
int entries = rec.getInt(LightIntBandDB::Entries);
if (entries == 0)
{
mmin[i] = -1;
}
else
{
mmin[i] = rec.getInt(LightIntBandDB::Times);
for (int l = 0; l < entries; l++)
{
SkyColor sc(rec.getInt(LightIntBandDB::Times + l), rec.getInt(LightIntBandDB::Values + l));
colorRows[i].push_back(sc);
}
}
}
}
int light_float_start = paramId * NUM_SkyFloatParamsNames - 5;
for (int i = 0; i < NUM_SkyFloatParamsNames; ++i)
{
try
{
DBCFile::Record rec = gLightFloatBandDB.getByID(light_float_start + i);
int entries = rec.getInt(LightFloatBandDB::Entries);
if (entries == 0)
{
mmin_float[i] = -1;
}
else
{
mmin_float[i] = rec.getInt(LightFloatBandDB::Times);
for (int l = 0; l < entries; l++)
{
SkyFloatParam sc(rec.getInt(LightFloatBandDB::Times + l), rec.getFloat(LightFloatBandDB::Values + l));
floatParams[i].push_back(sc);
}
}
}
catch (...)
{
LogError << "When trying to intialize sky, there was an error with getting an entry in LightFloatBand DBC (" << i << "). Sorry." << std::endl;
DBCFile::Record rec = gLightFloatBandDB.getByID(i);
int entries = rec.getInt(LightFloatBandDB::Entries);
if (entries == 0)
{
mmin_float[i] = -1;
}
else
{
mmin_float[i] = rec.getInt(LightFloatBandDB::Times);
for (int l = 0; l < entries; l++)
{
SkyFloatParam sc(rec.getInt(LightFloatBandDB::Times + l), rec.getFloat(LightFloatBandDB::Values + l));
floatParams[i].push_back(sc);
}
}
}
}
try
{
DBCFile::Record light_param = gLightParamsDB.getByID(paramId);
int skybox_id = light_param.getInt(LightParamsDB::skybox);
_highlight_sky = light_param.getInt(LightParamsDB::highlightSky);
_river_shallow_alpha = light_param.getFloat(LightParamsDB::water_shallow_alpha);
_river_deep_alpha = light_param.getFloat(LightParamsDB::water_deep_alpha);
_ocean_shallow_alpha = light_param.getFloat(LightParamsDB::ocean_shallow_alpha);
_ocean_deep_alpha = light_param.getFloat(LightParamsDB::ocean_deep_alpha);
_glow = light_param.getFloat(LightParamsDB::glow);
if (skybox_id)
{
skybox.emplace(gLightSkyboxDB.getByID(skybox_id).getString(LightSkyboxDB::filename), _context);
}
}
catch (...)
{
LogError << "When trying to get the skybox for the entry " << paramId << " in LightParams.dbc. Sad." << std::endl;
}
}
Sky::Sky(DBCFile::Iterator data, Noggit::NoggitRenderContext context) Sky::Sky(DBCFile::Iterator data, Noggit::NoggitRenderContext context)
: _context(context) : _context(context)
, _selected(false) , _selected(false)
{ {
Id = data->getInt(LightDB::ID);
pos = glm::vec3(data->getFloat(LightDB::PositionX) / skymul, data->getFloat(LightDB::PositionY) / skymul, data->getFloat(LightDB::PositionZ) / skymul); pos = glm::vec3(data->getFloat(LightDB::PositionX) / skymul, data->getFloat(LightDB::PositionY) / skymul, data->getFloat(LightDB::PositionZ) / skymul);
r1 = data->getFloat(LightDB::RadiusInner) / skymul; r1 = data->getFloat(LightDB::RadiusInner) / skymul;
r2 = data->getFloat(LightDB::RadiusOuter) / skymul; r2 = data->getFloat(LightDB::RadiusOuter) / skymul;
for (int i = 0; i < 36; ++i) // for (int i = 0; i < 36; ++i)
{ // {
mmin[i] = -2; // mmin[i] = -2;
} // }
for (int i = 0; i < 6; ++i) // for (int i = 0; i < 6; ++i)
{ // {
mmin_float[i] = -2; // mmin_float[i] = -2;
} // }
global = (pos.x == 0.0f && pos.y == 0.0f && pos.z == 0.0f); global = (pos.x == 0.0f && pos.y == 0.0f && pos.z == 0.0f);
int light_param_0 = data->getInt(LightDB::DataIDs); // int light_param_0 = data->getInt(LightDB::DataIDs);
int light_int_start = light_param_0 * NUM_SkyColorNames - 17; // int light_int_start = light_param_0 * NUM_SkyColorNames - 17;
for (int i = 0; i < NUM_SkyColorNames; ++i) for (int i = 0; i < NUM_SkyParamsNames; ++i)
{ {
try int sky_param_id = data->getInt(LightDB::DataIDs + i);
{ if (sky_param_id == 0)
DBCFile::Record rec = gLightIntBandDB.getByID(light_int_start + i); {
int entries = rec.getInt(LightIntBandDB::Entries); skyParams[i] = nullptr;
continue;
}
if (entries == 0) SkyParam* sky_param = new SkyParam(sky_param_id, _context);
{ skyParams[i] = sky_param;
mmin[i] = -1;
}
else
{
mmin[i] = rec.getInt(LightIntBandDB::Times);
for (int l = 0; l < entries; l++)
{
SkyColor sc(rec.getInt(LightIntBandDB::Times + l), rec.getInt(LightIntBandDB::Values + l));
colorRows[i].push_back(sc);
}
}
}
catch (...)
{
LogError << "When trying to intialize sky " << data->getInt(LightDB::ID) << ", there was an error with getting an entry in a DBC (" << i << "). Sorry." << std::endl;
DBCFile::Record rec = gLightIntBandDB.getByID(i);
int entries = rec.getInt(LightIntBandDB::Entries);
if (entries == 0)
{
mmin[i] = -1;
}
else
{
mmin[i] = rec.getInt(LightIntBandDB::Times);
for (int l = 0; l < entries; l++)
{
SkyColor sc(rec.getInt(LightIntBandDB::Times + l), rec.getInt(LightIntBandDB::Values + l));
colorRows[i].push_back(sc);
}
}
}
} }
int light_float_start = light_param_0 * NUM_SkyFloatParamsNames - 5; // for (int i = 0; i < NUM_SkyColorNames; ++i)
// {
for (int i = 0; i < NUM_SkyFloatParamsNames; ++i) // try
{ // {
try // DBCFile::Record rec = gLightIntBandDB.getByID(light_int_start + i);
{ // int entries = rec.getInt(LightIntBandDB::Entries);
DBCFile::Record rec = gLightFloatBandDB.getByID(light_float_start + i); //
int entries = rec.getInt(LightFloatBandDB::Entries); // if (entries == 0)
// {
if (entries == 0) // mmin[i] = -1;
{ // }
mmin_float[i] = -1; // else
} // {
else // mmin[i] = rec.getInt(LightIntBandDB::Times);
{ // for (int l = 0; l < entries; l++)
mmin_float[i] = rec.getInt(LightFloatBandDB::Times); // {
for (int l = 0; l < entries; l++) // SkyColor sc(rec.getInt(LightIntBandDB::Times + l), rec.getInt(LightIntBandDB::Values + l));
{ // colorRows[i].push_back(sc);
SkyFloatParam sc(rec.getInt(LightFloatBandDB::Times + l), rec.getFloat(LightFloatBandDB::Values + l)); // }
floatParams[i].push_back(sc); // }
} // }
} // catch (...)
} // {
catch (...) // LogError << "When trying to intialize sky " << data->getInt(LightDB::ID) << ", there was an error with getting an entry in a DBC (" << i << "). Sorry." << std::endl;
{ // DBCFile::Record rec = gLightIntBandDB.getByID(i);
LogError << "When trying to intialize sky " << data->getInt(LightDB::ID) << ", there was an error with getting an entry in a DBC (" << i << "). Sorry." << std::endl; // int entries = rec.getInt(LightIntBandDB::Entries);
DBCFile::Record rec = gLightFloatBandDB.getByID(i); //
int entries = rec.getInt(LightFloatBandDB::Entries); // if (entries == 0)
// {
if (entries == 0) // mmin[i] = -1;
{ // }
mmin_float[i] = -1; // else
} // {
else // mmin[i] = rec.getInt(LightIntBandDB::Times);
{ // for (int l = 0; l < entries; l++)
mmin_float[i] = rec.getInt(LightFloatBandDB::Times); // {
for (int l = 0; l < entries; l++) // SkyColor sc(rec.getInt(LightIntBandDB::Times + l), rec.getInt(LightIntBandDB::Values + l));
{ // colorRows[i].push_back(sc);
SkyFloatParam sc(rec.getInt(LightFloatBandDB::Times + l), rec.getFloat(LightFloatBandDB::Values + l)); // }
floatParams[i].push_back(sc); // }
} // }
} // }
} //
} // int light_float_start = light_param_0 * NUM_SkyFloatParamsNames - 5;
//
try // for (int i = 0; i < NUM_SkyFloatParamsNames; ++i)
{ // {
DBCFile::Record light_param = gLightParamsDB.getByID(light_param_0); // try
int skybox_id = light_param.getInt(LightParamsDB::skybox); // {
// DBCFile::Record rec = gLightFloatBandDB.getByID(light_float_start + i);
_river_shallow_alpha = light_param.getFloat(LightParamsDB::water_shallow_alpha); // int entries = rec.getInt(LightFloatBandDB::Entries);
_river_deep_alpha = light_param.getFloat(LightParamsDB::water_deep_alpha); //
_ocean_shallow_alpha = light_param.getFloat(LightParamsDB::ocean_shallow_alpha); // if (entries == 0)
_ocean_deep_alpha = light_param.getFloat(LightParamsDB::ocean_deep_alpha); // {
_glow = light_param.getFloat(LightParamsDB::glow); // mmin_float[i] = -1;
// }
if (skybox_id) // else
{ // {
skybox.emplace(gLightSkyboxDB.getByID(skybox_id).getString(LightSkyboxDB::filename), _context); // mmin_float[i] = rec.getInt(LightFloatBandDB::Times);
} // for (int l = 0; l < entries; l++)
} // {
catch (...) // SkyFloatParam sc(rec.getInt(LightFloatBandDB::Times + l), rec.getFloat(LightFloatBandDB::Values + l));
{ // floatParams[i].push_back(sc);
LogError << "When trying to get the skybox for the entry " << light_param_0 << " in LightParams.dbc. Sad." << std::endl; // }
} // }
// }
// catch (...)
// {
// LogError << "When trying to intialize sky " << data->getInt(LightDB::ID) << ", there was an error with getting an entry in a DBC (" << i << "). Sorry." << std::endl;
// DBCFile::Record rec = gLightFloatBandDB.getByID(i);
// int entries = rec.getInt(LightFloatBandDB::Entries);
//
// if (entries == 0)
// {
// mmin_float[i] = -1;
// }
// else
// {
// mmin_float[i] = rec.getInt(LightFloatBandDB::Times);
// for (int l = 0; l < entries; l++)
// {
// SkyFloatParam sc(rec.getInt(LightFloatBandDB::Times + l), rec.getFloat(LightFloatBandDB::Values + l));
// floatParams[i].push_back(sc);
// }
// }
// }
// }
//
// try
// {
// DBCFile::Record light_param = gLightParamsDB.getByID(light_param_0);
// int skybox_id = light_param.getInt(LightParamsDB::skybox);
//
// _highlight_sky = light_param.getInt(LightParamsDB::highlightSky);
// _river_shallow_alpha = light_param.getFloat(LightParamsDB::water_shallow_alpha);
// _river_deep_alpha = light_param.getFloat(LightParamsDB::water_deep_alpha);
// _ocean_shallow_alpha = light_param.getFloat(LightParamsDB::ocean_shallow_alpha);
// _ocean_deep_alpha = light_param.getFloat(LightParamsDB::ocean_deep_alpha);
// _glow = light_param.getFloat(LightParamsDB::glow);
//
// if (skybox_id)
// {
// skybox.emplace(gLightSkyboxDB.getByID(skybox_id).getString(LightSkyboxDB::filename), _context);
// }
// }
// catch (...)
// {
// LogError << "When trying to get the skybox for the entry " << light_param_0 << " in LightParams.dbc. Sad." << std::endl;
// }
} }
float Sky::floatParamFor(int r, int t) const float Sky::floatParamFor(int r, int t) const
{ {
if (mmin_float[r]<0) auto sky_param = skyParams[curr_sky_param];
if (sky_param->mmin_float[r]<0)
{ {
return 0.0; return 0.0;
} }
float c1, c2; float c1, c2;
int t1, t2; int t1, t2;
size_t last = floatParams[r].size() - 1; size_t last = sky_param->floatParams[r].size() - 1;
if (t<mmin_float[r]) if (t< sky_param->mmin_float[r])
{ {
// reverse interpolate // reverse interpolate
c1 = floatParams[r][last].value; c1 = sky_param->floatParams[r][last].value;
c2 = floatParams[r][0].value; c2 = sky_param->floatParams[r][0].value;
t1 = floatParams[r][last].time; t1 = sky_param->floatParams[r][last].time;
t2 = floatParams[r][0].time + 2880; t2 = sky_param->floatParams[r][0].time + 2880;
t += 2880; t += 2880;
} }
else else
{ {
for (size_t i = last; true; i--) for (size_t i = last; true; i--)
{ //! \todo iterator this. { //! \todo iterator this.
if (floatParams[r][i].time <= t) if (sky_param->floatParams[r][i].time <= t)
{ {
c1 = floatParams[r][i].value; c1 = sky_param->floatParams[r][i].value;
t1 = floatParams[r][i].time; t1 = sky_param->floatParams[r][i].time;
if (i == last) if (i == last)
{ {
c2 = floatParams[r][0].value; c2 = sky_param->floatParams[r][0].value;
t2 = floatParams[r][0].time + 2880; t2 = sky_param->floatParams[r][0].time + 2880;
} }
else else
{ {
c2 = floatParams[r][i + 1].value; c2 = sky_param->floatParams[r][i + 1].value;
t2 = floatParams[r][i + 1].time; t2 = sky_param->floatParams[r][i + 1].time;
} }
break; break;
} }
@@ -211,45 +361,57 @@ float Sky::floatParamFor(int r, int t) const
glm::vec3 Sky::colorFor(int r, int t) const glm::vec3 Sky::colorFor(int r, int t) const
{ {
if (mmin[r]<0) auto sky_param = skyParams[curr_sky_param];
if (sky_param->mmin[r]<0)
{ {
return glm::vec3(0, 0, 0); return glm::vec3(0, 0, 0);
} }
glm::vec3 c1, c2; glm::vec3 c1, c2;
int t1, t2; int t1, t2;
size_t last = colorRows[r].size() - 1; int last = sky_param->colorRows[r].size() - 1;
if (t<mmin[r]) if (last == 0)
{ {
// reverse interpolate c1 = sky_param->colorRows[r][last].color;
c1 = colorRows[r][last].color; c2 = sky_param->colorRows[r][0].color;
c2 = colorRows[r][0].color; t1 = sky_param->colorRows[r][last].time;
t1 = colorRows[r][last].time; t2 = sky_param->colorRows[r][0].time + 2880;
t2 = colorRows[r][0].time + 2880; t += 2880;
t += 2880;
} }
else else
{ {
for (size_t i = last; true; i--) if (t < sky_param->mmin[r])
{ //! \todo iterator this.
if (colorRows[r][i].time <= t)
{ {
c1 = colorRows[r][i].color; // reverse interpolate
t1 = colorRows[r][i].time; c1 = sky_param->colorRows[r][last].color;
c2 = sky_param->colorRows[r][0].color;
if (i == last) t1 = sky_param->colorRows[r][last].time;
{ t2 = sky_param->colorRows[r][0].time + 2880;
c2 = colorRows[r][0].color; t += 2880;
t2 = colorRows[r][0].time + 2880; }
} else
else {
{ for (int i = last; true; i--)
c2 = colorRows[r][i + 1].color; { //! \todo iterator this.
t2 = colorRows[r][i + 1].time; if (sky_param->colorRows[r][i].time <= t)
} {
break; c1 = sky_param->colorRows[r][i].color;
t1 = sky_param->colorRows[r][i].time;
if (i == last)
{
c2 = sky_param->colorRows[r][0].color;
t2 = sky_param->colorRows[r][0].time + 2880;
}
else
{
c2 = sky_param->colorRows[r][i + 1].color;
t2 = sky_param->colorRows[r][i + 1].time;
}
break;
}
}
} }
}
} }
float tt = static_cast<float>(t - t1) / static_cast<float>(t2 - t1); float tt = static_cast<float>(t - t1) / static_cast<float>(t2 - t1);
@@ -350,6 +512,51 @@ Sky* Skies::findSkyWeights(glm::vec3 pos)
return default_sky; return default_sky;
} }
Sky* Skies::findClosestSkyByWeight()
{
// gets the highest weight sky
if (skies.size() == 0)
return nullptr;
Sky* closest_sky = &skies[0];
for (auto& sky : skies)
{
if (sky.weight > closest_sky->weight)
closest_sky = &sky;
}
return closest_sky;
}
Sky* Skies::findClosestSkyByDistance(glm::vec3 pos)
{
if (skies.size() == 0)
return nullptr;
Sky* closest = &skies[0];
float distance = 1000000.f;
for (auto& sky : skies)
{
float distanceToCenter = glm::distance(pos, sky.pos);
if (distanceToCenter <= sky.r2 && distanceToCenter < distance)
{
distance = distanceToCenter;
closest = &sky;
}
}
return closest;
}
void Skies::setCurrentParam(int param_id)
{
for (auto& sky : skies)
{
Sky* skyptr = &sky;
skyptr->curr_sky_param = param_id;
}
}
void Skies::update_sky_colors(glm::vec3 pos, int time) void Skies::update_sky_colors(glm::vec3 pos, int time)
{ {
if (numSkies == 0 || (_last_time == time && _last_pos == pos)) if (numSkies == 0 || (_last_time == time && _last_pos == pos))
@@ -369,11 +576,12 @@ void Skies::update_sky_colors(glm::vec3 pos, int time)
_fog_distance = default_sky->floatParamFor(0, time); _fog_distance = default_sky->floatParamFor(0, time);
_fog_multiplier = default_sky->floatParamFor(1, time); _fog_multiplier = default_sky->floatParamFor(1, time);
_river_shallow_alpha = default_sky->river_shallow_alpha(); auto default_sky_param = default_sky->skyParams[default_sky->curr_sky_param];
_river_deep_alpha = default_sky->river_deep_alpha(); _river_shallow_alpha = default_sky_param->river_shallow_alpha();
_ocean_shallow_alpha = default_sky->ocean_shallow_alpha(); _river_deep_alpha = default_sky_param->river_deep_alpha();
_ocean_deep_alpha = default_sky->ocean_deep_alpha(); _ocean_shallow_alpha = default_sky_param->ocean_shallow_alpha();
_glow = default_sky->glow(); _ocean_deep_alpha = default_sky_param->ocean_deep_alpha();
_glow = default_sky_param->glow();
} }
else else
@@ -417,13 +625,14 @@ void Skies::update_sky_colors(glm::vec3 pos, int time)
_fog_distance = (_fog_distance * (1.0f - sky.weight)) + (sky.floatParamFor(0, time) * sky.weight); _fog_distance = (_fog_distance * (1.0f - sky.weight)) + (sky.floatParamFor(0, time) * sky.weight);
_fog_multiplier = (_fog_multiplier * (1.0f - sky.weight)) + (sky.floatParamFor(1, time) * sky.weight); _fog_multiplier = (_fog_multiplier * (1.0f - sky.weight)) + (sky.floatParamFor(1, time) * sky.weight);
// sky.skyParams[sky.curr_sky_param]->river_shallow_alpha(); // new
// sky.skyParams[sky.curr_sky_param].river_shallow_alpha(); // old
_river_shallow_alpha = (_river_shallow_alpha * (1.0f - sky.weight)) + (sky.skyParams[sky.curr_sky_param]->river_shallow_alpha() * sky.weight);
_river_deep_alpha = (_river_deep_alpha * (1.0f - sky.weight)) + (sky.skyParams[sky.curr_sky_param]->river_deep_alpha() * sky.weight);
_ocean_shallow_alpha = (_ocean_shallow_alpha * (1.0f - sky.weight)) + (sky.skyParams[sky.curr_sky_param]->ocean_shallow_alpha() * sky.weight);
_ocean_deep_alpha = (_ocean_deep_alpha * (1.0f - sky.weight)) + (sky.skyParams[sky.curr_sky_param]->ocean_deep_alpha() * sky.weight);
_river_shallow_alpha = (_river_shallow_alpha * (1.0f - sky.weight)) + (sky.river_shallow_alpha() * sky.weight); _glow = (_glow * (1.0f - sky.weight)) + (sky.skyParams[sky.curr_sky_param]->glow() * sky.weight);
_river_deep_alpha = (_river_deep_alpha * (1.0f - sky.weight)) + (sky.river_deep_alpha() * sky.weight);
_ocean_shallow_alpha = (_ocean_shallow_alpha * (1.0f - sky.weight)) + (sky.ocean_shallow_alpha() * sky.weight);
_ocean_deep_alpha = (_ocean_deep_alpha * (1.0f - sky.weight)) + (sky.ocean_deep_alpha() * sky.weight);
_glow = (_glow * (1.0f - sky.weight)) + (sky.glow() * sky.weight);
} }
} }
@@ -558,12 +767,15 @@ void Skies::drawLightingSpheres (glm::mat4x4 const& model_view
{ {
for (Sky& sky : skies) for (Sky& sky : skies)
{ {
if (glm::distance(sky.pos, camera_pos) - sky.r2 <= cull_distance) // TODO: frustum cull here if (glm::distance(sky.pos, camera_pos) <= cull_distance) // TODO: frustum cull here
{ {
glm::vec3 diffuse = color_set[LIGHT_GLOBAL_DIFFUSE]; glm::vec4 diffuse = { color_set[LIGHT_GLOBAL_DIFFUSE], 1.f };
glm::vec3 ambient = color_set[LIGHT_GLOBAL_AMBIENT]; glm::vec4 ambient = { color_set[LIGHT_GLOBAL_AMBIENT], 1.f };
_sphere_render.draw(model_view * projection, sky.pos, {ambient.x, ambient.y, ambient.z, 0.3}, sky.r1);
_sphere_render.draw(model_view * projection, sky.pos, {diffuse.x, diffuse.y, diffuse.z, 0.3}, sky.r2); Log << sky.Id << " <=> (x,y,z) : " << sky.pos.x << "," << sky.pos.y << "," << sky.pos.z << " -- r1 : " << sky.r1 << " -- r2 : " << sky.r2 << std::endl;
_sphere_render.draw(model_view * projection, sky.pos, ambient, sky.r1, 32, 18, 1.f);
_sphere_render.draw(model_view * projection, sky.pos, diffuse, sky.r2, 32, 18, 1.f);
} }
} }
} }
@@ -586,7 +798,6 @@ void Skies::drawLightingSphereHandles (glm::mat4x4 const& model_view
{ {
glm::vec3 diffuse = color_set[LIGHT_GLOBAL_DIFFUSE]; glm::vec3 diffuse = color_set[LIGHT_GLOBAL_DIFFUSE];
glm::vec3 ambient = color_set[LIGHT_GLOBAL_AMBIENT]; glm::vec3 ambient = color_set[LIGHT_GLOBAL_AMBIENT];
_sphere_render.draw(model_view * projection, sky.pos, {ambient.x, ambient.y, ambient.z, 0.3}, sky.r1); _sphere_render.draw(model_view * projection, sky.pos, {ambient.x, ambient.y, ambient.z, 0.3}, sky.r1);
_sphere_render.draw(model_view * projection, sky.pos, {diffuse.x, diffuse.y, diffuse.z, 0.3}, sky.r2); _sphere_render.draw(model_view * projection, sky.pos, {diffuse.x, diffuse.y, diffuse.z, 0.3}, sky.r2);
} }
@@ -827,3 +1038,142 @@ OutdoorLightStats OutdoorLighting::getLightStats(int time)
return out; return out;
} }
void Sky::save_to_dbc()
{
// Save Light.dbc record
// find new empty ID : gLightDB.getEmptyRecordID(); .prob do it when creating new light instead.
DBCFile::Record data = is_new_record ? gLightDB.addRecord(Id) : gLightDB.getByID(Id);
// pos = glm::vec3(data->getFloat(LightDB::PositionX) / skymul, data->getFloat(LightDB::PositionY) / skymul, data->getFloat(LightDB::PositionZ) / skymul);
// record.write(1, _curr_sky-> map id
data.write(LightDB::PositionX, pos.x * skymul);
data.write(LightDB::PositionY, pos.y * skymul);
data.write(LightDB::PositionZ, pos.z * skymul);
data.write(LightDB::RadiusInner, r1 * skymul);
data.write(LightDB::RadiusOuter,r2 * skymul);
// data.write(7, Params Id TODO only needed for new entries
// save LightParams.dbc
// TODO : all params, not just clear.
for (int param_id = 0; param_id < NUM_SkyFloatParamsNames; param_id++)
{
// skip if no param
if (skyParams[param_id] == nullptr)
continue;
// TODO : several lights can use the same param, ask user if he wants to save a copy or edit it for all ?
int lightParam_dbc_id = 0;
if (is_new_record) // not for duplicates
lightParam_dbc_id = gLightParamsDB.getEmptyRecordID();
else
lightParam_dbc_id = data.getInt(LightDB::DataIDs + param_id);
if (lightParam_dbc_id == 0)
continue;
int light_int_start = lightParam_dbc_id * NUM_SkyColorNames - 17;
for (int i = 0; i < NUM_SkyColorNames; ++i)
{
try
{
DBCFile::Record rec = is_new_record ? gLightIntBandDB.addRecord(light_int_start + i) : gLightIntBandDB.getByID(light_int_start + i);
// int entries = rec.getInt(LightIntBandDB::Entries);
int entries = skyParams[param_id]->colorRows[i].size();
rec.write(LightIntBandDB::Entries, entries); // nb of entries
for (int l = 0; l < 16; l++)
{
if (l >= entries)
{
rec.write(LightIntBandDB::Times + l, 0);
rec.write(LightIntBandDB::Values + l, 0);
}
else
{
rec.write(LightIntBandDB::Times + l, skyParams[param_id]->colorRows[i][l].time);
int rebuilt_color_int = static_cast<int>(skyParams[param_id]->colorRows[i][l].color.z * 255.0f)
+ (static_cast<int>(skyParams[param_id]->colorRows[i][l].color.y * 255.0f) << 8)
+ (static_cast<int>(skyParams[param_id]->colorRows[i][l].color.x * 255.0f) << 16);
rec.write(LightIntBandDB::Values + l, rebuilt_color_int);
}
}
}
catch (...)
{
LogError << "When trying to intialize sky " << data.getInt(LightDB::ID) << ", there was an error with getting an entry in gLightIntBand (" << i << "). Sorry." << std::endl;
}
}
int light_float_start = lightParam_dbc_id * NUM_SkyFloatParamsNames - 5;
for (int i = 0; i < NUM_SkyFloatParamsNames; ++i)
{
try
{
DBCFile::Record rec = is_new_record ? gLightFloatBandDB.addRecord(light_float_start + i) : gLightFloatBandDB.getByID(light_float_start + i);
int entries = skyParams[param_id]->floatParams[i].size();
rec.write(LightFloatBandDB::Entries, entries); // nb of entries
// for (int l = 0; l < entries; l++)
for (int l = 0; l < 16; l++)
{
if (l >= entries)
{
rec.write(LightFloatBandDB::Times + l, 0);
rec.write(LightFloatBandDB::Values + l, 0.0f);
}
else
{
rec.write(LightFloatBandDB::Times + l, skyParams[param_id]->floatParams[i][l].time);
rec.write(LightFloatBandDB::Values + l, skyParams[param_id]->floatParams[i][l].value);
}
}
}
catch (...)
{
LogError << "When trying to intialize sky " << data.getInt(LightDB::ID) << ", there was an error with getting an entry in LightFloatBand (" << i << "). Sorry." << std::endl;
}
}
try
{
DBCFile::Record light_param = gLightParamsDB.getByID(lightParam_dbc_id);
if (skybox.has_value()) // TODO skybox dbc
{
// light_param.write(LightParamsDB::skybox, TODO);
}
else
light_param.write(LightParamsDB::skybox, 0);
light_param.write(LightParamsDB::highlightSky, int(skyParams[param_id]->highlight_sky()));
light_param.write(LightParamsDB::water_shallow_alpha, skyParams[param_id]->river_shallow_alpha());
light_param.write(LightParamsDB::water_deep_alpha, skyParams[param_id]->river_deep_alpha());
light_param.write(LightParamsDB::ocean_shallow_alpha, skyParams[param_id]->ocean_shallow_alpha());
light_param.write(LightParamsDB::ocean_deep_alpha, skyParams[param_id]->ocean_deep_alpha());
light_param.write(LightParamsDB::glow, skyParams[param_id]->glow());
}
catch (...)
{
LogError << "When trying to get the skybox for the entry " << lightParam_dbc_id << " in LightParams.dbc. Sad." << std::endl;
}
}
gLightDB.save();
gLightIntBandDB.save();
gLightFloatBandDB.save();
gLightParamsDB.save();
gLightSkyboxDB.save();
// emit map_dbc_updated();
is_new_record = false;
}

View File

@@ -47,20 +47,64 @@ struct SkyFloatParam
int time; int time;
}; };
class SkyParam
{
public:
std::optional<ModelInstance> skybox;
int Id;
SkyParam() = default;
explicit SkyParam(int paramId, Noggit::NoggitRenderContext context);
std::vector<SkyColor> colorRows[36];
std::vector<SkyFloatParam> floatParams[6];
int mmin[36];
int mmin_float[6];
bool highlight_sky() const { return _highlight_sky; }
float river_shallow_alpha() const { return _river_shallow_alpha; }
float river_deep_alpha() const { return _river_deep_alpha; }
float ocean_shallow_alpha() const { return _ocean_shallow_alpha; }
float ocean_deep_alpha() const { return _ocean_deep_alpha; }
float glow() const { return _glow; }
void set_glow(float glow) { _glow = glow; }
void set_highlight_sky(bool state) { _highlight_sky = state; }
void set_river_shallow_alpha(float alpha) { _river_shallow_alpha = alpha; }
void set_river_deep_alpha(float alpha) { _river_deep_alpha = alpha; }
void set_ocean_shallow_alpha(float alpha) { _ocean_shallow_alpha = alpha; }
void set_ocean_deep_alpha(float alpha) { _ocean_deep_alpha = alpha; }
private:
bool _highlight_sky;
float _river_shallow_alpha;
float _river_deep_alpha;
float _ocean_shallow_alpha;
float _ocean_deep_alpha;
float _glow;
Noggit::NoggitRenderContext _context;
};
class Sky class Sky
{ {
public: public:
std::optional<ModelInstance> skybox; std::optional<ModelInstance> skybox;
int Id;
glm::vec3 pos; glm::vec3 pos;
float r1, r2; float r1, r2;
explicit Sky(DBCFile::Iterator data, Noggit::NoggitRenderContext context); explicit Sky(DBCFile::Iterator data, Noggit::NoggitRenderContext context);
std::vector<SkyColor> colorRows[36]; SkyParam* skyParams[8];
std::vector<SkyFloatParam> floatParams[6]; int curr_sky_param = 0;
int mmin[36];
int mmin_float[6]; // std::vector<SkyColor> colorRows[36];
// std::vector<SkyFloatParam> floatParams[6];
// int mmin[36];
// int mmin_float[6];
char name[32]; char name[32];
@@ -70,6 +114,8 @@ public:
float weight; float weight;
bool global; bool global;
bool is_new_record = false;
bool operator<(const Sky& s) const bool operator<(const Sky& s) const
{ {
if (global) return false; if (global) return false;
@@ -77,20 +123,31 @@ public:
else return r2 < s.r2; else return r2 < s.r2;
} }
float river_shallow_alpha() const { return _river_shallow_alpha; } // bool highlight_sky() const { return _highlight_sky; }
float river_deep_alpha() const { return _river_deep_alpha; } // float river_shallow_alpha() const { return _river_shallow_alpha; }
float ocean_shallow_alpha() const { return _ocean_shallow_alpha; } // float river_deep_alpha() const { return _river_deep_alpha; }
float ocean_deep_alpha() const { return _ocean_deep_alpha; } // float ocean_shallow_alpha() const { return _ocean_shallow_alpha; }
float glow() const { return _glow; } // float ocean_deep_alpha() const { return _ocean_deep_alpha; }
// float glow() const { return _glow; }
bool selected() const { return _selected; } bool selected() const { return _selected; }
//
// void set_glow(float glow) { _glow = glow; }
// void set_highlight_sky(bool state) { _highlight_sky = state; }
// void set_river_shallow_alpha(float alpha) { _river_shallow_alpha = alpha; }
// void set_river_deep_alpha(float alpha) { _river_deep_alpha = alpha; }
// void set_ocean_shallow_alpha(float alpha) { _ocean_shallow_alpha = alpha; }
// void set_ocean_deep_alpha(float alpha) { _ocean_deep_alpha = alpha; }
void save_to_dbc();
private: private:
float _river_shallow_alpha; // bool _highlight_sky;
float _river_deep_alpha; // float _river_shallow_alpha;
float _ocean_shallow_alpha; // float _river_deep_alpha;
float _ocean_deep_alpha; // float _ocean_shallow_alpha;
// float _ocean_deep_alpha;
float _glow; // float _glow;
bool _selected; bool _selected;
Noggit::NoggitRenderContext _context; Noggit::NoggitRenderContext _context;
@@ -125,11 +182,24 @@ enum SkyFloatParamsNames
FOG_MULTIPLIER, FOG_MULTIPLIER,
CELESTIAL_FLOW, CELESTIAL_FLOW,
CLOUD_DENSITY, CLOUD_DENSITY,
UNK_1, UNK_FLOAT_PARAM_1,
UNK_2, UNK_FLOAT_PARAM_2,
NUM_SkyFloatParamsNames NUM_SkyFloatParamsNames
}; };
enum SkyParamsNames
{
CLEAR,
CLEAR_WATER,
STORM,
STORM_WATER,
DEATH,
UNK_PARAM_1,
UNK_PARAM_2,
UNK_PARAM_3,
NUM_SkyParamsNames
};
class Skies class Skies
{ {
private: private:
@@ -157,6 +227,11 @@ public:
explicit Skies(unsigned int mapid, Noggit::NoggitRenderContext context); explicit Skies(unsigned int mapid, Noggit::NoggitRenderContext context);
Sky* findSkyWeights(glm::vec3 pos); Sky* findSkyWeights(glm::vec3 pos);
Sky* findClosestSkyByWeight();
Sky* findClosestSkyByDistance(glm::vec3 pos);
void setCurrentParam(int param_id);
void update_sky_colors(glm::vec3 pos, int time); void update_sky_colors(glm::vec3 pos, int time);
bool draw ( glm::mat4x4 const& model_view bool draw ( glm::mat4x4 const& model_view

View File

@@ -1,12 +1,519 @@
// This file is part of Noggit3, licensed under GNU General Public License (version 3). // This file is part of Noggit3, licensed under GNU General Public License (version 3).
#include "LightEditor.hpp" #include "LightEditor.hpp"
#include <noggit/DBC.h>
#include <format>
// #include <iostream>
#include <string>
#include <map>
#include "LightColorEditor.h"
#include <noggit/World.h>
#include <noggit/MapView.h>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QFormLayout>
// #include <QtWidgets/QLabel>
#include <QtWidgets/qtreewidget.h>
#include <QtWidgets/QGroupBox>
#include <QtWidgets/QCheckBox>
using namespace Noggit::Ui::Tools; using namespace Noggit::Ui::Tools;
LightEditor::LightEditor(MapView* map_view, QWidget* parent) LightEditor::LightEditor(MapView* map_view, QWidget* parent)
: QWidget(parent) : QWidget(parent)
, _map_view(map_view) , _map_view(map_view)
, _world(map_view->getWorld())
{ {
// auto Skies = _map_view->getWorld()->renderer()->skies()->skies;
// Sky CurrSky = Skies[0];
// get curent sky from camera position
// Sky* CurrSky = _map_view->getWorld()->renderer()->skies()->findSkyWeights(map_view->getCamera()->position);
setMinimumWidth(250);
setMaximumWidth(250);
auto layout(new QVBoxLayout(this));
layout->setAlignment(Qt::AlignTop);
auto lightning_tabs = new QTabWidget(this);
layout->addWidget(lightning_tabs);
auto light_selection_widget = new QWidget(this);
light_selection_widget->setContentsMargins(0, 0, 0, 0);
auto light_selection_layout = new QFormLayout(light_selection_widget); // QFormLayout
light_selection_layout->setContentsMargins(0, 0, 0, 0);
lightning_tabs->addTab(light_selection_widget, "Light Selection");
auto light_editing_widget = new QWidget(lightning_tabs);
light_editing_widget->setEnabled(false);
auto light_editing_layout = new QVBoxLayout(light_editing_widget);
lightning_tabs->addTab(light_editing_widget, "Edit Light");
// set time _world->time
light_selection_layout->addWidget(new QLabel("Set current time :", this));
auto time_dial = new QDial(this);
light_selection_layout->addWidget(time_dial);
time_dial->setRange(0, 2880); // Time Values from 0 to 2880 where each number represents a half minute from midnight to midnight
time_dial->setWrapping(true);
time_dial->setSliderPosition(0); // to get ingame orientation
// time_value0_dial->setValue(color0.time);
time_dial->setInvertedAppearance(false); // sets the position at top
time_dial->setToolTip("Time (24hours)");
time_dial->setSingleStep(360); // ticks are 360 units
QPushButton* GetCurrentSkyButton = new QPushButton("Edit current light", this);
light_selection_layout->addWidget(GetCurrentSkyButton);
_light_tree = new QTreeWidget();
light_selection_layout->addWidget(_light_tree);
_light_tree->setHeaderLabel("Current map lights");
_light_tree->setColumnCount(1);
// _light_tree->setMaximumHeight(400); // TODO : editing the height fucks up the layout
// for (auto& sky : _world->renderer()->skies()->skies) // bad idea, renderer needs to be loaded first
for (DBCFile::Iterator i = gLightDB.begin(); i != gLightDB.end(); ++i)
{
if (i->getInt(LightDB::Map) == _world->getMapID())
{
QTreeWidgetItem* item = new QTreeWidgetItem();
std::stringstream ss;
auto light_id = i->getUInt(LightDB::ID);
item->setData(0, 0, QVariant(light_id) );
std::string light_name = "Unamed Light";
if (light_names_map.contains(light_id))
light_name = light_names_map.at(light_id);
else if (i->getFloat(LightDB::PositionX) == 0.0f && i->getFloat(LightDB::PositionY) == 0.0f && i->getFloat(LightDB::PositionZ) == 0.0f)
light_name = "Global Light";
ss << i->getUInt(LightDB::ID) << "-" << light_name;// gAreaDB.getAreaName(area_id);
item->setText(0, QString(ss.str().c_str()));// TODO : light names
// if (global)
_light_tree->addTopLevelItem(item);
}
}
QPushButton* GetSelectedSkyButton = new QPushButton("Edit selected light", this);
light_selection_layout->addWidget(GetSelectedSkyButton);
// global settings ********************************************************************************************** //
// TODO : name lights on laoding instead
light_editing_layout->addWidget(new QLabel("Selected Light :", this), 0, 0);
auto lightid_label = new QLabel("No light selected", this);
light_editing_layout->addWidget(lightid_label);
QPushButton* SaveCurrentSkyButton = new QPushButton("Save Light(Write DBCs)", this);
SaveCurrentSkyButton->setEnabled(false);
light_editing_layout->addWidget(SaveCurrentSkyButton);
QGroupBox* global_values_group = new QGroupBox("Global settings", this);
// alpha_values_group->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
auto global_values_layout = new QGridLayout(global_values_group);
global_values_layout->addWidget(new QLabel("Name:", this), 0, 0);
auto name_line_edit = new QLineEdit(this);
global_values_layout->addWidget(name_line_edit, 0, 1);
global_values_layout->addWidget(new QLabel("Position X:", this),1,0);
auto pos_x_spin = new QDoubleSpinBox(this);
pos_x_spin->setRange(-17066.66656 * 2, 17066.66656*2); // size = <20>17066.66656
pos_x_spin->setValue(0);
pos_x_spin->setSingleStep(50);
pos_x_spin->setEnabled(false);
global_values_layout->addWidget(pos_x_spin,1,1);
global_values_layout->addWidget(new QLabel("Position Y:", this),2,0);
auto pos_y_spin = new QDoubleSpinBox(this);
pos_y_spin->setRange(-17066.66656 * 2, 17066.66656*2); // size = <20>17066.66656
pos_y_spin->setValue(0);
pos_y_spin->setSingleStep(50);
pos_y_spin->setEnabled(false);
global_values_layout->addWidget(pos_y_spin,2,1);
global_values_layout->addWidget(new QLabel("Position Z:", this),3,0);
auto pos_z_spin = new QDoubleSpinBox(this);
pos_z_spin->setRange(-17066.66656 * 2, 17066.66656*2); // ????
pos_z_spin->setValue(0);
pos_z_spin->setSingleStep(50);
pos_z_spin->setEnabled(false);
global_values_layout->addWidget(pos_z_spin,3,1);
global_values_layout->addWidget(new QLabel("Inner Radius:", this),4,0);
auto inner_radius_spin = new QDoubleSpinBox(this);
inner_radius_spin->setRange(0, 100000); // max seen in dbc is 3871 (139363 <20> 36 )
inner_radius_spin->setValue(0);
inner_radius_spin->setSingleStep(50);
inner_radius_spin->setEnabled(false);
global_values_layout->addWidget(inner_radius_spin,4,1);
global_values_layout->addWidget(new QLabel("Outer Radius:", this),5,0);
auto outer_radius_spin = new QDoubleSpinBox(this);
outer_radius_spin->setRange(0, 100000); // max seen in dbc is 3871 (139363 <20> 36 )
outer_radius_spin->setValue(0);
outer_radius_spin->setSingleStep(50);
outer_radius_spin->setEnabled(false);
global_values_layout->addWidget(outer_radius_spin,5,1);
light_editing_layout->addWidget(global_values_group);
// BELOW IS PARAM SPECIFIC SETTINGS
light_editing_layout->addWidget(new QLabel("Param Type :", this));
param_combobox = new QComboBox(this);
param_combobox->setEnabled(false);
light_editing_layout->addWidget(param_combobox);
param_combobox->addItem("Clear Weather"); // Used in clear weather.
param_combobox->addItem("Clear Weather Underwater"); // Used in clear weather while being underwater.
param_combobox->addItem("Storm Weather"); // Used in rainy/snowy/sandstormy weather.
param_combobox->addItem("Storm Weather Underwater"); // Used in rainy/snowy/sandstormy weather while being underwater.
param_combobox->addItem("Death Effect"); // ParamsDeath. Only 4 and in newer ones 3 are used as value here (with some exceptions). Changing this seems to have no effect in 3.3.5a (is death light setting hardcoded?)
// param_combobox->addItem("Clear Weather");
// param_combobox->addItem("Clear Weather");
// param_combobox->addItem("Clear Weather");
// for (int i = 0; i < NUM_SkyParamsNames; ++i)
// {
// // auto sky_param = _curr_sky->skyParams[i];
// }
QGroupBox* light_param_group = new QGroupBox("Light Params", this);
light_editing_layout->addWidget(light_param_group);
auto light_param_layout = new QVBoxLayout(light_param_group);
_nb_param_users = new QLabel(this);
light_param_layout->addWidget(_nb_param_users);
// QGroupBox* alpha_values_group = new QGroupBox("Alpha Values", this);
// alpha_values_group->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
auto param_grid_layout = new QGridLayout(light_param_group);
light_param_layout->addLayout(param_grid_layout);
param_grid_layout->addWidget(new QLabel("Glow:", this),0,0);
glow_slider = new QSlider(Qt::Horizontal, this);
glow_slider->setRange(0, 100); // between 0 and 1, increases by 0.05. Multiplying everything by 100 cuz Qslider doesn't seem to support floats
glow_slider->setTickInterval(5);
glow_slider->setSingleStep(5);
glow_slider->setValue(100);
glow_slider->setEnabled(false);
param_grid_layout->addWidget(glow_slider,0,1);
param_grid_layout->addWidget(new QLabel("Highlight Sky:", this), 1, 0);
highlight_sky_checkbox = new QCheckBox(this);
highlight_sky_checkbox->setCheckState(Qt::Unchecked);
highlight_sky_checkbox->setEnabled(false);
param_grid_layout->addWidget(highlight_sky_checkbox, 1, 1);
param_grid_layout->addWidget(new QLabel("Skybox model:", this), 2, 0);
skybox_model_lineedit = new QLineEdit(this);
skybox_model_lineedit->setEnabled(false);
param_grid_layout->addWidget(skybox_model_lineedit, 2, 1);
// Alpha values ********************************************************************************************** //
QGroupBox* alpha_values_group = new QGroupBox("Alpha Values", light_param_group);
// light_editing_layout->addWidget(alpha_values_group);
light_param_layout->addWidget(alpha_values_group);
// alpha_values_group->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
auto alpha_values_layout = new QGridLayout(alpha_values_group);
alpha_values_layout->addWidget(new QLabel("Shallow Water", alpha_values_group), 0, 0);
shallow_water_alpha_slider = new QSlider(Qt::Horizontal, alpha_values_group);
shallow_water_alpha_slider->setRange(0, 100); // between 0 and 1, increases by 0.05. Multiplying everything by 100 cuz Qslider doesn't seem to support floats
shallow_water_alpha_slider->setTickInterval(5);
shallow_water_alpha_slider->setSingleStep(5);
shallow_water_alpha_slider->setValue(100);
shallow_water_alpha_slider->setEnabled(false);
alpha_values_layout->addWidget(shallow_water_alpha_slider, 0, 1);
alpha_values_layout->addWidget(new QLabel("Deep Water", alpha_values_group), 1, 0);
deep_water_alpha_slider = new QSlider(Qt::Horizontal, alpha_values_group);
deep_water_alpha_slider->setRange(0, 100); // between 0 and 1, increases by 0.05. Multiplying everything by 100 cuz Qslider doesn't seem to support floats
deep_water_alpha_slider->setTickInterval(5);
deep_water_alpha_slider->setSingleStep(5);
deep_water_alpha_slider->setValue(100);
deep_water_alpha_slider->setEnabled(false);
alpha_values_layout->addWidget(deep_water_alpha_slider, 1, 1);
alpha_values_layout->addWidget(new QLabel("Shallow Ocean", alpha_values_group), 2, 0);
shallow_ocean_alpha_slider = new QSlider(Qt::Horizontal, alpha_values_group);
shallow_ocean_alpha_slider->setRange(0, 100); // between 0 and 1, increases by 0.05. Multiplying everything by 100 cuz Qslider doesn't seem to support floats
shallow_ocean_alpha_slider->setTickInterval(5);
shallow_ocean_alpha_slider->setSingleStep(5);
shallow_ocean_alpha_slider->setValue(100);
shallow_ocean_alpha_slider->setEnabled(false);
alpha_values_layout->addWidget(shallow_ocean_alpha_slider, 2, 1);
alpha_values_layout->addWidget(new QLabel("Deep Ocean", alpha_values_group), 3, 0);
deep_ocean_alpha_slider = new QSlider(Qt::Horizontal, alpha_values_group);
deep_ocean_alpha_slider->setRange(0, 100); // between 0 and 1, increases by 0.05. Multiplying everything by 100 cuz Qslider doesn't seem to support floats
deep_ocean_alpha_slider->setTickInterval(5);
deep_ocean_alpha_slider->setSingleStep(5);
deep_ocean_alpha_slider->setValue(100);
deep_ocean_alpha_slider->setEnabled(false);
alpha_values_layout->addWidget(deep_ocean_alpha_slider, 3, 1);
// Color values ********************************************************************************************** //
QGroupBox* color_values_group = new QGroupBox("Light color values", this);
// alpha_values_group->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
auto color_values_layout = new QGridLayout(color_values_group);
for (int i = 0; i < NUM_SkyColorNames; ++i)
{
std::string color_name = sky_color_names_map.at(i);
LightViewPreview* LightPrev = new LightViewPreview(QString("%1 Color").arg(color_name.c_str()),
QSize(150, LIGHT_VIEW_PREVIEW_HEIGHT));
LightsPreview.push_back(LightPrev);
color_values_layout->addWidget(LightPrev, i, 0);
connect(LightPrev, &LightViewPreview::LeftClicked, [this, i, LightPrev]()
{
if (!_curr_sky)
return;
LightViewEditor* Editor = new LightViewEditor(_map_view, _curr_sky->skyParams[param_combobox->currentIndex()], SkyColorNames(i), this);
ActiveEditor.push_back(Editor);
Editor->show();
connect(Editor, &LightViewEditor::Delete, [=](LightViewEditor* self)
{
for (int i = 0; i < ActiveEditor.size(); ++i)
if (ActiveEditor[i] == self)
ActiveEditor.erase(ActiveEditor.begin() + i, ActiveEditor.begin() + i);
});
connect(Editor, &LightViewEditor::UpdatePixmap, [this, LightPrev](const QPixmap Updated)
{
LightPrev->UpdatePixmap(Updated);
});
});
}
light_editing_layout->addWidget(color_values_group);
connect(time_dial, &QDial::valueChanged, [&](int v) // [this]
{
_map_view->getWorld()->time = v;
_world->renderer()->skies()->update_sky_colors(_map_view->getCamera()->position, static_cast<int>(_world->time) % 2880);
}
);
connect(GetCurrentSkyButton, &QPushButton::clicked, [=]() {
// _curr_sky = _map_view->getWorld()->renderer()->skies()->findSkyWeights(map_view->getCamera()->position);
auto new_sky = _map_view->getWorld()->renderer()->skies()->findClosestSkyByWeight();
if (_curr_sky == nullptr)
return; // todo error
else
_curr_sky = new_sky;
light_editing_widget->setEnabled(true);
lightning_tabs->setCurrentWidget(light_editing_widget);
SaveCurrentSkyButton->setEnabled(true);
// maybe move the inits to a separate function
// global values
std::stringstream ss;
std::string light_name = "Unamed Light";
if (light_names_map.contains(_curr_sky->Id))
light_name = light_names_map.at(_curr_sky->Id);
else if (_curr_sky->global)
light_name = "Global Light";
ss << _curr_sky->Id << "-" << light_name;
lightid_label->setText(QString::fromStdString(ss.str().c_str()));
name_line_edit->setText(_curr_sky->name);
pos_x_spin->setValue(_curr_sky->pos.x);
pos_x_spin->setEnabled(true);
pos_y_spin->setValue(_curr_sky->pos.z); // swap Z and Y
pos_y_spin->setEnabled(true);
pos_z_spin->setValue(_curr_sky->pos.y);
pos_z_spin->setEnabled(true);
inner_radius_spin->setValue(_curr_sky->r1);
inner_radius_spin->setEnabled(true);
outer_radius_spin->setValue(_curr_sky->r2);
outer_radius_spin->setEnabled(true);
param_combobox->setEnabled(true);
param_combobox->setCurrentIndex(0);
// light param specific data (only 0 currently)
auto default_param = _curr_sky->skyParams[param_combobox->currentIndex()];
glow_slider->setSliderPosition(default_param->glow() * 100);
glow_slider->setEnabled(true);
highlight_sky_checkbox->setCheckState(Qt::CheckState(default_param->highlight_sky() ) );
highlight_sky_checkbox->setEnabled(true);
if (_curr_sky->skybox.has_value())
skybox_model_lineedit->setText(QString::fromStdString(default_param->skybox.value().model.get()->file_key().filepath()));
// alpha values
shallow_water_alpha_slider->setSliderPosition(default_param->river_shallow_alpha() * 100); // TODO bug : when reselecting the same light, sliders with digits values reset to 0.
shallow_water_alpha_slider->setEnabled(true);
deep_water_alpha_slider->setSliderPosition(default_param->river_deep_alpha() * 100);
deep_water_alpha_slider->setEnabled(true);
shallow_ocean_alpha_slider->setSliderPosition(default_param->ocean_shallow_alpha() * 100);
shallow_ocean_alpha_slider->setEnabled(true);
deep_ocean_alpha_slider->setSliderPosition(default_param->ocean_deep_alpha() * 100);
deep_ocean_alpha_slider->setEnabled(true);
// color values
for (int i = 0; i < NUM_SkyColorNames; ++i)
{
LightsPreview[i]->SetPreview(default_param->colorRows[i]);
//for (int l = 0; l < default_param->colorRows[i]; ++)
//default_param->colorRows[i]
//_color_value_Buttons[i]->setText(QString::fromStdString(std::format("{} / 16 values", default_param->colorRows[i].size())));
//_color_value_Buttons[i]->setEnabled(true);
}
});
connect(GetSelectedSkyButton, &QPushButton::clicked, [=]() {
// TODO : load selected sky and teleport to it
// auto selecetd_light = _light_tree->selectedItems().data
auto const& selected_items = _light_tree->selectedItems();
if (selected_items.size())
{
auto selected_light_id = selected_items.back()->data(0, 0).toInt(); // TODO : doesn't work since moving to role 0
for (int i = 0; i < _map_view->getWorld()->renderer()->skies()->skies.size(); i++)
{
auto &sky = _map_view->getWorld()->renderer()->skies()->skies[i];
if (sky.Id == selected_light_id)
{
_curr_sky = &sky;
_map_view->_camera.position = _curr_sky->pos;
_map_view->_camera.position.z += 100;
// get terrain's height for Z axis.
// auto chunk = _world->getChunkAt(glm::vec3(_curr_sky->pos.x, _curr_sky->pos.y, _curr_sky->pos.z)); // need to load tile first ??
// if (chunk != nullptr)
// _map_view->_camera.position.z = chunk->getMaxHeight() + 20.0f;
// TODO : initialise
}
}
}
});
connect(param_combobox, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
// update rendering to selected param
_curr_sky->curr_sky_param = index;
_world->renderer()->skies()->update_sky_colors(_map_view->getCamera()->position, static_cast<int>(_world->time) % 2880); // find how to update sky
DBCFile::Record data = gLightDB.getByID(_curr_sky->Id);
int nb_user = 0;
for (DBCFile::Iterator i = gLightDB.begin(); i != gLightDB.end(); ++i)
{
for (int l = 0; l < NUM_SkyParamsNames; l++)
{
if (i->getInt(LightDB::DataIDs + l) == data.getInt(LightDB::DataIDs + index))
nb_user++;
}
}
_nb_param_users->setText("This param is used " + nb_user);
auto sky_param = _curr_sky->skyParams[index];
glow_slider->setSliderPosition(sky_param->glow() * 100);
highlight_sky_checkbox->setCheckState(Qt::CheckState(sky_param->highlight_sky()));
if (_curr_sky->skybox.has_value())
skybox_model_lineedit->setText(QString::fromStdString(sky_param->skybox.value().model.get()->file_key().filepath()));
// alpha values
shallow_water_alpha_slider->setSliderPosition(sky_param->river_shallow_alpha() * 100);
deep_water_alpha_slider->setSliderPosition(sky_param->river_deep_alpha() * 100);
shallow_ocean_alpha_slider->setSliderPosition(sky_param->ocean_shallow_alpha() * 100);
deep_ocean_alpha_slider->setSliderPosition(sky_param->ocean_deep_alpha() * 100);
// color values
for (int i = 0; i < NUM_SkyColorNames; ++i)
{
LightsPreview[i]->SetPreview(sky_param->colorRows[i]);
//_color_value_Buttons[i]->setText(QString::fromStdString(std::format("{} / 16 values", sky_param->colorRows[i].size())));
}
});
connect(SaveCurrentSkyButton, &QPushButton::clicked, [=]() {
_curr_sky->save_to_dbc();
});
connect(pos_x_spin, qOverload<double>(&QDoubleSpinBox::valueChanged), [&](double v) {
_curr_sky->pos.x = v; // pos_x_spin->value();
_world->renderer()->skies()->update_sky_colors(_map_view->getCamera()->position, static_cast<int>(_world->time) % 2880); // find how to update sky
});
connect(pos_y_spin, qOverload<double>(&QDoubleSpinBox::valueChanged), [&](double v) {
_curr_sky->pos.z = v; // pos_y_spin->value();
_world->renderer()->skies()->update_sky_colors(_map_view->getCamera()->position, static_cast<int>(_world->time) % 2880); // find how to update sky
});
connect(pos_z_spin, qOverload<double>(&QDoubleSpinBox::valueChanged), [&](double v) {
_curr_sky->pos.y = v; // pos_z_spin->value();
_world->renderer()->skies()->update_sky_colors(_map_view->getCamera()->position, static_cast<int>(_world->time) % 2880); // find how to update sky
});
connect(inner_radius_spin, qOverload<double>(&QDoubleSpinBox::valueChanged), [&](double v) {
_curr_sky->r1 = v; // inner_radius_spin->value();
_world->renderer()->skies()->update_sky_colors(_map_view->getCamera()->position, static_cast<int>(_world->time) % 2880); // find how to update sky
});
connect(outer_radius_spin, qOverload<double>(&QDoubleSpinBox::valueChanged), [&](double v) {
_curr_sky->r2 = v; // outer_radius_spin->value();
_world->renderer()->skies()->update_sky_colors(_map_view->getCamera()->position, static_cast<int>(_world->time) % 2880); // find how to update sky
});
connect(glow_slider, &QSlider::valueChanged, [&](int v) {
_curr_sky->skyParams[param_combobox->currentIndex()]->set_glow(v / 100); // glow_slider->value() / 100; // crashes, glow_slider is null.
_world->renderer()->skies()->update_sky_colors(_map_view->getCamera()->position, static_cast<int>(_world->time) % 2880); // find how to update sky
});
connect(highlight_sky_checkbox, &QCheckBox::stateChanged, [&](int state) {
_curr_sky->skyParams[param_combobox->currentIndex()]->set_highlight_sky(state);
_world->renderer()->skies()->update_sky_colors(_map_view->getCamera()->position, static_cast<int>(_world->time) % 2880); // find how to update sky
});
connect(shallow_water_alpha_slider, &QSlider::valueChanged, [&](int v) {
_curr_sky->skyParams[param_combobox->currentIndex()]->set_river_shallow_alpha(v / 100);
_world->renderer()->skies()->update_sky_colors(_map_view->getCamera()->position, static_cast<int>(_world->time) % 2880); // find how to update sky
});
connect(deep_water_alpha_slider, &QSlider::valueChanged, [&](int v) {
_curr_sky->skyParams[param_combobox->currentIndex()]->set_river_deep_alpha(v / 100);
_world->renderer()->skies()->update_sky_colors(_map_view->getCamera()->position, static_cast<int>(_world->time) % 2880); // find how to update sky
});
connect(shallow_ocean_alpha_slider, &QSlider::valueChanged, [&](int v) {
_curr_sky->skyParams[param_combobox->currentIndex()]->set_ocean_shallow_alpha(v / 100);
_world->renderer()->skies()->update_sky_colors(_map_view->getCamera()->position, static_cast<int>(_world->time) % 2880); // find how to update sky
});
connect(deep_ocean_alpha_slider, &QSlider::valueChanged, [&](int v) {
_curr_sky->skyParams[param_combobox->currentIndex()]->set_ocean_deep_alpha(v / 100);
_world->renderer()->skies()->update_sky_colors(_map_view->getCamera()->position, static_cast<int>(_world->time) % 2880); // find how to update sky
});
}
void LightEditor::UpdateWorldTime()
{
if (ActiveEditor.size() == 0)
return;
for (int i = 0; i < ActiveEditor.size(); ++i)
ActiveEditor[i]->UpdateWorldTime();
}
void LightEditor::load_light_param()
{
// _radius_slider->setValue(radius);
}
}

View File

@@ -5,18 +5,311 @@
#include <QWidget> #include <QWidget>
#include <noggit/MapView.h> #include <noggit/MapView.h>
#include <QtWidgets/qtreewidget.h>
#include <noggit/ui/widgets/LightViewWidget.h>
namespace Noggit::Ui::Tools namespace Noggit::Ui::Tools
{ {
static std::map <int, std::string> sky_color_names_map = {
{0 , "Direct"},
{1 , "Ambiant"},
{2 , "Sky Top"},
{3 , "Sky Midle"},
{4 , "Sky Band 1"},
{5 , "Sky Band 2"},
{6 , "Sky Smog"},
{7 , "Sky Fog"},
{8 , "Sun"},
{9 , "Cloud Sun"},
{10 , "Cloud Emissive"},
{11 , "Cloud Layer 1 Ambian"},
{12 , "Cloud Layer 2 Ambiant"},
{13 , "Unknown/Unused"},
{14 , "Ocean Close"},
{15 , "Ocean Far"},
{16 , "River Close"},
{17 , "River Far"}
};
static std::map <int, std::string> light_names_map = {
{1 , "Global Light"},
{2 , "DuskWood"},
{3 , "Swamp Of Sorrows"},
{4 , "WestFall n 2"},
{5 , "Deadwind Pass"},
{6 , "Blasted Lands"},
{7 , "Burning Steppes"},
{8 , "WestFall 2 razan"},
{9 , "StrangleThorn"},
{10 , "Badlands enter"},
{11 , "WetLands"},
{12 , "Arathi Highlands"},
{13 , "Alterac Mountains"},
{14 , "Swamp Of Sorrows 3"},
{15 , "Duskwood East al 3"},
{16 , "Dun Morogh"},
{17 , "Deadwind Pass Tower"},
{18 , "Duskwood East2"},
{19 , "Blasted Lands Demon"},
{20 , "Burning Steppes2"},
{21 , "Badlands2"},
{22 , "Dun Morogh2"},
{23 , "Dun Morogh3"},
{24 , "Dun Morogh4"},
{25 , "Loch Modan"},
{26 , "Loch Modan 2"},
{27 , "Tirisfall Glades"},
{28 , "SilverPine"},
{29 , "Tirisfall Glades 3"},
{30 , "PlagueLands03"},
{31 , "PlagueLandsWest01"},
{32 , "PlagueLandsWest04"},
{33 , "PlagueLandsEast02"},
{34 , "PlagueLandsWestUther"},
{35 , "PlagueLandsWest05"},
{36 , "AeriePeak"},
{37 , "AeriePeakEast"},
{38 , "AeriePeakWorldTree"},
{39 , "StrangleBootyBay"},
{40 , "DuskWoodNagleHouse"},
{41 , "DuskWood World Tree"},
{42 , "PlagueLandsEast01"},
{43 , "PlagueEastCorrupt01"},
{44 , "Alterac Snow"},
{45 , "ArathiHighlandsCoast"},
{46 , "PlagueEastCorrupt02"},
{47 , "PlagueEastCorrupt03"},
{48 , "PlagueEastCorrupt04"},
{49 , "PlagueEastCorrupt05"},
{50 , "Burning Steppes Fix"},
{51 , "StormwindIndustrial"},
{52 , "StormwindIndustrial2"},
{53 , "Tirisfall Glades 4"},
{54 , "Outland01"},
{55 , "HillsbradTowerIsle"},
{56 , "HillsbradTowerIsDark"},
{57 , "ZulGurub"},
{58 , "WetLands2"},
{59 , "OutlandDemon"},
{60 , "OutlandDemon2"},
{61 , "AlteracRavenholt"},
{62 , "PlagueEastCorrupt06"},
{63 , "AeriePeakTrollCity"},
{64 , "Blasted Lands2 ity"},
{65 , "Blasted Lands3"},
{66 , "Blasted Lands4"},
{67 , "Blasterd LandsPortal"},
{68 , "Swamp Of Sorrows Fix"},
{69 , "Blasted Lands Peak"},
{70 , "ProgramerIsleDeadWin"},
{71 , "Deadwind Swamp"},
{72 , "SearingGorge01"},
{73 , "SearingGorge02"},
{74 , "SearingGorgeFix1"},
{75 , "SearingGorgeFix2"},
{76 , "SearingGorgeFix3"},
{77 , "Stormwind"},
{78 , "Burning Steppes Fix2"},
{79 , "PlagueEastElfLodge"},
{80 , "PlagueEastTroll"},
{81 , "PlagueLandsEastDarro"},
{82 , "Global Light"},
{83 , "Global Light"},
{84 , "Global Light"},
{85 , "CavernsSwamp"},
{86 , "Hillsbrad orrows"},
{87 , "BlockingLight01"},
{88 , "BlockingLight02"},
{89 , "BlockingLight03"},
{90 , "BlockingLight04"},
{91 , "BlockingLight05"},
{92 , "BlockingLight06"},
{93 , "BlockingLight07"},
{94 , "BlockingLight08"},
{95 , "BlockingLight09"},
{96 , "BlockingLight091"},
{97 , "Global Light"},
{98 , "WestFall n 2"},
{99 , "WestFallDeadmines"},
{179, "Global Light"},
{180, "DireMaul"},
{181, "DirePlague01"},
{182, "DirePlague02 es"},
{183, "DirePlague03 zan"},
{184, "DireDarkshore01"},
{185, "DireDarkshore03"},
{186, "DireCorrupt 03"},
{187, "Ashenvale"},
{188, "EmeraldDream01"},
{189, "EmeraldDreamCanyon"},
{190, "EmeraldTestArea"},
{191, "Global Light"},
{192, "Ashenvale"},
{193, "Barrens ighlands"},
{194, "Desolace"},
{195, "Tanaris Desert"},
{196, "Moonglade"},
{197, "Darkshore"},
{198, "Duskwallow ds Demon"},
{199, "Darkshore2"},
{200, "Kalidar"},
{201, "Mullgore"},
{202, "MullgoreSouth"},
{203, "DurotarSouth"},
{204, "DurotarNorth"},
{205, "BarrensSouth01"},
{206, "BarrensSouth02"},
{207, "BarrensSouth03"},
{208, "Ashenvale02 03"},
{209, "Ashenvale03"},
{210, "Ashenvale04"},
{211, "ThousandNeedles01"},
{212, "ThousandNeedles02"},
{213, "ThousandNeedles03"},
{214, "Felwood 1 sWest05"},
{215, "Felwood02"},
{216, "Felwood03 ast"},
{217, "Feralas01 orldTree"},
{218, "AshenvaleHellScream"},
{219, "KalidarDarnassus"},
{220, "MullgoreBurrow"},
{221, "BarrensOilRig"},
{222, "Feralas02"},
{223, "BarrensDreadMistPeak"},
{224, "StonetalonBarrens"},
{225, "StonetalonClearCut"},
{226, "StonetalonHarpy"},
{227, "Stonetalon01"},
{228, "StonetalonPeak"},
{229, "AshenvaleCoast"},
{230, "ThousandNeedlesSalt"},
{231, "DuskwallowBarrens"},
{232, "FelwoodJadenar"},
{233, "FelwoodJadenar2"},
{234, "MullgoreHarpy"},
{235, "AshenvaleHellScream2"},
{236, "ThousandNeedles05"},
{237, "ThousandNeedles06"},
{238, "Azshara2"},
{239, "DurotarOgrimmar"},
{240, "FeralasCoast"},
{241, "FeralasTwinColossus"},
{242, "Tanaris Desert2"},
{243, "Tanaris Desert3"},
{244, "Tanaries Desert4"},
{245, "Tanaries Desert5"},
{246, "Desolace2"},
{247, "Azshara1 ea2"},
{248, "UnGoro 1 ea2"},
{249, "Silithus"},
{250, "FeralasCoast02"},
{251, "TanarisCavernsTime"},
{252, "TanarisOger01"},
{253, "DuskwallowTheramore"},
{254, "AshenvaleFelwood"},
{255, "UnGoroTarPites"},
{256, "UnGoroRaptorMarsh"},
{257, "UnGoroTRex"},
{258, "SilithusSouth"},
{259, "WinterSpring01"},
{260, "WinterSpring02"},
{261, "WinterSpring03"},
{262, "Hyjal Demon"},
{263, "Hyjal Demon2"},
{264, "WinterSpring05"},
{265, "Hyjal Demon3"},
{266, "Hyjal Demon4"},
{267, "FeralasCoast03"},
{268, "FeralasTwinColossus2"},
{269, "KalidarBaseRoots"},
{270, "WinterSpringDemon"},
{271, "GM Island"},
{272, "WinterSpringDemon2"},
{273, "BarrensOasis01"},
{274, "BarrensOasis02"},
{275, "BarrensOasis03"},
{276, "BarrensQuilBoar"},
{277, "BarrensQuilBoar2"},
{278, "SilithusUngoroEnter"},
{279, "UnGoroSilithisEnter"},
{280, "BarrensSouth04"},
{281, "BarrensQuilBoar3"},
{282, "UnGoroRiver01"},
{283, "UnGoroRiver02"},
{284, "UnGoroRiver03"},
{285, "UnGoroRiver04"},
{286, "UnGoroRiver05"},
{287, "UnGoroRiver06"},
{288, "UnGoroRiver07"},
{289, "Darkshore3"},
{290, "Felwood03Fix"},
{291, "FelwoodFix"},
{292, "DesolaceNightElf1"},
{293, "DesolaceNightElf2"},
{294, "AshenvaleIrisLake"},
{295, "AshenvaleStardstLake"},
{296, "AshenvaleOrcCamp"},
{297, "DesolaceFix"},
{298, "DesolaceFix2"},
{299, "AshenvaleFurbolg"},
{300, "AshenvaleDarkshore"},
{301, "AshenvaleDarkshore2"},
{302, "WinterSpringDemon3"},
{303, "WinterSpringWildkin1"},
{304, "WinterSpringWildkin2"},
{305, "DesolaceCorrupt1"},
{306, "DesolaceOrc upt1"},
{307, "DesolaceCorrupt2"},
{308, "SilithusNorthWest"},
{309, "DesolaceNagaIsle"},
{310, "StonetalonWeb"},
{311, "StonetalonTauren"},
{312, "AshenvalePurple01"},
{313, "AshenvalePurple02"},
{314, "SilithusFix"},
{315, "SilithusDemonHamer1"},
{316, "SilithusDemonHamer2"},
{317, "SilithusDemonHamer3"}
};
class LightEditor : public QWidget class LightEditor : public QWidget
{ {
public: public:
LightEditor(MapView* map_view, QWidget* parent = nullptr); LightEditor(MapView* map_view, QWidget* parent = nullptr);
void UpdateWorldTime();
private: private:
MapView* _map_view; MapView* _map_view;
World* _world;
Sky* _curr_sky;
QPushButton* _color_value_Buttons[18]{ 0 };
QLabel* _color_value_labels[18]{ 0 };
std::vector<LightViewPreview*> LightsPreview;
std::vector<LightViewEditor*> ActiveEditor;
QLabel* _nb_param_users;
QTreeWidget* _light_tree;
QComboBox* param_combobox;
QSlider* glow_slider;
QCheckBox* highlight_sky_checkbox;
QLineEdit* skybox_model_lineedit;
QSlider* shallow_water_alpha_slider;
QSlider* deep_water_alpha_slider;
QSlider* shallow_ocean_alpha_slider;
QSlider* deep_ocean_alpha_slider;
bool _is_new_record = false;
void load_light_param();
}; };
} }
#endif //NOGGIT_LIGHTEDITOR_HPP #endif //NOGGIT_LIGHTEDITOR_HPP