pgtools 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +25 -0
  3. data/bin/bxm_decoder +2 -0
  4. data/bin/bxm_encoder +2 -0
  5. data/bin/clh_convert +2 -0
  6. data/bin/clp_convert +2 -0
  7. data/bin/clw_convert +2 -0
  8. data/bin/dat_creator +2 -0
  9. data/bin/dat_extractor +2 -0
  10. data/bin/dat_ls +2 -0
  11. data/bin/eff_idd_creator +2 -0
  12. data/bin/eff_idd_extractor +2 -0
  13. data/bin/exp_convert_wiiu_pc +2 -0
  14. data/bin/exp_tool +2 -0
  15. data/bin/mot_convert_wiiu_pc +2 -0
  16. data/bin/mot_tool +2 -0
  17. data/bin/pkz_extractor +2 -0
  18. data/bin/scr_creator +2 -0
  19. data/bin/scr_extractor +2 -0
  20. data/bin/wmb_cleanup +2 -0
  21. data/bin/wmb_common_bones +2 -0
  22. data/bin/wmb_convert_pc_switch +2 -0
  23. data/bin/wmb_convert_wiiu_pc +2 -0
  24. data/bin/wmb_export_assimp +2 -0
  25. data/bin/wmb_get_bone_map +2 -0
  26. data/bin/wmb_import_assimp +2 -0
  27. data/bin/wmb_import_nier +2 -0
  28. data/bin/wmb_import_wiiu +2 -0
  29. data/bin/wtb_convert_wiiu_pc +2 -0
  30. data/bin/wtx_creator +2 -0
  31. data/bin/wtx_extractor +2 -0
  32. data/lib/bayonetta/alignment.rb +14 -0
  33. data/lib/bayonetta/bone.rb +55 -0
  34. data/lib/bayonetta/bxm.rb +180 -0
  35. data/lib/bayonetta/clh.rb +159 -0
  36. data/lib/bayonetta/clp.rb +212 -0
  37. data/lib/bayonetta/clw.rb +166 -0
  38. data/lib/bayonetta/dat.rb +261 -0
  39. data/lib/bayonetta/eff.rb +314 -0
  40. data/lib/bayonetta/endianness.rb +53 -0
  41. data/lib/bayonetta/exp.rb +768 -0
  42. data/lib/bayonetta/linalg.rb +416 -0
  43. data/lib/bayonetta/material_database.yaml +2581 -0
  44. data/lib/bayonetta/mot.rb +763 -0
  45. data/lib/bayonetta/pkz.rb +63 -0
  46. data/lib/bayonetta/scr.rb +393 -0
  47. data/lib/bayonetta/tools/bxm_decoder.rb +23 -0
  48. data/lib/bayonetta/tools/bxm_encoder.rb +37 -0
  49. data/lib/bayonetta/tools/clh_convert.rb +60 -0
  50. data/lib/bayonetta/tools/clp_convert.rb +70 -0
  51. data/lib/bayonetta/tools/clw_convert.rb +60 -0
  52. data/lib/bayonetta/tools/dat_creator.rb +57 -0
  53. data/lib/bayonetta/tools/dat_extractor.rb +94 -0
  54. data/lib/bayonetta/tools/dat_ls.rb +106 -0
  55. data/lib/bayonetta/tools/eff_idd_creator.rb +66 -0
  56. data/lib/bayonetta/tools/eff_idd_extractor.rb +73 -0
  57. data/lib/bayonetta/tools/exp_convert_wiiu_pc.rb +33 -0
  58. data/lib/bayonetta/tools/exp_tool.rb +48 -0
  59. data/lib/bayonetta/tools/mot_convert_wiiu_pc.rb +33 -0
  60. data/lib/bayonetta/tools/mot_tool.rb +60 -0
  61. data/lib/bayonetta/tools/pkz_extractor.rb +75 -0
  62. data/lib/bayonetta/tools/scr_creator.rb +63 -0
  63. data/lib/bayonetta/tools/scr_extractor.rb +78 -0
  64. data/lib/bayonetta/tools/wmb_cleanup.rb +250 -0
  65. data/lib/bayonetta/tools/wmb_common_bones.rb +45 -0
  66. data/lib/bayonetta/tools/wmb_convert_pc_switch.rb +35 -0
  67. data/lib/bayonetta/tools/wmb_convert_wiiu_pc.rb +33 -0
  68. data/lib/bayonetta/tools/wmb_export_assimp.rb +479 -0
  69. data/lib/bayonetta/tools/wmb_get_bone_map.rb +50 -0
  70. data/lib/bayonetta/tools/wmb_import_assimp.rb +735 -0
  71. data/lib/bayonetta/tools/wmb_import_geometry_wiiu_pc.rb +472 -0
  72. data/lib/bayonetta/tools/wmb_import_nier.rb +309 -0
  73. data/lib/bayonetta/tools/wtb_convert_wiiu_pc.rb +95 -0
  74. data/lib/bayonetta/tools/wtb_import_textures.rb +103 -0
  75. data/lib/bayonetta/tools/wtx_creator.rb +69 -0
  76. data/lib/bayonetta/tools/wtx_extractor.rb +85 -0
  77. data/lib/bayonetta/vertex_types.yaml +213 -0
  78. data/lib/bayonetta/vertex_types2.yaml +164 -0
  79. data/lib/bayonetta/vertex_types_nier.yaml +145 -0
  80. data/lib/bayonetta/wmb.rb +2443 -0
  81. data/lib/bayonetta/wmb3.rb +759 -0
  82. data/lib/bayonetta/wtb.rb +481 -0
  83. data/lib/bayonetta.rb +60 -0
  84. metadata +254 -0
