1
1
using System . Numerics ;
2
2
using Dalamud . Interface . Utility . Raii ;
3
3
using Dalamud . Interface . Windowing ;
4
+ using FFXIVClientStructs . FFXIV . Client . Graphics . Render ;
4
5
using FFXIVClientStructs . FFXIV . Client . System . Resource . Handle ;
5
6
using FFXIVClientStructs . Interop ;
6
7
using ImGuiNET ;
7
8
using Meddle . Plugin . Models ;
8
9
using Meddle . Plugin . Utils ;
9
10
using Meddle . Utils . Constants ;
10
11
using Meddle . Utils . Files ;
11
- using Meddle . Utils . Files . SqPack ;
12
+ using Microsoft . Extensions . Logging ;
12
13
13
14
namespace Meddle . Plugin . UI . Windows ;
14
15
15
16
public class MdlMaterialWindow : Window
16
17
{
17
- private readonly SqPack pack ;
18
18
private readonly MdlMaterialWindowManager windowManager ;
19
19
private readonly Pointer < ModelResourceHandle > model ;
20
- private readonly Dictionary < string , ShpkFile > shpkCache = new ( ) ;
20
+ private readonly Pointer < Model > model1 ;
21
21
public readonly string Id ;
22
22
23
- public unsafe MdlMaterialWindow ( SqPack pack , MdlMaterialWindowManager windowManager , Pointer < ModelResourceHandle > model ) : base ( "Material Editor" , ImGuiWindowFlags . None )
23
+ public unsafe MdlMaterialWindow ( MdlMaterialWindowManager windowManager , Pointer < ModelResourceHandle > model ) :
24
+ base ( "Material Editor" )
24
25
{
25
- this . pack = pack ;
26
26
this . windowManager = windowManager ;
27
27
this . model = model ;
28
- WindowName = $ "Material Editor { model . Value ->FileName . ParseString ( ) } ";
29
28
Id = $ "{ ( nint ) this . model . Value : X8} ";
29
+ WindowName = $ "Material Editor { model . Value ->FileName . ParseString ( ) } ###{ Id } ";
30
+ SizeConstraints = new WindowSizeConstraints
31
+ {
32
+ MinimumSize = new Vector2 ( 375 , 350 ) ,
33
+ MaximumSize = new Vector2 ( 1200 , 1000 )
34
+ } ;
35
+ }
36
+
37
+ public unsafe MdlMaterialWindow ( MdlMaterialWindowManager windowManager , Pointer < Model > model ) :
38
+ base ( "Material Editor" )
39
+ {
40
+ this . windowManager = windowManager ;
41
+ this . model1 = model ;
42
+ Id = $ "{ ( nint ) this . model . Value : X8} ";
43
+ WindowName = $ "Material Editor { model . Value ->ModelResourceHandle ->FileName . ParseString ( ) } ###{ Id } ";
44
+ SizeConstraints = new WindowSizeConstraints
45
+ {
46
+ MinimumSize = new Vector2 ( 375 , 350 ) ,
47
+ MaximumSize = new Vector2 ( 1200 , 1000 )
48
+ } ;
30
49
}
31
50
32
- public override void OnClose ( )
51
+
52
+ public override unsafe void OnClose ( )
33
53
{
34
54
windowManager . RemoveMaterialWindow ( this ) ;
35
55
base . OnClose ( ) ;
36
56
}
37
57
38
58
public override void Draw ( )
39
59
{
40
- DrawModel ( model ) ;
60
+ if ( model1 != null )
61
+ {
62
+ DrawModel ( model1 ) ;
63
+ }
64
+ else
65
+ {
66
+ DrawModel ( model ) ;
67
+ }
68
+ }
69
+ private unsafe void DrawModel ( Pointer < Model > modelPtr )
70
+ {
71
+ if ( modelPtr == null || modelPtr . Value == null )
72
+ {
73
+ ImGui . Text ( "Model data is null." ) ;
74
+ return ;
75
+ }
76
+
77
+ var modelName = modelPtr . Value ->ModelResourceHandle ->FileName . ParseString ( ) ;
78
+ using var modelId = ImRaii . PushId ( modelName ) ;
79
+
80
+ ImGui . Text ( $ "Model: { modelName } ") ;
81
+
82
+ var materials = modelPtr . Value ->MaterialsSpan ;
83
+ ImGui . Text ( $ "Material Count: { materials . Length } ") ;
84
+
85
+ for ( var i = 0 ; i < materials . Length ; i ++ )
86
+ {
87
+ var material = materials [ i ] ;
88
+ if ( material == null || material . Value == null || material . Value ->MaterialResourceHandle == null ) continue ;
89
+ using var materialId = ImRaii . PushId ( i ) ;
90
+ var shpkName = material . Value ->MaterialResourceHandle ->ShpkNameString ;
91
+ using var materialNode = ImRaii . TreeNode ( $ "[{ shpkName } ]Material { i } : { material . Value ->MaterialResourceHandle ->FileName . ParseString ( ) } ") ;
92
+ if ( ! materialNode . Success ) continue ;
93
+ DrawMtrl ( material . Value ->MaterialResourceHandle ) ;
94
+ // DrawMtrlTextures(material.Value->MaterialResourceHandle);
95
+ // using var materialParamNode = ImRaii.TreeNode("Material Parameters");
96
+ // if (materialParamNode.Success)
97
+ // {
98
+ // DrawMtrl(material.Value->MaterialResourceHandle);
99
+ // }
100
+ //
101
+ // using var materialTexturesNode = ImRaii.TreeNode("Material Textures");
102
+ // if (materialTexturesNode.Success)
103
+ // {
104
+ // DrawMtrlTextures(material.Value->MaterialResourceHandle);
105
+ // }
106
+ }
41
107
}
42
108
43
109
private unsafe void DrawModel ( Pointer < ModelResourceHandle > modelPtr )
@@ -65,10 +131,59 @@ private unsafe void DrawModel(Pointer<ModelResourceHandle> modelPtr)
65
131
using var materialNode = ImRaii . TreeNode ( $ "[{ shpkName } ]Material { i } : { material . Value ->FileName . ParseString ( ) } ") ;
66
132
if ( ! materialNode . Success ) continue ;
67
133
DrawMtrl ( material ) ;
134
+ // using var materialParamNode = ImRaii.TreeNode("Material Parameters");
135
+ // if (materialParamNode.Success)
136
+ // {
137
+ // DrawMtrl(material);
138
+ // }
139
+ //
140
+ // using var materialTexturesNode = ImRaii.TreeNode("Material Textures");
141
+ // if (materialTexturesNode.Success)
142
+ // {
143
+ // DrawMtrlTextures(material);
144
+ // }
68
145
}
69
146
}
70
147
71
- private Dictionary < nint , float [ ] > materialParamsCache = new ( ) ;
148
+ private readonly Dictionary < nint , float [ ] > materialParamsCache = new ( ) ;
149
+
150
+ public unsafe void DrawMtrlTextures ( Pointer < MaterialResourceHandle > mtrlPtr )
151
+ {
152
+ if ( mtrlPtr == null || mtrlPtr . Value == null )
153
+ {
154
+ return ;
155
+ }
156
+
157
+ var textures = mtrlPtr . Value ->TexturesSpan ;
158
+ if ( textures . Length == 0 )
159
+ {
160
+ ImGui . Text ( "No textures." ) ;
161
+ return ;
162
+ }
163
+
164
+ var availWidth = ImGui . GetContentRegionAvail ( ) . X ;
165
+ using var table = ImRaii . Table ( "MaterialTextures" , 3 , ImGuiTableFlags . Borders |
166
+ ImGuiTableFlags . RowBg |
167
+ ImGuiTableFlags . Hideable |
168
+ ImGuiTableFlags . Resizable ) ;
169
+
170
+ ImGui . TableSetupColumn ( "ID" , ImGuiTableColumnFlags . WidthFixed , availWidth * 0.05f ) ;
171
+ ImGui . TableSetupColumn ( "Name" , ImGuiTableColumnFlags . WidthFixed , availWidth * 0.2f ) ;
172
+ ImGui . TableSetupColumn ( "Path" , ImGuiTableColumnFlags . WidthStretch ) ;
173
+ ImGui . TableHeadersRow ( ) ;
174
+
175
+ for ( var i = 0 ; i < textures . Length ; i ++ )
176
+ {
177
+ var texture = textures [ i ] ;
178
+ if ( texture . TextureResourceHandle == null ) continue ;
179
+ using var textureId = ImRaii . PushId ( i ) ;
180
+ ImGui . TableNextRow ( ) ;
181
+ ImGui . TableNextColumn ( ) ;
182
+ ImGui . Text ( i . ToString ( ) ) ;
183
+ ImGui . TableNextColumn ( ) ;
184
+ ImGui . Text ( texture . TextureResourceHandle ->FileName . ParseString ( ) ) ;
185
+ }
186
+ }
72
187
73
188
public unsafe void DrawMtrl ( Pointer < MaterialResourceHandle > mtrlPtr )
74
189
{
@@ -89,19 +204,7 @@ public unsafe void DrawMtrl(Pointer<MaterialResourceHandle> mtrlPtr)
89
204
90
205
var shpkName = mtrlPtr . Value ->ShpkNameString ;
91
206
var shpkPath = $ "shader/sm5/shpk/{ shpkName } ";
92
- if ( ! shpkCache . TryGetValue ( shpkPath , out var shpk ) )
93
- {
94
- var shpkData = pack . GetFileOrReadFromDisk ( shpkPath ) ;
95
- if ( shpkData != null )
96
- {
97
- shpk = new ShpkFile ( shpkData ) ;
98
- shpkCache [ shpkPath ] = shpk ;
99
- }
100
- else
101
- {
102
- throw new Exception ( $ "Failed to load { shpkPath } ") ;
103
- }
104
- }
207
+ var shpk = windowManager . GetShpkFile ( shpkPath ) ;
105
208
106
209
ImGui . Text ( $ "Shader Package: { shpkName } ") ;
107
210
var orderedMaterialParams = shpk . MaterialParams . Select ( ( x , idx ) => ( x , idx ) )
0 commit comments