comparison io_scene_touhou/import_std.py @ 0:8265ef6db380

Hello Gensokyo _o/
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Tue, 05 Mar 2013 20:10:10 +0100
parents
children ba73c663a227
comparison
equal deleted inserted replaced
-1:000000000000 0:8265ef6db380
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software Foundation,
15 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8-80 compliant>
20
21 """
22 This script imports Touhou EoSD stages files to Blender.
23
24 Usage:
25 Execute this script from the "File->Import" menu and choose a Touhou
26 stage file to open.
27 """
28
29
30 from pytouhou.formats.std import Stage
31 from pytouhou.formats.anm0 import ANM0
32 from pytouhou.resource.anmwrapper import AnmWrapper
33 from pytouhou.vm.anmrunner import ANMRunner
34 from pytouhou.game.sprite import Sprite
35 from pytouhou.ui.sprite import get_sprite_rendering_data
36 import bpy
37 import os.path
38
39
40 def build_models(stage, anm_wrapper):
41 """Taken from pytouhou.game.background."""
42 models = []
43 for obj in stage.models:
44 quads = []
45 for script_index, ox, oy, oz, width_override, height_override in obj.quads:
46 sprite = Sprite(width_override, height_override)
47 anm_runner = ANMRunner(anm_wrapper, script_index, sprite)
48 anm_runner.run_frame()
49 quads.append((ox, oy, oz, sprite))
50 models.append(quads)
51 return models
52
53
54 def read_mesh(obj_name, stage, model, image):
55 verts = []
56 texcoords = []
57 cols = []
58 nb_vertices = 0
59 faces_indices = []
60
61 for ox, oy, oz, sprite in model:
62 key, (vertices, uvs, colors) = get_sprite_rendering_data(sprite)
63 (x1, y1, z1), (x2, y2, z2), (x3, y3, z3), (x4, y4, z4) = vertices
64 left, right, bottom, top = uvs
65 r, g, b, a = colors
66
67 #verts.extend(((x1 + ox, y1 + oy, z1 + oz),
68 # (x2 + ox, y2 + oy, z2 + oz),
69 # (x3 + ox, y3 + oy, z3 + oz),
70 # (x4 + ox, y4 + oy, z4 + oz)))
71
72 # Blender coordinates are z-inverted.
73 verts.extend(((x1 + ox, y1 + oy, -(z1 + oz)),
74 (x2 + ox, y2 + oy, -(z2 + oz)),
75 (x3 + ox, y3 + oy, -(z3 + oz)),
76 (x4 + ox, y4 + oy, -(z4 + oz))))
77
78 texcoords.extend(((left, bottom),
79 (right, bottom),
80 (right, top),
81 (left, top)))
82
83 #TODO: use them.
84 cols.append((r, g, b, a))
85
86 faces_indices.append((nb_vertices, nb_vertices + 1, nb_vertices + 2, nb_vertices + 3))
87
88 nb_vertices += 4
89
90 mesh = bpy.data.meshes.new(obj_name)
91 mesh.from_pydata(verts, [], faces_indices)
92
93 texture = mesh.uv_textures.new('Texture')
94 for tex in texture.data:
95 tex.image = image
96
97 uvs = mesh.uv_layers[0]
98 for i, uv_loop in enumerate(uvs.data):
99 uv_loop.uv = texcoords[i]
100
101 return mesh
102
103
104 def add_object(name, mesh, position):
105 scene = bpy.context.scene
106
107 for obj in scene.objects:
108 obj.select = False
109
110 mesh.update()
111 mesh.validate()
112
113 obj = bpy.data.objects.new(name, mesh)
114 obj.location = position
115 scene.objects.link(obj)
116 obj.select = True
117
118 if scene.objects.active is None or scene.objects.active.mode == 'OBJECT':
119 scene.objects.active = obj
120
121
122 def read(stage_path):
123 dirname = os.path.dirname(stage_path)
124
125 obj_name = bpy.path.display_name_from_filepath(stage_path)
126 assert obj_name[:5] == 'stage'
127 stage_number = int(obj_name[5])
128
129 with open(stage_path, "rb") as filehandle:
130 stage = Stage.read(filehandle)
131
132 anm_path = os.path.join(dirname, 'stg{}bg.anm'.format(stage_number))
133 with open(anm_path, "rb") as filehandle:
134 anm = ANM0.read(filehandle)
135 anm_wrapper = AnmWrapper((anm,), (0,))
136
137 models = build_models(stage, anm_wrapper)
138
139 texture_path = os.path.join(dirname, 'stg{}bg.png'.format(stage_number))
140 image = bpy.data.images.load(texture_path)
141
142 meshes = []
143 for i, model in enumerate(models):
144 name = '{}-mesh{}'.format(obj_name, i)
145 mesh = read_mesh(name, stage, model, image)
146 meshes.append(mesh)
147
148 for i, (model_id, ox, oy, oz) in enumerate(stage.object_instances):
149 name = '{}-object{}'.format(obj_name, i)
150 add_object(name, meshes[model_id], (ox, oy, -oz))