@@ -0,0 +1,479 @@
1
+ require 'assimp-ffi'
2
+ require 'optparse'
3
+ require 'set'
4
+ require_relative '../../bayonetta'
5
+ require 'yaml'
6
+ require 'nokogiri'
7
+ include Bayonetta
8
+
9
+ $options = {
10
+ output: nil
11
+ }
12
+ parser = OptionParser.new do |opts|
13
+ opts.banner = "Usage: wmb_export_assim.rb file [format]"
14
+
15
+ opts.on("-h", "--help", "Prints this help") do
16
+ puts opts
17
+ exit
18
+ end
19
+
20
+ opts.on("-o", "--output=dirname", "directory to output result") do |name|
21
+ $options[:output] = name
22
+ end
23
+
24
+ opts.on("-f", "--formats", "Prints supported formats (default collada)") do
25
+ Assimp::export_format_descriptions.each { |d|
26
+ puts "\t#{d.id.to_s} (.#{d.file_extension})"
27
+ }
28
+ exit
29
+ end
30
+
31
+ end
32
+ parser.parse!
33
+
34
+ source = ARGV[0]
35
+ format = 'collada'
36
+ format = ARGV[1] if ARGV[1]
37
+
38
+ if !source
39
+ puts "Invalid Arguments!"
40
+ puts parser
41
+ exit
42
+ end
43
+
44
+
45
+ raise "Invalid file #{source}" unless File::file?(source)
46
+
47
+ #log = Assimp::LogStream::stderr
48
+ #log.attach
49
+ #Assimp::LogStream::verbose(1)
50
+
51
+ module Assimp
52
+ class SceneCreated < Scene
53
+
54
+ def initialize
55
+ @ref_ptr = FFI::MemoryPointer::new(Assimp::SceneCreated)
56
+ super(FFI::Pointer::new(@ref_ptr))
57
+ end
58
+
59
+ def self.release
60
+ end
61
+ end
62
+ end
63
+
64
+ extension = nil
65
+ Assimp::export_format_descriptions.each { |d|
66
+ if d.id.to_s == format
67
+ extension = d.file_extension
68
+ end
69
+ }
70
+ raise "Unsupported format: #{format}!" unless extension
71
+
72
+ $scene = Assimp::SceneCreated::new
73
+ $scene.flags = [:FLAGS_ALLOW_SHARED]
74
+ $root_node = Assimp::Node::new
75
+ $root_node.name = File::basename(source, ".wmb")
76
+ $scene[:root_node] = $root_node
77
+
78
+ $meshes = []
79
+ $num_meshes = 0
80
+
81
+ $wmb = WMBFile::load(source)
82
+ #$wmb.scale(100.0) if format == "fbx"
83
+ tex_file_name = source.gsub(/wmb\z/,"wtb")
84
+ $wtb = WTBFile::new(File::new(tex_file_name, "rb"))
85
+ #Meshes
86
+
87
+ def create_bone_hierarchy
88
+ skeleton = Assimp::Node::new
89
+ skeleton.name = "skeleton"
90
+
91
+ $wmb_bones = bones = $wmb.get_bone_structure
92
+ table = $wmb.bone_index_translate_table.table.invert
93
+ $bone_nodes = bones.collect { |b|
94
+ n = Assimp::Node::new
95
+ n.name = "bone_%03d" % table[b.index]
96
+ n.transformation = Assimp::Matrix4x4.translation(b.relative_position)
97
+ n
98
+ }
99
+ sekeleton_children = []
100
+ bones.zip($bone_nodes).each_with_index { |(b, n), i|
101
+ if b.parent
102
+ n.parent = $bone_nodes[b.parent.index]
103
+ else
104
+ n.parent = skeleton
105
+ sekeleton_children.push(n)
106
+ end
107
+ n.children = b.children.collect { |c| $bone_nodes[c.index] }
108
+ }
109
+ skeleton.children = sekeleton_children
110
+ skeleton
111
+ end
112
+
113
+ def create_vertex_properties(mesh, vertices, bone_refs)
114
+ vertex_map = vertices.each_with_index.collect.to_h
115
+ num_vertices = vertices.size
116
+ mesh.num_vertices = num_vertices
117
+ fields = $wmb.get_vertex_fields
118
+ res = {}
119
+ num_colors = 0
120
+ num_texture_coords = 0
121
+ bones = $bone_nodes.each_with_index.collect { |n, i|
122
+ bone = Assimp::Bone::new
123
+ bone.name = n.name
124
+ bone.offset_matrix = Assimp::Matrix4x4.translation( -$wmb_bones[i].position )
125
+ bone
126
+ }
127
+ fields.each { |field|
128
+ case field
129
+ when :position
130
+ mesh.vertices = vertex_map.collect { |orig_index, index|
131
+ p = Assimp::Vector3D::new
132
+ o_p = $wmb.get_vertex_field(field, orig_index)
133
+ p.x = o_p.x
134
+ p.y = o_p.y
135
+ p.z = o_p.z
136
+ p
137
+ }
138
+ when :normal
139
+ mesh.normals = vertex_map.collect { |orig_index, index|
140
+ n = Assimp::Vector3D::new
141
+ o_n = $wmb.get_vertex_field(field, orig_index)
142
+ n.x = o_n.x
143
+ n.y = o_n.y
144
+ n.z = o_n.z
145
+ n
146
+ }
147
+ when :tangents
148
+ mesh.tangents = vertex_map.collect { |orig_index, index|
149
+ t = Assimp::Vector3D::new
150
+ o_t = $wmb.get_vertex_field(field, orig_index)
151
+ t.x = o_t.x
152
+ t.y = o_t.y
153
+ t.z = o_t.z
154
+ t
155
+ }
156
+ when :mapping, :mapping2, :mapping3, :mapping4, :mapping5
157
+ coords = vertex_map.collect { |orig_index, index|
158
+ m = Assimp::Vector3D::new
159
+ m_o = $wmb.get_vertex_field(field, orig_index)
160
+ m.x = m_o.u
161
+ m.y = m_o.v
162
+ m
163
+ }
164
+ mesh.num_uv_components[num_texture_coords] = 2
165
+ mesh.set_texture_coords(num_texture_coords, coords)
166
+ num_texture_coords += 1
167
+ when :color, :color2
168
+ colors = vertex_map.collect { |orig_index, index|
169
+ c = Assimp::Color4D::new
170
+ c_o = $wmb.get_vertex_field(field, orig_index)
171
+ c.r = c_o.r.to_f / 255.0
172
+ c.g = c_o.g.to_f / 255.0
173
+ c.b = c_o.b.to_f / 255.0
174
+ c.a = c_o.a.to_f / 255.0
175
+ c
176
+ }
177
+ mesh.set_colors(num_colors, colors)
178
+ num_colors += 1
179
+ when :bone_infos
180
+ vertex_map.each { |orig_index, index|
181
+ b_i = $wmb.get_vertex_field(field, orig_index).get_indexes_and_weights
182
+ b_i.each { |ind, wgt|
183
+ bone_index = bone_refs[ind]
184
+ bones[bone_index].add_weight(index, wgt/255.0)
185
+ }
186
+ }
187
+ else
188
+ puts "skipping #{field}" unless field == :bone_infos
189
+ end
190
+ }
191
+ bones.select! { |b| b.num_weights > 0 }
192
+ # p bones.collect { |b| b.name }
193
+ mesh.bones = bones
194
+ if mesh.normals? && mesh.tangents?
195
+ tangents = mesh.tangents
196
+ normals = mesh.normals
197
+ mesh.bitangents = vertex_map.collect { |orig_index, index|
198
+ b_t = Assimp::Vector3D::new
199
+ o_t = $wmb.get_vertex_field(:tangents, orig_index)
200
+ t = tangents[index]
201
+ n = normals[index]
202
+ n_b_t = (n ^ t)
203
+ n_b_t = ( o_t.s > 0 ? n_b_t * -1.0 : n_b_t )
204
+ b_t.x = n_b_t.x
205
+ b_t.y = n_b_t.y
206
+ b_t.z = n_b_t.z
207
+ b_t
208
+ }
209
+ end
210
+ end
211
+
212
+
213
+
214
+ def create_mesh( m, i, b, j)
215
+ uniq_vertices = b.vertex_indices.uniq.sort
216
+ vertex_map = uniq_vertices.each_with_index.collect.to_h
217
+ num_vertices = uniq_vertices.size
218
+ first_index = uniq_vertices.first
219
+ triangles = b.triangles
220
+ num_triangles = triangles.size
221
+
222
+ mesh = Assimp::Mesh::new
223
+ mesh.primitive_types = :TRIANGLE
224
+ mesh.name = ("batch_%02d_" % i) + m.header.name.unpack("Z*").first+("_%02d" % j)
225
+ res = create_vertex_properties(mesh, uniq_vertices, b.bone_refs)
226
+ if $wmb.tex_infos then
227
+ mesh.material_index = b.header.ex_mat_id
228
+ else
229
+ mesh.material_index = b.header.material_id
230
+ end
231
+
232
+ mesh.faces = triangles.collect { |tri|
233
+ f = Assimp::Face::new
234
+ t = tri.collect{ |v| vertex_map[v] }
235
+ f.indices = t
236
+ f
237
+ }
238
+
239
+ $meshes.push mesh
240
+
241
+ n = Assimp::Node::new
242
+ n.name = mesh.name
243
+ n.meshes = [$num_meshes]
244
+ $num_meshes += 1
245
+ n
246
+ end
247
+
248
+ $root_node.children =[create_bone_hierarchy] + $wmb.meshes.each_with_index.collect { |m, i|
249
+ n = Assimp::Node::new
250
+ n.name = ("mesh_%02d_"%i) + m.header.name
251
+ n.children = m.batches.each_with_index.collect { |b, j|
252
+ b = create_mesh(m, i, b, j)
253
+ b.parent = n
254
+ b
255
+ }
256
+ n.parent = $root_node
257
+ n
258
+ }
259
+
260
+ $scene.meshes = $meshes
261
+
262
+ $texture_names = $wtb.each.each_with_index.collect { |info_f, i|
263
+ info, f = info_f
264
+ ext, _, _ = info
265
+ "./#{$root_node.name}_#{"%02d"%i}#{ext}"
266
+ }
267
+ $texture_count = $texture_names.count
268
+ fields = $wmb.get_vertex_fields
269
+ $scene.materials = $wmb.advanced_materials.each_with_index.collect { |m, i|
270
+ mat = Assimp::Material::new
271
+
272
+ mat.add_property(Assimp::MATKEY_NAME, "mat_%02d" % i)
273
+ mat.add_property(Assimp::MATKEY_SHADING_MODEL, :Phong)
274
+ mat.add_property(Assimp::MATKEY_TWOSIDED, false)
275
+ mat.add_property(Assimp::MATKEY_ENABLE_WIREFRAME, false)
276
+ # c = Assimp::Color4D::new.set(0.0, 0.0, 0.0, 1.0)
277
+ # mat.add_property(Assimp::MATKEY_COLOR_EMISSIVE, c)
278
+ # c = Assimp::Color4D::new.set(0.0, 0.0, 0.0, 0.0)
279
+ # mat.add_property(Assimp::MATKEY_COLOR_REFLECTIVE, c)
280
+ # mat.add_property(Assimp::MATKEY_REFLECTIVITY, 0.0)
281
+ # mat.add_property(Assimp::MATKEY_REFRACTI, 1.55)
282
+ # mat.add_property(Assimp::MATKEY_OPACITY, 1.0)
283
+
284
+ if m.kind_of?(WMBFile::Bayo1Material)
285
+ if m.parameters["diffuse"]
286
+ c = Assimp::Color4D::new.set(m.parameters["diffuse"][0],
287
+ m.parameters["diffuse"][1],
288
+ m.parameters["diffuse"][2], 1.0)
289
+ mat.add_property(Assimp::MATKEY_COLOR_DIFFUSE, c)
290
+ end
291
+ if m.parameters["ambient"]
292
+ c = Assimp::Color4D::new.set(m.parameters["ambient"][0],
293
+ m.parameters["ambient"][1],
294
+ m.parameters["ambient"][2], 1.0)
295
+ mat.add_property(Assimp::MATKEY_COLOR_AMBIENT, c)
296
+ end
297
+ if m.parameters["specular"]
298
+ c = Assimp::Color4D::new.set(m.parameters["specular"][0],
299
+ m.parameters["specular"][1],
300
+ m.parameters["specular"][2], 1.0)
301
+ mat.add_property(Assimp::MATKEY_COLOR_SPECULAR, c)
302
+ end
303
+ mat.add_property(Assimp::MATKEY_SHININESS, m.parameters["shine"]) if m.parameters["shine"]
304
+ sampler_count = 0
305
+ m.samplers.each { |name, value|
306
+ case name
307
+ when "Color_1", "Color_2", "Color_3"
308
+ next if value >= $texture_count
309
+ index = 0 if name == "Color_1"
310
+ index = 1 if name == "Color_2"
311
+ index = 2 if name == "Color_3"
312
+ mat.add_property(Assimp::MATKEY_TEXTURE, $texture_names[value], semantic: :DIFFUSE, index: index)
313
+ # mat.add_property(Assimp::MATKEY_TEXOP, :Multiply, semantic: :DIFFUSE, index: index)
314
+ mat.add_property(Assimp::MATKEY_MAPPING, :UV, semantic: :DIFFUSE, index: index)
315
+ mat.add_property(Assimp::MATKEY_MAPPINGMODE_U, :Wrap, semantic: :DIFFUSE, index: index)
316
+ mat.add_property(Assimp::MATKEY_MAPPINGMODE_V, :Wrap, semantic: :DIFFUSE, index: index)
317
+ mat.add_property(Assimp::MATKEY_TEXBLEND, 1.0, semantic: :DIFFUSE, index: index)
318
+ mat.add_property(Assimp::MATKEY_UVWSRC, 0, semantic: :DIFFUSE, index: index)
319
+ tr = Assimp::UVTransform::new
320
+ tr.translation.x = 0
321
+ tr.translation.y = 0
322
+ if name == "Color_1" && m.parameters["Color_1_Tile"]
323
+ tr.scaling.x = m.parameters["Color_1_Tile"][0]
324
+ tr.scaling.y = m.parameters["Color_1_Tile"][1]
325
+ elsif name == "Color_2" && m.parameters["Color_2_Tile"]
326
+ tr.scaling.x = m.parameters["Color_2_Tile"][0]
327
+ tr.scaling.y = m.parameters["Color_2_Tile"][1]
328
+ elsif name == "Color_3" && m.parameters["Color_3_Tile"]
329
+ tr.scaling.x = m.parameters["Color_3_Tile"][0]
330
+ tr.scaling.y = m.parameters["Color_3_Tile"][1]
331
+ else
332
+ tr.scaling.x = 1.0
333
+ tr.scaling.y = 1.0
334
+ end
335
+ tr.rotation = 0.0
336
+ mat.add_property(Assimp::MATKEY_UVTRANSFORM, tr, semantic: :DIFFUSE, index: index)
337
+ sampler_count += 1
338
+ when "effectmap"
339
+ next if value >= $texture_count
340
+ mat.add_property(Assimp::MATKEY_TEXTURE, $texture_names[value], semantic: :EMISSIVE, index: sampler_count - 1)
341
+ mat.add_property(Assimp::MATKEY_MAPPING, :UV, semantic: :EMISSIVE, index: sampler_count - 1)
342
+ mat.add_property(Assimp::MATKEY_MAPPINGMODE_U, :Wrap, semantic: :EMISSIVE, index: sampler_count - 1)
343
+ mat.add_property(Assimp::MATKEY_MAPPINGMODE_V, :Wrap, semantic: :EMISSIVE, index: sampler_count - 1)
344
+ mat.add_property(Assimp::MATKEY_UVWSRC, 0, semantic: :EMISSIVE, index: sampler_count - 1)
345
+ when "env_amb"
346
+ next if value >= $texture_count || m.samplers.include?("envmap")
347
+ mat.add_property(Assimp::MATKEY_TEXTURE, $texture_names[value], semantic: :REFLECTION, index: sampler_count - 1)
348
+ mat.add_property(Assimp::MATKEY_MAPPING, :BOX, semantic: :REFLECTION, index: sampler_count - 1)
349
+ when "envmap"
350
+ next if value >= $texture_count
351
+ mat.add_property(Assimp::MATKEY_TEXTURE, $texture_names[value], semantic: :REFLECTION, index: sampler_count - 1)
352
+ mat.add_property(Assimp::MATKEY_MAPPING, :BOX, semantic: :REFLECTION, index: sampler_count - 1)
353
+ when "lightmap"
354
+ next if value >= $texture_count
355
+ next unless fields.include?(:mapping2)
356
+ mat.add_property(Assimp::MATKEY_TEXTURE, $texture_names[value], semantic: :LIGHTMAP, index: sampler_count - 1)
357
+ mat.add_property(Assimp::MATKEY_MAPPING, :UV, semantic: :LIGHTMAP, index: sampler_count - 1)
358
+ mat.add_property(Assimp::MATKEY_MAPPINGMODE_U, :Wrap, semantic: :LIGHTMAP, index: sampler_count - 1)
359
+ mat.add_property(Assimp::MATKEY_MAPPINGMODE_V, :Wrap, semantic: :LIGHTMAP, index: sampler_count - 1)
360
+ mat.add_property(Assimp::MATKEY_UVWSRC, 1, semantic: :LIGHTMAP, index: sampler_count - 1)
361
+ when "refractmap"
362
+ next if value >= $texture_count
363
+ mat.add_property(Assimp::MATKEY_TEXTURE, $texture_names[value], semantic: :OPACITY, index: sampler_count - 1)
364
+ mat.add_property(Assimp::MATKEY_MAPPING, :UV, semantic: :OPACITY, index: sampler_count - 1)
365
+ mat.add_property(Assimp::MATKEY_MAPPINGMODE_U, :Wrap, semantic: :OPACITY, index: sampler_count - 1)
366
+ mat.add_property(Assimp::MATKEY_MAPPINGMODE_V, :Wrap, semantic: :OPACITY, index: sampler_count - 1)
367
+ mat.add_property(Assimp::MATKEY_UVWSRC, 0, semantic: :OPACITY, index: sampler_count - 1)
368
+ when "reliefmap"
369
+ next if value >= $texture_count
370
+ mat.add_property(Assimp::MATKEY_TEXTURE, $texture_names[value], semantic: :NORMALS, index: sampler_count - 1)
371
+ # mat.add_property(Assimp::MATKEY_TEXOP, :Multiply, semantic: :NORMALS, index: sampler_count - 1)
372
+ mat.add_property(Assimp::MATKEY_MAPPING, :UV, semantic: :NORMALS, index: sampler_count - 1)
373
+ mat.add_property(Assimp::MATKEY_MAPPINGMODE_U, :Wrap, semantic: :NORMALS, index: sampler_count - 1)
374
+ mat.add_property(Assimp::MATKEY_MAPPINGMODE_V, :Wrap, semantic: :NORMALS, index: sampler_count - 1)
375
+ # mat.add_property(Assimp::MATKEY_TEXBLEND, 1.0, semantic: :NORMALS, index: sampler_count - 1)
376
+ uvsrc = 0
377
+ uvsrc = 1 if fields.include?(:mapping2) && !m.parameters.include?("lightmap")
378
+ mat.add_property(Assimp::MATKEY_UVWSRC, uvsrc, semantic: :NORMALS, index: sampler_count - 1)
379
+ tr = Assimp::UVTransform::new
380
+ tr.translation.x = 0
381
+ tr.translation.y = 0
382
+ tr.scaling.x = 1.0
383
+ tr.scaling.y = 1.0
384
+ tr.rotation = 0.0
385
+ mat.add_property(Assimp::MATKEY_UVTRANSFORM, tr, semantic: :NORMALS, index: sampler_count - 1)
386
+ when "Spec_Mask"
387
+ next if value >= $texture_count
388
+ mat.add_property(Assimp::MATKEY_TEXTURE, $texture_names[value], semantic: :SPECULAR, index: sampler_count - 1)
389
+ mat.add_property(Assimp::MATKEY_MAPPING, :UV, semantic: :SPECULAR, index: sampler_count - 1)
390
+ mat.add_property(Assimp::MATKEY_MAPPINGMODE_U, :Wrap, semantic: :SPECULAR, index: sampler_count - 1)
391
+ mat.add_property(Assimp::MATKEY_MAPPINGMODE_V, :Wrap, semantic: :SPECULAR, index: sampler_count - 1)
392
+ mat.add_property(Assimp::MATKEY_UVWSRC, 0, semantic: :SPECULAR, index: sampler_count - 1)
393
+ when "Spec_Pow"
394
+ next if value >= $texture_count
395
+ mat.add_property(Assimp::MATKEY_TEXTURE, $texture_names[value], semantic: :SHININESS, index: sampler_count - 1)
396
+ mat.add_property(Assimp::MATKEY_MAPPING, :UV, semantic: :SHININESS, index: sampler_count - 1)
397
+ mat.add_property(Assimp::MATKEY_MAPPINGMODE_U, :Wrap, semantic: :SHININESS, index: sampler_count - 1)
398
+ mat.add_property(Assimp::MATKEY_MAPPINGMODE_V, :Wrap, semantic: :SHININESS, index: sampler_count - 1)
399
+ mat.add_property(Assimp::MATKEY_UVWSRC, 0, semantic: :SHININESS, index: sampler_count - 1)
400
+ end
401
+ }
402
+ else
403
+ 4.times { |j|
404
+ if m.material_data[j] < $texture_count
405
+ mat.add_property(Assimp::MATKEY_TEXTURE, $texture_names[m.material_data[j]], semantic: :DIFFUSE)
406
+ mat.add_property(Assimp::MATKEY_MAPPINGMODE_U, :Wrap, semantic: :DIFFUSE)
407
+ mat.add_property(Assimp::MATKEY_MAPPINGMODE_V, :Wrap, semantic: :DIFFUSE)
408
+ mat.add_property(Assimp::MATKEY_TEXBLEND, 1.0, semantic: :DIFFUSE)
409
+ mat.add_property(Assimp::MATKEY_UVWSRC, 0, semantic: :DIFFUSE)
410
+ tr = Assimp::UVTransform::new
411
+ tr.translation.x = 0
412
+ tr.translation.y = 0
413
+ tr.scaling.x = 1.0
414
+ tr.scaling.y = 1.0
415
+ tr.rotation = 0.0
416
+ mat.add_property(Assimp::MATKEY_UVTRANSFORM, tr, semantic: :DIFFUSE)
417
+ break
418
+ end
419
+ }
420
+ end
421
+ mat
422
+ }
423
+
424
+ output_dir = $options[:output]
425
+ if !output_dir
426
+ Dir.mkdir("assimp_output") unless Dir.exist?("assimp_output")
427
+ output_dir = File.join("assimp_output", "#{$root_node.name}_#{format}")
428
+ else
429
+ raise "Invalid directory provided: #{output_dir}!" unless Dir.exist?(output_dir)
430
+ output_dir = File.join(output_dir, "#{$root_node.name}_#{format}")
431
+ end
432
+ Dir.mkdir(output_dir) unless Dir.exist?(output_dir)
433
+ $wtb.each.each_with_index { |info_f, i|
434
+ info, f = info_f
435
+ ext, _, _ = info
436
+ File::open(File.join(output_dir, "#{$root_node.name}_#{"%02d"%i}#{ext}"), "wb") { |f2|
437
+ f.rewind
438
+ f2.write(f.read)
439
+ }
440
+ }
441
+ GC.start
442
+ postprocess = [:FlipWindingOrder]
443
+ #if format == "obj"
444
+ postprocess.push :FlipUVs
445
+ #end
446
+ path = File.join(output_dir, "#{$root_node.name}.#{extension}")
447
+ $scene.export(format, path, preprocessing: postprocess)
448
+
449
+ if format == "collada"
450
+ doc = Nokogiri::XML(File.read(path))
451
+
452
+ doc.search("node").select { |n| n["id"].match("bone") && n["type"] == "NODE" }.each { |n| n["sid"] = n["id"]; n["type"] = "JOINT" }
453
+ doc.search("skeleton").each { |s| s.child.replace( "#skeleton") }
454
+
455
+ doc.search("bump").each { |b| b["bumptype"] = "NORMALMAP" }
456
+
457
+ # rest is for Noesis
458
+
459
+ mat_map = {}
460
+ batch_map = {}
461
+ doc.search("instance_material").each { |im|
462
+ ansc = im.ancestors("instance_controller").first
463
+ im["symbol"] = im["target"].tr("#","")
464
+ str = ansc["url"].to_s
465
+ str = str.tr("#","").gsub("-skin","")
466
+ ansc = im.ancestors("node").first
467
+ batch_map[str] = ansc["name"]
468
+ mat_map[ str ]= im["symbol"]
469
+ }
470
+
471
+ doc.search("polylist").each { |p|
472
+ ansc = p.ancestors("geometry").first
473
+ batch = ansc["id"].to_s
474
+ ansc["name"] = batch_map[batch]
475
+ p["material"] = mat_map[batch]
476
+ }
477
+
478
+ File.open(path, "w") { |f| f.write doc.to_xml }
479
+ end
@@ -0,0 +1,50 @@
1
+ require 'set'
2
+ require 'yaml'
3
+ require 'optparse'
4
+ require_relative '../../bayonetta'
5
+ include Bayonetta
6
+
7
+ $options = {
8
+ filter: nil
9
+ }
10
+
11
+ OptionParser.new do |opts|
12
+ opts.banner = <<EOF
13
+ Usage: wmb_get_bone_map target_file
14
+ EOF
15
+ opts.on("-h", "--help", "Prints this help") do
16
+ puts opts
17
+ exit
18
+ end
19
+
20
+ opts.on("-f", "--filter=YAML_FILE", "A YAML file containing the list of global bones to get the mapping for") do |f|
21
+ $options[:filter] = f
22
+ end
23
+
24
+ end.parse!
25
+
26
+ def decode_bone_index_translate_table(wmb, filter=nil)
27
+ table = wmb.bone_index_translate_table.table.dup
28
+ table.select! { |k,v| filter.include?(k) } if filter
29
+ table
30
+ end
31
+
32
+ input_file = ARGV[0]
33
+ filter = $options[:filter]
34
+ if filter
35
+ raise "Invalid filter file: #{filter}!" unless File.exist?(filter)
36
+ f = YAML::load_file(filter).to_set
37
+ else
38
+ f = nil
39
+ end
40
+
41
+ raise "Invalid file #{input_file}" unless input_file && File::file?(input_file)
42
+ if File.extname(input_file) == ".dat"
43
+ wmb = DATFile::load(input_file).each.select { |name, f|
44
+ name == File.basename(input_file, ".dat")+".wmb"
45
+ }.first[1]
46
+ wmb = WMBFile::load(wmb)
47
+ else
48
+ wmb = WMBFile::load(input_file)
49
+ end
50
+ puts YAML::dump decode_bone_index_translate_table(wmb, f).to_h