@@ -20,6 +20,7 @@ public record SkinningContext(List<BoneNodeBuilder> Bones, BoneNodeBuilder? Root
20
20
private readonly ComposerCache composerCache ;
21
21
private readonly Configuration . ExportConfiguration exportConfig ;
22
22
private readonly CancellationToken cancellationToken ;
23
+ private readonly Dictionary < ParsedCharacterInfo , Dictionary < string , MaterialBuilder > > materialCache = new ( ) ;
23
24
24
25
public CharacterComposer ( ComposerCache composerCache , Configuration . ExportConfiguration exportConfig , CancellationToken cancellationToken )
25
26
{
@@ -42,12 +43,12 @@ private void HandleModel(ParsedCharacterInfo characterInfo, ParsedModelInfo m, S
42
43
{
43
44
if ( m . Path . GamePath . Contains ( "b0003_top" ) )
44
45
{
45
- Plugin . Logger ? . LogDebug ( "Skipping model {ModelPath}" , m . Path . GamePath ) ;
46
+ Plugin . Logger . LogDebug ( "Skipping model {ModelPath}" , m . Path . GamePath ) ;
46
47
return ;
47
48
}
48
49
49
50
var mdlFile = composerCache . GetMdlFile ( m . Path . FullPath ) ;
50
- Plugin . Logger ? . LogInformation ( "Loaded model {modelPath}" , m . Path . FullPath ) ;
51
+ Plugin . Logger . LogInformation ( "Loaded model {modelPath}" , m . Path . FullPath ) ;
51
52
var materialBuilders = new MaterialBuilder [ m . Materials . Length ] ;
52
53
for ( int i = 0 ; i < m . Materials . Length ; i ++ )
53
54
{
@@ -60,14 +61,26 @@ private void HandleModel(ParsedCharacterInfo characterInfo, ParsedModelInfo m, S
60
61
61
62
try
62
63
{
63
- materialBuilders [ i ] = composerCache . ComposeMaterial ( materialInfo . Path . FullPath ,
64
- materialInfo : materialInfo ,
65
- characterInfo : characterInfo ,
66
- colorTableSet : materialInfo . ColorTable ) ;
64
+ if ( ! materialCache . TryGetValue ( characterInfo , out var characterCache ) )
65
+ {
66
+ characterCache = new Dictionary < string , MaterialBuilder > ( ) ;
67
+ materialCache [ characterInfo ] = characterCache ;
68
+ }
69
+
70
+ if ( characterCache . TryGetValue ( materialInfo . GetHash ( ) , out var cachedBuilder ) )
71
+ {
72
+ materialBuilders [ i ] = cachedBuilder ;
73
+ }
74
+ else
75
+ {
76
+ materialBuilders [ i ] = composerCache . ComposeMaterial ( materialInfo . Path . FullPath ,
77
+ materialInfo : materialInfo ,
78
+ characterInfo : characterInfo ) ;
79
+ }
67
80
}
68
81
catch ( Exception e )
69
82
{
70
- Plugin . Logger ? . LogError ( e , "Failed to load material\n {Message}\n {MaterialInfo}" , e . Message ,
83
+ Plugin . Logger . LogError ( e , "Failed to load material\n {Message}\n {MaterialInfo}" , e . Message ,
71
84
JsonSerializer . Serialize ( m . Materials [ i ] ,
72
85
MaterialComposer . JsonOptions ) ) ;
73
86
materialBuilders [ i ] = new MaterialBuilder ( "error" ) ;
@@ -91,7 +104,7 @@ private void HandleModel(ParsedCharacterInfo characterInfo, ParsedModelInfo m, S
91
104
deform = ( ( GenderRace ) m . Deformer . Value . DeformerId ,
92
105
( GenderRace ) m . Deformer . Value . RaceSexId ,
93
106
new RaceDeformer ( pbdFile , skinningContext . Bones ) ) ;
94
- Plugin . Logger ? . LogDebug ( "Using deformer pbd {Path}" , m . Deformer . Value . PbdPath ) ;
107
+ Plugin . Logger . LogDebug ( "Using deformer pbd {Path}" , m . Deformer . Value . PbdPath ) ;
95
108
}
96
109
else
97
110
{
@@ -197,7 +210,7 @@ private bool HandleAttach((ParsedCharacterInfo Owner, List<BoneNodeBuilder> Owne
197
210
if ( rootBone == null ) throw new InvalidOperationException ( "Root bone not found" ) ;
198
211
var attachName = attachData . Owner . Skeleton . PartialSkeletons [ attach . PartialSkeletonIdx ]
199
212
. HkSkeleton ! . BoneNames [ ( int ) attach . BoneIdx ] ;
200
- Plugin . Logger ? . LogInformation ( "Attaching {AttachName} to {RootBone}" , attachName , rootBone . BoneName ) ;
213
+ Plugin . Logger . LogInformation ( "Attaching {AttachName} to {RootBone}" , attachName , rootBone . BoneName ) ;
201
214
lock ( attachLock )
202
215
{
203
216
Interlocked . Increment ( ref attachSuffix ) ;
@@ -252,11 +265,11 @@ private bool HandleRootAttach(
252
265
var rootAttach = characterInfo . Attaches . FirstOrDefault ( x => x . Attach . ExecuteType == 0 ) ;
253
266
if ( rootAttach == null )
254
267
{
255
- Plugin . Logger ? . LogWarning ( "Root attach not found" ) ;
268
+ Plugin . Logger . LogWarning ( "Root attach not found" ) ;
256
269
}
257
270
else
258
271
{
259
- Plugin . Logger ? . LogWarning ( "Root attach found" ) ;
272
+ Plugin . Logger . LogWarning ( "Root attach found" ) ;
260
273
// handle root first, then attach this to the root
261
274
var rootAttachProgress = new ExportProgress ( rootAttach . Models . Length , "Root attach" ) ;
262
275
rootProgress . Children . Add ( rootAttachProgress ) ;
@@ -343,13 +356,13 @@ private bool HandleRootAttach(
343
356
bones = SkeletonUtils . GetBoneMap ( characterInfo . Skeleton , exportConfig . PoseMode , out rootBone ) ;
344
357
if ( rootBone == null )
345
358
{
346
- Plugin . Logger ? . LogWarning ( "Root bone not found" ) ;
359
+ Plugin . Logger . LogWarning ( "Root bone not found" ) ;
347
360
return null ;
348
361
}
349
362
}
350
363
catch ( Exception e )
351
364
{
352
- Plugin . Logger ? . LogError ( e , "Failed to get bone map" ) ;
365
+ Plugin . Logger . LogError ( e , "Failed to get bone map" ) ;
353
366
return null ;
354
367
}
355
368
@@ -366,7 +379,7 @@ private bool HandleRootAttach(
366
379
}
367
380
catch ( Exception e )
368
381
{
369
- Plugin . Logger ? . LogError ( e , "Failed to handle attach {AttachData}" , JsonSerializer . Serialize ( new
382
+ Plugin . Logger . LogError ( e , "Failed to handle attach {AttachData}" , JsonSerializer . Serialize ( new
370
383
{
371
384
AttachData = attachData . Value . Attach ,
372
385
Owner = attachData . Value . Owner
@@ -384,7 +397,7 @@ private bool HandleRootAttach(
384
397
}
385
398
catch ( Exception e )
386
399
{
387
- Plugin . Logger ? . LogError ( e , "Failed to handle root attach {CharacterInfo}" , JsonSerializer . Serialize ( characterInfo , MaterialComposer . JsonOptions ) ) ;
400
+ Plugin . Logger . LogError ( e , "Failed to handle root attach {CharacterInfo}" , JsonSerializer . Serialize ( characterInfo , MaterialComposer . JsonOptions ) ) ;
388
401
}
389
402
}
390
403
@@ -397,7 +410,7 @@ private bool HandleRootAttach(
397
410
{
398
411
if ( cancellationToken . IsCancellationRequested )
399
412
{
400
- Plugin . Logger ? . LogInformation ( "Export cancelled, stopping model processing" ) ;
413
+ Plugin . Logger . LogInformation ( "Export cancelled, stopping model processing" ) ;
401
414
break ;
402
415
}
403
416
@@ -409,7 +422,7 @@ private bool HandleRootAttach(
409
422
}
410
423
catch ( Exception e )
411
424
{
412
- Plugin . Logger ? . LogError ( e , "Failed to handle model\n {Message}\n {ModelInfo}" , e . Message , JsonSerializer . Serialize ( t , MaterialComposer . JsonOptions ) ) ;
425
+ Plugin . Logger . LogError ( e , "Failed to handle model\n {Message}\n {ModelInfo}" , e . Message , JsonSerializer . Serialize ( t , MaterialComposer . JsonOptions ) ) ;
413
426
}
414
427
415
428
rootProgress . IncrementProgress ( ) ;
@@ -419,7 +432,7 @@ private bool HandleRootAttach(
419
432
{
420
433
if ( cancellationToken . IsCancellationRequested )
421
434
{
422
- Plugin . Logger ? . LogInformation ( "Export cancelled, stopping attach processing" ) ;
435
+ Plugin . Logger . LogInformation ( "Export cancelled, stopping attach processing" ) ;
423
436
break ;
424
437
}
425
438
@@ -433,7 +446,7 @@ private bool HandleRootAttach(
433
446
}
434
447
catch ( Exception e )
435
448
{
436
- Plugin . Logger ? . LogError ( e , "Failed to handle attach {Attach}" , JsonSerializer . Serialize ( t , MaterialComposer . JsonOptions ) ) ;
449
+ Plugin . Logger . LogError ( e , "Failed to handle attach {Attach}" , JsonSerializer . Serialize ( t , MaterialComposer . JsonOptions ) ) ;
437
450
}
438
451
finally
439
452
{
@@ -470,7 +483,7 @@ public static void EnsureBonesExist(Model model, List<BoneNodeBuilder> bones, Bo
470
483
var parent = FindLogicalParent ( model , bone , bones ) ?? root ;
471
484
parent . AddNode ( bone ) ;
472
485
473
- Plugin . Logger ? . LogWarning ( "Added bone {BoneName} to {ParentBone}\n " +
486
+ Plugin . Logger . LogWarning ( "Added bone {BoneName} to {ParentBone}\n " +
474
487
"NOTE: This may break posing in some cases, you may find better results " +
475
488
"deleting the bone after importing into editing software" , boneName , parent . BoneName ) ;
476
489
bones . Add ( bone ) ;
0 commit comments