Mercurial > touhou-blender
view io_scene_touhou/import_std.py @ 1:ba73c663a227 default tip
Make it work with the latest PyTouhou.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 20 Dec 2013 17:11:29 +0100 |
parents | 8265ef6db380 |
children |
line wrap: on
line source
# ##### BEGIN GPL LICENSE BLOCK ##### # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # ##### END GPL LICENSE BLOCK ##### # <pep8-80 compliant> """ This script imports Touhou EoSD stages files to Blender. Usage: Execute this script from the "File->Import" menu and choose a Touhou stage file to open. """ from pytouhou.formats.std import Stage from pytouhou.formats.anm0 import ANM from pytouhou.vm.anmrunner import ANMRunner from pytouhou.game.sprite import Sprite from pytouhou.ui.opengl.sprite import get_sprite_rendering_data import bpy import os.path def build_models(stage, anm): """Taken from pytouhou.game.background.""" models = [] for obj in stage.models: quads = [] for script_index, ox, oy, oz, width_override, height_override in obj.quads: sprite = Sprite(width_override, height_override) anm_runner = ANMRunner(anm, script_index, sprite) quads.append((ox, oy, oz, sprite)) models.append(quads) return models def read_mesh(obj_name, stage, model, image): verts = [] texcoords = [] cols = [] nb_vertices = 0 faces_indices = [] for ox, oy, oz, sprite in model: key, (vertices, uvs, colors) = get_sprite_rendering_data(sprite) x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4 = vertices left, right, bottom, top = uvs r, g, b, a = colors #verts.extend(((x1 + ox, y1 + oy, z1 + oz), # (x2 + ox, y2 + oy, z2 + oz), # (x3 + ox, y3 + oy, z3 + oz), # (x4 + ox, y4 + oy, z4 + oz))) # Blender coordinates are z-inverted. verts.extend(((x1 + ox, y1 + oy, -(z1 + oz)), (x2 + ox, y2 + oy, -(z2 + oz)), (x3 + ox, y3 + oy, -(z3 + oz)), (x4 + ox, y4 + oy, -(z4 + oz)))) texcoords.extend(((left, 1.-bottom), (right, 1.-bottom), (right, 1.-top), (left, 1.-top))) #TODO: use them. cols.append((r, g, b, a)) faces_indices.append((nb_vertices, nb_vertices + 1, nb_vertices + 2, nb_vertices + 3)) nb_vertices += 4 mesh = bpy.data.meshes.new(obj_name) mesh.from_pydata(verts, [], faces_indices) texture = mesh.uv_textures.new('Texture') for tex in texture.data: tex.image = image uvs = mesh.uv_layers[0] for i, uv_loop in enumerate(uvs.data): uv_loop.uv = texcoords[i] return mesh def add_object(name, mesh, position): scene = bpy.context.scene for obj in scene.objects: obj.select = False mesh.update() mesh.validate() obj = bpy.data.objects.new(name, mesh) obj.location = position scene.objects.link(obj) obj.select = True if scene.objects.active is None or scene.objects.active.mode == 'OBJECT': scene.objects.active = obj def read(stage_path): dirname = os.path.dirname(stage_path) obj_name = bpy.path.display_name_from_filepath(stage_path) assert obj_name[:5] == 'stage' stage_number = int(obj_name[5]) with open(stage_path, "rb") as filehandle: stage = Stage.read(filehandle) anm_path = os.path.join(dirname, 'stg{}bg.anm'.format(stage_number)) with open(anm_path, "rb") as filehandle: anm = ANM.read(filehandle) entry = anm[0] #XXX models = build_models(stage, entry) texture_path = os.path.join(dirname, 'stg{}bg.png'.format(stage_number)) image = bpy.data.images.load(texture_path) meshes = [] for i, model in enumerate(models): name = '{}-mesh{}'.format(obj_name, i) mesh = read_mesh(name, stage, model, image) meshes.append(mesh) for i, (model_id, ox, oy, oz) in enumerate(stage.object_instances): name = '{}-object{:02}'.format(obj_name, i) add_object(name, meshes[model_id], (ox, oy, -oz))