1717
1818#include " PCH.h"
1919
20+ #include " TerrainHelper.h"
21+
2022#define DLLEXPORT __declspec (dllexport)
2123
2224using namespace std;
2325
24- unordered_set<string> texturesErrorLogged;
26+
2527void SetupLog () {
2628 auto logsFolder = SKSE::log::log_directory ();
2729 if (!logsFolder) {
@@ -35,63 +37,18 @@ void SetupLog() {
3537 spdlog::flush_on (spdlog::level::trace);
3638}
3739
38- struct ExtendedSlots {
39- array<RE::NiSourceTexturePtr, 6 > parallax;
40- };
41- mutex extendedSlotsMutex;
42- unordered_map<uint32_t , ExtendedSlots> extendedSlots;
43-
4440struct BSLightingShader_SetupMaterial
4541{
4642 static void thunk (RE::BSLightingShader* shader, RE::BSLightingShaderMaterialBase const * material)
4743 {
4844 func (shader, material);
4945
50- if (material == nullptr ) {
51- // material is null
52- return ;
53- }
54-
55- ExtendedSlots materialBase;
56- {
57- const lock_guard<mutex> lock (extendedSlotsMutex);
58- if (!extendedSlots.contains (material->hashKey )) {
59- // hash does not exists
60- return ;
61- }
62-
63- materialBase = extendedSlots[material->hashKey ];
64- }
65-
66- // get renderer and shadow state
67- auto shadowState = RE::BSGraphics::RendererShadowState::GetSingleton ();
68-
69- const auto & stateData = RE::BSGraphics::State::GetSingleton ()->GetRuntimeData ();
70-
71- static constexpr size_t ParallaxStartIndex = 16 ; // 16-21
72-
73- // Populate extended slots
74- for (uint32_t textureI = 0 ; textureI < 6 ; ++textureI) {
75- const uint32_t heightIndex = ParallaxStartIndex + textureI;
76- if (materialBase.parallax [textureI] != nullptr && materialBase.parallax [textureI] != stateData.defaultTextureNormalMap ) {
77- shadowState->SetPSTexture (heightIndex, materialBase.parallax [textureI]->rendererTexture );
78- }
79- else {
80- // set default texture, which is empty
81- shadowState->SetPSTexture (heightIndex, nullptr );
82- }
83- }
46+ TerrainHelper::BSLightingShader_SetupMaterial (shader, material);
8447 };
8548
8649 static inline REL::Relocation<decltype (thunk)> func;
8750};
8851
89- RE::TESLandTexture* GetDefaultLandTexture ()
90- {
91- static const auto defaultLandTextureAddress = REL::Relocation<RE::TESLandTexture**>(RELOCATION_ID (514783 , 400936 ));
92- return *defaultLandTextureAddress;
93- }
94-
9552struct TESObjectLAND_SetupMaterial
9653{
9754 static bool thunk (RE::TESObjectLAND* land)
@@ -103,107 +60,17 @@ struct TESObjectLAND_SetupMaterial
10360 return vanResult;
10461 }
10562
106- for (uint32_t quadI = 0 ; quadI < 4 ; ++quadI) {
107- // Get hash key of vanilla material
108- uint32_t hashKey = 0 ;
109-
110- if (land->loadedData ->mesh [quadI] == nullptr ) {
111- // continue if cannot find mesh
112- continue ;
113- }
114-
115- const auto & children = land->loadedData ->mesh [quadI]->GetChildren ();
116- auto geometry = children.empty () ? nullptr : static_cast <RE::BSGeometry*>(children[0 ].get ());
117- if (geometry != nullptr ) {
118- const auto shaderProp = static_cast <RE::BSLightingShaderProperty*>(geometry->GetGeometryRuntimeData ().properties [1 ].get ());
119- if (shaderProp != nullptr ) {
120- hashKey = shaderProp->GetBaseMaterial ()->hashKey ;
121- }
122- }
123-
124- if (hashKey == 0 ) {
125- // continue if cannot find hash key
126- continue ;
127- }
128-
129- {
130- const lock_guard<mutex> lock (extendedSlotsMutex);
131- if (!extendedSlots.contains (hashKey)) {
132- extendedSlots[hashKey] = {};
133- }
134- }
135-
136- // Create array of texture sets (6 tiles)
137- std::array<RE::BGSTextureSet*, 6 > textureSets;
138- auto defTexture = land->loadedData ->defQuadTextures [quadI];
139- if (defTexture != nullptr && defTexture->formID != 0 ) {
140- textureSets[0 ] = defTexture->textureSet ;
141- }
142- else {
143- // this is a default texture
144- textureSets[0 ] = GetDefaultLandTexture ()->textureSet ;
145- }
146- for (uint32_t textureI = 0 ; textureI < 5 ; ++textureI) {
147- auto curTexture = land->loadedData ->quadTextures [quadI][textureI];
148- if (curTexture == nullptr ) {
149- textureSets[textureI + 1 ] = nullptr ;
150- continue ;
151- }
152-
153- if (curTexture->formID == 0 ) {
154- // this is a default texture
155- textureSets[textureI + 1 ] = GetDefaultLandTexture ()->textureSet ;
156- }
157- else {
158- textureSets[textureI + 1 ] = land->loadedData ->quadTextures [quadI][textureI]->textureSet ;
159- }
160- }
161-
162- // Assign textures to material
163- for (uint32_t textureI = 0 ; textureI < 6 ; ++textureI) {
164- if (textureSets[textureI] == nullptr ) {
165- continue ;
166- }
167-
168- auto txSet = textureSets[textureI];
169- if (txSet->GetTexturePath (static_cast <RE::BSTextureSet::Texture>(3 )) != nullptr ) {
170- const lock_guard<mutex> lock (extendedSlotsMutex);
171- txSet->SetTexture (static_cast <RE::BSTextureSet::Texture>(3 ), extendedSlots[hashKey].parallax [textureI]);
172-
173- if (extendedSlots[hashKey].parallax [textureI] == RE::BSGraphics::State::GetSingleton ()->GetRuntimeData ().defaultTextureNormalMap ) {
174- // this file was not found
175- if (get<1 >(texturesErrorLogged.insert (txSet->GetTexturePath (static_cast <RE::BSTextureSet::Texture>(3 ))))) {
176- spdlog::error (" Unable to find parallax map {} while setting up material" , txSet->GetTexturePath (static_cast <RE::BSTextureSet::Texture>(3 )));
177- }
178- }
179- }
180- }
181- }
182-
63+ TerrainHelper::TESObjectLAND_SetupMaterial (land);
18364 return true ;
18465 }
18566
18667 static inline REL::Relocation<decltype (thunk)> func;
18768};
18869
189- void onDataLoaded () {
190- // Get the default landscape texture set for terrain helper
191- const auto defaultLandTextureSet = RE::TESForm::LookupByEditorID<RE::BGSTextureSet>(" LandscapeDefault" );
192-
193- if (defaultLandTextureSet != nullptr ) {
194- spdlog::info (" LandscapeDefault EDID texture set found" );
195- // set default texture set to this one
196- GetDefaultLandTexture ()->textureSet = defaultLandTextureSet;
197- }
198- else {
199- spdlog::info (" LandscapeDefault EDID texture set not found, using default" );
200- }
201- }
202-
20370void MessageHandler (SKSE::MessagingInterface::Message* a_msg) {
20471 switch (a_msg->type ) {
20572 case SKSE::MessagingInterface::kDataLoaded :
206- onDataLoaded ();
73+ TerrainHelper:: onDataLoaded ();
20774 break ;
20875 }
20976}
@@ -235,8 +102,7 @@ extern "C" DLLEXPORT constinit auto SKSEPlugin_Version = []() noexcept {
235102 return v;
236103 }();
237104
238- extern " C" DLLEXPORT bool SKSEAPI SKSEPlugin_Query (const SKSE::QueryInterface*, SKSE::PluginInfo* pluginInfo)
239- {
105+ extern " C" DLLEXPORT bool SKSEAPI SKSEPlugin_Query (const SKSE::QueryInterface*, SKSE::PluginInfo* pluginInfo) {
240106 pluginInfo->name = SKSEPlugin_Version.pluginName ;
241107 pluginInfo->infoVersion = SKSE::PluginInfo::kVersion ;
242108 pluginInfo->version = SKSEPlugin_Version.pluginVersion ;
0 commit comments