Skip to content

Commit eae9b44

Browse files
authored
hopefully improve speed more
1 parent 7d67ece commit eae9b44

1 file changed

Lines changed: 44 additions & 36 deletions

File tree

src/GameEventHandler.cpp

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace plugin {
2828
std::map<std::tuple<RE::NiNode *, RE::TESNPC *, std::string>, FaceMorphData> queued_morphs;
2929
std::unordered_map<uint32_t, RE::ActorHandle> queued_recalcs;
3030

31-
static void WalkRecalculateNormals(RE::NiNode *node) {
31+
static void WalkRecalculateNormals(RE::NiNode *node, std::recursive_mutex& thread_mutex, std::vector<std::thread>& spawned_threads) {
3232
if (node == nullptr) {
3333
return;
3434
}
@@ -37,7 +37,7 @@ namespace plugin {
3737
continue;
3838
}
3939
if (auto c_node = obj->AsNode()) {
40-
WalkRecalculateNormals(c_node);
40+
WalkRecalculateNormals(c_node,thread_mutex,spawned_threads);
4141
}
4242
if (auto geo = obj->AsGeometry()) {
4343
if (geo->GetGeometryRuntimeData().skinInstance == nullptr) {
@@ -61,35 +61,41 @@ namespace plugin {
6161
if (!material) {
6262
continue;
6363
}
64-
RE::NiPointer<RE::NiObject> newPartition = nullptr;
65-
geo->GetGeometryRuntimeData().skinInstance->skinPartition->CreateDeepCopy(newPartition);
66-
if (!newPartition) {
67-
continue;
68-
}
69-
RE::NiPointer<RE::NiSkinPartition> newSkinPartition =
70-
RE::NiPointer<RE::NiSkinPartition>((RE::NiSkinPartition *) newPartition.get());
71-
if (newSkinPartition->partitions.size() == 0) {
72-
newSkinPartition->DecRefCount();
73-
continue;
74-
}
7564
{
76-
NormalApplicatorBackported applicator(RE::NiPointer<RE::BSGeometry>((RE::BSGeometry *) geo), newSkinPartition);
77-
applicator.Apply();
78-
}
79-
for (uint32_t p = 1; p < newSkinPartition->partitions.size(); ++p) {
80-
auto &pPartition = newSkinPartition->partitions[p];
81-
memcpy(pPartition.buffData->rawVertexData, newSkinPartition->partitions[0].buffData->rawVertexData,
82-
newSkinPartition->vertexCount * newSkinPartition->partitions[0].buffData->vertexDesc.GetSize());
83-
}
84-
uint64_t UpdateSkinPartition_object[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
85-
UpdateSkinPartition_object[0] = NIOVTaskUpdateSkinPartitionvtable;
65+
std::lock_guard<std::recursive_mutex> l(thread_mutex);
66+
spawned_threads.push_back(std::thread([=]() {
67+
RE::NiPointer<RE::NiObject> newPartition = nullptr;
68+
geo->GetGeometryRuntimeData().skinInstance->skinPartition->CreateDeepCopy(newPartition);
69+
if (!newPartition) {
70+
return;
71+
}
72+
RE::NiPointer<RE::NiSkinPartition> newSkinPartition =
73+
RE::NiPointer<RE::NiSkinPartition>((RE::NiSkinPartition *) newPartition.get());
74+
if (newSkinPartition->partitions.size() == 0) {
75+
newSkinPartition->DecRefCount();
76+
return;
77+
}
78+
{
79+
NormalApplicatorBackported applicator(RE::NiPointer<RE::BSGeometry>((RE::BSGeometry *) geo), newSkinPartition);
80+
applicator.Apply();
81+
}
82+
for (uint32_t p = 1; p < newSkinPartition->partitions.size(); ++p) {
83+
auto &pPartition = newSkinPartition->partitions[p];
84+
memcpy(pPartition.buffData->rawVertexData, newSkinPartition->partitions[0].buffData->rawVertexData,
85+
newSkinPartition->vertexCount * newSkinPartition->partitions[0].buffData->vertexDesc.GetSize());
86+
}
87+
uint64_t UpdateSkinPartition_object[6] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
88+
UpdateSkinPartition_object[0] = NIOVTaskUpdateSkinPartitionvtable;
89+
90+
uint64_t *skinInstPtr = (uint64_t *) (geo->GetGeometryRuntimeData().skinInstance.get());
91+
uint64_t *skinPartPtr = (uint64_t *) (newSkinPartition.get());
92+
UpdateSkinPartition_object[1] = (uint64_t) skinPartPtr;
93+
UpdateSkinPartition_object[2] = (uint64_t) skinInstPtr;
94+
auto RunNIOVTaskUpdateSkinPartition = ((void (*)(uint64_t *))((uint64_t *) UpdateSkinPartition_object[0])[0]);
95+
RunNIOVTaskUpdateSkinPartition(UpdateSkinPartition_object);
96+
}));
8697

87-
uint64_t *skinInstPtr = (uint64_t *) (geo->GetGeometryRuntimeData().skinInstance.get());
88-
uint64_t *skinPartPtr = (uint64_t *) (newSkinPartition.get());
89-
UpdateSkinPartition_object[1] = (uint64_t) skinPartPtr;
90-
UpdateSkinPartition_object[2] = (uint64_t) skinInstPtr;
91-
auto RunNIOVTaskUpdateSkinPartition = ((void (*)(uint64_t *))((uint64_t *) UpdateSkinPartition_object[0])[0]);
92-
RunNIOVTaskUpdateSkinPartition(UpdateSkinPartition_object);
98+
}
9399
}
94100
}
95101
}
@@ -118,23 +124,29 @@ namespace plugin {
118124
std::vector<std::thread> spawned_threads;
119125
for (auto p: temp_recalcs) {
120126
spawned_threads.push_back(std::thread([hp = p]() {
127+
std::recursive_mutex thread_mutex;
128+
std::vector<std::thread> spawned_threads_recalc;
121129
auto actor = hp.second.get();
122130
if (actor->Is3DLoaded()) {
123131
if (auto obj = actor->Get3D1(true)) {
124132
if (auto node = obj->AsNode()) {
125-
WalkRecalculateNormals(node);
133+
134+
WalkRecalculateNormals(node,thread_mutex,spawned_threads_recalc);
126135
}
127136
}
128137
if (auto obj = actor->Get3D1(false)) {
129138
if (auto node = obj->AsNode()) {
130-
WalkRecalculateNormals(node);
139+
WalkRecalculateNormals(node, thread_mutex, spawned_threads_recalc);
131140
}
132141
}
133142
if (auto facenode = actor->GetFaceNode()) {
134143
UpdateFaceModel(facenode);
135-
WalkRecalculateNormals(facenode);
144+
WalkRecalculateNormals(facenode, thread_mutex, spawned_threads_recalc);
136145
}
137146
}
147+
for (auto &t : spawned_threads_recalc) {
148+
t.join();
149+
}
138150
actor->DecRefCount();
139151
}));
140152
}
@@ -222,7 +234,6 @@ namespace plugin {
222234
AddActorToRecalculate(actor.get());
223235
}
224236
}
225-
WalkRecalculateNormals(node);
226237
}
227238
}
228239
static void (*ApplyMorphHookFaceNormalsDetour)(void *e, RE::TESNPC *, RE::BGSHeadPart *,
@@ -236,7 +247,6 @@ namespace plugin {
236247
AddActorToRecalculate(actor.get());
237248
}
238249
}
239-
WalkRecalculateNormals(node);
240250
}
241251
}
242252
static void (*ApplyMorphsHookBodyNormalsDetour)(void *e, RE::TESObjectREFR *, RE::NiNode *, bool isAttaching,
@@ -246,14 +256,12 @@ namespace plugin {
246256
ApplyMorphsHookBodyNormalsDetour(morphInterface, refr, node, isAttaching, defer);
247257
if (node) {
248258
if (node->AsNode()) {
249-
WalkRecalculateNormals(node);
250259
if (auto actor = refr->As<RE::Actor>()) {
251260
if (actor->Is3DLoaded()) {
252261
AddActorToRecalculate(actor);
253262
}
254263
}
255264
}
256-
WalkRecalculateNormals(node);
257265
}
258266
}
259267
void GameEventHandler::onLoad() {

0 commit comments

Comments
 (0)