@@ -309,6 +309,9 @@ public ShaderInfo GetShaderInfo()
309
309
case "bg.shpk" :
310
310
info . Shader = MtrlShader . Furniture ;
311
311
break ;
312
+ case "bgcolorchange.shpk" :
313
+ info . Shader = MtrlShader . DyeableFurniture ;
314
+ break ;
312
315
default :
313
316
info . Shader = MtrlShader . Other ;
314
317
break ;
@@ -356,6 +359,9 @@ public void SetShaderInfo(ShaderInfo info)
356
359
case MtrlShader . Furniture :
357
360
Shader = "bg.shpk" ;
358
361
break ;
362
+ case MtrlShader . DyeableFurniture :
363
+ Shader = "bgcolorchange.shpk" ;
364
+ break ;
359
365
default :
360
366
// No change to the Shader for 'Other' type entries.
361
367
break ;
@@ -419,6 +425,11 @@ public MapInfo GetMapInfo(XivTexType MapType)
419
425
mapIndex = ( int ) paramSet . TextureIndex ;
420
426
info . Format = GetFormat ( paramSet . FileFormat ) ;
421
427
}
428
+ else if ( paramSet . TextureType == Mtrl . FurnitureTextureDescriptorValues [ MapType ] )
429
+ {
430
+ mapIndex = ( int ) paramSet . TextureIndex ;
431
+ info . Format = GetFormat ( paramSet . FileFormat ) ;
432
+ }
422
433
}
423
434
424
435
if ( mapIndex < 0 )
@@ -472,7 +483,12 @@ public MapInfo GetMapInfo(string path)
472
483
if ( Mtrl . TextureDescriptorValues . ContainsValue ( descriptor . TextureType ) )
473
484
{
474
485
info . Usage = Mtrl . TextureDescriptorValues . First ( x => x . Value == descriptor . TextureType ) . Key ;
475
- } else
486
+ }
487
+ else if ( Mtrl . FurnitureTextureDescriptorValues . ContainsValue ( descriptor . TextureType ) )
488
+ {
489
+ info . Usage = Mtrl . FurnitureTextureDescriptorValues . First ( x => x . Value == descriptor . TextureType ) . Key ;
490
+ }
491
+ else
476
492
{
477
493
info . Usage = XivTexType . Other ;
478
494
}
@@ -519,44 +535,34 @@ public void SetMapInfo(XivTexType MapType, MapInfo info)
519
535
// Deleting existing info.
520
536
if ( info == null )
521
537
{
522
- if ( paramIdx < 0 )
523
- {
524
- // Didn't exist to start, nothing to do.
525
- return ;
526
- }
527
538
528
- // Remove texture from path list if it exists.
529
- if ( TexturePathList . Count > oldInfo . TextureIndex )
530
- {
531
- TexturePathList . RemoveAt ( ( int ) oldInfo . TextureIndex ) ;
532
- TexturePathUnknownList . RemoveAt ( ( int ) oldInfo . TextureIndex ) ;
533
- }
534
539
535
- // Remove Parameter List
536
- TextureDescriptorList . RemoveAt ( paramIdx ) ;
537
-
538
- // Update other texture offsets
539
- for ( var i = 0 ; i < TextureDescriptorList . Count ; i ++ )
540
+ if ( paramIdx >= 0 )
540
541
{
541
- var p = TextureDescriptorList [ i ] ;
542
- if ( p . TextureIndex > oldInfo . TextureIndex )
542
+ // Remove texture from path list if it exists.
543
+ if ( TexturePathList . Count > oldInfo . TextureIndex )
543
544
{
544
- p . TextureIndex -- ;
545
+ TexturePathList . RemoveAt ( ( int ) oldInfo . TextureIndex ) ;
546
+ TexturePathUnknownList . RemoveAt ( ( int ) oldInfo . TextureIndex ) ;
545
547
}
546
- TextureDescriptorList [ i ] = p ;
547
- }
548
548
549
- // Remove struct1 entry for the removed map type, if it exists.
550
- for ( var i = 0 ; i < TextureUsageList . Count ; i ++ )
551
- {
552
- var s = TextureUsageList [ i ] ;
553
- if ( s . TextureType == Mtrl . TextureUsageValues [ MapType ] . TextureType )
549
+ // Remove Parameter List
550
+ TextureDescriptorList . RemoveAt ( paramIdx ) ;
551
+
552
+ // Update other texture offsets
553
+ for ( var i = 0 ; i < TextureDescriptorList . Count ; i ++ )
554
554
{
555
- TextureUsageList . RemoveAt ( i ) ;
556
- break ;
555
+ var p = TextureDescriptorList [ i ] ;
556
+ if ( p . TextureIndex > oldInfo . TextureIndex )
557
+ {
558
+ p . TextureIndex -- ;
559
+ }
560
+ TextureDescriptorList [ i ] = p ;
557
561
}
558
562
}
559
563
564
+ RegenerateTextureUsageList ( ) ;
565
+
560
566
return ;
561
567
562
568
}
@@ -608,31 +614,103 @@ public void SetMapInfo(XivTexType MapType, MapInfo info)
608
614
TexturePathList [ ( int ) raw . TextureIndex ] = info . path ;
609
615
}
610
616
611
- // Update struct1 entry with the appropriate entry if it's not already there.
612
- bool foundEntry = false ;
613
- for ( var i = 0 ; i < TextureUsageList . Count ; i ++ )
617
+ RegenerateTextureUsageList ( ) ;
618
+ }
619
+
620
+ /// <summary>
621
+ /// Regenerates/Cleans up the texture usage list based on the
622
+ /// Texture Maps that are set in the Texture Description Fields.
623
+ /// </summary>
624
+ private void RegenerateTextureUsageList ( )
625
+ {
626
+ var shaderInfo = GetShaderInfo ( ) ;
627
+
628
+ // Furniture shaders do not use the texture usage list at all.
629
+ if ( shaderInfo . Shader == MtrlShader . Furniture || shaderInfo . Shader == MtrlShader . DyeableFurniture )
614
630
{
615
- var s = TextureUsageList [ i ] ;
616
- if ( s . TextureType == Mtrl . TextureUsageValues [ MapType ] . TextureType )
617
- {
618
- foundEntry = true ;
619
- break ;
620
- }
631
+ TextureUsageList . Clear ( ) ;
632
+ return ;
621
633
}
622
634
623
- if ( ! foundEntry )
635
+ // Everything (should) have a normal, so this is redundant.
636
+ // bool hasNormal = GetMapInfo(XivTexType.Normal) != null;
637
+ bool hasSpec = GetMapInfo ( XivTexType . Specular ) != null ;
638
+ bool hasDiffuse = GetMapInfo ( XivTexType . Diffuse ) != null ;
639
+ bool hasMulti = GetMapInfo ( XivTexType . Multi ) != null ;
640
+
641
+ ClearTextureUsage ( XivTexType . Normal ) ;
642
+ ClearTextureUsage ( XivTexType . Diffuse ) ;
643
+ ClearTextureUsage ( XivTexType . Specular ) ;
644
+ ClearTextureUsage ( XivTexType . Multi ) ;
645
+
646
+ // These need to be set in relatively specific order
647
+ // in order to use the maps correctly
648
+
649
+ SetTextureUsage ( XivTexType . Normal ) ;
650
+
651
+ if ( hasDiffuse )
624
652
{
625
- var s1 = new TextureUsageStruct ( )
626
- {
627
- TextureType = Mtrl . TextureUsageValues [ MapType ] . TextureType ,
628
- Unknown = Mtrl . TextureUsageValues [ MapType ] . Unknown
629
- } ;
653
+ // Diffuse
654
+ SetTextureUsage ( XivTexType . Diffuse ) ;
655
+ }
630
656
631
- TextureUsageList . Add ( s1 ) ;
657
+ if ( hasSpec || hasMulti )
658
+ {
659
+ // Including both of these seems to guarantee best results,
660
+ // vs including only one or the other.
661
+ SetTextureUsage ( XivTexType . Multi ) ;
662
+ SetTextureUsage ( XivTexType . Specular ) ;
632
663
}
633
664
634
665
}
635
666
667
+ /// <summary>
668
+ /// Clears a texture usage value.
669
+ /// </summary>
670
+ /// <param name="usage"></param>
671
+ private bool ClearTextureUsage ( XivTexType usage )
672
+ {
673
+ var oldCount = TextureUsageList . Count ;
674
+ TextureUsageList = TextureUsageList . Where ( x => x . TextureType != Mtrl . TextureUsageValues [ usage ] . TextureType ) . ToList ( ) ;
675
+ return oldCount != TextureUsageList . Count ;
676
+ }
677
+
678
+ /// <summary>
679
+ /// Adds or changes a texture usage value.
680
+ /// </summary>
681
+ /// <param name="usage"></param>
682
+ /// <param name="unknownValue"></param>
683
+ private void SetTextureUsage ( XivTexType usage , uint ? unknownValue = null )
684
+ {
685
+ if ( unknownValue == null )
686
+ {
687
+ unknownValue = Mtrl . TextureUsageValues [ usage ] . Unknown ;
688
+ }
689
+ try
690
+ {
691
+ var val = TextureUsageList . First ( x => x . TextureType == Mtrl . TextureUsageValues [ usage ] . TextureType ) ;
692
+ if ( val != null )
693
+ {
694
+ // Despite being named 'Struct' this is actually a class.
695
+ val . Unknown = ( uint ) unknownValue ;
696
+ } else
697
+ {
698
+ TextureUsageList . Add ( new TextureUsageStruct ( )
699
+ {
700
+ TextureType = Mtrl . TextureUsageValues [ usage ] . TextureType ,
701
+ Unknown = ( uint ) unknownValue
702
+ } ) ;
703
+ }
704
+ } catch ( Exception ex )
705
+ {
706
+ TextureUsageList . Add ( new TextureUsageStruct ( )
707
+ {
708
+ TextureType = Mtrl . TextureUsageValues [ usage ] . TextureType ,
709
+ Unknown = ( uint ) unknownValue
710
+ } ) ;
711
+ }
712
+ }
713
+
636
714
/// <summary>
637
715
/// Retrieve all MapInfo structs for all textures associated with this MTRL,
638
716
/// Including textures with unknown usage.
@@ -641,6 +719,7 @@ public void SetMapInfo(XivTexType MapType, MapInfo info)
641
719
public List < MapInfo > GetAllMapInfos ( bool tokenize = true )
642
720
{
643
721
var ret = new List < MapInfo > ( ) ;
722
+ var shaderInfo = GetShaderInfo ( ) ;
644
723
for ( var i = 0 ; i < TexturePathList . Count ; i ++ )
645
724
{
646
725
var info = new MapInfo ( ) ;
@@ -661,7 +740,16 @@ public List<MapInfo> GetAllMapInfos(bool tokenize = true)
661
740
return ( x . Value == p . TextureType ) ;
662
741
} ) . Key ;
663
742
info . Usage = usage ;
664
- } else
743
+ } else if ( Mtrl . FurnitureTextureDescriptorValues . ContainsValue ( p . TextureType ) )
744
+ {
745
+ // Known parameter for the furniture shaders.
746
+ var usage = Mtrl . FurnitureTextureDescriptorValues . First ( x =>
747
+ {
748
+ return ( x . Value == p . TextureType ) ;
749
+ } ) . Key ;
750
+ info . Usage = usage ;
751
+
752
+ } else
665
753
{
666
754
info . Usage = XivTexType . Other ;
667
755
}
@@ -695,12 +783,13 @@ public List<TexTypePath> GetTextureTypePathList()
695
783
TexTypePath ttp ;
696
784
foreach ( var map in maps )
697
785
{
698
-
699
-
700
786
if ( shaderInfo . Shader == MtrlShader . Skin && map . Usage == XivTexType . Multi )
701
787
{
702
788
ttp = new TexTypePath ( ) { DataFile = GetDataFile ( ) , Path = map . path , Type = XivTexType . Skin } ;
703
789
790
+ } else if ( shaderInfo . Shader == MtrlShader . Furniture && map . path . Contains ( "dummy" ) ) {
791
+ // Dummy textures are skipped.
792
+ continue ;
704
793
}
705
794
else
706
795
{
@@ -996,13 +1085,14 @@ public enum MtrlTextureDescriptorFormat
996
1085
// Enum representation of the shader names used in mtrl files.
997
1086
public enum MtrlShader
998
1087
{
999
- Standard , // character.shpk
1000
- Glass , // characterglass.shpk
1001
- Skin , // skin.shpk
1002
- Hair , // hair.shpk
1003
- Iris , // iris.shpk
1004
- Furniture , // bg.shpk
1005
- Other // Unknown Shader
1088
+ Standard , // character.shpk
1089
+ Glass , // characterglass.shpk
1090
+ Skin , // skin.shpk
1091
+ Hair , // hair.shpk
1092
+ Iris , // iris.shpk
1093
+ Furniture , // bg.shpk
1094
+ DyeableFurniture , //bgcolorchange.shpk
1095
+ Other // Unknown Shader
1006
1096
}
1007
1097
1008
1098
/// <summary>
0 commit comments