diff --git a/src/noggit/Sky.cpp b/src/noggit/Sky.cpp index 61f3a917..980c6c91 100755 --- a/src/noggit/Sky.cpp +++ b/src/noggit/Sky.cpp @@ -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) : _context(context) , _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); r1 = data->getFloat(LightDB::RadiusInner) / skymul; r2 = data->getFloat(LightDB::RadiusOuter) / skymul; - for (int i = 0; i < 36; ++i) - { - mmin[i] = -2; - } + // 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 < 6; ++i) + // { + // mmin_float[i] = -2; + // } global = (pos.x == 0.0f && pos.y == 0.0f && pos.z == 0.0f); - int light_param_0 = data->getInt(LightDB::DataIDs); - int light_int_start = light_param_0 * NUM_SkyColorNames - 17; + // int light_param_0 = data->getInt(LightDB::DataIDs); + // 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 - { - DBCFile::Record rec = gLightIntBandDB.getByID(light_int_start + i); - int entries = rec.getInt(LightIntBandDB::Entries); + int sky_param_id = data->getInt(LightDB::DataIDs + i); + if (sky_param_id == 0) + { + skyParams[i] = nullptr; + continue; + } - 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; - 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); - } - } - } + SkyParam* sky_param = new SkyParam(sky_param_id, _context); + skyParams[i] = sky_param; } - int light_float_start = light_param_0 * 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 " << 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); - - _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; - } + // 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; + // 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_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 " << 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 { - if (mmin_float[r]<0) + auto sky_param = skyParams[curr_sky_param]; + if (sky_param->mmin_float[r]<0) { return 0.0; } float c1, c2; int t1, t2; - size_t last = floatParams[r].size() - 1; + size_t last = sky_param->floatParams[r].size() - 1; - if (tmmin_float[r]) { // reverse interpolate - c1 = floatParams[r][last].value; - c2 = floatParams[r][0].value; - t1 = floatParams[r][last].time; - t2 = floatParams[r][0].time + 2880; + c1 = sky_param->floatParams[r][last].value; + c2 = sky_param->floatParams[r][0].value; + t1 = sky_param->floatParams[r][last].time; + t2 = sky_param->floatParams[r][0].time + 2880; t += 2880; } else { for (size_t i = last; true; i--) { //! \todo iterator this. - if (floatParams[r][i].time <= t) + if (sky_param->floatParams[r][i].time <= t) { - c1 = floatParams[r][i].value; - t1 = floatParams[r][i].time; + c1 = sky_param->floatParams[r][i].value; + t1 = sky_param->floatParams[r][i].time; if (i == last) { - c2 = floatParams[r][0].value; - t2 = floatParams[r][0].time + 2880; + c2 = sky_param->floatParams[r][0].value; + t2 = sky_param->floatParams[r][0].time + 2880; } else { - c2 = floatParams[r][i + 1].value; - t2 = floatParams[r][i + 1].time; + c2 = sky_param->floatParams[r][i + 1].value; + t2 = sky_param->floatParams[r][i + 1].time; } break; } @@ -211,45 +361,57 @@ float Sky::floatParamFor(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); } glm::vec3 c1, c2; int t1, t2; - size_t last = colorRows[r].size() - 1; + int last = sky_param->colorRows[r].size() - 1; - if (tcolorRows[r][last].color; + c2 = sky_param->colorRows[r][0].color; + t1 = sky_param->colorRows[r][last].time; + t2 = sky_param->colorRows[r][0].time + 2880; + t += 2880; } else { - for (size_t i = last; true; i--) - { //! \todo iterator this. - if (colorRows[r][i].time <= t) + if (t < sky_param->mmin[r]) { - c1 = colorRows[r][i].color; - t1 = colorRows[r][i].time; - - if (i == last) - { - c2 = colorRows[r][0].color; - t2 = colorRows[r][0].time + 2880; - } - else - { - c2 = colorRows[r][i + 1].color; - t2 = colorRows[r][i + 1].time; - } - break; + // reverse interpolate + c1 = sky_param->colorRows[r][last].color; + c2 = sky_param->colorRows[r][0].color; + t1 = sky_param->colorRows[r][last].time; + t2 = sky_param->colorRows[r][0].time + 2880; + t += 2880; + } + else + { + for (int i = last; true; i--) + { //! \todo iterator this. + if (sky_param->colorRows[r][i].time <= t) + { + 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(t - t1) / static_cast(t2 - t1); @@ -350,6 +512,51 @@ Sky* Skies::findSkyWeights(glm::vec3 pos) 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) { 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_multiplier = default_sky->floatParamFor(1, time); - _river_shallow_alpha = default_sky->river_shallow_alpha(); - _river_deep_alpha = default_sky->river_deep_alpha(); - _ocean_shallow_alpha = default_sky->ocean_shallow_alpha(); - _ocean_deep_alpha = default_sky->ocean_deep_alpha(); - _glow = default_sky->glow(); + auto default_sky_param = default_sky->skyParams[default_sky->curr_sky_param]; + _river_shallow_alpha = default_sky_param->river_shallow_alpha(); + _river_deep_alpha = default_sky_param->river_deep_alpha(); + _ocean_shallow_alpha = default_sky_param->ocean_shallow_alpha(); + _ocean_deep_alpha = default_sky_param->ocean_deep_alpha(); + _glow = default_sky_param->glow(); } 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_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); - _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); + _glow = (_glow * (1.0f - sky.weight)) + (sky.skyParams[sky.curr_sky_param]->glow() * sky.weight); } } @@ -558,12 +767,15 @@ void Skies::drawLightingSpheres (glm::mat4x4 const& model_view { 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::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, {diffuse.x, diffuse.y, diffuse.z, 0.3}, sky.r2); + glm::vec4 diffuse = { color_set[LIGHT_GLOBAL_DIFFUSE], 1.f }; + glm::vec4 ambient = { color_set[LIGHT_GLOBAL_AMBIENT], 1.f }; + + 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 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, {diffuse.x, diffuse.y, diffuse.z, 0.3}, sky.r2); } @@ -827,3 +1038,142 @@ OutdoorLightStats OutdoorLighting::getLightStats(int time) 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(skyParams[param_id]->colorRows[i][l].color.z * 255.0f) + + (static_cast(skyParams[param_id]->colorRows[i][l].color.y * 255.0f) << 8) + + (static_cast(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; + + +} \ No newline at end of file diff --git a/src/noggit/Sky.h b/src/noggit/Sky.h index d1ef1c6a..6a2ff566 100755 --- a/src/noggit/Sky.h +++ b/src/noggit/Sky.h @@ -47,20 +47,64 @@ struct SkyFloatParam int time; }; +class SkyParam +{ +public: + std::optional skybox; + int Id; + + SkyParam() = default; + explicit SkyParam(int paramId, Noggit::NoggitRenderContext context); + + std::vector colorRows[36]; + std::vector 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 { public: std::optional skybox; + int Id; glm::vec3 pos; float r1, r2; explicit Sky(DBCFile::Iterator data, Noggit::NoggitRenderContext context); - std::vector colorRows[36]; - std::vector floatParams[6]; - int mmin[36]; - int mmin_float[6]; + SkyParam* skyParams[8]; + int curr_sky_param = 0; + + // std::vector colorRows[36]; + // std::vector floatParams[6]; + // int mmin[36]; + // int mmin_float[6]; char name[32]; @@ -70,6 +114,8 @@ public: float weight; bool global; + bool is_new_record = false; + bool operator<(const Sky& s) const { if (global) return false; @@ -77,20 +123,31 @@ public: else return r2 < s.r2; } - 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; } + // 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; } 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: - float _river_shallow_alpha; - float _river_deep_alpha; - float _ocean_shallow_alpha; - float _ocean_deep_alpha; + // bool _highlight_sky; + // float _river_shallow_alpha; + // float _river_deep_alpha; + // float _ocean_shallow_alpha; + // float _ocean_deep_alpha; - float _glow; + // float _glow; bool _selected; Noggit::NoggitRenderContext _context; @@ -125,11 +182,24 @@ enum SkyFloatParamsNames FOG_MULTIPLIER, CELESTIAL_FLOW, CLOUD_DENSITY, - UNK_1, - UNK_2, + UNK_FLOAT_PARAM_1, + UNK_FLOAT_PARAM_2, NUM_SkyFloatParamsNames }; +enum SkyParamsNames +{ + CLEAR, + CLEAR_WATER, + STORM, + STORM_WATER, + DEATH, + UNK_PARAM_1, + UNK_PARAM_2, + UNK_PARAM_3, + NUM_SkyParamsNames +}; + class Skies { private: @@ -157,6 +227,11 @@ public: explicit Skies(unsigned int mapid, Noggit::NoggitRenderContext context); 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); bool draw ( glm::mat4x4 const& model_view diff --git a/src/noggit/ui/tools/LightEditor/LightEditor.cpp b/src/noggit/ui/tools/LightEditor/LightEditor.cpp index b28604c2..0fa9e466 100755 --- a/src/noggit/ui/tools/LightEditor/LightEditor.cpp +++ b/src/noggit/ui/tools/LightEditor/LightEditor.cpp @@ -1,12 +1,519 @@ // This file is part of Noggit3, licensed under GNU General Public License (version 3). #include "LightEditor.hpp" +#include +#include +// #include +#include +#include +#include "LightColorEditor.h" +#include +#include +#include +#include +// #include +#include + +#include +#include using namespace Noggit::Ui::Tools; LightEditor::LightEditor(MapView* map_view, QWidget* parent) : 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)); + 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 = ±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 = ±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 ÷ 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 ÷ 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(_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(&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(_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(&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(_world->time) % 2880); // find how to update sky + }); + + connect(pos_y_spin, qOverload(&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(_world->time) % 2880); // find how to update sky + }); + + connect(pos_z_spin, qOverload(&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(_world->time) % 2880); // find how to update sky + }); + + connect(inner_radius_spin, qOverload(&QDoubleSpinBox::valueChanged), [&](double v) { + _curr_sky->r1 = v; // inner_radius_spin->value(); + _world->renderer()->skies()->update_sky_colors(_map_view->getCamera()->position, static_cast(_world->time) % 2880); // find how to update sky + }); + + connect(outer_radius_spin, qOverload(&QDoubleSpinBox::valueChanged), [&](double v) { + _curr_sky->r2 = v; // outer_radius_spin->value(); + _world->renderer()->skies()->update_sky_colors(_map_view->getCamera()->position, static_cast(_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(_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(_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(_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(_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(_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(_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); + +} -} \ No newline at end of file diff --git a/src/noggit/ui/tools/LightEditor/LightEditor.hpp b/src/noggit/ui/tools/LightEditor/LightEditor.hpp index 397bb340..6d9c0e67 100755 --- a/src/noggit/ui/tools/LightEditor/LightEditor.hpp +++ b/src/noggit/ui/tools/LightEditor/LightEditor.hpp @@ -5,18 +5,311 @@ #include #include +#include +#include namespace Noggit::Ui::Tools { + + static std::map 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 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 { public: LightEditor(MapView* map_view, QWidget* parent = nullptr); + void UpdateWorldTime(); private: MapView* _map_view; + World* _world; + Sky* _curr_sky; + QPushButton* _color_value_Buttons[18]{ 0 }; + QLabel* _color_value_labels[18]{ 0 }; + std::vector LightsPreview; + std::vector 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 + + + +