Light editor updates WIP
This commit is contained in:
@@ -4505,6 +4505,7 @@ void MapView::tick (float dt)
|
||||
_world->time += this->mTimespeed * dt;
|
||||
_world->animtime += dt * 1000.0f;
|
||||
|
||||
if (mTimespeed > 0.0f)
|
||||
lightEditor->UpdateWorldTime();
|
||||
|
||||
if (_draw_model_animations.get())
|
||||
|
||||
@@ -37,15 +37,15 @@ SkyParam::SkyParam(int paramId, Noggit::NoggitRenderContext context)
|
||||
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;
|
||||
}
|
||||
// for (int i = 0; i < NUM_SkyColorNames; ++i)
|
||||
// {
|
||||
// mmin[i] = -2;
|
||||
// }
|
||||
//
|
||||
// for (int i = 0; i < NUM_SkyFloatParamsNames; ++i)
|
||||
// {
|
||||
// mmin_float[i] = -2;
|
||||
// }
|
||||
|
||||
// int light_param_0 = data->getInt(LightDB::DataIDs);
|
||||
int light_int_start = paramId * NUM_SkyColorNames - 17;
|
||||
@@ -59,11 +59,12 @@ SkyParam::SkyParam(int paramId, Noggit::NoggitRenderContext context)
|
||||
|
||||
if (entries == 0)
|
||||
{
|
||||
mmin[i] = -1;
|
||||
// mmin[i] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mmin[i] = rec.getInt(LightIntBandDB::Times);
|
||||
// smallest/first time value
|
||||
// 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));
|
||||
@@ -106,11 +107,11 @@ SkyParam::SkyParam(int paramId, Noggit::NoggitRenderContext context)
|
||||
|
||||
if (entries == 0)
|
||||
{
|
||||
mmin_float[i] = -1;
|
||||
// mmin_float[i] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
mmin_float[i] = rec.getInt(LightFloatBandDB::Times);
|
||||
// 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));
|
||||
@@ -156,7 +157,9 @@ SkyParam::SkyParam(int paramId, Noggit::NoggitRenderContext context)
|
||||
|
||||
if (skybox_id)
|
||||
{
|
||||
skybox.emplace(gLightSkyboxDB.getByID(skybox_id).getString(LightSkyboxDB::filename), _context);
|
||||
auto skyboxRec = gLightSkyboxDB.getByID(skybox_id);
|
||||
skybox.emplace(skyboxRec.getString(LightSkyboxDB::filename), _context);
|
||||
skyboxFlags = skyboxRec.getInt(LightSkyboxDB::flags);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
@@ -171,6 +174,7 @@ Sky::Sky(DBCFile::Iterator data, Noggit::NoggitRenderContext context)
|
||||
, _selected(false)
|
||||
{
|
||||
Id = data->getInt(LightDB::ID);
|
||||
mapId = data->getInt(LightDB::Map);
|
||||
pos = glm::vec3(data->getFloat(LightDB::PositionX) / skymul, data->getFloat(LightDB::PositionY) / skymul, data->getFloat(LightDB::PositionZ) / skymul);
|
||||
r1 = data->getFloat(LightDB::RadiusInner) / skymul;
|
||||
r2 = data->getFloat(LightDB::RadiusOuter) / skymul;
|
||||
@@ -194,7 +198,8 @@ Sky::Sky(DBCFile::Iterator data, Noggit::NoggitRenderContext context)
|
||||
float Sky::floatParamFor(int r, int t) const
|
||||
{
|
||||
auto sky_param = skyParams[curr_sky_param];
|
||||
if (sky_param->mmin_float[r]<0)
|
||||
// if (sky_param->mmin_float[r]<0)
|
||||
if (sky_param->floatParams[r].empty())
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
@@ -202,7 +207,7 @@ float Sky::floatParamFor(int r, int t) const
|
||||
int t1, t2;
|
||||
size_t last = sky_param->floatParams[r].size() - 1;
|
||||
|
||||
if (t< sky_param->mmin_float[r])
|
||||
if (t < sky_param->floatParams[r].front().time)
|
||||
{
|
||||
// reverse interpolate
|
||||
c1 = sky_param->floatParams[r][last].value;
|
||||
@@ -242,7 +247,8 @@ float Sky::floatParamFor(int r, int t) const
|
||||
glm::vec3 Sky::colorFor(int r, int t) const
|
||||
{
|
||||
auto sky_param = skyParams[curr_sky_param];
|
||||
if (sky_param->mmin[r]<0)
|
||||
// if (sky_param->mmin[r]<0)
|
||||
if (sky_param->colorRows[r].empty())
|
||||
{
|
||||
return glm::vec3(0, 0, 0);
|
||||
}
|
||||
@@ -260,7 +266,9 @@ glm::vec3 Sky::colorFor(int r, int t) const
|
||||
}
|
||||
else
|
||||
{
|
||||
if (t < sky_param->mmin[r])
|
||||
|
||||
// if (t < sky_param->mmin[r])
|
||||
if (t < sky_param->colorRows[r].front().time)
|
||||
{
|
||||
// reverse interpolate
|
||||
c1 = sky_param->colorRows[r][last].color;
|
||||
@@ -354,6 +362,36 @@ Skies::Skies(unsigned int mapid, Noggit::NoggitRenderContext context)
|
||||
std::sort(skies.begin(), skies.end());
|
||||
}
|
||||
|
||||
Sky* Skies::createNewSky(Sky* old_sky, unsigned int new_id, glm::vec3& pos)
|
||||
{
|
||||
Sky new_sky_copy = *old_sky;
|
||||
new_sky_copy.Id = new_id;
|
||||
new_sky_copy.pos = pos;
|
||||
|
||||
new_sky_copy.weight = 0.f;
|
||||
new_sky_copy.is_new_record = true;
|
||||
|
||||
new_sky_copy.save_to_dbc();
|
||||
|
||||
skies.push_back(new_sky_copy);
|
||||
|
||||
numSkies++;
|
||||
|
||||
// refresh rendering & weights
|
||||
std::sort(skies.begin(), skies.end());
|
||||
force_update();
|
||||
|
||||
for (Sky& sky : skies)
|
||||
{
|
||||
if (sky.Id == new_id)
|
||||
{
|
||||
return &sky;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// returns the global light, not the highest weight
|
||||
Sky* Skies::findSkyWeights(glm::vec3 pos)
|
||||
{
|
||||
Sky* default_sky = nullptr;
|
||||
@@ -404,7 +442,10 @@ Sky* Skies::findClosestSkyByWeight()
|
||||
Sky* closest_sky = &skies[0];
|
||||
for (auto& sky : skies)
|
||||
{
|
||||
if (sky.weight > closest_sky->weight)
|
||||
// use >= to make sure when we have multiple with the same weight,
|
||||
// last one has priority, because it is the closest
|
||||
// skies is sorted by distance to center
|
||||
if (sky.weight > 0.0f && sky.weight >= closest_sky->weight)
|
||||
closest_sky = &sky;
|
||||
}
|
||||
return closest_sky;
|
||||
@@ -442,10 +483,11 @@ void Skies::setCurrentParam(int param_id)
|
||||
|
||||
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 && !_force_update))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_force_update = false;
|
||||
|
||||
Sky* default_sky = findSkyWeights(pos);
|
||||
|
||||
@@ -476,14 +518,14 @@ void Skies::update_sky_colors(glm::vec3 pos, int time)
|
||||
color_set[i] = glm::vec3(1, 1, 1);
|
||||
}
|
||||
|
||||
_fog_multiplier = 0.f;
|
||||
_fog_distance = 0.f;
|
||||
_fog_multiplier = 0.1;
|
||||
_fog_distance = 6500;
|
||||
|
||||
_river_shallow_alpha = 0.f;
|
||||
_river_deep_alpha = 0.f;
|
||||
_ocean_shallow_alpha = 0.f;
|
||||
_ocean_deep_alpha = 0.f;
|
||||
_glow = 0.0f;
|
||||
_river_shallow_alpha = 0.5f;
|
||||
_river_deep_alpha = 1.0f;
|
||||
_ocean_shallow_alpha = 0.75f;
|
||||
_ocean_deep_alpha = 1.0f;
|
||||
_glow = 0.5f;
|
||||
|
||||
}
|
||||
|
||||
@@ -492,7 +534,7 @@ void Skies::update_sky_colors(glm::vec3 pos, int time)
|
||||
{
|
||||
Sky const& sky = skies[j];
|
||||
|
||||
if (sky.weight>0)
|
||||
if (sky.weight > 0.f)
|
||||
{
|
||||
// now calculate the color rows
|
||||
for (int i = 0; i < NUM_SkyColorNames; ++i)
|
||||
@@ -583,16 +625,22 @@ bool Skies::draw(glm::mat4x4 const& model_view
|
||||
}
|
||||
}
|
||||
|
||||
bool has_skybox = false;
|
||||
if (draw_skybox)
|
||||
{
|
||||
bool combine_flag = false;
|
||||
bool has_skybox = false;
|
||||
|
||||
// only draw one skybox model ?
|
||||
for (Sky& sky : skies)
|
||||
{
|
||||
if (sky.weight > 0.f && sky.skybox)
|
||||
if (sky.weight > 0.f && sky.skyParams[sky.curr_sky_param]->skybox)
|
||||
{
|
||||
has_skybox = true;
|
||||
|
||||
auto& model = sky.skybox.value();
|
||||
if ((sky.skyParams[sky.curr_sky_param]->skyboxFlags & LIGHT_SKYBOX_COMBINE))
|
||||
combine_flag = true; // flag 0x2 = still render stars, sun and moons and clouds
|
||||
|
||||
auto& model = sky.skyParams[sky.curr_sky_param]->skybox.value();
|
||||
model.model->trans = sky.weight;
|
||||
model.pos = camera_pos;
|
||||
model.scale = 0.1f;
|
||||
@@ -612,11 +660,17 @@ bool Skies::draw(glm::mat4x4 const& model_view
|
||||
m2_shader.uniform("tex_unit_lookup_2", 0);
|
||||
m2_shader.uniform("pixel_shader", 0);
|
||||
|
||||
// TODO : implement flag LIGHT_SKYBOX_FULL_DAY
|
||||
if ((sky.skyParams[sky.curr_sky_param]->skyboxFlags & LIGHT_SKYBOX_FULL_DAY))
|
||||
{
|
||||
// animtime = ...
|
||||
}
|
||||
|
||||
model.model->renderer()->draw(model_view, model, m2_shader, model_render_state, frustum, 1000000, camera_pos, animtime, display_mode::in_3D);
|
||||
}
|
||||
}
|
||||
// if it's night, draw the stars
|
||||
if (light_stats.nightIntensity > 0 /* && !has_skybox*/)
|
||||
if (light_stats.nightIntensity > 0 && (combine_flag || !has_skybox))
|
||||
{
|
||||
stars.model->trans = light_stats.nightIntensity;
|
||||
stars.pos = camera_pos;
|
||||
@@ -932,44 +986,117 @@ void Sky::save_to_dbc()
|
||||
// find new empty ID : gLightDB.getEmptyRecordID(); .prob do it when creating new light instead.
|
||||
try
|
||||
{
|
||||
DBCFile::Record data = is_new_record ? gLightDB.addRecord(Id) : gLightDB.getByID(Id);
|
||||
// assuming a new unused id is already set with is_new_record
|
||||
DBCFile::Record lightDbRecord = 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);
|
||||
if (is_new_record)
|
||||
lightDbRecord.write(LightDB::Map, mapId);
|
||||
|
||||
lightDbRecord.write(LightDB::PositionX, pos.x * skymul);
|
||||
lightDbRecord.write(LightDB::PositionY, pos.y * skymul);
|
||||
lightDbRecord.write(LightDB::PositionZ, pos.z * skymul);
|
||||
lightDbRecord.write(LightDB::RadiusInner, r1 * skymul);
|
||||
lightDbRecord.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.
|
||||
bool save_param_dbc = false;
|
||||
bool save_colors_dbc = false;
|
||||
bool save_floats_dbc = false;
|
||||
bool save_skybox_dbc = false;
|
||||
|
||||
for (int param_id = 0; param_id < NUM_SkyFloatParamsNames; param_id++)
|
||||
{
|
||||
SkyParam* sky_param = skyParams[param_id];
|
||||
// skip if no param
|
||||
if (skyParams[param_id] == nullptr)
|
||||
if (sky_param == nullptr)
|
||||
continue;
|
||||
|
||||
assert(sky_param->Id > 0);
|
||||
|
||||
lightDbRecord.write(LightDB::DataIDs + param_id, sky_param->Id);
|
||||
|
||||
// if (!sky_param->_need_save && !sky_param->_is_new_param_record)
|
||||
// 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);
|
||||
int lightParam_dbc_id = sky_param->_is_new_param_record ? gLightParamsDB.getEmptyRecordID()
|
||||
: lightDbRecord.getInt(LightDB::DataIDs + param_id);
|
||||
|
||||
if (lightParam_dbc_id == 0)
|
||||
continue;
|
||||
|
||||
// save lightparams.dbc
|
||||
if (sky_param->_need_save || sky_param->_is_new_param_record)
|
||||
{
|
||||
save_param_dbc = true;
|
||||
try
|
||||
{
|
||||
DBCFile::Record light_param = sky_param->_is_new_param_record ? gLightParamsDB.addRecord(lightParam_dbc_id)
|
||||
: gLightParamsDB.getByID(lightParam_dbc_id);
|
||||
|
||||
light_param.write(LightParamsDB::highlightSky, int(sky_param->highlight_sky()));
|
||||
light_param.write(LightParamsDB::water_shallow_alpha, sky_param->river_shallow_alpha());
|
||||
light_param.write(LightParamsDB::water_deep_alpha, sky_param->river_deep_alpha());
|
||||
light_param.write(LightParamsDB::ocean_shallow_alpha, sky_param->ocean_shallow_alpha());
|
||||
light_param.write(LightParamsDB::ocean_deep_alpha, sky_param->ocean_deep_alpha());
|
||||
light_param.write(LightParamsDB::glow, sky_param->glow());
|
||||
|
||||
if (sky_param->skybox.has_value()) // TODO skybox dbc
|
||||
{
|
||||
// try to find an existing record with those params
|
||||
bool exists = false;
|
||||
for (DBCFile::Iterator i = gLightSkyboxDB.begin(); i != gLightSkyboxDB.end(); ++i)
|
||||
{
|
||||
if (i->getString(LightSkyboxDB::filename) == sky_param->skybox.value().model->file_key().filepath()
|
||||
&& i->getInt(LightSkyboxDB::flags) == sky_param->skyboxFlags)
|
||||
{
|
||||
int id = i->getInt(LightSkyboxDB::ID);
|
||||
light_param.write(LightParamsDB::skybox, id);
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!exists) // doesn't exist, create a new record
|
||||
{
|
||||
int new_skybox_dbc_id = gLightSkyboxDB.getEmptyRecordID();
|
||||
DBCFile::Record rec = gLightSkyboxDB.addRecord(new_skybox_dbc_id);
|
||||
rec.writeString(LightSkyboxDB::filename, sky_param->skybox.value().model->file_key().filepath());
|
||||
rec.write(LightSkyboxDB::flags, sky_param->skyboxFlags);
|
||||
|
||||
gLightSkyboxDB.save();
|
||||
|
||||
light_param.write(LightParamsDB::skybox, new_skybox_dbc_id);
|
||||
}
|
||||
}
|
||||
else
|
||||
light_param.write(LightParamsDB::skybox, 0);
|
||||
}
|
||||
catch (DBCFile::NotFound)
|
||||
{
|
||||
assert(false);
|
||||
LogError << "When trying to get the lightparams for the entry " << lightParam_dbc_id << " in LightParams.dbc" << std::endl;
|
||||
|
||||
// failsafe, don't point to new id that couldn't be created
|
||||
if (sky_param->_is_new_param_record)
|
||||
lightDbRecord.write(LightDB::DataIDs + param_id, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// save LightIntBand.dbc
|
||||
if (sky_param->_colors_need_save || sky_param->_is_new_param_record)
|
||||
{
|
||||
save_colors_dbc = true;
|
||||
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);
|
||||
DBCFile::Record rec = sky_param->_is_new_param_record ? gLightIntBandDB.addRecord(light_int_start + i)
|
||||
: gLightIntBandDB.getByID(light_int_start + i);
|
||||
// int entries = rec.getInt(LightIntBandDB::Entries);
|
||||
int entries = static_cast<int>(skyParams[param_id]->colorRows[i].size());
|
||||
int entries = static_cast<int>(sky_param->colorRows[i].size());
|
||||
|
||||
rec.write(LightIntBandDB::Entries, entries); // nb of entries
|
||||
|
||||
@@ -982,29 +1109,36 @@ void Sky::save_to_dbc()
|
||||
}
|
||||
else
|
||||
{
|
||||
rec.write(LightIntBandDB::Times + l, skyParams[param_id]->colorRows[i][l].time);
|
||||
rec.write(LightIntBandDB::Times + l, sky_param->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);
|
||||
int rebuilt_color_int = static_cast<int>(sky_param->colorRows[i][l].color.z * 255.0f)
|
||||
+ (static_cast<int>(sky_param->colorRows[i][l].color.y * 255.0f) << 8)
|
||||
+ (static_cast<int>(sky_param->colorRows[i][l].color.x * 255.0f) << 16);
|
||||
rec.write(LightIntBandDB::Values + l, rebuilt_color_int);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
assert(false);
|
||||
LogError << "When trying to save sky colors, sky id : " << data.getInt(LightDB::ID) << std::endl;
|
||||
LogError << "When trying to save sky colors, sky id : " << lightDbRecord.getInt(LightDB::ID) << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// save LightFloatBand.dbc
|
||||
if (sky_param->_floats_need_save || sky_param->_is_new_param_record)
|
||||
{
|
||||
save_floats_dbc = true;
|
||||
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);
|
||||
DBCFile::Record rec = sky_param->_is_new_param_record ? gLightFloatBandDB.addRecord(light_float_start + i)
|
||||
: gLightFloatBandDB.getByID(light_float_start + i);
|
||||
int entries = static_cast<int>(skyParams[param_id]->floatParams[i].size());
|
||||
|
||||
rec.write(LightFloatBandDB::Entries, entries); // nb of entries
|
||||
@@ -1023,45 +1157,26 @@ void Sky::save_to_dbc()
|
||||
rec.write(LightFloatBandDB::Values + l, skyParams[param_id]->floatParams[i][l].value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LogError << "Error when trying to save sky float params, sky id : " << data.getInt(LightDB::ID) << std::endl;
|
||||
LogError << "Error when trying to save sky float params, sky id : " << lightDbRecord.getInt(LightDB::ID) << 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 (DBCFile::NotFound)
|
||||
{
|
||||
assert(false);
|
||||
LogError << "When trying to get the lightparams for the entry " << lightParam_dbc_id << " in LightParams.dbc" << std::endl;
|
||||
}
|
||||
sky_param->_need_save = false;
|
||||
sky_param->_is_new_param_record = false;
|
||||
}
|
||||
|
||||
gLightDB.save();
|
||||
if (save_colors_dbc)
|
||||
gLightIntBandDB.save();
|
||||
if (save_colors_dbc)
|
||||
gLightFloatBandDB.save();
|
||||
if (save_param_dbc)
|
||||
gLightParamsDB.save();
|
||||
gLightSkyboxDB.save();
|
||||
|
||||
// emit map_dbc_updated();
|
||||
|
||||
is_new_record = false;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ enum SkyFloatParamsNames
|
||||
{
|
||||
SKY_FOG_DISTANCE,
|
||||
SKY_FOG_MULTIPLIER,
|
||||
SKY_CELESTIAL_FLOW,
|
||||
SKY_CELESTIAL_GLOW,
|
||||
SKY_CLOUD_DENSITY,
|
||||
SKY_UNK_FLOAT_PARAM_4,
|
||||
SKY_UNK_FLOAT_PARAM_5,
|
||||
@@ -59,6 +59,17 @@ enum SkyParamsNames
|
||||
NUM_SkyParamsNames
|
||||
};
|
||||
|
||||
enum SkyModelSkyBoxFlags
|
||||
{
|
||||
LIGHT_SKYBOX_FULL_DAY = 0x1, // Full day Skybox: animation syncs with time of day (uses animation 0, time of day is just in percentage).
|
||||
LIGHT_SKYBOX_COMBINE = 0x2, // Combine Procedural And Skybox : render stars, sun and moons and clouds as well
|
||||
/*
|
||||
0x04 Procedural Fog Color Blend
|
||||
0x08 Force Sun-shafts
|
||||
0x10 Disable use Sun Fog Color
|
||||
*/
|
||||
};
|
||||
|
||||
struct OutdoorLightStats
|
||||
{
|
||||
float nightIntensity;
|
||||
@@ -161,19 +172,40 @@ struct SkyFloatParam
|
||||
int time;
|
||||
};
|
||||
|
||||
// modern LightData.db
|
||||
// unified timestamps for float and int data
|
||||
struct LightData
|
||||
{
|
||||
LightData(int paramId);
|
||||
|
||||
unsigned int paramId;
|
||||
unsigned int time = 0;
|
||||
glm::vec3 colorRows[NUM_SkyColorNames] = {};
|
||||
float floatParams[NUM_SkyParamsNames] = {};
|
||||
};
|
||||
|
||||
class SkyParam
|
||||
{
|
||||
public:
|
||||
std::optional<ModelInstance> skybox;
|
||||
int skyboxFlags = 0;
|
||||
|
||||
int Id;
|
||||
|
||||
SkyParam() = default;
|
||||
explicit SkyParam(int paramId, Noggit::NoggitRenderContext context);
|
||||
|
||||
std::vector<SkyColor> colorRows[NUM_SkyColorNames]; // [NUM_SkyColorNames] // 36
|
||||
//array of 18 vectors(for each color), each vector item is a time/value
|
||||
std::vector<SkyColor> colorRows[NUM_SkyColorNames];
|
||||
std::vector<SkyFloatParam> floatParams[NUM_SkyFloatParamsNames];
|
||||
int mmin[NUM_SkyColorNames]; // [NUM_SkyColorNames] // 36
|
||||
int mmin_float[NUM_SkyFloatParamsNames];
|
||||
|
||||
// first/min time value for each entry
|
||||
// titi : deprecated those and replaced it by checking the time value of the first vector element
|
||||
// int mmin[NUM_SkyColorNames];
|
||||
// int mmin_float[NUM_SkyFloatParamsNames];
|
||||
|
||||
// potential structure rework, more similar to retail/classic LightData.db
|
||||
// std::vector<LightData> lightData;
|
||||
|
||||
bool highlight_sky() const { return _highlight_sky; }
|
||||
float river_shallow_alpha() const { return _river_shallow_alpha; }
|
||||
@@ -189,6 +221,13 @@ public:
|
||||
void set_ocean_shallow_alpha(float alpha) { _ocean_shallow_alpha = alpha; }
|
||||
void set_ocean_deep_alpha(float alpha) { _ocean_deep_alpha = alpha; }
|
||||
|
||||
// always save them for now
|
||||
// later we can have a system to only save modified dbcs
|
||||
bool _need_save = true;
|
||||
bool _colors_need_save = true;
|
||||
bool _floats_need_save = true;
|
||||
bool _is_new_param_record = false;
|
||||
|
||||
private: // most common settings
|
||||
bool _highlight_sky = false;
|
||||
float _river_shallow_alpha = 0.5f;
|
||||
@@ -203,9 +242,11 @@ private: // most common settings
|
||||
class Sky
|
||||
{
|
||||
public:
|
||||
std::optional<ModelInstance> skybox;
|
||||
// std::optional<ModelInstance> skybox;
|
||||
|
||||
int Id;
|
||||
int mapId; // just for saving...
|
||||
|
||||
glm::vec3 pos = glm::vec3(0, 0, 0);
|
||||
float r1 = 0.f, r2 = 0.f;
|
||||
|
||||
@@ -214,7 +255,7 @@ public:
|
||||
SkyParam* skyParams[NUM_SkyParamsNames];
|
||||
int curr_sky_param = SKY_PARAM_CLEAR;
|
||||
|
||||
// std::string name;
|
||||
std::string name;
|
||||
|
||||
glm::vec3 colorFor(int r, int t) const;
|
||||
float floatParamFor(int r, int t) const;
|
||||
@@ -250,6 +291,7 @@ private:
|
||||
int cs = -1;
|
||||
ModelInstance stars;
|
||||
|
||||
bool _force_update = true;
|
||||
int _last_time = -1;
|
||||
glm::vec3 _last_pos;
|
||||
|
||||
@@ -271,6 +313,8 @@ public:
|
||||
|
||||
explicit Skies(unsigned int mapid, Noggit::NoggitRenderContext context);
|
||||
|
||||
Sky* createNewSky(Sky* old_sky, unsigned int new_id, glm::vec3& pos);
|
||||
|
||||
Sky* findSkyWeights(glm::vec3 pos);
|
||||
|
||||
Sky* findClosestSkyByWeight();
|
||||
@@ -323,6 +367,8 @@ public:
|
||||
|
||||
void unload();
|
||||
|
||||
void force_update() { _force_update = true; }
|
||||
|
||||
private:
|
||||
bool _uploaded = false;
|
||||
bool _need_color_buffer_update = true;
|
||||
|
||||
@@ -1038,7 +1038,8 @@ void WorldRender::draw (glm::mat4x4 const& model_view
|
||||
|
||||
if (terrainMode == editing_mode::light)
|
||||
{
|
||||
Sky* CurrentSky = skies()->findClosestSkyByDistance(camera_pos);
|
||||
// Sky* CurrentSky = skies()->findClosestSkyByDistance(camera_pos);
|
||||
Sky* CurrentSky = skies()->findClosestSkyByWeight();
|
||||
if (!CurrentSky)
|
||||
return;
|
||||
|
||||
@@ -1048,14 +1049,18 @@ void WorldRender::draw (glm::mat4x4 const& model_view
|
||||
const int CurrenTime = static_cast<int>(_world->time) % MAX_TIME_VALUE_C;
|
||||
|
||||
glCullFace(GL_FRONT);
|
||||
if (!draw_only_inside_light_sphere)
|
||||
{
|
||||
for (Sky& sky : skies()->skies)
|
||||
{
|
||||
if (CurrentSkyID > 1 && draw_only_inside_light_sphere)
|
||||
break;
|
||||
|
||||
// we draw the current sky below with glCullFace(GL_BACK);
|
||||
if (CurrentSkyID == sky.Id)
|
||||
continue;
|
||||
|
||||
if (sky.global)
|
||||
continue;
|
||||
|
||||
if (glm::distance(sky.pos, camera_pos) <= _cull_distance) // TODO: frustum cull here
|
||||
{
|
||||
glm::vec4 diffuse = { sky.colorFor(LIGHT_GLOBAL_DIFFUSE, CurrenTime), 1.f };
|
||||
@@ -1063,17 +1068,32 @@ void WorldRender::draw (glm::mat4x4 const& model_view
|
||||
|
||||
_sphere_render.draw(mvp, sky.pos, ambient, sky.r1, 32, 18, alpha_light_sphere, false, draw_wireframe_light_sphere);
|
||||
_sphere_render.draw(mvp, sky.pos, diffuse, sky.r2, 32, 18, alpha_light_sphere, false, draw_wireframe_light_sphere);
|
||||
|
||||
// TODO Those lines tank fps by 50%
|
||||
// std::vector<glm::vec3> linePoints;
|
||||
// linePoints.push_back(glm::vec3(sky.pos.x, sky.pos.y, sky.pos.z - sky.r2));
|
||||
// linePoints.push_back(glm::vec3(sky.pos.x, sky.pos.y, sky.pos.z + sky.r2));
|
||||
// _line_render.draw(mvp, linePoints, glm::vec4(1.f), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glCullFace(GL_BACK);
|
||||
if (CurrentSky && draw_only_inside_light_sphere)
|
||||
if (CurrentSky && !CurrentSky->global)
|
||||
{
|
||||
glm::vec4 diffuse = { CurrentSky->colorFor(LIGHT_GLOBAL_DIFFUSE, CurrenTime), 1.f };
|
||||
glm::vec4 ambient = { CurrentSky->colorFor(LIGHT_GLOBAL_AMBIENT, CurrenTime), 1.f };
|
||||
|
||||
_sphere_render.draw(mvp, CurrentSky->pos, ambient, CurrentSky->r1, 32, 18, alpha_light_sphere, false, draw_wireframe_light_sphere);
|
||||
_sphere_render.draw(mvp, CurrentSky->pos, diffuse, CurrentSky->r2, 32, 18, alpha_light_sphere, false, draw_wireframe_light_sphere);
|
||||
// always render wireframe in the current light
|
||||
// need to render outer first or it gets culled
|
||||
_sphere_render.draw(mvp, CurrentSky->pos, diffuse, CurrentSky->r2, 32, 18, alpha_light_sphere, false, true);
|
||||
_sphere_render.draw(mvp, CurrentSky->pos, ambient, CurrentSky->r1, 32, 18, alpha_light_sphere, false, true);
|
||||
|
||||
|
||||
// std::vector<glm::vec3> linePoints;
|
||||
// linePoints.push_back(glm::vec3(CurrentSky->pos.x, CurrentSky->pos.z, CurrentSky->pos.y - CurrentSky->r2));
|
||||
// linePoints.push_back(glm::vec3(CurrentSky->pos.x, CurrentSky->pos.z, CurrentSky->pos.y + CurrentSky->r2));
|
||||
// _line_render.draw(mvp, linePoints, glm::vec4(1.f, 0.f, 0.f, 1.f), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,34 +23,28 @@ LightEditor::LightEditor(MapView* map_view, QWidget* parent)
|
||||
, _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));
|
||||
auto layout = new QVBoxLayout(this);
|
||||
layout->setAlignment(Qt::AlignTop);
|
||||
|
||||
|
||||
|
||||
auto lightning_tabs = new QTabWidget(this);
|
||||
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 select tab
|
||||
auto light_selection_widget = new QWidget(lightning_tabs);
|
||||
auto light_selection_layout = new QVBoxLayout(light_selection_widget);
|
||||
light_selection_layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
lightning_tabs->addTab(light_selection_widget, "Light Selection");
|
||||
|
||||
// light edit tab
|
||||
_light_editing_widget = new QWidget(lightning_tabs);
|
||||
_light_editing_widget->setEnabled(false);
|
||||
auto light_editing_layout = new QVBoxLayout(_light_editing_widget);
|
||||
light_editing_layout->setContentsMargins(0, 0, 0, 0);
|
||||
lightning_tabs->addTab(_light_editing_widget, "Edit Light");
|
||||
|
||||
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));
|
||||
@@ -58,129 +52,163 @@ LightEditor::LightEditor(MapView* map_view, QWidget* parent)
|
||||
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_dial->setSliderPosition((int)_world->time); // to get ingame orientation
|
||||
// time_value0_dial->setValue(color0.time);
|
||||
time_dial->setInvertedAppearance(false); // sets the position at top
|
||||
time_dial->setInvertedAppearance(true); // sets the position at top
|
||||
time_dial->setToolTip("Time (24hours)");
|
||||
time_dial->setSingleStep(360); // ticks are 360 units
|
||||
time_dial->setSingleStep(360); // ticks are 360 units (1/8 = 3 hours)
|
||||
|
||||
QPushButton* GetCurrentSkyButton = new QPushButton("Edit current light", this);
|
||||
QPushButton* GetCurrentSkyButton = new QPushButton("Edit current position's light", this);
|
||||
GetCurrentSkyButton->setToolTip("Selection the highest weight light at camera's position");
|
||||
GetCurrentSkyButton->setIcon(Noggit::Ui::FontAwesomeIcon(Noggit::Ui::FontAwesome::cog));
|
||||
light_selection_layout->addWidget(GetCurrentSkyButton);
|
||||
|
||||
|
||||
light_selection_layout->addWidget(new QLabel("Current Map Lights :", this));
|
||||
|
||||
_light_tree = new QTreeWidget();
|
||||
_light_tree = new QListWidget(this);
|
||||
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
|
||||
// _light_tree->setWindowTitle("Current map lights");
|
||||
_light_tree->setViewMode(QListView::ListMode);
|
||||
_light_tree->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
_light_tree->setSelectionBehavior(QAbstractItemView::SelectItems);
|
||||
_light_tree->setFixedHeight(580);
|
||||
_light_tree->setUniformItemSizes(true);
|
||||
|
||||
// for (auto& sky : _world->renderer()->skies()->skies) // bad idea, renderer needs to be loaded first
|
||||
// for (auto& sky : _world->renderer()->skies()->skies) // 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();
|
||||
QListWidgetItem* item = new QListWidgetItem();
|
||||
|
||||
std::stringstream ss;
|
||||
auto light_id = i->getUInt(LightDB::ID);
|
||||
item->setData(0, 0, QVariant(light_id) );
|
||||
unsigned int light_id = i->getUInt(LightDB::ID);
|
||||
item->setData(Qt::UserRole + 1, QVariant(light_id) ); // when setting an icon (global light), it uses role 1
|
||||
|
||||
bool global = (i->getFloat(LightDB::PositionX) == 0.0f && i->getFloat(LightDB::PositionY) == 0.0f
|
||||
&& i->getFloat(LightDB::PositionZ) == 0.0f);
|
||||
|
||||
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)
|
||||
else if (global)
|
||||
light_name = "Global Light";
|
||||
|
||||
if (global)
|
||||
{
|
||||
item->setIcon(Noggit::Ui::FontAwesomeIcon(Noggit::Ui::FontAwesome::sun));
|
||||
}
|
||||
|
||||
ss << i->getUInt(LightDB::ID) << "-" << light_name;// gAreaDB.getAreaName(area_id);
|
||||
item->setText(0, QString(ss.str().c_str()));// TODO : light names
|
||||
item->setText(QString(ss.str().c_str()));// TODO : light names
|
||||
// if (global)
|
||||
_light_tree->addTopLevelItem(item);
|
||||
_light_tree->addItem(item);
|
||||
|
||||
if (global)
|
||||
{
|
||||
_light_tree->setItemSelected(item, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QPushButton* GetSelectedSkyButton = new QPushButton("Edit selected light", this);
|
||||
GetSelectedSkyButton->setIcon(Noggit::Ui::FontAwesomeIcon(Noggit::Ui::FontAwesome::cog));
|
||||
light_selection_layout->addWidget(GetSelectedSkyButton);
|
||||
|
||||
QPushButton* addNewSkyButton = new QPushButton("(IN DEV) Duplicate selected(create new)", this);
|
||||
addNewSkyButton->setIcon(Noggit::Ui::FontAwesomeIcon(Noggit::Ui::FontAwesome::plus));
|
||||
light_selection_layout->addWidget(addNewSkyButton);
|
||||
|
||||
QPushButton* deleteSkyButton = new QPushButton("(IN DEV) delete light", this);
|
||||
deleteSkyButton->setIcon(Noggit::Ui::FontAwesomeIcon(Noggit::Ui::FontAwesome::times));
|
||||
light_selection_layout->addWidget(deleteSkyButton);
|
||||
|
||||
QPushButton* portToSkyButton = new QPushButton("(IN DEV) port to light", this);
|
||||
portToSkyButton->setIcon(Noggit::Ui::FontAwesomeIcon(Noggit::Ui::FontAwesome::running));
|
||||
light_selection_layout->addWidget(portToSkyButton);
|
||||
|
||||
light_selection_layout->addStretch(); // Add a stretch to prevent expansion
|
||||
|
||||
// global settings ********************************************************************************************** //
|
||||
// TODO : name lights on laoding instead
|
||||
light_editing_layout->addWidget(new QLabel("Selected Light :", this), 0);
|
||||
auto lightid_label = new QLabel("No light selected", this);
|
||||
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);
|
||||
save_current_sky_button = new QPushButton("Save Light(Write DBCs)", this);
|
||||
save_current_sky_button->setEnabled(false);
|
||||
light_editing_layout->addWidget(save_current_sky_button);
|
||||
|
||||
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);
|
||||
// auto global_values_layout = new QGridLayout(global_values_group);
|
||||
auto global_values_layout = new QFormLayout(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);
|
||||
name_line_edit = new QLineEdit(this);
|
||||
name_line_edit->setDisabled(true);
|
||||
global_values_layout->addRow("Name:", name_line_edit);
|
||||
|
||||
global_values_layout->addWidget(new QLabel("Position X:", this),1,0);
|
||||
auto pos_x_spin = new QDoubleSpinBox(this);
|
||||
global_light_chk = new QCheckBox("Global Light", this);
|
||||
global_light_chk->setToolTip("The map's global light will be used when the player isn't within any other light radius.");
|
||||
global_light_chk->setDisabled(true);
|
||||
global_values_layout->addRow(global_light_chk);
|
||||
|
||||
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->addRow("Position X:", pos_x_spin);
|
||||
|
||||
global_values_layout->addWidget(new QLabel("Position Y:", this),2,0);
|
||||
auto pos_y_spin = new QDoubleSpinBox(this);
|
||||
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->addRow("Position Y:", pos_y_spin);
|
||||
|
||||
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 = new QDoubleSpinBox(this);
|
||||
pos_z_spin->setRange(-17066.66656 * 2, 17066.66656*2); // ???? highest seen in 3.3.5 is 33,360
|
||||
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->addRow("Position Z:", pos_z_spin);
|
||||
|
||||
global_values_layout->addWidget(new QLabel("Inner Radius:", this),4,0);
|
||||
auto inner_radius_spin = new QDoubleSpinBox(this);
|
||||
inner_radius_spin = new QDoubleSpinBox(this);
|
||||
inner_radius_spin->setRange(0, 100000); // max seen in dbc is 3871 (139363 <20>E36 )
|
||||
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->addRow("Inner Radius:", inner_radius_spin);
|
||||
|
||||
global_values_layout->addWidget(new QLabel("Outer Radius:", this),5,0);
|
||||
auto outer_radius_spin = new QDoubleSpinBox(this);
|
||||
outer_radius_spin = new QDoubleSpinBox(this);
|
||||
outer_radius_spin->setRange(0, 100000); // max seen in dbc is 3871 (139363 <20>E36 )
|
||||
outer_radius_spin->setValue(0);
|
||||
outer_radius_spin->setSingleStep(50);
|
||||
outer_radius_spin->setEnabled(false);
|
||||
global_values_layout->addWidget(outer_radius_spin,5,1);
|
||||
global_values_layout->addRow("Outer Radius:", outer_radius_spin);
|
||||
|
||||
light_editing_layout->addWidget(global_values_group);
|
||||
|
||||
// BELOW IS PARAM SPECIFIC SETTINGS
|
||||
auto warning_label = new QLabel("Warning : Can't currently change param id,\n changes will affect all users of this param");
|
||||
warning_label->setStyleSheet("QLabel { color : orange; }");
|
||||
light_editing_layout->addWidget(warning_label);
|
||||
|
||||
light_editing_layout->addWidget(new QLabel("Param Type :", this));
|
||||
param_combobox = new QComboBox(this);
|
||||
param_combobox->setEnabled(false);
|
||||
light_editing_layout->addWidget(param_combobox);
|
||||
// NUM_SkyParamsNames
|
||||
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];
|
||||
// }
|
||||
param_combobox->addItem("unknown param 1");
|
||||
param_combobox->addItem("unknown param 2");
|
||||
param_combobox->addItem("unknown param 3");
|
||||
|
||||
QGroupBox* light_param_group = new QGroupBox("Light Params", this);
|
||||
light_editing_layout->addWidget(light_param_group);
|
||||
@@ -198,7 +226,7 @@ LightEditor::LightEditor(MapView* map_view, QWidget* parent)
|
||||
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->setValue(50);
|
||||
glow_slider->setEnabled(false);
|
||||
param_grid_layout->addWidget(glow_slider,0,1);
|
||||
|
||||
@@ -213,6 +241,18 @@ LightEditor::LightEditor(MapView* map_view, QWidget* parent)
|
||||
skybox_model_lineedit->setEnabled(false);
|
||||
param_grid_layout->addWidget(skybox_model_lineedit, 2, 1);
|
||||
|
||||
skybox_flag_1 = new QCheckBox("Full day Skybox", this);
|
||||
skybox_flag_1->setCheckState(Qt::Unchecked);
|
||||
skybox_flag_1->setEnabled(false);
|
||||
skybox_flag_1->setToolTip("animation syncs with time of day (uses animation 0, time of day is just in percentage).");
|
||||
param_grid_layout->addWidget(skybox_flag_1, 3, 0, 1, 2);
|
||||
skybox_flag_2 = new QCheckBox("Combine Procedural And Skybox", this);
|
||||
skybox_flag_2->setCheckState(Qt::Unchecked);
|
||||
skybox_flag_2->setEnabled(false);
|
||||
skybox_flag_2->setToolTip("render stars, sun and moons and clouds as well.");
|
||||
param_grid_layout->addWidget(skybox_flag_2, 4, 0, 1, 2);
|
||||
|
||||
|
||||
// Alpha values ********************************************************************************************** //
|
||||
|
||||
QGroupBox* alpha_values_group = new QGroupBox("Alpha Values", light_param_group);
|
||||
@@ -268,10 +308,15 @@ LightEditor::LightEditor(MapView* map_view, QWidget* parent)
|
||||
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));
|
||||
QSize(180, LIGHT_VIEW_PREVIEW_HEIGHT));
|
||||
LightsPreview.push_back(LightPrev);
|
||||
color_values_layout->addWidget(LightPrev, i, 0);
|
||||
|
||||
int availableWidth = color_values_group->width() - color_values_layout->contentsMargins().left()
|
||||
- color_values_layout->contentsMargins().right() - color_values_layout->spacing();
|
||||
int test_suggestedWidth = LightPrev->sizeHint().width();
|
||||
int test_suggestedWidth2 = LightPrev->minimumSizeHint().width();
|
||||
|
||||
connect(LightPrev, &LightViewPreview::LeftClicked, [this, i, LightPrev]()
|
||||
{
|
||||
if (!_curr_sky)
|
||||
@@ -303,23 +348,291 @@ LightEditor::LightEditor(MapView* map_view, QWidget* parent)
|
||||
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);
|
||||
_world->renderer()->skies()->force_update();
|
||||
UpdateWorldTime();
|
||||
}
|
||||
);
|
||||
|
||||
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)
|
||||
// Sky* new_sky = _map_view->getWorld()->renderer()->skies()->findSkyWeights(map_view->getCamera()->position); // this just returns the global sky
|
||||
// Sky* new_sky = _map_view->getWorld()->renderer()->skies()->findClosestSkyByDistance(map_view->getCamera()->position);
|
||||
Sky* new_sky = _map_view->getWorld()->renderer()->skies()->findClosestSkyByWeight();
|
||||
if (new_sky == nullptr)
|
||||
return; // todo error
|
||||
else
|
||||
_curr_sky = new_sky;
|
||||
{
|
||||
loadSelectSky(new_sky);
|
||||
}
|
||||
});
|
||||
|
||||
light_editing_widget->setEnabled(true);
|
||||
lightning_tabs->setCurrentWidget(light_editing_widget);
|
||||
|
||||
SaveCurrentSkyButton->setEnabled(true);
|
||||
|
||||
connect(GetSelectedSkyButton, &QPushButton::clicked, [=]() {
|
||||
|
||||
auto const& selected_items = _light_tree->selectedItems();
|
||||
if (selected_items.size())
|
||||
{
|
||||
unsigned int selected_light_id = selected_items.back()->data(Qt::UserRole + 1).toUInt();
|
||||
|
||||
for (Sky& sky : _map_view->getWorld()->renderer()->skies()->skies)
|
||||
{
|
||||
if (sky.Id == selected_light_id)
|
||||
{
|
||||
loadSelectSky(&sky);
|
||||
|
||||
// TODO : load tile and teleport where the light is at
|
||||
//
|
||||
// _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 : initialize
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
connect(_light_tree, &QListWidget::itemDoubleClicked, this, [=](QListWidgetItem* item)
|
||||
{
|
||||
unsigned int selected_light_id = item->data(Qt::UserRole + 1).toUInt();
|
||||
|
||||
for (Sky& sky : _map_view->getWorld()->renderer()->skies()->skies)
|
||||
{
|
||||
if (sky.Id == selected_light_id)
|
||||
{
|
||||
loadSelectSky(&sky);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
connect(addNewSkyButton, &QPushButton::clicked, [=]() {
|
||||
|
||||
// TODO. when there is no light to duplicate we need create new function
|
||||
|
||||
// _world->getRenderContext();
|
||||
|
||||
// get selected sky to duplicate
|
||||
Sky* old_sky = nullptr;
|
||||
|
||||
std::string old_name = "";
|
||||
|
||||
auto const& selected_items = _light_tree->selectedItems();
|
||||
if (selected_items.size())
|
||||
{
|
||||
old_name = selected_items.back()->text().toStdString();
|
||||
unsigned int selected_light_id = selected_items.back()->data(Qt::UserRole + 1).toUInt();
|
||||
|
||||
for (Sky& sky : _map_view->getWorld()->renderer()->skies()->skies)
|
||||
{
|
||||
if (sky.Id == selected_light_id)
|
||||
{
|
||||
old_sky = &sky;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (old_sky == nullptr)
|
||||
return;
|
||||
|
||||
if (old_sky->global)
|
||||
{
|
||||
QMessageBox::warning
|
||||
(nullptr
|
||||
, "Error"
|
||||
, "You cannot duplicate a Global light. "
|
||||
"There can only be one global light per map."
|
||||
, QMessageBox::Ok
|
||||
);
|
||||
}
|
||||
|
||||
unsigned int new_light_id = gLightDB.getEmptyRecordID(LightDB::ID);
|
||||
|
||||
// create new sky entry (duplicate)
|
||||
Sky* new_sky = _map_view->getWorld()->renderer()->skies()->createNewSky(old_sky, new_light_id, _map_view->getCamera()->position);
|
||||
|
||||
// add new item to tree
|
||||
{
|
||||
QListWidgetItem* item = new QListWidgetItem();
|
||||
|
||||
std::stringstream ss;
|
||||
item->setData(Qt::UserRole + 1, QVariant(new_light_id)); // when setting an icon (global light), it uses role 1
|
||||
|
||||
std::string new_light_name = "Noggit Copy of " + old_name;
|
||||
|
||||
ss << new_light_id << "-" << new_light_name;
|
||||
item->setText(QString(ss.str().c_str()));
|
||||
|
||||
_light_tree->addItem(item);
|
||||
|
||||
_light_tree->setCurrentItem(item);
|
||||
_light_tree->scrollToItem(item);
|
||||
}
|
||||
|
||||
// loadSelectSky(new_sky);
|
||||
|
||||
});
|
||||
|
||||
connect(deleteSkyButton, &QPushButton::clicked, [=]() {
|
||||
|
||||
});
|
||||
|
||||
connect(portToSkyButton, &QPushButton::clicked, [=]() {
|
||||
|
||||
});
|
||||
|
||||
connect(param_combobox, qOverload<int>(&QComboBox::currentIndexChanged), [this](int index) {
|
||||
|
||||
// update rendering to selected param
|
||||
if (!_curr_sky)
|
||||
{
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_curr_sky->skyParams[index])
|
||||
return;
|
||||
|
||||
_curr_sky->curr_sky_param = index;
|
||||
_world->renderer()->skies()->force_update();
|
||||
|
||||
load_light_param(index);
|
||||
|
||||
});
|
||||
|
||||
connect(save_current_sky_button, &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()->force_update();
|
||||
});
|
||||
|
||||
connect(pos_y_spin, qOverload<double>(&QDoubleSpinBox::valueChanged), [&](double v) {
|
||||
_curr_sky->pos.z = v; // pos_y_spin->value();
|
||||
_world->renderer()->skies()->force_update();
|
||||
});
|
||||
|
||||
connect(pos_z_spin, qOverload<double>(&QDoubleSpinBox::valueChanged), [&](double v) {
|
||||
_curr_sky->pos.y = v; // pos_z_spin->value();
|
||||
_world->renderer()->skies()->force_update();
|
||||
});
|
||||
|
||||
connect(inner_radius_spin, qOverload<double>(&QDoubleSpinBox::valueChanged), [&](double v) {
|
||||
_curr_sky->r1 = v; // inner_radius_spin->value();
|
||||
_world->renderer()->skies()->force_update();
|
||||
});
|
||||
|
||||
connect(outer_radius_spin, qOverload<double>(&QDoubleSpinBox::valueChanged), [&](double v) {
|
||||
_curr_sky->r2 = v; // outer_radius_spin->value();
|
||||
_world->renderer()->skies()->force_update();
|
||||
});
|
||||
|
||||
connect(glow_slider, &QSlider::valueChanged, [&](int v) {
|
||||
_curr_sky->skyParams[param_combobox->currentIndex()]->set_glow(v / 100);
|
||||
_world->renderer()->skies()->force_update();
|
||||
});
|
||||
|
||||
connect(highlight_sky_checkbox, &QCheckBox::stateChanged, [&](int state) {
|
||||
_curr_sky->skyParams[param_combobox->currentIndex()]->set_highlight_sky(state);
|
||||
_world->renderer()->skies()->force_update();
|
||||
});
|
||||
|
||||
connect(shallow_water_alpha_slider, &QSlider::valueChanged, [&](int v) {
|
||||
_curr_sky->skyParams[param_combobox->currentIndex()]->set_river_shallow_alpha(v / 100);
|
||||
_world->renderer()->skies()->force_update();
|
||||
});
|
||||
|
||||
connect(deep_water_alpha_slider, &QSlider::valueChanged, [&](int v) {
|
||||
_curr_sky->skyParams[param_combobox->currentIndex()]->set_river_deep_alpha(v / 100);
|
||||
_world->renderer()->skies()->force_update();
|
||||
});
|
||||
|
||||
connect(shallow_ocean_alpha_slider, &QSlider::valueChanged, [&](int v) {
|
||||
_curr_sky->skyParams[param_combobox->currentIndex()]->set_ocean_shallow_alpha(v / 100);
|
||||
_world->renderer()->skies()->force_update();
|
||||
});
|
||||
|
||||
connect(deep_ocean_alpha_slider, &QSlider::valueChanged, [&](int v) {
|
||||
_curr_sky->skyParams[param_combobox->currentIndex()]->set_ocean_deep_alpha(v / 100);
|
||||
_world->renderer()->skies()->force_update();
|
||||
});
|
||||
|
||||
// connect(skybox_model_lineedit, &QLineEdit::textChanged, [&](std::string v) {
|
||||
QLineEdit::connect(skybox_model_lineedit, &QLineEdit::textChanged
|
||||
, [=]
|
||||
{
|
||||
auto text = skybox_model_lineedit->text().toStdString();
|
||||
if (text.empty())
|
||||
_curr_sky->skyParams[param_combobox->currentIndex()]->skybox.reset();
|
||||
else
|
||||
_curr_sky->skyParams[param_combobox->currentIndex()]->skybox.emplace(text.c_str(), _world->getRenderContext());
|
||||
|
||||
_world->renderer()->skies()->force_update();
|
||||
});
|
||||
|
||||
connect(skybox_flag_1, &QCheckBox::stateChanged, [&](int state) {
|
||||
if (state) // set bit
|
||||
_curr_sky->skyParams[param_combobox->currentIndex()]->skyboxFlags |= (1 << (0));
|
||||
else // remove bit
|
||||
_curr_sky->skyParams[param_combobox->currentIndex()]->skyboxFlags &= ~(1 << (0));
|
||||
});
|
||||
|
||||
connect(skybox_flag_2, &QCheckBox::stateChanged, [&](int state) {
|
||||
if (state) // set bit
|
||||
_curr_sky->skyParams[param_combobox->currentIndex()]->skyboxFlags |= (1 << (1));
|
||||
else // remove bit
|
||||
_curr_sky->skyParams[param_combobox->currentIndex()]->skyboxFlags &= ~(1 << (1));
|
||||
});
|
||||
|
||||
// connect(floats_editor_button, &QPushButton::clicked, [=]() {
|
||||
// LightFloatsEditor * Editor = new LightFloatsEditor(_map_view, _curr_sky->skyParams[param_combobox->currentIndex()], this);
|
||||
//
|
||||
// Editor->show();
|
||||
// );
|
||||
|
||||
}
|
||||
|
||||
void LightEditor::loadSelectSky(Sky* sky)
|
||||
{
|
||||
QSignalBlocker const _1(pos_x_spin);
|
||||
QSignalBlocker const _2(pos_y_spin);
|
||||
QSignalBlocker const _3(pos_z_spin);
|
||||
QSignalBlocker const _4(inner_radius_spin);
|
||||
QSignalBlocker const _5(outer_radius_spin);
|
||||
|
||||
_curr_sky = sky;
|
||||
|
||||
// disable combobox param items if param is not set or doesn't exist
|
||||
// in the future allow to add/edit param id
|
||||
for (int i = 0; i < NUM_SkyParamsNames; ++i)
|
||||
{
|
||||
auto sky_param = _curr_sky->skyParams[i];
|
||||
if (!sky_param)
|
||||
{
|
||||
QStandardItemModel* model = qobject_cast<QStandardItemModel*>(param_combobox->model());
|
||||
|
||||
if (model) {
|
||||
QStandardItem* item = model->item(i);
|
||||
if (item) {
|
||||
item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_light_editing_widget->setEnabled(true);
|
||||
lightning_tabs->setCurrentWidget(_light_editing_widget);
|
||||
|
||||
save_current_sky_button->setEnabled(true);
|
||||
// maybe move the inits to a separate function
|
||||
// global values
|
||||
std::stringstream ss;
|
||||
@@ -331,182 +644,42 @@ LightEditor::LightEditor(MapView* map_view, QWidget* parent)
|
||||
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);
|
||||
// name_line_edit->setText(QString::fromStdString(_curr_sky->name));
|
||||
name_line_edit->setText(QString::fromStdString(light_name));
|
||||
|
||||
if (_curr_sky->global)
|
||||
{
|
||||
global_light_chk->setChecked(true);
|
||||
pos_x_spin->setEnabled(false);
|
||||
pos_y_spin->setEnabled(false);
|
||||
pos_z_spin->setEnabled(false);
|
||||
inner_radius_spin->setEnabled(false);
|
||||
outer_radius_spin->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
global_light_chk->setChecked(false);
|
||||
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);
|
||||
}
|
||||
|
||||
pos_x_spin->setValue(_curr_sky->pos.x);
|
||||
pos_y_spin->setValue(_curr_sky->pos.z); // swap Z and Y
|
||||
pos_z_spin->setValue(_curr_sky->pos.y);
|
||||
inner_radius_spin->setValue(_curr_sky->r1);
|
||||
outer_radius_spin->setValue(_curr_sky->r2);
|
||||
|
||||
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);
|
||||
QSignalBlocker const __(param_combobox);
|
||||
param_combobox->setCurrentIndex(_curr_sky->curr_sky_param);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
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
|
||||
|
||||
try
|
||||
{
|
||||
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())));
|
||||
}
|
||||
}
|
||||
catch (LightDB::NotFound)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
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
|
||||
});
|
||||
|
||||
load_light_param(param_combobox->currentIndex());
|
||||
}
|
||||
|
||||
void LightEditor::UpdateWorldTime()
|
||||
@@ -518,9 +691,95 @@ void LightEditor::UpdateWorldTime()
|
||||
ActiveEditor[i]->UpdateWorldTime();
|
||||
}
|
||||
|
||||
void LightEditor::load_light_param()
|
||||
void LightEditor::load_light_param(int param_id)
|
||||
{
|
||||
if (!_curr_sky)
|
||||
{
|
||||
assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_curr_sky->skyParams[param_id])
|
||||
return;
|
||||
|
||||
// _curr_sky->curr_sky_param = param_id;
|
||||
// _world->renderer()->skies()->force_update();
|
||||
|
||||
QSignalBlocker const _1(glow_slider);
|
||||
QSignalBlocker const _2(highlight_sky_checkbox);
|
||||
QSignalBlocker const _3(shallow_water_alpha_slider);
|
||||
QSignalBlocker const _4(deep_water_alpha_slider);
|
||||
QSignalBlocker const _5(shallow_ocean_alpha_slider);
|
||||
QSignalBlocker const _6(deep_ocean_alpha_slider);
|
||||
|
||||
QSignalBlocker const _7(skybox_model_lineedit);
|
||||
QSignalBlocker const _8(skybox_flag_1);
|
||||
QSignalBlocker const _9(skybox_flag_2);
|
||||
|
||||
auto sky_param = _curr_sky->skyParams[param_combobox->currentIndex()];
|
||||
|
||||
int nb_user = 0;
|
||||
try
|
||||
{
|
||||
DBCFile::Record data = gLightDB.getByID(_curr_sky->Id);
|
||||
|
||||
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 + param_combobox->currentIndex()))
|
||||
nb_user++;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// _radius_slider->setValue(radius);
|
||||
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "LightParam Id : " << sky_param->Id << "\nThis param is used " << nb_user << " times.";
|
||||
_nb_param_users->setText(QString::fromStdString(ss.str().c_str()));
|
||||
|
||||
glow_slider->setSliderPosition(sky_param->glow() * 100);
|
||||
glow_slider->setEnabled(true);
|
||||
highlight_sky_checkbox->setCheckState(Qt::CheckState(sky_param->highlight_sky()));
|
||||
highlight_sky_checkbox->setEnabled(true);
|
||||
// alpha values
|
||||
shallow_water_alpha_slider->setSliderPosition(sky_param->river_shallow_alpha() * 100);
|
||||
shallow_water_alpha_slider->setEnabled(true);
|
||||
deep_water_alpha_slider->setSliderPosition(sky_param->river_deep_alpha() * 100);
|
||||
deep_water_alpha_slider->setEnabled(true);
|
||||
shallow_ocean_alpha_slider->setSliderPosition(sky_param->ocean_shallow_alpha() * 100);
|
||||
shallow_ocean_alpha_slider->setEnabled(true);
|
||||
deep_ocean_alpha_slider->setSliderPosition(sky_param->ocean_deep_alpha() * 100);
|
||||
deep_ocean_alpha_slider->setEnabled(true);
|
||||
// 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())));
|
||||
}
|
||||
|
||||
// skybox
|
||||
skybox_model_lineedit->setText("");
|
||||
if (sky_param->skybox.has_value())
|
||||
{
|
||||
skybox_model_lineedit->setText(QString::fromStdString(sky_param->skybox.value().model.get()->file_key().filepath()));
|
||||
}
|
||||
skybox_model_lineedit->setEnabled(true);
|
||||
|
||||
skybox_flag_1->setChecked(false);
|
||||
skybox_flag_2->setChecked(false);
|
||||
|
||||
if (sky_param->skyboxFlags & (1 << 0))
|
||||
skybox_flag_1->setChecked(true);
|
||||
|
||||
if (sky_param->skyboxFlags & (1 << 1))
|
||||
skybox_flag_1->setChecked(true);
|
||||
|
||||
skybox_flag_1->setEnabled(true);
|
||||
skybox_flag_2->setEnabled(true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <noggit/MapView.h>
|
||||
#include <QtWidgets/qtreewidget.h>
|
||||
#include <noggit/ui/widgets/LightViewWidget.h>
|
||||
#include <QTabWidget>
|
||||
|
||||
namespace Noggit::Ui::Tools
|
||||
{
|
||||
@@ -23,7 +24,7 @@ namespace Noggit::Ui::Tools
|
||||
{8 , "Sun"},
|
||||
{9 , "Cloud Sun"},
|
||||
{10 , "Cloud Emissive"},
|
||||
{11 , "Cloud Layer 1 Ambian"},
|
||||
{11 , "Cloud Layer 1 Ambiant"},
|
||||
{12 , "Cloud Layer 2 Ambiant"},
|
||||
{13 , "Unknown/Unused"},
|
||||
{14 , "Ocean Close"},
|
||||
@@ -32,6 +33,15 @@ namespace Noggit::Ui::Tools
|
||||
{17 , "River Far"}
|
||||
};
|
||||
|
||||
static const std::map <int, std::string> sky_float_values_names_map = {
|
||||
{0 , "Fog Distance"},
|
||||
{1 , "Fog Multiplier"},
|
||||
{2 , "Celestial Glow Through"},
|
||||
{3 , "Cloud Density"},
|
||||
{4 , "Unkown/Unused1"},
|
||||
{5 , "Unkown/Unused2"}
|
||||
};
|
||||
|
||||
// TODO : move to definitions files
|
||||
static const std::unordered_map <int, std::string> light_names_map = {
|
||||
{1 , "Global Light"},
|
||||
@@ -278,6 +288,7 @@ namespace Noggit::Ui::Tools
|
||||
{
|
||||
public:
|
||||
LightEditor(MapView* map_view, QWidget* parent = nullptr);
|
||||
|
||||
void UpdateWorldTime();
|
||||
|
||||
private:
|
||||
@@ -290,12 +301,30 @@ namespace Noggit::Ui::Tools
|
||||
std::vector<LightViewPreview*> LightsPreview;
|
||||
std::vector<LightViewEditor*> ActiveEditor;
|
||||
|
||||
QWidget* _light_editing_widget;
|
||||
|
||||
QTabWidget* lightning_tabs;
|
||||
QPushButton* save_current_sky_button;
|
||||
QLabel* lightid_label;
|
||||
|
||||
QCheckBox* global_light_chk;
|
||||
QLineEdit* name_line_edit;
|
||||
QDoubleSpinBox* pos_x_spin;
|
||||
QDoubleSpinBox* pos_y_spin;
|
||||
QDoubleSpinBox* pos_z_spin;
|
||||
QDoubleSpinBox* inner_radius_spin;
|
||||
QDoubleSpinBox* outer_radius_spin;
|
||||
|
||||
QLabel* _nb_param_users;
|
||||
QTreeWidget* _light_tree;
|
||||
QListWidget* _light_tree;
|
||||
QComboBox* param_combobox;
|
||||
QSlider* glow_slider;
|
||||
QCheckBox* highlight_sky_checkbox;
|
||||
|
||||
QLineEdit* skybox_model_lineedit;
|
||||
QCheckBox* skybox_flag_1;
|
||||
QCheckBox* skybox_flag_2;
|
||||
|
||||
QSlider* shallow_water_alpha_slider;
|
||||
QSlider* deep_water_alpha_slider;
|
||||
QSlider* shallow_ocean_alpha_slider;
|
||||
@@ -303,7 +332,8 @@ namespace Noggit::Ui::Tools
|
||||
|
||||
bool _is_new_record = false;
|
||||
|
||||
void load_light_param();
|
||||
void load_light_param(int param_id);
|
||||
void loadSelectSky(Sky* sky);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -66,6 +66,8 @@ LightViewPreview::LightViewPreview(QString LightName, QSize Size, QWidget* paren
|
||||
: DynamicMouseWidget(parent), MainLayout(new QVBoxLayout(this)), Name(new QLabel(this)),
|
||||
Preview(new LightViewPixmap(Size, this))
|
||||
{
|
||||
// Preview->ShowLines(true);
|
||||
|
||||
Name->setText(LightName);
|
||||
|
||||
MainLayout->addWidget(Name);
|
||||
@@ -245,12 +247,41 @@ bool LightViewPixmap::DrawLines()
|
||||
QPixmap ResultPixmap = QPixmap(Final.size());
|
||||
|
||||
QPainter Painter(&ResultPixmap);
|
||||
|
||||
const bool blend_lines = false;
|
||||
for (int i = 0; i < Data.size(); ++i)
|
||||
{
|
||||
for (int y = 0; y < LIGHT_VIEW_PREVIEW_LINE_SIZE; ++y)
|
||||
{
|
||||
int X = Data[i].time * Final.width() / MAX_TIME_VALUE - LIGHT_VIEW_PREVIEW_LINE_SIZE / 2 + y;
|
||||
if (!blend_lines)
|
||||
{
|
||||
Final = LightViewWidget::FillImagePart(Final, X, QColor(LIGHT_VIEW_PREVIEW_LINE_COLOR));
|
||||
continue;
|
||||
}
|
||||
|
||||
// blend the line instead, it just looks better with red.
|
||||
if (X == Image.width() || X < 0)
|
||||
continue;
|
||||
|
||||
QColor new_color(255, 0, 0, 150);
|
||||
|
||||
for (int Y = 0; Y < Image.height(); ++Y)
|
||||
{
|
||||
QColor existingColor = Image.pixelColor(X, Y);
|
||||
QColor blendedColor;
|
||||
|
||||
float alpha = new_color.alphaF();
|
||||
|
||||
// Blend the colors
|
||||
int red = static_cast<int>(new_color.red() * alpha + existingColor.red() * (1.0 - alpha));
|
||||
int green = static_cast<int>(new_color.green() * alpha + existingColor.green() * (1.0 - alpha));
|
||||
int blue = static_cast<int>(new_color.blue() * alpha + existingColor.blue() * (1.0 - alpha));
|
||||
|
||||
blendedColor.setRgb(red, green, blue);
|
||||
Image.setPixelColor(QPoint(X, Y), blendedColor);
|
||||
}
|
||||
Final = Image;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -458,7 +489,7 @@ void LightViewEditor::closeEvent(QCloseEvent* event)
|
||||
void LightViewEditor::UpdateSkyColorRowsValue()
|
||||
{
|
||||
UpdateWidgetEdition(CurrentIndex);
|
||||
_World->renderer()->skies()->update_sky_colors(_Map->getCamera()->position, static_cast<int>(_World->time) % MAX_TIME_VALUE);
|
||||
_World->renderer()->skies()->force_update();
|
||||
|
||||
Arrow->UpdateData(_Sky->colorRows[_eSkyColorIndex]);
|
||||
Preview->SetPreview(_Sky->colorRows[_eSkyColorIndex]);
|
||||
|
||||
Reference in New Issue
Block a user