-
Notifications
You must be signed in to change notification settings - Fork 47
/
Copy pathGfdImporter.ms
317 lines (279 loc) · 13.8 KB
/
GfdImporter.ms
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
/* Persona 3: DMN, Persona 4: DAN, Persona5: DSN & Persona 5 model and animation importer (*.gmd; *.gfs; *.gap) written in MaxScript
Version 0.14
Script by TGE. Please give credit where is due.
Special thanks to PolarSoda, mrdudesworkshop
Changelog:
v0.14:
Implement support for importing morphers.
Implement partial incomplete support for loading morph animations.
v0.13:
Further improve support for P3D/P5D models.
Add checkbox to control whether or not to reset animation before loading a new one.
Automatically enable backface culling for imported models.
Support new animation keyframe types used in P3D/P5D animations.
v0.12:
Improve support for P3D/P5D models.
v0.11:
Reset button now properly resets the skeleton to its initial default pose.
Note that this uses the pose the model is in when you first load an animation!
v0.10:
Implemented a GUI for configuring options, and selecting which animation to load
- There's 2 types of animations: Normal, and Blend animations.
Blend animations are overlaid ontop of other animations
Complete rewritten animation file parsing based on my latest research
Various code cleanups
Additions to brute force method for particle attachments, making more models load
Fixed a bug that caused some models to not load (eg. Arsene)
v0.9:
Proper parsing of materials, morphers, meshes, lights, cameras; in short: everything works a bit better now
Implemented brute force parsing for particle attachments, makes quite a few enemies load now
Removed redudant "RootNode" node
Improved naming of things
Disabled 'ghosting' of the process while the script is running which prevents 3ds max from locking up, hope it works
Implemented parsing of additional property types
Misc bug fixes
*/
FileIn "include\\MaxScriptExtensions\\DisableProcessWindowsGhosting.ms"
FileIn "include\\MaxScriptExtensions\\FileUtils.ms"
FileIn "include\\GfdFileLoader.ms"
(
local loader = GfdFileLoader()
local importedModel = undefined
local transforms = undefined
fn ResetAnimation =
(
for i = 1 to objects.Count do DeleteKeys objects[i].Controller #allkeys
for i = 1 to objects.Count do
(
local obj = objects[i];
obj.Controller.Position = transforms[i][1]
obj.Controller.Rotation = transforms[i][2]
obj.Controller.Scale = transforms[i][3]
local hasMorpherMod = false;
for m in obj.modifiers do
(
if ( classof m == morpher ) then
(
hasMorpherMod = true;
break;
)
)
if ( hasMorpherMod ) then
(
for i = 1 to 100 do
(
if ( WM3_MC_HasData obj.Morpher i ) then
WM3_MC_SetValue obj.Morpher i 0.0;
)
)
)
)
rollout GfdImporterRollout "GMD/GFS/GAP importer" width:350 height:360
(
label 'versionLabel' "GMD/GFS/GAP importer version 0.14 Alpha by TGE" pos:[50,15] width:250 height:25 align:#left
GroupBox 'optionsGroupBox' "Options" pos:[20,50] width:306 height:111 align:#left
checkbox 'applyNormalsCheckbox' "Apply Normals" pos:[35,70] width:96 height:15 enabled:false checked:true align:#left
checkbox 'applySkinCheckbox' "Apply Skin" pos:[35,110] width:96 height:15 enabled:false checked:true align:#left
checkbox 'applyColorsCheckbox' "Apply Colors" pos:[35,90] width:96 height:15 enabled:false checked:true align:#left
checkbox 'yToZUpCheckbox' "Convert Y to Z up" pos:[35,130] width:103 height:15 enabled:false checked:false align:#left
checkbox 'overwriteTexturesCheckbox' "Overwrite Existing Textures" pos:[145,70] width:154 height:15 enabled:false checked:false align:#left
checkbox 'exportTexturesOnlyCheckbox' "Export Textures only" pos:[145,90] width:165 height:15 checked:false align:#left
checkbox 'resetAnimOnLoad' "Reset Animation On Load" pos:[145,110] width:165 height:15 enabled:false checked:true align:#left
button 'importFileButton' "Import File" pos:[125,278] width:100 height:30 align:#left
button 'loadModelButton' "Load Model" pos:[15,313] width:100 height:30 enabled:false align:#left
button 'loadAnimationButton' "Load Animation" pos:[125,313] width:100 height:30 enabled:false align:#left
spinner 'animationIndexSpinner' "" pos:[190,243] width:70 height:16 enabled:false type:#integer align:#left
label 'animationIndexLabel' "Animation Index" pos:[85,243] width:80 height:20 align:#left
label 'animationsLoadedLabel' "Animations Loaded:" pos:[85,223] width:93 height:14 align:#left
label 'animationsLoadedNumberLabel' "0" pos:[196,223] width:55 height:13 align:#left
dropdownList 'animationTypeDropdown' "Animation Type" pos:[134,170] width:82 height:40 enabled:false items:#("Normal", "Blend") selection:1 align:#left
button 'resetAnimationButton' "Reset Animation" pos:[235,313] width:100 height:30 enabled:false align:#left
on importFileButton pressed do
(
GC()
GC()
ClearListener()
local filePath = FileUtils.RunOpenFileDialog "Open model or animation file" "Persona 5 Model (*.gmd; *.gfs; *.gap)|*.gmd; *.gfs; *.gap" "P5 Object Presets"
if ( filePath != undefined ) then
(
if (not (GfdFileLoader.IsValidFile( filePath ))) then
(
Format "Not a valid Persona 5 model file. (File doesn't start with GFS0 signature)\n"
)
else
(
-- Configure loader options
loader.ApplyNormals = applyNormalsCheckbox.Checked
loader.ApplyColors = applyColorsCheckbox.Checked
loader.ApplySkin = applySkinCheckbox.Checked
loader.ApplyYToZUp = yToZUpCheckbox.Checked
loader.OverwriteExistingTextures = overwriteTexturesCheckbox.Checked
loader.ExportTexturesOnly = exportTexturesOnlyCheckbox.Checked
-- Load model
try (
with redraw off
(
importedModel = loader.Load( filepath )
)
Format "File loaded successfully.\n"
) catch (Print (getCurrentException()))
-- Update UI
if ( importedModel != undefined ) then
(
if ( importedModel.Scene != undefined ) then
(
applyNormalsCheckbox.Enabled = true
applySkinCheckbox.Enabled = true
applyColorsCheckbox.Enabled = true
yToZUpCheckbox.Enabled = true
loadModelButton.Enabled = true
transforms = #()
for i = 1 to objects.Count do
append transforms #( objects[i].Controller.Position, objects[i].Controller.Rotation, objects[i].Controller.Scale )
resetAnimationButton.Enabled = true
)
else
(
applyNormalsCheckbox.Enabled = false
applySkinCheckbox.Enabled = false
applyColorsCheckbox.Enabled = false
yToZUpCheckbox.Enabled = false
loadModelButton.Enabled = false
resetAnimationButton.Enabled = true;
if ( transforms == undefined ) then
(
transforms = #()
for i = 1 to objects.Count do
append transforms #( objects[i].Controller.Position, objects[i].Controller.Rotation, objects[i].Controller.Scale )
)
)
loadAnimationButton.Enabled = false
animationTypeDropdown.Enabled = false
animationsLoadedNumberLabel.Text = "0"
animationTypeDropdown.Selection = 1
if ( importedModel.AnimationPackage != undefined ) then
(
local animationCount = importedModel.AnimationPackage.AnimationCount
if ( animationCount == 0 ) then
(
animationCount = importedModel.AnimationPackage.BlendAnimationCount
animationTypeDropdown.Selection = 2
)
animationsLoadedNumberLabel.Text = animationCount as string
animationTypeDropdown.Enabled = true
if ( animationCount != 0 ) then
(
animationIndexSpinner.Range = [0, animationCount - 1, 0]
animationIndexSpinner.Enabled = true
loadAnimationButton.Enabled = true
resetAnimOnLoad.Enabled = true;
)
else
(
animationTypeDropdown.Selection = 1
animationIndexSpinner.Range = [0, 0, 0]
animationIndexSpinner.Enabled = false
loadAnimationButton.Enabled = false
resetAnimOnLoad.Enabled = false;
)
)
)
else
(
applyNormalsCheckbox.Enabled = false
applySkinCheckbox.Enabled = false
applyColorsCheckbox.Enabled = false
yToZUpCheckbox.Enabled = false
loadModelButton.Enabled = false
loadAnimationButton.Enabled = false
animationsLoadedNumberLabel.Text = "0"
animationIndexSpinner.Enabled = false
animationTypeDropdown.Selection = 1
animationTypeDropdown.Enabled = false
)
-- Clean up, not that it will help much
GC()
GC()
)
)
)
on loadModelButton pressed do
(
-- Configure loader options
loader.ApplyNormals = applyNormalsCheckbox.Checked
loader.ApplyColors = applyColorsCheckbox.Checked
loader.ApplySkin = applySkinCheckbox.Checked
loader.ApplyYToZUp = yToZUpCheckbox.Checked
loader.OverwriteExistingTextures = overwriteTexturesCheckbox.Checked
loader.ExportTexturesOnly = exportTexturesOnlyCheckbox.Checked
loader.SetupScene( importedModel )
transforms = undefined
)
on loadAnimationButton pressed do
(
if ( transforms == undefined ) then
(
-- Save default pose
transforms = #()
for i = 1 to objects.Count do
append transforms #( objects[i].Controller.Position, objects[i].Controller.Rotation, objects[i].Controller.Scale )
)
else if ( resetAnimOnLoad.Checked ) then
(
ResetAnimation()
)
if ( importedModel.AnimationPackage != undefined ) then
(
local animation = undefined
local isBlend = false
if ( animationTypeDropdown.Selection == 1 ) then
(
animation = importedModel.AnimationPackage.Animations[ animationIndexSpinner.value + 1 ]
)
else if ( animationTypeDropdown.Selection == 2 ) then
(
animation = importedModel.AnimationPackage.BlendAnimations[ animationIndexSpinner.value + 1 ]
isBlend = true
)
if ( animation != undefined ) then
(
loader.SetupAnimation animation isBlend
)
)
)
on animationTypeDropdown selected sel do
(
if ( importedModel.AnimationPackage != undefined ) then
(
local animationCount = 0
if ( sel == 1 ) then
(
animationCount = importedModel.AnimationPackage.AnimationCount
)
else if ( sel == 2 ) then
(
animationCount = importedModel.AnimationPackage.BlendAnimationCount
)
animationsLoadedNumberLabel.Text = animationCount as string
animationTypeDropdown.Enabled = true
if ( animationCount != 0 ) then
(
animationIndexSpinner.Range = [0, animationCount - 1, 0]
animationIndexSpinner.Enabled = true
loadAnimationButton.Enabled = true
)
else
(
animationIndexSpinner.Range = [0, 0, 0]
animationIndexSpinner.Enabled = false
loadAnimationButton.Enabled = false
)
)
)
on resetAnimationButton pressed do
(
ResetAnimation()
)
)
CreateDialog GfdImporterRollout
)