From 444198f0320a6b5dadba4c70d4d5a50671da9f16 Mon Sep 17 00:00:00 2001 From: Deamon87 Date: Fri, 5 Jul 2024 02:44:26 +0300 Subject: [PATCH] temp commit --- wowViewerLib/CMakeLists.txt | 2 + wowViewerLib/src/engine/objects/iMapApi.h | 7 - .../DayNightLightHolder.cpp | 601 ++++++++++++++++++ .../dayNightDataHolder/DayNightLightHolder.h | 44 ++ .../src/engine/objects/scenes/map.cpp | 533 +--------------- wowViewerLib/src/engine/objects/scenes/map.h | 30 +- .../renderer/mapScene/MapSceneRenderer.cpp | 8 +- 7 files changed, 663 insertions(+), 562 deletions(-) create mode 100644 wowViewerLib/src/engine/objects/scenes/dayNightDataHolder/DayNightLightHolder.cpp create mode 100644 wowViewerLib/src/engine/objects/scenes/dayNightDataHolder/DayNightLightHolder.h diff --git a/wowViewerLib/CMakeLists.txt b/wowViewerLib/CMakeLists.txt index c913f7e3..00b2dce6 100644 --- a/wowViewerLib/CMakeLists.txt +++ b/wowViewerLib/CMakeLists.txt @@ -378,6 +378,8 @@ set(SOURCE_FILES src/engine/objects/lights/CSpotLight.h src/engine/objects/lights/CWmoNewLight.cpp src/engine/objects/lights/CWmoNewLight.h + src/engine/objects/scenes/dayNightDataHolder/DayNightLightHolder.cpp + src/engine/objects/scenes/dayNightDataHolder/DayNightLightHolder.h ) if (LINK_OGL2) diff --git a/wowViewerLib/src/engine/objects/iMapApi.h b/wowViewerLib/src/engine/objects/iMapApi.h index 616842fa..3d7f4e35 100644 --- a/wowViewerLib/src/engine/objects/iMapApi.h +++ b/wowViewerLib/src/engine/objects/iMapApi.h @@ -19,13 +19,6 @@ class IMapApi { virtual std::shared_ptr getWmoObject(int fileDataId, SMMapObjDef &mapObjDef) = 0; virtual std::shared_ptr getWmoObject(std::string fileName, SMMapObjDefObj1 &mapObjDef) = 0; virtual std::shared_ptr getWmoObject(int fileDataId, SMMapObjDefObj1 &mapObjDef) = 0; - virtual void getLightResultsFromDB(mathfu::vec3 &cameraVec3, const Config *config, - SkyColors &skyColors, - ExteriorColors &exteriorColors, - FogResult &fogResult, - LiquidColors &liquidColors, - StateForConditions *stateForConditions) = 0; - virtual animTime_t getCurrentSceneTime() = 0; }; diff --git a/wowViewerLib/src/engine/objects/scenes/dayNightDataHolder/DayNightLightHolder.cpp b/wowViewerLib/src/engine/objects/scenes/dayNightDataHolder/DayNightLightHolder.cpp new file mode 100644 index 00000000..f4a0f56f --- /dev/null +++ b/wowViewerLib/src/engine/objects/scenes/dayNightDataHolder/DayNightLightHolder.cpp @@ -0,0 +1,601 @@ +// +// Created by Deamon on 7/5/2024. +// + +#include "DayNightLightHolder.h" +#include "../../../../include/database/dbStructs.h" +#include "../../../algorithms/mathHelper.h" + +DayNightLightHolder::DayNightLightHolder(const HApiContainer &api, int mapId) : m_api(api), m_mapId(mapId) { + +} + +void DayNightLightHolder::loadZoneLights() { + if (m_api->databaseHandler != nullptr) { + std::vector zoneLights; + m_api->databaseHandler->getZoneLightsForMap(m_mapId, zoneLights); + + for (const auto &zoneLight : zoneLights) { + mapInnerZoneLightRecord innerZoneLightRecord; + innerZoneLightRecord.ID = zoneLight.ID; + innerZoneLightRecord.name = zoneLight.name; + innerZoneLightRecord.LightID = zoneLight.LightID; +// innerZoneLightRecord.Zmin = zoneLight.Zmin; +// innerZoneLightRecord.Zmax = zoneLight.Zmax; + + float minX = 9999; float maxX = -9999; + float minY = 9999; float maxY = -9999; + + auto &points = innerZoneLightRecord.points; + for (auto &zonePoint : zoneLight.points) { + minX = std::min(zonePoint.x, minX); minY = std::min(zonePoint.y, minY); + maxX = std::max(zonePoint.x, maxX); maxY = std::max(zonePoint.y, maxY); + + points.push_back(mathfu::vec2(zonePoint.x, zonePoint.y)); + } + + innerZoneLightRecord.aabb = CAaBox( + C3Vector(mathfu::vec3(minX, minY, zoneLight.Zmin)), + C3Vector(mathfu::vec3(maxX, maxY, zoneLight.Zmax)) + ); + + auto &lines = innerZoneLightRecord.lines; + for (int i = 0; i < (points.size() - 1); i++) { + lines.push_back(points[i + 1] - points[i]); + } + lines.push_back( points[0] - points[points.size() - 1]); + + m_zoneLights.push_back(innerZoneLightRecord); + } + } +} + +void DayNightLightHolder::updateLightAndSkyboxData(const HMapRenderPlan &mapRenderPlan, + MathHelper::FrustumCullingData &frustumData, + StateForConditions &stateForConditions, + const AreaRecord &areaRecord) { + + ZoneScoped ; + + Config* config = this->m_api->getConfig(); + + bool fogRecordWasFound = false; + mathfu::vec3 endFogColor = mathfu::vec3(0.0, 0.0, 0.0); + + std::vector wmoFogData = {}; + if (mapRenderPlan->m_currentWMO != emptyWMO) { + auto l_currentWmoObject = wmoFactory.getObjectById<0>(mapRenderPlan->m_currentWMO); + if (l_currentWmoObject != nullptr) { + l_currentWmoObject->checkFog(frustumData.cameraPos, wmoFogData); + } + } + + std::vector lightResults; + if ((m_api->databaseHandler != nullptr)) { + //Check zoneLight + SkyColors skyColors; + ExteriorColors exteriorColors; + FogResult fogResult; + LiquidColors liquidColors; + + getLightResultsFromDB(frustumData.cameraPos, config, skyColors, exteriorColors, fogResult, liquidColors, &stateForConditions); + + //TODO: restore skyboxes + /* + //Delete skyboxes that are not in light array + std::unordered_map> perFdidMap; + auto modelIt = m_exteriorSkyBoxes.begin(); + while (modelIt != m_exteriorSkyBoxes.end()) { + bool found = false; + for (auto &_light : lightResults) { + if (_light.skyBoxFdid == (*modelIt)->getModelFileId()) { + if (!drawDefaultSkybox && _light.isDefault) continue; + + found = true; + break; + } + } + + if (found) { + perFdidMap[(*modelIt)->getModelFileId()] = *modelIt; + modelIt++; + } else { + modelIt = m_exteriorSkyBoxes.erase(modelIt); + } + } + + m_skyConeAlpha = 1.0; + + + + for (auto &_light : lightResults) { + if (_light.skyBoxFdid == 0 || _light.lightSkyboxId == 0) continue; + + stateForConditions.currentSkyboxIds.push_back(_light.lightSkyboxId); + std::shared_ptr skyBox = nullptr; + if (perFdidMap[_light.skyBoxFdid] == nullptr) { + skyBox = m2Factory.createObject(m_api, true); + skyBox->setLoadParams(0, {}, {}); + + skyBox->setModelFileId(_light.skyBoxFdid); + + skyBox->createPlacementMatrix(mathfu::vec3(0, 0, 0), 0, mathfu::vec3(1, 1, 1), nullptr); + skyBox->calcWorldPosition(); + m_exteriorSkyBoxes.push_back(skyBox); + } else { + skyBox = perFdidMap[_light.skyBoxFdid]; + } + + skyBox->setAlpha(_light.blendCoef); + if ((_light.skyBoxFlags & 4) > 0 ) { + //In this case conus is still rendered been, but all values are final fog values. + auto fdd = mapRenderPlan->frameDependentData; + fdd->overrideValuesWithFinalFog = true; + } + + if ((_light.skyBoxFlags & 2) == 0) { +// m_skyConeAlpha -= _light.blendCoef; + m_skyConeAlpha -= _light.blendCoef; + } + + if (_light.skyBoxFlags & 1) { + skyBox->setOverrideAnimationPerc(config->currentTime / 2880.0, true); + } + } + */ + + float ambientMult = areaRecord.ambientMultiplier * 2.0f + 1; + + if (config->glowSource == EParameterSource::eDatabase) { + auto fdd = mapRenderPlan->frameDependentData; + fdd->currentGlow = currentGlow; + } else if (config->glowSource == EParameterSource::eConfig) { + auto fdd = mapRenderPlan->frameDependentData; + fdd->currentGlow = config->currentGlow; + } + + + if (config->globalLighting == EParameterSource::eDatabase) { + auto fdd = mapRenderPlan->frameDependentData; + + fdd->colors = exteriorColors; + + auto extDir = MathHelper::calcExteriorColorDir( + frustumData.viewMat, + m_api->getConfig()->currentTime + ); + fdd->exteriorDirectColorDir = { extDir.x, extDir.y, extDir.z }; + } else if (config->globalLighting == EParameterSource::eConfig) { + auto fdd = mapRenderPlan->frameDependentData; + + fdd->colors.exteriorAmbientColor = config->exteriorColors.exteriorAmbientColor; + fdd->colors.exteriorGroundAmbientColor = config->exteriorColors.exteriorGroundAmbientColor; + fdd->colors.exteriorHorizontAmbientColor = config->exteriorColors.exteriorHorizontAmbientColor; + fdd->colors.exteriorDirectColor = config->exteriorColors.exteriorDirectColor; + auto extDir = MathHelper::calcExteriorColorDir( + frustumData.viewMat, + m_api->getConfig()->currentTime + ); + fdd->exteriorDirectColorDir = { extDir.x, extDir.y, extDir.z }; + } + + { + auto fdd = mapRenderPlan->frameDependentData; + fdd->useMinimapWaterColor = config->useMinimapWaterColor; + fdd->useCloseRiverColorForDB = config->useCloseRiverColorForDB; + } + if (config->waterColorParams == EParameterSource::eDatabase) + { + auto fdd = mapRenderPlan->frameDependentData; + fdd->liquidColors = liquidColors; + } else if (config->waterColorParams == EParameterSource::eConfig) { + auto fdd = mapRenderPlan->frameDependentData; + fdd->liquidColors.closeRiverColor_shallowAlpha = config->closeRiverColor; + fdd->liquidColors.farRiverColor_deepAlpha = config->farRiverColor; + fdd->liquidColors.closeOceanColor_shallowAlpha = config->closeOceanColor; + fdd->liquidColors.farOceanColor_deepAlpha = config->farOceanColor; + } + if (config->skyParams == EParameterSource::eDatabase) { + auto fdd = mapRenderPlan->frameDependentData; + fdd->skyColors = skyColors; + } + } + + //Handle fog + { + std::vector combinedResults = {}; + float totalSummator = 0.0; + + //Apply fog from WMO + { + for (auto &wmoFog : wmoFogData) { + auto &lightResult = combinedResults.emplace_back(); + auto farPlaneClamped = std::min(config->farPlane, wmoFog.end); + + std::array colorConverted; + ImVectorToArrBGR(colorConverted, wmoFog.color); + + lightResult.FogEnd = farPlaneClamped; + lightResult.FogStart = farPlaneClamped * wmoFog.start_scalar; + lightResult.SkyFogColor = colorConverted; + lightResult.FogDensity = 1.0; + lightResult.FogHeightColor = colorConverted; + lightResult.EndFogColor = colorConverted; + lightResult.SunFogColor = colorConverted; + lightResult.HeightEndFogColor = colorConverted; + + if (farPlaneClamped < 30.f) { + lightResult.FogEnd = farPlaneClamped; + farPlaneClamped = 30.f; + } + + bool mapHasWeightedBlendFlag = false; + if (!mapHasWeightedBlendFlag) { + float difference = farPlaneClamped - lightResult.FogStart; + float farPlaneClamped2 = std::min(config->farPlane, 700.0f) - 200.0f; + if ((difference > farPlaneClamped2) || (farPlaneClamped2 <= 0.0f)) { + lightResult.FogDensity = 1.5; + } else { + lightResult.FogDensity = ((1.0 - (difference / farPlaneClamped2)) * 5.5) + 1.5; + } + lightResult.FogEnd = config->farPlane; + if (lightResult.FogStart < 0.0f) + lightResult.FogStart = 0.0; + } + + lightResult.FogHeightDensity = lightResult.FogDensity; + lightResult.FogStartOffset = 0; + lightResult.FogHeightScaler = 1.0; + lightResult.FogZScalar = 0; + lightResult.FogHeight = -10000.0; + lightResult.LegacyFogScalar = 1.0; + lightResult.EndFogColorDistance = 10000.0; + } + } + + //Apply fogs from lights + if (totalSummator < 1.0) { + if (config->globalFog == EParameterSource::eDatabase) { + + } else if (config->globalFog == EParameterSource::eConfig) { + LightResult globalFog; + globalFog.FogScaler = config->fogResult.FogScaler; + globalFog.FogEnd = config->fogResult.FogEnd; + globalFog.FogDensity = config->fogResult.FogDensity; + + globalFog.FogHeightScaler = config->fogResult.FogHeightScaler; + globalFog.FogHeightDensity = config->fogResult.FogHeightDensity; + globalFog.SunFogAngle = config->fogResult.SunFogAngle; + globalFog.EndFogColorDistance = config->fogResult.EndFogColorDistance; + globalFog.SunFogStrength = config->fogResult.SunFogStrength; + + globalFog.blendCoef = 1.0 - totalSummator; + globalFog.isDefault = true; + + globalFog.EndFogColor = {config->fogResult.EndFogColor.z, config->fogResult.EndFogColor.y, config->fogResult.EndFogColor.x}; + globalFog.SunFogColor = {config->fogResult.SunFogColor.z, config->fogResult.SunFogColor.y, config->fogResult.SunFogColor.x}; + globalFog.FogHeightColor = {config->fogResult.FogHeightColor.z, config->fogResult.FogHeightColor.y, config->fogResult.FogHeightColor.x}; + + combinedResults = {globalFog}; + } + } + std::sort(combinedResults.begin(), combinedResults.end(), [](const LightResult &a, const LightResult &b) -> bool { + return a.blendCoef > b.blendCoef; + }); + + //Rebalance blendCoefs + if (totalSummator < 1.0f && totalSummator > 0.0f) { + for (auto &_light : combinedResults) { + _light.blendCoef = _light.blendCoef / totalSummator; + } + } + + //In case of no data -> disable the fog + { + auto fdd = mapRenderPlan->frameDependentData; + fdd->FogDataFound = !combinedResults.empty(); + + auto &fogResult = fdd->fogResults.emplace_back(); + for (auto &_light : lightResults) { + fogResult.FogEnd = mix(fogResult.FogEnd, _light.FogEnd, _light.blendCoef); + fogResult.FogScaler = mix(fogResult.FogScaler, _light.FogScaler, _light.blendCoef); + fogResult.FogDensity = mix(fogResult.FogDensity, _light.FogDensity, _light.blendCoef); + fogResult.FogHeight = mix(fogResult.FogHeight, _light.FogHeight, _light.blendCoef); + fogResult.FogHeightScaler = mix(fogResult.FogHeightScaler, _light.FogHeightScaler, _light.blendCoef); + fogResult.FogHeightDensity = mix(fogResult.FogHeightDensity, _light.FogHeightDensity, _light.blendCoef); + fogResult.SunFogAngle = mix(fogResult.SunFogAngle, _light.SunFogAngle, _light.blendCoef); + if (fdd->overrideValuesWithFinalFog) { + fogResult.FogColor = mix(fogResult.FogColor, mathfu::vec3(_light.EndFogColor[2], _light.EndFogColor[1], _light.EndFogColor[0]), _light.blendCoef); + } else { + fogResult.FogColor = mix(fogResult.FogColor, mathfu::vec3(_light.SkyFogColor[2], _light.SkyFogColor[1], _light.SkyFogColor[0]), _light.blendCoef); + } + fogResult.EndFogColor = mix(fogResult.EndFogColor, mathfu::vec3(_light.EndFogColor[2], _light.EndFogColor[1], _light.EndFogColor[0]), _light.blendCoef); + fogResult.EndFogColorDistance = mix(fogResult.EndFogColorDistance, _light.EndFogColorDistance, _light.blendCoef); + fogResult.SunFogColor = mix(fogResult.SunFogColor, mathfu::vec3(_light.SunFogColor[2], _light.SunFogColor[1], _light.SunFogColor[0]), _light.blendCoef); + fogResult.SunFogStrength = mix(fogResult.SunFogStrength, _light.SunFogStrength, _light.blendCoef); + fogResult.FogHeightColor = mix(fogResult.FogHeightColor, mathfu::vec3(_light.FogHeightColor[2], _light.FogHeightColor[1], _light.FogHeightColor[0]), _light.blendCoef); + fogResult.FogHeightCoefficients = mix( + fogResult.FogHeightCoefficients, + mathfu::vec4(_light.FogHeightCoefficients[3], _light.FogHeightCoefficients[2], + _light.FogHeightCoefficients[1], _light.FogHeightCoefficients[0]), _light.blendCoef); + fogResult.MainFogCoefficients = mix( + fogResult.MainFogCoefficients, + mathfu::vec4(_light.MainFogCoefficients[3], _light.MainFogCoefficients[2], + _light.MainFogCoefficients[1], _light.MainFogCoefficients[0]), _light.blendCoef); + fogResult.HeightDensityFogCoefficients = mix( + fogResult.HeightDensityFogCoefficients, + mathfu::vec4(_light.HeightDensityFogCoefficients[3], + _light.HeightDensityFogCoefficients[2], + _light.HeightDensityFogCoefficients[1], + _light.HeightDensityFogCoefficients[0]), _light.blendCoef); + + fogResult.FogZScalar = mix(fogResult.FogZScalar, _light.FogZScalar, _light.blendCoef); + fogResult.LegacyFogScalar = mix(fogResult.LegacyFogScalar, _light.LegacyFogScalar, _light.blendCoef); + fogResult.MainFogStartDist = mix(fogResult.MainFogStartDist, _light.MainFogStartDist, _light.blendCoef); + fogResult.MainFogEndDist = mix(fogResult.MainFogEndDist, _light.MainFogEndDist, _light.blendCoef); + fogResult.FogBlendAlpha = mix(fogResult.FogBlendAlpha, _light.blendCoef, _light.blendCoef); + fogResult.HeightEndFogColor = mix(fogResult.HeightEndFogColor, mathfu::vec3(_light.HeightEndFogColor[2], _light.HeightEndFogColor[1], _light.HeightEndFogColor[0]), _light.blendCoef); + fogResult.FogStartOffset = mix(fogResult.FogStartOffset, _light.FogStartOffset, _light.blendCoef); + } + } + } +} + + +template +inline float getFloatFromInt(int value) { + if constexpr (T == 0) { + return (value & 0xFF) / 255.0f; + } + if constexpr (T == 1) { + return ((value >> 8) & 0xFF) / 255.0f; + } + if constexpr (T == 2) { + return ((value >> 16) & 0xFF) / 255.0f; + } +} + +inline mathfu::vec3 intToColor3(int a) { + //BGR + return mathfu::vec3( + getFloatFromInt<2>(a), + getFloatFromInt<1>(a), + getFloatFromInt<0>(a) + ); +} +inline mathfu::vec4 intToColor4(int a) { + //BGRA + return mathfu::vec4( + getFloatFromInt<2>(a), + getFloatFromInt<1>(a), + getFloatFromInt<0>(a), + getFloatFromInt<3>(a) + ); +} +inline mathfu::vec4 floatArr(std::array a) { + //BGRA + return mathfu::vec4( + a[3], + a[2], + a[1], + a[0] + ); +} + +template +decltype(auto) mixMembers(LightParamData& data, T LightTimedData::*member, float blendTimeCoeff) { + if constexpr (C == 3) { + static_assert(std::is_same::value, "the type must be int for vector component"); + return mix(intToColor3(data.lightTimedData[0].*member), intToColor3(data.lightTimedData[1].*member), blendTimeCoeff); + } + if constexpr (C == 4 && std::is_same>::value) { + return mix(floatArr(data.lightTimedData[0].*member), floatArr(data.lightTimedData[1].*member), blendTimeCoeff); + } else if constexpr (C == 4) { + static_assert(std::is_same::value, "the type must be int for vector component"); + return mix(intToColor4(data.lightTimedData[0].*member), intToColor4(data.lightTimedData[1].*member), blendTimeCoeff); + } + if constexpr (C == 1) { + static_assert(std::is_same::value, "the type must be float for one component"); + return mix(data.lightTimedData[0].*member, data.lightTimedData[1].*member, blendTimeCoeff); + } +} + +bool vec3EqZero(const mathfu::vec3 &a) { + return feq(a.x, 0.0f) && feq(a.y, 0.0f) && feq(a.z, 0.0f); +} + +float maxFarClip(float farClip) { + + return std::max(std::min(farClip, 50000.0), 1000.0); +} + +float getClampedFarClip(float farClip) { + int someflag = 0; + float multiplier = 1.0f; + + if ((map_has0x10000Flag) != 0 && farClip >= 4400.0f) + farClip = 4400.0; + farClip = farClip * multiplier; + + return maxFarClip( + + ); +} + +void fixLightTimedData(LightTimedData &data, float farClip) { + if (data.EndFogColor == 0) { + data.EndFogColor = data.SkyFogColor; + } + + if (data.FogHeightColor == 0) { + data.FogHeightColor = data.SkyFogColor; + } + + if (data.EndFogHeightColor == 0) { + data.EndFogHeightColor = data.EndFogColor; + } + + //Clamp into (-1.0f, 1.0f) + data.FogScaler = std::max(std::min(data.FogScaler, 1.0f), -1.0f); + data.FogEnd = std::max(data.FogEnd, 10.0f); + data.FogHeight = std::max(data.FogHeight, -10000.0f); + data.FogHeightScaler = std::max(std::min(data.FogScaler, 1.0f), -1.0f); + + if (data.SunFogColor == 0) + data.SunFogAngle = 1.0f; + + if (data.EndFogColorDistance <= 0.0f) + data.EndFogColorDistance = getClampedFarClip(farClip); +} + +void DayNightLightHolder::getLightResultsFromDB(mathfu::vec3 &cameraVec3, const Config *config, + SkyColors &skyColors, + ExteriorColors &exteriorColors, + FogResult &fogResult, + LiquidColors &liquidColors, + StateForConditions *stateForConditions) { + if (m_api->databaseHandler == nullptr) + return ; + + LightResult zoneLightResult; + + bool zoneLightFound = false; + int LightId; + for (const auto &zoneLight : m_zoneLights) { + CAaBox laabb = zoneLight.aabb; + auto const vec50 = mathfu::vec3(50.0f,50.0f,0); + laabb.min = (mathfu::vec3(laabb.min) - vec50); + laabb.max = (mathfu::vec3(laabb.max) + vec50); + if (MathHelper::isPointInsideNonConvex(cameraVec3, zoneLight.aabb, zoneLight.points)) { + zoneLightFound = true; + + if (stateForConditions != nullptr) { + stateForConditions->currentZoneLights.push_back(zoneLight.ID); + } + LightId = zoneLight.LightID; + break; + } + } + + uint8_t currentLightParamIdIndex = 0; + + int selectedLightParam = 0; + int selectedLightId = 0; + + if (zoneLightFound) { + selectedLightId = LightId; + m_api->databaseHandler->getLightById(LightId, config->currentTime, zoneLightResult); + if (stateForConditions != nullptr) { + selectedLightParam = zoneLightResult.lightParamId[currentLightParamIdIndex]; + stateForConditions->currentZoneLights.push_back(zoneLightResult.lightParamId[currentLightParamIdIndex]); + } + } + + //Get light from DB + std::vector lightResults; + m_api->databaseHandler->getEnvInfo(m_mapId, + cameraVec3.x, + cameraVec3.y, + cameraVec3.z, + lightResults + ); + std::sort(lightResults.begin(), lightResults.end(), [](const LightResult &a, const LightResult &b) -> bool { + return a.blendAlpha > b.blendAlpha; + }); + + + for (auto it = lightResults.begin(); it != lightResults.end(); it++) { + if (feq(it->pos[0], 0.0) && feq(it->pos[1], 0.0) && feq(it->pos[2], 0.0)) { + //This is default record. If zoneLight was selected -> skip it. + if (!zoneLightFound) { + selectedLightParam = it->lightParamId[currentLightParamIdIndex]; + selectedLightId = it->id; + } + } else { + selectedLightParam = it->lightParamId[currentLightParamIdIndex]; + selectedLightId = it->id; + break; + } + } + + if (stateForConditions != nullptr) { + stateForConditions->currentZoneLights.push_back(selectedLightParam); + stateForConditions->currentLightIds.push_back(selectedLightId); + } + + LightParamData lightParamData; + if (m_api->databaseHandler->getLightParamData(selectedLightParam, config->currentTime, lightParamData)) { + + float blendTimeCoeff = (config->currentTime - lightParamData.lightTimedData[0].time) / (float)(lightParamData.lightTimedData[1].time - lightParamData.lightTimedData[0].time); + + auto &dataA = lightParamData.lightTimedData[0]; + auto &dataB = lightParamData.lightTimedData[1]; + //Blend two times using certain rules + fixLightTimedData(dataA, config->farPlane); + fixLightTimedData(dataB, config->farPlane); + + //Ambient lights + exteriorColors.exteriorAmbientColor = mixMembers<4>(lightParamData, &LightTimedData::ambientLight, blendTimeCoeff); + exteriorColors.exteriorGroundAmbientColor = mixMembers<4>(lightParamData, &LightTimedData::groundAmbientColor, blendTimeCoeff); + if (vec3EqZero(exteriorColors.exteriorGroundAmbientColor.xyz())) + exteriorColors.exteriorGroundAmbientColor = exteriorColors.exteriorAmbientColor; + + exteriorColors.exteriorHorizontAmbientColor = mixMembers<4>(lightParamData, &LightTimedData::horizontAmbientColor, blendTimeCoeff); + if (vec3EqZero(exteriorColors.exteriorHorizontAmbientColor.xyz())) + exteriorColors.exteriorHorizontAmbientColor = exteriorColors.exteriorAmbientColor; + + exteriorColors.exteriorDirectColor = mixMembers<4>(lightParamData, &LightTimedData::directColor, blendTimeCoeff); + + //Liquid colors + liquidColors.closeOceanColor_shallowAlpha = mixMembers<4>(lightParamData, &LightTimedData::closeOceanColor, blendTimeCoeff); + liquidColors.farOceanColor_deepAlpha = mixMembers<4>(lightParamData, &LightTimedData::farOceanColor, blendTimeCoeff); + liquidColors.closeRiverColor_shallowAlpha = mixMembers<4>(lightParamData, &LightTimedData::closeRiverColor, blendTimeCoeff); + liquidColors.farRiverColor_deepAlpha = mixMembers<4>(lightParamData, &LightTimedData::farRiverColor, blendTimeCoeff); + + liquidColors.closeOceanColor_shallowAlpha.w = lightParamData.oceanShallowAlpha; + liquidColors.farOceanColor_deepAlpha.w = lightParamData.oceanDeepAlpha; + liquidColors.closeRiverColor_shallowAlpha.w = lightParamData.waterShallowAlpha; + liquidColors.farRiverColor_deepAlpha.w = lightParamData.waterDeepAlpha; + + //SkyColors + skyColors.SkyTopColor = mixMembers<4>(lightParamData, &LightTimedData::SkyTopColor, blendTimeCoeff); + skyColors.SkyMiddleColor = mixMembers<4>(lightParamData, &LightTimedData::SkyMiddleColor, blendTimeCoeff); + skyColors.SkyBand1Color = mixMembers<4>(lightParamData, &LightTimedData::SkyBand1Color, blendTimeCoeff); + skyColors.SkyBand2Color = mixMembers<4>(lightParamData, &LightTimedData::SkyBand2Color, blendTimeCoeff); + skyColors.SkySmogColor = mixMembers<4>(lightParamData, &LightTimedData::SkySmogColor, blendTimeCoeff); + skyColors.SkyFogColor = mixMembers<4>(lightParamData, &LightTimedData::SkyFogColor, blendTimeCoeff); + + //Fog! + fogResult.FogEnd = mixMembers<1>(lightParamData, &LightTimedData::FogEnd, blendTimeCoeff); + fogResult.FogScaler = mixMembers<1>(lightParamData, &LightTimedData::FogScaler, blendTimeCoeff); + fogResult.FogDensity = mixMembers<1>(lightParamData, &LightTimedData::FogDensity, blendTimeCoeff); + fogResult.FogHeight = mixMembers<1>(lightParamData, &LightTimedData::FogHeight, blendTimeCoeff); + fogResult.FogHeightScaler = mixMembers<1>(lightParamData, &LightTimedData::FogHeightScaler, blendTimeCoeff); + fogResult.FogHeightDensity = mixMembers<1>(lightParamData, &LightTimedData::FogHeightDensity, blendTimeCoeff); + fogResult.SunFogAngle = mixMembers<1>(lightParamData, &LightTimedData::SunFogAngle, blendTimeCoeff); + + if (false) {//fdd->overrideValuesWithFinalFog) { + fogResult.FogColor = mixMembers<3>(lightParamData, &LightTimedData::EndFogColor, blendTimeCoeff); + } else { + fogResult.FogColor = mixMembers<3>(lightParamData, &LightTimedData::SkyFogColor, blendTimeCoeff); + } + + fogResult.EndFogColor = mixMembers<3>(lightParamData, &LightTimedData::EndFogColor, blendTimeCoeff); + fogResult.EndFogColorDistance = mixMembers<1>(lightParamData, &LightTimedData::EndFogColorDistance, blendTimeCoeff); + fogResult.SunFogColor = mixMembers<3>(lightParamData, &LightTimedData::SunFogColor, blendTimeCoeff); + fogResult.SunFogStrength = mixMembers<1>(lightParamData, &LightTimedData::SunFogStrength, blendTimeCoeff); + fogResult.FogHeightColor = mixMembers<3>(lightParamData, &LightTimedData::FogHeightColor, blendTimeCoeff); + fogResult.FogHeightCoefficients = mixMembers<4>(lightParamData, &LightTimedData::FogHeightCoefficients, blendTimeCoeff); + fogResult.MainFogCoefficients = mixMembers<4>(lightParamData, &LightTimedData::MainFogCoefficients, blendTimeCoeff); + fogResult.HeightDensityFogCoefficients = mixMembers<4>(lightParamData, &LightTimedData::MainFogCoefficients, blendTimeCoeff); + + fogResult.FogZScalar = mixMembers<1>(lightParamData, &LightTimedData::FogZScalar, blendTimeCoeff); +// fogResult.LegacyFogScalar = mixMembers<1>(lightParamData, &LightTimedData::LegacyFogScalar, blendTimeCoeff); + fogResult.MainFogStartDist = mixMembers<1>(lightParamData, &LightTimedData::MainFogStartDist, blendTimeCoeff); + fogResult.MainFogEndDist = mixMembers<1>(lightParamData, &LightTimedData::MainFogEndDist, blendTimeCoeff); +// fogResult.FogBlendAlpha = mixMembers<1>(lightParamData, &LightTimedData::FogBlendAlpha, blendTimeCoeff); + fogResult.HeightEndFogColor = mixMembers<3>(lightParamData, &LightTimedData::EndFogHeightColor, blendTimeCoeff); + fogResult.FogStartOffset = mixMembers<1>(lightParamData, &LightTimedData::FogStartOffset, blendTimeCoeff); + + } +} \ No newline at end of file diff --git a/wowViewerLib/src/engine/objects/scenes/dayNightDataHolder/DayNightLightHolder.h b/wowViewerLib/src/engine/objects/scenes/dayNightDataHolder/DayNightLightHolder.h new file mode 100644 index 00000000..e4e4372d --- /dev/null +++ b/wowViewerLib/src/engine/objects/scenes/dayNightDataHolder/DayNightLightHolder.h @@ -0,0 +1,44 @@ +// +// Created by Deamon on 7/5/2024. +// + +#ifndef AWEBWOWVIEWERCPP_DAYNIGHTLIGHTHOLDER_H +#define AWEBWOWVIEWERCPP_DAYNIGHTLIGHTHOLDER_H + +#include +#include +#include "../../../persistance/header/commonFileStructs.h" +#include "../../../ApiContainer.h" + +class DayNightLightHolder { +public: + DayNightLightHolder(const HApiContainer &api, int mapId); + +private: + struct mapInnerZoneLightRecord { + int ID; + std::string name; + int LightID; + CAaBox aabb; + std::vector points; + std::vector lines; + }; + std::vector m_zoneLights; + + HApiContainer m_api; + int m_mapId = -1; +public: + void loadZoneLights(); + void updateLightAndSkyboxData(const HMapRenderPlan &mapRenderPlan, MathHelper::FrustumCullingData &frustumData, + StateForConditions &stateForConditions, const AreaRecord &areaRecord); + + void getLightResultsFromDB(mathfu::vec3 &cameraVec3, const Config *config, + SkyColors &skyColors, + ExteriorColors &exteriorColors, + FogResult &fogResult, + LiquidColors &liquidColors, + StateForConditions *stateForConditions); +}; + + +#endif //AWEBWOWVIEWERCPP_DAYNIGHTLIGHTHOLDER_H diff --git a/wowViewerLib/src/engine/objects/scenes/map.cpp b/wowViewerLib/src/engine/objects/scenes/map.cpp index e69fbcc8..4085faff 100644 --- a/wowViewerLib/src/engine/objects/scenes/map.cpp +++ b/wowViewerLib/src/engine/objects/scenes/map.cpp @@ -272,7 +272,7 @@ HGVertexBufferBindings createSkyBindings(const HMapSceneBufferCreate &sceneRende return skyBindings; } -Map::Map(HApiContainer api, int mapId, const std::string &mapName) { +Map::Map(HApiContainer api, int mapId, const std::string &mapName) : dayNightLightHolder(api, mapId) { initMapTiles(); m_mapId = mapId; m_api = api; this->mapName = mapName; @@ -282,6 +282,7 @@ Map::Map(HApiContainer api, int mapId, const std::string &mapName) { MapRecord mapRecord; api->databaseHandler->getMapById(mapId, mapRecord); useWeightedBlend = (mapRecord.flags0 & 0x4) > 0; + has0x200000Flag = (mapRecord.flags0 & 0x200000) > 0; std::string wdtFileName = "world/maps/"+mapName+"/"+mapName+".wdt"; @@ -294,8 +295,7 @@ Map::Map(HApiContainer api, int mapId, const std::string &mapName) { m_wdlObject = std::make_shared(api, wdlFileName); m_wdlObject->setMapApi(this); - - loadZoneLights(); + dayNightLightHolder.loadZoneLights(); m_sceneWideBlockVSPSChunk = nullptr; } @@ -586,493 +586,10 @@ static inline float mix(const float &a, const float &b, float alpha) { void Map::updateLightAndSkyboxData(const HMapRenderPlan &mapRenderPlan, MathHelper::FrustumCullingData &frustumData, StateForConditions &stateForConditions, const AreaRecord &areaRecord) { - ZoneScoped ; - - Config* config = this->m_api->getConfig(); - - bool fogRecordWasFound = false; - mathfu::vec3 endFogColor = mathfu::vec3(0.0, 0.0, 0.0); - - std::vector wmoFogData = {}; - if (mapRenderPlan->m_currentWMO != emptyWMO) { - auto l_currentWmoObject = wmoFactory.getObjectById<0>(mapRenderPlan->m_currentWMO); - if (l_currentWmoObject != nullptr) { - l_currentWmoObject->checkFog(frustumData.cameraPos, wmoFogData); - } - } - - std::vector lightResults; - if ((m_api->databaseHandler != nullptr)) { - //Check zoneLight - SkyColors skyColors; - ExteriorColors exteriorColors; - FogResult fogResult; - LiquidColors liquidColors; - - getLightResultsFromDB(frustumData.cameraPos, config, skyColors, exteriorColors, fogResult, liquidColors, &stateForConditions); - - //TODO: restore skyboxes - /* - //Delete skyboxes that are not in light array - std::unordered_map> perFdidMap; - auto modelIt = m_exteriorSkyBoxes.begin(); - while (modelIt != m_exteriorSkyBoxes.end()) { - bool found = false; - for (auto &_light : lightResults) { - if (_light.skyBoxFdid == (*modelIt)->getModelFileId()) { - if (!drawDefaultSkybox && _light.isDefault) continue; - - found = true; - break; - } - } - - if (found) { - perFdidMap[(*modelIt)->getModelFileId()] = *modelIt; - modelIt++; - } else { - modelIt = m_exteriorSkyBoxes.erase(modelIt); - } - } - - m_skyConeAlpha = 1.0; - - - - for (auto &_light : lightResults) { - if (_light.skyBoxFdid == 0 || _light.lightSkyboxId == 0) continue; - - stateForConditions.currentSkyboxIds.push_back(_light.lightSkyboxId); - std::shared_ptr skyBox = nullptr; - if (perFdidMap[_light.skyBoxFdid] == nullptr) { - skyBox = m2Factory.createObject(m_api, true); - skyBox->setLoadParams(0, {}, {}); - - skyBox->setModelFileId(_light.skyBoxFdid); - - skyBox->createPlacementMatrix(mathfu::vec3(0, 0, 0), 0, mathfu::vec3(1, 1, 1), nullptr); - skyBox->calcWorldPosition(); - m_exteriorSkyBoxes.push_back(skyBox); - } else { - skyBox = perFdidMap[_light.skyBoxFdid]; - } - - skyBox->setAlpha(_light.blendCoef); - if ((_light.skyBoxFlags & 4) > 0 ) { - //In this case conus is still rendered been, but all values are final fog values. - auto fdd = mapRenderPlan->frameDependentData; - fdd->overrideValuesWithFinalFog = true; - } - - if ((_light.skyBoxFlags & 2) == 0) { -// m_skyConeAlpha -= _light.blendCoef; - m_skyConeAlpha -= _light.blendCoef; - } - - if (_light.skyBoxFlags & 1) { - skyBox->setOverrideAnimationPerc(config->currentTime / 2880.0, true); - } - } - */ - float ambientMult = areaRecord.ambientMultiplier * 2.0f + 1; - - if (config->glowSource == EParameterSource::eDatabase) { - auto fdd = mapRenderPlan->frameDependentData; - fdd->currentGlow = currentGlow; - } else if (config->glowSource == EParameterSource::eConfig) { - auto fdd = mapRenderPlan->frameDependentData; - fdd->currentGlow = config->currentGlow; - } - - - if (config->globalLighting == EParameterSource::eDatabase) { - auto fdd = mapRenderPlan->frameDependentData; - - fdd->colors = exteriorColors; - - auto extDir = MathHelper::calcExteriorColorDir( - frustumData.viewMat, - m_api->getConfig()->currentTime - ); - fdd->exteriorDirectColorDir = { extDir.x, extDir.y, extDir.z }; - } else if (config->globalLighting == EParameterSource::eConfig) { - auto fdd = mapRenderPlan->frameDependentData; - - fdd->colors.exteriorAmbientColor = config->exteriorColors.exteriorAmbientColor; - fdd->colors.exteriorGroundAmbientColor = config->exteriorColors.exteriorGroundAmbientColor; - fdd->colors.exteriorHorizontAmbientColor = config->exteriorColors.exteriorHorizontAmbientColor; - fdd->colors.exteriorDirectColor = config->exteriorColors.exteriorDirectColor; - auto extDir = MathHelper::calcExteriorColorDir( - frustumData.viewMat, - m_api->getConfig()->currentTime - ); - fdd->exteriorDirectColorDir = { extDir.x, extDir.y, extDir.z }; - } - - { - auto fdd = mapRenderPlan->frameDependentData; - fdd->useMinimapWaterColor = config->useMinimapWaterColor; - fdd->useCloseRiverColorForDB = config->useCloseRiverColorForDB; - } - if (config->waterColorParams == EParameterSource::eDatabase) - { - auto fdd = mapRenderPlan->frameDependentData; - fdd->liquidColors = liquidColors; - } else if (config->waterColorParams == EParameterSource::eConfig) { - auto fdd = mapRenderPlan->frameDependentData; - fdd->liquidColors.closeRiverColor_shallowAlpha = config->closeRiverColor; - fdd->liquidColors.farRiverColor_deepAlpha = config->farRiverColor; - fdd->liquidColors.closeOceanColor_shallowAlpha = config->closeOceanColor; - fdd->liquidColors.farOceanColor_deepAlpha = config->farOceanColor; - } - if (config->skyParams == EParameterSource::eDatabase) { - auto fdd = mapRenderPlan->frameDependentData; - fdd->skyColors = skyColors; - } - } - - //Handle fog - { - std::vector combinedResults = {}; - float totalSummator = 0.0; - - //Apply fog from WMO - { - for (auto &wmoFog : wmoFogData) { - auto &lightResult = combinedResults.emplace_back(); - auto farPlaneClamped = std::min(config->farPlane, wmoFog.end); - - std::array colorConverted; - ImVectorToArrBGR(colorConverted, wmoFog.color); - - lightResult.FogEnd = farPlaneClamped; - lightResult.FogStart = farPlaneClamped * wmoFog.start_scalar; - lightResult.SkyFogColor = colorConverted; - lightResult.FogDensity = 1.0; - lightResult.FogHeightColor = colorConverted; - lightResult.EndFogColor = colorConverted; - lightResult.SunFogColor = colorConverted; - lightResult.HeightEndFogColor = colorConverted; - - if (farPlaneClamped < 30.f) { - lightResult.FogEnd = farPlaneClamped; - farPlaneClamped = 30.f; - } - - bool mapHasWeightedBlendFlag = false; - if (!mapHasWeightedBlendFlag) { - float difference = farPlaneClamped - lightResult.FogStart; - float farPlaneClamped2 = std::min(config->farPlane, 700.0f) - 200.0f; - if ((difference > farPlaneClamped2) || (farPlaneClamped2 <= 0.0f)) { - lightResult.FogDensity = 1.5; - } else { - lightResult.FogDensity = ((1.0 - (difference / farPlaneClamped2)) * 5.5) + 1.5; - } - lightResult.FogEnd = config->farPlane; - if (lightResult.FogStart < 0.0f) - lightResult.FogStart = 0.0; - } - - lightResult.FogHeightDensity = lightResult.FogDensity; - lightResult.FogStartOffset = 0; - lightResult.FogHeightScaler = 1.0; - lightResult.FogZScalar = 0; - lightResult.FogHeight = -10000.0; - lightResult.LegacyFogScalar = 1.0; - lightResult.EndFogColorDistance = 10000.0; - } - } - - //Apply fogs from lights - if (totalSummator < 1.0) { - if (config->globalFog == EParameterSource::eDatabase) { - - } else if (config->globalFog == EParameterSource::eConfig) { - LightResult globalFog; - globalFog.FogScaler = config->fogResult.FogScaler; - globalFog.FogEnd = config->fogResult.FogEnd; - globalFog.FogDensity = config->fogResult.FogDensity; - - globalFog.FogHeightScaler = config->fogResult.FogHeightScaler; - globalFog.FogHeightDensity = config->fogResult.FogHeightDensity; - globalFog.SunFogAngle = config->fogResult.SunFogAngle; - globalFog.EndFogColorDistance = config->fogResult.EndFogColorDistance; - globalFog.SunFogStrength = config->fogResult.SunFogStrength; - - globalFog.blendCoef = 1.0 - totalSummator; - globalFog.isDefault = true; - - globalFog.EndFogColor = {config->fogResult.EndFogColor.z, config->fogResult.EndFogColor.y, config->fogResult.EndFogColor.x}; - globalFog.SunFogColor = {config->fogResult.SunFogColor.z, config->fogResult.SunFogColor.y, config->fogResult.SunFogColor.x}; - globalFog.FogHeightColor = {config->fogResult.FogHeightColor.z, config->fogResult.FogHeightColor.y, config->fogResult.FogHeightColor.x}; - - combinedResults = {globalFog}; - } - } - std::sort(combinedResults.begin(), combinedResults.end(), [](const LightResult &a, const LightResult &b) -> bool { - return a.blendCoef > b.blendCoef; - }); - - //Rebalance blendCoefs - if (totalSummator < 1.0f && totalSummator > 0.0f) { - for (auto &_light : combinedResults) { - _light.blendCoef = _light.blendCoef / totalSummator; - } - } - - //In case of no data -> disable the fog - { - auto fdd = mapRenderPlan->frameDependentData; - fdd->FogDataFound = !combinedResults.empty(); - - auto &fogResult = fdd->fogResults.emplace_back(); - for (auto &_light : lightResults) { - fogResult.FogEnd = mix(fogResult.FogEnd, _light.FogEnd, _light.blendCoef); - fogResult.FogScaler = mix(fogResult.FogScaler, _light.FogScaler, _light.blendCoef); - fogResult.FogDensity = mix(fogResult.FogDensity, _light.FogDensity, _light.blendCoef); - fogResult.FogHeight = mix(fogResult.FogHeight, _light.FogHeight, _light.blendCoef); - fogResult.FogHeightScaler = mix(fogResult.FogHeightScaler, _light.FogHeightScaler, _light.blendCoef); - fogResult.FogHeightDensity = mix(fogResult.FogHeightDensity, _light.FogHeightDensity, _light.blendCoef); - fogResult.SunFogAngle = mix(fogResult.SunFogAngle, _light.SunFogAngle, _light.blendCoef); - if (fdd->overrideValuesWithFinalFog) { - fogResult.FogColor = mix(fogResult.FogColor, mathfu::vec3(_light.EndFogColor[2], _light.EndFogColor[1], _light.EndFogColor[0]), _light.blendCoef); - } else { - fogResult.FogColor = mix(fogResult.FogColor, mathfu::vec3(_light.SkyFogColor[2], _light.SkyFogColor[1], _light.SkyFogColor[0]), _light.blendCoef); - } - fogResult.EndFogColor = mix(fogResult.EndFogColor, mathfu::vec3(_light.EndFogColor[2], _light.EndFogColor[1], _light.EndFogColor[0]), _light.blendCoef); - fogResult.EndFogColorDistance = mix(fogResult.EndFogColorDistance, _light.EndFogColorDistance, _light.blendCoef); - fogResult.SunFogColor = mix(fogResult.SunFogColor, mathfu::vec3(_light.SunFogColor[2], _light.SunFogColor[1], _light.SunFogColor[0]), _light.blendCoef); - fogResult.SunFogStrength = mix(fogResult.SunFogStrength, _light.SunFogStrength, _light.blendCoef); - fogResult.FogHeightColor = mix(fogResult.FogHeightColor, mathfu::vec3(_light.FogHeightColor[2], _light.FogHeightColor[1], _light.FogHeightColor[0]), _light.blendCoef); - fogResult.FogHeightCoefficients = mix( - fogResult.FogHeightCoefficients, - mathfu::vec4(_light.FogHeightCoefficients[3], _light.FogHeightCoefficients[2], - _light.FogHeightCoefficients[1], _light.FogHeightCoefficients[0]), _light.blendCoef); - fogResult.MainFogCoefficients = mix( - fogResult.MainFogCoefficients, - mathfu::vec4(_light.MainFogCoefficients[3], _light.MainFogCoefficients[2], - _light.MainFogCoefficients[1], _light.MainFogCoefficients[0]), _light.blendCoef); - fogResult.HeightDensityFogCoefficients = mix( - fogResult.HeightDensityFogCoefficients, - mathfu::vec4(_light.HeightDensityFogCoefficients[3], - _light.HeightDensityFogCoefficients[2], - _light.HeightDensityFogCoefficients[1], - _light.HeightDensityFogCoefficients[0]), _light.blendCoef); - - fogResult.FogZScalar = mix(fogResult.FogZScalar, _light.FogZScalar, _light.blendCoef); - fogResult.LegacyFogScalar = mix(fogResult.LegacyFogScalar, _light.LegacyFogScalar, _light.blendCoef); - fogResult.MainFogStartDist = mix(fogResult.MainFogStartDist, _light.MainFogStartDist, _light.blendCoef); - fogResult.MainFogEndDist = mix(fogResult.MainFogEndDist, _light.MainFogEndDist, _light.blendCoef); - fogResult.FogBlendAlpha = mix(fogResult.FogBlendAlpha, _light.blendCoef, _light.blendCoef); - fogResult.HeightEndFogColor = mix(fogResult.HeightEndFogColor, mathfu::vec3(_light.HeightEndFogColor[2], _light.HeightEndFogColor[1], _light.HeightEndFogColor[0]), _light.blendCoef); - fogResult.FogStartOffset = mix(fogResult.FogStartOffset, _light.FogStartOffset, _light.blendCoef); - } - } - } + dayNightLightHolder.updateLightAndSkyboxData(mapRenderPlan, frustumData, stateForConditions, areaRecord); } -template -inline float getFloatFromInt(int value) { - if constexpr (T == 0) { - return (value & 0xFF) / 255.0f; - } - if constexpr (T == 1) { - return ((value >> 8) & 0xFF) / 255.0f; - } - if constexpr (T == 2) { - return ((value >> 16) & 0xFF) / 255.0f; - } -} - -inline mathfu::vec3 intToColor3(int a) { - //BGR - return mathfu::vec3( - getFloatFromInt<2>(a), - getFloatFromInt<1>(a), - getFloatFromInt<0>(a) - ); -} -inline mathfu::vec4 intToColor4(int a) { - //BGRA - return mathfu::vec4( - getFloatFromInt<2>(a), - getFloatFromInt<1>(a), - getFloatFromInt<0>(a), - getFloatFromInt<3>(a) - ); -} -inline mathfu::vec4 floatArr(std::array a) { - //BGRA - return mathfu::vec4( - a[3], - a[2], - a[1], - a[0] - ); -} - -template -decltype(auto) mixMembers(LightParamData& data, T LightTimedData::*member, float blendTimeCoeff) { - if constexpr (C == 3) { - static_assert(std::is_same::value, "the type must be int for vector component"); - return mix(intToColor3(data.lightTimedData[0].*member), intToColor3(data.lightTimedData[0].*member), blendTimeCoeff); - } - if constexpr (C == 4 && std::is_same>::value) { - return mix(floatArr(data.lightTimedData[0].*member), floatArr(data.lightTimedData[1].*member), blendTimeCoeff); - } else if constexpr (C == 4) { - static_assert(std::is_same::value, "the type must be int for vector component"); - return mix(intToColor4(data.lightTimedData[0].*member), intToColor4(data.lightTimedData[0].*member), blendTimeCoeff); - } - if constexpr (C == 1) { - static_assert(std::is_same::value, "the type must be float for one component"); - return mix(data.lightTimedData[0].*member, data.lightTimedData[0].*member, blendTimeCoeff); - } -} - -void Map::getLightResultsFromDB(mathfu::vec3 &cameraVec3, const Config *config, - SkyColors &skyColors, - ExteriorColors &exteriorColors, - FogResult &fogResult, - LiquidColors &liquidColors, - StateForConditions *stateForConditions) { - if (m_api->databaseHandler == nullptr) - return ; - - LightResult zoneLightResult; - - bool zoneLightFound = false; - int LightId; - for (const auto &zoneLight : m_zoneLights) { - CAaBox laabb = zoneLight.aabb; - auto const vec50 = mathfu::vec3(50.0f,50.0f,0); - laabb.min = (mathfu::vec3(laabb.min) - vec50); - laabb.max = (mathfu::vec3(laabb.max) + vec50); - if (MathHelper::isPointInsideNonConvex(cameraVec3, zoneLight.aabb, zoneLight.points)) { - zoneLightFound = true; - - if (stateForConditions != nullptr) { - stateForConditions->currentZoneLights.push_back(zoneLight.ID); - } - LightId = zoneLight.LightID; - break; - } - } - - uint8_t currentLightParamIdIndex = 0; - - int selectedLightParam = 0; - int selectedLightId = 0; - - if (zoneLightFound) { - selectedLightId = LightId; - m_api->databaseHandler->getLightById(LightId, config->currentTime, zoneLightResult); - if (stateForConditions != nullptr) { - selectedLightParam = zoneLightResult.lightParamId[currentLightParamIdIndex]; - stateForConditions->currentZoneLights.push_back(zoneLightResult.lightParamId[currentLightParamIdIndex]); - } - } - - //Get light from DB - std::vector lightResults; - m_api->databaseHandler->getEnvInfo(m_mapId, - cameraVec3.x, - cameraVec3.y, - cameraVec3.z, - lightResults - ); - std::sort(lightResults.begin(), lightResults.end(), [](const LightResult &a, const LightResult &b) -> bool { - return a.blendAlpha > b.blendAlpha; - }); - - - for (auto it = lightResults.begin(); it != lightResults.end(); it++) { - if (feq(it->pos[0], 0.0) && feq(it->pos[1], 0.0) && feq(it->pos[2], 0.0)) { - //This is default record. If zoneLight was selected -> skip it. - if (!zoneLightFound) { - selectedLightParam = it->lightParamId[currentLightParamIdIndex]; - selectedLightId = it->id; - } - } else { - selectedLightParam = it->lightParamId[currentLightParamIdIndex]; - selectedLightId = it->id; - break; - } - } - - if (stateForConditions != nullptr) { - stateForConditions->currentZoneLights.push_back(selectedLightParam); - stateForConditions->currentLightIds.push_back(selectedLightId); - } - - LightParamData lightParamData; - if (m_api->databaseHandler->getLightParamData(selectedLightParam, config->currentTime, lightParamData)) { - - float blendTimeCoeff = (config->currentTime - lightParamData.lightTimedData[0].time) / (float)(lightParamData.lightTimedData[1].time - lightParamData.lightTimedData[0].time); - - auto &dataA = lightParamData.lightTimedData[0]; - auto &dataB = lightParamData.lightTimedData[1]; - //Blend two times using certain rules - - //Ambient lights - exteriorColors.exteriorAmbientColor = mixMembers<4>(lightParamData, &LightTimedData::ambientLight, blendTimeCoeff); - exteriorColors.exteriorGroundAmbientColor = mixMembers<4>(lightParamData, &LightTimedData::groundAmbientColor, blendTimeCoeff); - exteriorColors.exteriorHorizontAmbientColor = mixMembers<4>(lightParamData, &LightTimedData::horizontAmbientColor, blendTimeCoeff); - exteriorColors.exteriorDirectColor = mixMembers<4>(lightParamData, &LightTimedData::directColor, blendTimeCoeff); - - //Liquid colors - liquidColors.closeOceanColor_shallowAlpha = mixMembers<4>(lightParamData, &LightTimedData::closeOceanColor, blendTimeCoeff); - liquidColors.farOceanColor_deepAlpha = mixMembers<4>(lightParamData, &LightTimedData::farOceanColor, blendTimeCoeff); - liquidColors.closeRiverColor_shallowAlpha = mixMembers<4>(lightParamData, &LightTimedData::closeRiverColor, blendTimeCoeff); - liquidColors.farRiverColor_deepAlpha = mixMembers<4>(lightParamData, &LightTimedData::farRiverColor, blendTimeCoeff); - - liquidColors.closeOceanColor_shallowAlpha.w = lightParamData.oceanShallowAlpha; - liquidColors.farOceanColor_deepAlpha.w = lightParamData.oceanDeepAlpha; - liquidColors.closeRiverColor_shallowAlpha.w = lightParamData.waterShallowAlpha; - liquidColors.farRiverColor_deepAlpha.w = lightParamData.waterDeepAlpha; - - //SkyColors - skyColors.SkyTopColor = mixMembers<4>(lightParamData, &LightTimedData::SkyTopColor, blendTimeCoeff); - skyColors.SkyMiddleColor = mixMembers<4>(lightParamData, &LightTimedData::SkyMiddleColor, blendTimeCoeff); - skyColors.SkyBand1Color = mixMembers<4>(lightParamData, &LightTimedData::SkyBand1Color, blendTimeCoeff); - skyColors.SkyBand2Color = mixMembers<4>(lightParamData, &LightTimedData::SkyBand2Color, blendTimeCoeff); - skyColors.SkySmogColor = mixMembers<4>(lightParamData, &LightTimedData::SkySmogColor, blendTimeCoeff); - skyColors.SkyFogColor = mixMembers<4>(lightParamData, &LightTimedData::SkyFogColor, blendTimeCoeff); - - //Fog! - fogResult.FogEnd = mixMembers<1>(lightParamData, &LightTimedData::FogEnd, blendTimeCoeff); - fogResult.FogScaler = mixMembers<1>(lightParamData, &LightTimedData::FogScaler, blendTimeCoeff); - fogResult.FogDensity = mixMembers<1>(lightParamData, &LightTimedData::FogDensity, blendTimeCoeff); - fogResult.FogHeight = mixMembers<1>(lightParamData, &LightTimedData::FogHeight, blendTimeCoeff); - fogResult.FogHeightScaler = mixMembers<1>(lightParamData, &LightTimedData::FogHeightScaler, blendTimeCoeff); - fogResult.FogHeightDensity = mixMembers<1>(lightParamData, &LightTimedData::FogHeightDensity, blendTimeCoeff); - fogResult.SunFogAngle = mixMembers<1>(lightParamData, &LightTimedData::SunFogAngle, blendTimeCoeff); - - if (false) {//fdd->overrideValuesWithFinalFog) { - fogResult.FogColor = mixMembers<3>(lightParamData, &LightTimedData::EndFogColor, blendTimeCoeff); - } else { - fogResult.FogColor = mixMembers<3>(lightParamData, &LightTimedData::SkyFogColor, blendTimeCoeff); - } - - fogResult.EndFogColor = mixMembers<3>(lightParamData, &LightTimedData::EndFogColor, blendTimeCoeff); - fogResult.EndFogColorDistance = mixMembers<1>(lightParamData, &LightTimedData::EndFogColorDistance, blendTimeCoeff); - fogResult.SunFogColor = mixMembers<3>(lightParamData, &LightTimedData::SunFogColor, blendTimeCoeff); - fogResult.SunFogStrength = mixMembers<1>(lightParamData, &LightTimedData::SunFogStrength, blendTimeCoeff); - fogResult.FogHeightColor = mixMembers<3>(lightParamData, &LightTimedData::FogHeightColor, blendTimeCoeff); - fogResult.FogHeightCoefficients = mixMembers<4>(lightParamData, &LightTimedData::FogHeightCoefficients, blendTimeCoeff); - fogResult.MainFogCoefficients = mixMembers<4>(lightParamData, &LightTimedData::MainFogCoefficients, blendTimeCoeff); - fogResult.HeightDensityFogCoefficients = mixMembers<4>(lightParamData, &LightTimedData::MainFogCoefficients, blendTimeCoeff); - - fogResult.FogZScalar = mixMembers<1>(lightParamData, &LightTimedData::FogZScalar, blendTimeCoeff); -// fogResult.LegacyFogScalar = mixMembers<1>(lightParamData, &LightTimedData::LegacyFogScalar, blendTimeCoeff); - fogResult.MainFogStartDist = mixMembers<1>(lightParamData, &LightTimedData::MainFogStartDist, blendTimeCoeff); - fogResult.MainFogEndDist = mixMembers<1>(lightParamData, &LightTimedData::MainFogEndDist, blendTimeCoeff); -// fogResult.FogBlendAlpha = mixMembers<1>(lightParamData, &LightTimedData::FogBlendAlpha, blendTimeCoeff); - fogResult.HeightEndFogColor = mixMembers<3>(lightParamData, &LightTimedData::EndFogHeightColor, blendTimeCoeff); - fogResult.FogStartOffset = mixMembers<1>(lightParamData, &LightTimedData::FogStartOffset, blendTimeCoeff); - - } -} void Map::getPotentialEntities(const MathHelper::FrustumCullingData &frustumData, const mathfu::vec4 &cameraPos, const HMapRenderPlan &mapRenderPlan, @@ -1878,45 +1395,3 @@ std::shared_ptr Map::getWmoObject(int fileDataId, SMMapObjDefObj1 &ma animTime_t Map::getCurrentSceneTime() { return m_currentTime; } - -void Map::loadZoneLights() { - if (m_api->databaseHandler != nullptr) { - std::vector zoneLights; - m_api->databaseHandler->getZoneLightsForMap(m_mapId, zoneLights); - - for (const auto &zoneLight : zoneLights) { - mapInnerZoneLightRecord innerZoneLightRecord; - innerZoneLightRecord.ID = zoneLight.ID; - innerZoneLightRecord.name = zoneLight.name; - innerZoneLightRecord.LightID = zoneLight.LightID; -// innerZoneLightRecord.Zmin = zoneLight.Zmin; -// innerZoneLightRecord.Zmax = zoneLight.Zmax; - - float minX = 9999; float maxX = -9999; - float minY = 9999; float maxY = -9999; - - auto &points = innerZoneLightRecord.points; - for (auto &zonePoint : zoneLight.points) { - minX = std::min(zonePoint.x, minX); minY = std::min(zonePoint.y, minY); - maxX = std::max(zonePoint.x, maxX); maxY = std::max(zonePoint.y, maxY); - - points.push_back(mathfu::vec2(zonePoint.x, zonePoint.y)); - } - - innerZoneLightRecord.aabb = CAaBox( - C3Vector(mathfu::vec3(minX, minY, zoneLight.Zmin)), - C3Vector(mathfu::vec3(maxX, maxY, zoneLight.Zmax)) - ); - - auto &lines = innerZoneLightRecord.lines; - for (int i = 0; i < (points.size() - 1); i++) { - lines.push_back(points[i + 1] - points[i]); - } - lines.push_back( points[0] - points[points.size() - 1]); - - m_zoneLights.push_back(innerZoneLightRecord); - } - - } -} - diff --git a/wowViewerLib/src/engine/objects/scenes/map.h b/wowViewerLib/src/engine/objects/scenes/map.h index 89137eb8..183e0214 100644 --- a/wowViewerLib/src/engine/objects/scenes/map.h +++ b/wowViewerLib/src/engine/objects/scenes/map.h @@ -20,6 +20,7 @@ #include "../../../renderer/mapScene/MapScenePlan.h" #include "../../../renderer/mapScene/MapSceneParams.h" #include "../wdt/wdtLightsObject.h" +#include "dayNightDataHolder/DayNightLightHolder.h" enum class SceneMode { smMap, @@ -55,6 +56,7 @@ class Map : public IScene, public IMapApi { std::shared_ptr wmoMap = nullptr; bool useWeightedBlend = false; + bool has0x200000Flag = false; std::vector> m_exteriorSkyBoxes; @@ -115,16 +117,7 @@ class Map : public IScene, public IMapApi { virtual void updateLightAndSkyboxData(const HMapRenderPlan &mapRenderPlan, MathHelper::FrustumCullingData &frustumData, StateForConditions &stateForConditions, const AreaRecord &areaRecord); - struct mapInnerZoneLightRecord { - int ID; - std::string name; - int LightID; - CAaBox aabb; - std::vector points; - std::vector lines; - }; - std::vector m_zoneLights; - void loadZoneLights(); + DayNightLightHolder dayNightLightHolder; FreeStrategy adtFreeLambda; FreeStrategy zeroStateLambda; @@ -132,12 +125,12 @@ class Map : public IScene, public IMapApi { HADTRenderConfigDataHolder m_adtConfigHolder = nullptr; protected: - explicit Map() { + explicit Map() : dayNightLightHolder(nullptr, -1) { } public: explicit Map(HApiContainer api, int mapId, const std::string &mapName); - explicit Map(HApiContainer api, int mapId, int wdtFileDataId) { + explicit Map(HApiContainer api, int mapId, int wdtFileDataId) : dayNightLightHolder(api, mapId) { initMapTiles(); m_mapId = mapId; m_api = api; mapName = ""; @@ -146,15 +139,16 @@ class Map : public IScene, public IMapApi { MapRecord mapRecord; api->databaseHandler->getMapById(mapId, mapRecord); useWeightedBlend = (mapRecord.flags0 & 0x4) > 0; + has0x200000Flag = (mapRecord.flags0 & 0x200000) > 0; createAdtFreeLamdas(); m_wdtfile = api->cacheStorage->getWdtFileCache()->getFileId(wdtFileDataId); - loadZoneLights(); + dayNightLightHolder.loadZoneLights(); }; - explicit Map(HApiContainer api, std::string adtFileName, int i, int j, std::string mapName) { + explicit Map(HApiContainer api, std::string adtFileName, int i, int j, std::string mapName) : dayNightLightHolder(api, 0) { initMapTiles(); m_mapId = 0; m_api = api; this->mapName = mapName; @@ -205,14 +199,6 @@ class Map : public IScene, public IMapApi { // HDrawStage doGaussBlur(const HDrawStage &parentDrawStage, std::vector &uniformBufferChunks) const; - - void getLightResultsFromDB(mathfu::vec3 &cameraVec3, const Config *config, - SkyColors &skyColors, - ExteriorColors &exteriorColors, - FogResult &fogResult, - LiquidColors &liquidColors, - StateForConditions *stateForConditions) override; - void createAdtFreeLamdas(); }; typedef std::shared_ptr HMapScene; diff --git a/wowViewerLib/src/renderer/mapScene/MapSceneRenderer.cpp b/wowViewerLib/src/renderer/mapScene/MapSceneRenderer.cpp index da266895..a24ae3bd 100644 --- a/wowViewerLib/src/renderer/mapScene/MapSceneRenderer.cpp +++ b/wowViewerLib/src/renderer/mapScene/MapSceneRenderer.cpp @@ -176,10 +176,10 @@ void MapSceneRenderer::updateSceneWideChunk(const std::shared_ptrviewUp.xyz(), sceneTime); - blockPSVS.closeOceanColor = fdd->closeOceanColor; - blockPSVS.farOceanColor = fdd->farOceanColor; - blockPSVS.closeRiverColor = fdd->closeRiverColor; - blockPSVS.farRiverColor = fdd->farRiverColor; + blockPSVS.closeOceanColor = fdd->liquidColors.closeOceanColor_shallowAlpha; + blockPSVS.farOceanColor = fdd->liquidColors.farOceanColor_deepAlpha; + blockPSVS.closeRiverColor = fdd->liquidColors.closeRiverColor_shallowAlpha; + blockPSVS.farRiverColor = fdd->liquidColors.farRiverColor_deepAlpha; blockPSVS.extLight.uExteriorAmbientColor = fdd->colors.exteriorAmbientColor; blockPSVS.extLight.uExteriorHorizontAmbientColor = fdd->colors.exteriorHorizontAmbientColor;