pgtools 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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