@@ -62,77 +62,73 @@ namespace plugin {
6262 std::recursive_mutex recalcs_in_progress_lock;
6363 std::unordered_map<RE ::FormID,RecalcProgressData> recalcs_in_progress;
6464 uint64_t recalc_tasks_started = 0 ;
65- static void ProcessRecalcQueue (RE ::NiPointer<RE ::BSGeometry> geo) {
65+ static RE ::NiSkinPartition * ProcessRecalcQueue (RE ::NiPointer<RE ::BSGeometry>& geo) {
6666 if (GetUserDataFixed (geo.get ()) == nullptr ) {
6767 logger::info (" geometry doesn't have user data" );
68- return ;
68+ return nullptr ;
6969 }
7070 if (!geo->parent ) {
7171 logger::info (" geometry has no parent" );
72- return ;
72+ return nullptr ;
7373 }
74- if (geo->GetRefCount () <= 1 ) {
75- logger::info (" geometry not referenced" );
76- return ;
74+ logger::info (" old geo ref count before recalc {} {}" , geo->name .c_str (), geo->GetRefCount ());
75+ if (geo->GetRefCount () <= 2 ) {
76+ logger::info (" geometry not referenced by anything else" );
77+ return nullptr ;
7778 }
7879 if (geo->GetGeometryRuntimeData ().skinInstance == nullptr ) {
79- return ;
80+ return nullptr ;
8081 }
8182 if (geo->GetGeometryRuntimeData ().skinInstance ->skinPartition == nullptr ) {
82- return ;
83+ return nullptr ;
8384 }
8485 if ((!geo->GetGeometryRuntimeData ().vertexDesc .HasFlag (RE ::BSGraphics::Vertex::VF_NORMAL )) &&
8586 (!geo->GetGeometryRuntimeData ().vertexDesc .HasFlag (RE ::BSGraphics::Vertex::VF_TANGENT ))) {
86- return ;
87+ return nullptr ;
8788 }
8889 if (!geo->GetGeometryRuntimeData ().properties [RE ::BSGeometry::States::kEffect ] ||
8990 !geo->GetGeometryRuntimeData ().properties [RE ::BSGeometry::States::kEffect ]->GetRTTI ()->IsKindOf (
9091 (RE ::NiRTTI *) RE ::BSShaderProperty::Ni_RTTI.address ())) {
91- return ;
92+ return nullptr ;
9293 }
9394 RE ::BSShaderProperty *property =
9495 (RE ::BSShaderProperty *) geo->GetGeometryRuntimeData ().properties [RE ::BSGeometry::States::kEffect ].get ();
9596 auto material = property->material ;
9697 if (!material) {
97- return ;
98+ return nullptr ;
9899 }
99- RE ::NiPointer<RE ::NiObject> newPartition = nullptr ;
100- geo->GetGeometryRuntimeData ().skinInstance ->skinPartition ->CreateDeepCopy (newPartition);
101- if (!newPartition) {
102- return ;
103- }
104- RE ::NiPointer<RE ::NiSkinPartition> newSkinPartition =
105- RE ::NiPointer<RE ::NiSkinPartition>((RE ::NiSkinPartition *) newPartition.get ());
100+
101+ RE ::NiPointer<RE ::NiSkinPartition> newSkinPartition = geo->GetGeometryRuntimeData ().skinInstance ->skinPartition ;
106102
107103 if (newSkinPartition->partitions .size () == 0 ) {
108- newSkinPartition->DecRefCount ();
109- return ;
104+ return nullptr ;
110105 }
111- logger::info (" new skin partition ref count {}" ,newSkinPartition->GetRefCount ());
112- logger::info (" old skin instance ref count {}" , geo->GetGeometryRuntimeData ().skinInstance ->GetRefCount ());
106+
113107 {
114108 NormalApplicatorBackported applicator (RE ::NiPointer<RE ::BSGeometry>((RE ::BSGeometry *) geo.get ()), newSkinPartition);
115109 applicator.Apply ();
116110 for (uint32_t p = 1 ; p < newSkinPartition->partitions .size (); ++p) {
117111 auto &pPartition = newSkinPartition->partitions [p];
118112 memcpy (pPartition.buffData ->rawVertexData , newSkinPartition->partitions [0 ].buffData ->rawVertexData ,
119- newSkinPartition->vertexCount * newSkinPartition->partitions [0 ].buffData ->vertexDesc .GetSize ());
113+ (( size_t ) newSkinPartition->vertexCount ) * newSkinPartition->partitions [0 ].buffData ->vertexDesc .GetSize ());
120114 }
115+ logger::info (" new skin partition ref count before update {} {}" , geo->name .c_str (), newSkinPartition->GetRefCount ());
116+ logger::info (" old skin instance ref count before update {} {}" , geo->name .c_str (),
117+ geo->GetGeometryRuntimeData ().skinInstance ->GetRefCount ());
121118 uint64_t UpdateSkinPartition_object[6 ] = {0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 };
122119 UpdateSkinPartition_object[0 ] = NIOVTaskUpdateSkinPartitionvtable;
123- geo->GetGeometryRuntimeData ().skinInstance ->IncRefCount (); // skee64 decrements ref count with NiPointer destructor
124120 uint64_t *skinInstPtr = (uint64_t *) (geo->GetGeometryRuntimeData ().skinInstance .get ());
125- newSkinPartition->IncRefCount ();// skee64 decrements ref count with NiPointer destructor
126121 uint64_t *skinPartPtr = (uint64_t *) (newSkinPartition.get ());
127122 UpdateSkinPartition_object[1 ] = (uint64_t ) skinPartPtr;
128123 UpdateSkinPartition_object[2 ] = (uint64_t ) skinInstPtr;
129124 auto RunNIOVTaskUpdateSkinPartition = ((void (*)(uint64_t *))((uint64_t *) UpdateSkinPartition_object[0 ])[0 ]);
130125 RunNIOVTaskUpdateSkinPartition (UpdateSkinPartition_object);
131126 property->SetupGeometry (geo.get ());
132127 property->FinishSetupGeometry (geo.get ());
133- newSkinPartition->DecRefCount ();
134- logger::info (" new skin partition ref count after update {}" , newSkinPartition->GetRefCount ());
135- logger::info (" old skin instance ref count after update {}" , geo->GetGeometryRuntimeData ().skinInstance ->GetRefCount ());
128+ logger::info (" new skin partition ref count after update {} {}" , geo->name .c_str (),newSkinPartition->GetRefCount ());
129+ logger::info (" old skin instance ref count after update {} {}" , geo->name .c_str (),
130+ geo->GetGeometryRuntimeData ().skinInstance ->GetRefCount ());
131+ return (RE ::NiSkinPartition*)skinPartPtr;
136132 }
137133 }
138134 static void WalkRecalculateNormals (RE ::FormID actor_id,RE ::NiNode *node, std::vector<std::jthread> &spawned_threads, RecalcProgressData& progress_data) {
@@ -286,8 +282,14 @@ namespace plugin {
286282 recalcs_in_progress.erase (actor_id);
287283 return ;
288284 } else {
289- auto g = rd.geo_queue .front ();
290- ProcessRecalcQueue (g);
285+ auto &g = rd.geo_queue .front ();
286+
287+ auto nsp = ProcessRecalcQueue (g);
288+
289+ if (nsp) {
290+ logger::info (" new skin partition ref count after return {} {}" , g->name .c_str (),
291+ nsp->GetRefCount ());
292+ }
291293 rd.geo_queue .pop ();
292294 }
293295 };
0 commit comments