Mercurial > touhou
changeset 15:07fba4e1da65
Refactor
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Fri, 05 Aug 2011 21:21:06 +0200 |
parents | 07a7f28c8aaa |
children | 66ce9bb440ac |
files | pytouhou/formats/std.py pytouhou/game/background.py pytouhou/game/sprite.py pytouhou/opengl/texture.py stageviewer.py |
diffstat | 5 files changed, 120 insertions(+), 74 deletions(-) [+] |
line wrap: on
line diff
--- a/pytouhou/formats/std.py +++ b/pytouhou/formats/std.py @@ -11,7 +11,8 @@ class Object(object): class Stage(object): - def __init__(self): + def __init__(self, num): + self.num = num self.name = '' self.bgms = (('', ''), ('', ''), ('', '')) self.objects = [] @@ -20,8 +21,8 @@ class Stage(object): @classmethod - def read(cls, file): - stage = Stage() + def read(cls, file, num): + stage = Stage(num) nb_objects, nb_faces = unpack('<HH', file.read(4)) object_instances_offset, script_offset = unpack('<II', file.read(8))
--- a/pytouhou/game/background.py +++ b/pytouhou/game/background.py @@ -3,21 +3,20 @@ import os import struct from itertools import chain -from pytouhou.utils.matrix import Matrix from pytouhou.utils.interpolator import Interpolator - -from pytouhou.formats.std import Stage -from pytouhou.formats.anm0 import Animations +from pytouhou.game.sprite import Sprite class Background(object): - def __init__(self, archive, stage_num): - self.stage = Stage.read(BytesIO(archive.extract('stage%d.std' % stage_num))) - self.anim = Animations.read(BytesIO(archive.extract('stg%dbg.anm' % stage_num))) + def __init__(self, stage, anim): + self.stage = stage + self.anim = anim self.objects = [] self.object_instances = [] self._uvs = b'' self._vertices = b'' + self.nb_vertices = 0 + self.build_objects() self.build_object_instances() @@ -51,67 +50,10 @@ class Background(object): self.objects = [] for i, obj in enumerate(self.stage.objects): faces = [] - for script_index, x, y, z, width_override, height_override in obj.quads: - #TODO: refactor - vertices = [] - uvs = [] - vertmat = Matrix() - vertmat.data[0][0] = -.5 - vertmat.data[1][0] = -.5 - - vertmat.data[0][1] = .5 - vertmat.data[1][1] = -.5 - - vertmat.data[0][2] = .5 - vertmat.data[1][2] = .5 - - vertmat.data[0][3] = -.5 - vertmat.data[1][3] = .5 - - for i in range(4): - vertmat.data[2][i] = 0. - vertmat.data[3][i] = 1. - - properties = {} - for time, instr_type, data in self.anim.scripts[script_index]: - if instr_type == 15: - properties[15] = b'' - break - elif time == 0: #TODO - properties[instr_type] = data - #if 15 not in properties: #TODO: Skip properties - # continue - - #TODO: properties 3 and 4 - if 1 in properties: - tx, ty, tw, th = self.anim.sprites[struct.unpack('<I', properties[1])[0]] - width, height = 1., 1. - if 2 in properties: - width, height = struct.unpack('<ff', properties[2]) - width = width_override or width * tw - height = height_override or height * th - transform = Matrix.get_scaling_matrix(width, height, 1.) - if 7 in properties: - transform = Matrix.get_scaling_matrix(-1., 1., 1.).mult(transform) - if 9 in properties: - rx, ry, rz = struct.unpack('<fff', properties[9]) - transform = Matrix.get_rotation_matrix(-rx, 'x').mult(transform) - transform = Matrix.get_rotation_matrix(ry, 'y').mult(transform) - transform = Matrix.get_rotation_matrix(-rz, 'z').mult(transform) #TODO: minus, really? - if 23 in properties: # Reposition - transform = Matrix.get_translation_matrix(width / 2., height / 2., 0.).mult(transform) - vertmat = transform.mult(vertmat) - - uvs = [(tx / self.anim.size[0], 1. - (ty / self.anim.size[1])), - ((tx + tw) / self.anim.size[0], 1. - (ty / self.anim.size[1])), - ((tx + tw) / self.anim.size[0], 1. - ((ty + th) / self.anim.size[1])), - (tx / self.anim.size[0], 1. - ((ty + th) / self.anim.size[1]))] - - for i in xrange(4): - w = vertmat.data[3][i] - vertices.append((vertmat.data[0][i] / w + x, - vertmat.data[1][i] / w + y, - vertmat.data[2][i] / w + z)) + for script_index, ox, oy, oz, width_override, height_override in obj.quads: + sprite = Sprite(self.anim, script_index) + sprite.update(0, width_override, height_override) + uvs, vertices = sprite._uvs, tuple((x + ox, y + oy, z + oz) for x, y, z in sprite._vertices) faces.append((vertices, uvs)) self.objects.append(faces)
new file mode 100644 --- /dev/null +++ b/pytouhou/game/sprite.py @@ -0,0 +1,98 @@ +from struct import unpack + +from pytouhou.utils.matrix import Matrix + +class Sprite(object): + def __init__(self, anm, script_index): + self.anm = anm + self.script_index = script_index + self.texcoords = (0, 0, 0, 0) # x, y, width, height + self.mirrored = False + self.rescale = (1., 1.) + self.rotations_3d = (0., 0., 0.) + self.corner_relative_placement = False + self._uvs = [] + self._vertices = [] + + + def update_uvs_vertices(self, override_width=0, override_height=0): + vertmat = Matrix() + vertmat.data[0][0] = -.5 + vertmat.data[1][0] = -.5 + + vertmat.data[0][1] = .5 + vertmat.data[1][1] = -.5 + + vertmat.data[0][2] = .5 + vertmat.data[1][2] = .5 + + vertmat.data[0][3] = -.5 + vertmat.data[1][3] = .5 + + for i in range(4): + vertmat.data[2][i] = 0. + vertmat.data[3][i] = 1. + + tx, ty, tw, th = self.texcoords + sx, sy = self.rescale + width = override_width or (tw * sx) + height = override_height or (th * sy) + + transform = Matrix.get_scaling_matrix(width, height, 1.) + if self.mirrored: + transform = Matrix.get_scaling_matrix(-1., 1., 1.).mult(transform) + if self.rotations_3d != (0., 0., 0.): + rx, ry, rz = self.rotations_3d + transform = Matrix.get_rotation_matrix(-rx, 'x').mult(transform) + transform = Matrix.get_rotation_matrix(ry, 'y').mult(transform) + transform = Matrix.get_rotation_matrix(-rz, 'z').mult(transform) #TODO: minus, really? + if self.corner_relative_placement: # Reposition + transform = Matrix.get_translation_matrix(width / 2., height / 2., 0.).mult(transform) + vertmat = transform.mult(vertmat) + + uvs = [(tx / self.anm.size[0], 1. - (ty / self.anm.size[1])), + ((tx + tw) / self.anm.size[0], 1. - (ty / self.anm.size[1])), + ((tx + tw) / self.anm.size[0], 1. - ((ty + th) / self.anm.size[1])), + (tx / self.anm.size[0], 1. - ((ty + th) / self.anm.size[1]))] + + vertices = [] + for i in xrange(4): + w = vertmat.data[3][i] + vertices.append((vertmat.data[0][i] / w, + vertmat.data[1][i] / w, + vertmat.data[2][i] / w)) + + self._uvs, self._vertices = uvs, vertices + + + + def update(self, frame, override_width=0, override_height=0): + properties = {} + for time, instr_type, data in self.anm.scripts[self.script_index]: + if time == frame: + if instr_type == 15: #Return + break + else: + properties[instr_type] = data + if properties: + if 1 in properties: + self.texcoords = self.anm.sprites[unpack('<I', properties[1])[0]] + del properties[1] + if 2 in properties: + self.rescale = unpack('<ff', properties[2]) + del properties[2] + if 7 in properties: + self.mirrored = True #TODO + del properties[7] + if 9 in properties: + self.rotations_3d = unpack('<fff', properties[9]) + del properties[9] + if 23 in properties: + self.corner_relative_placement = True #TODO + del properties[23] + if properties: + print('Leftover properties: %r' % properties) #TODO + self.update_uvs_vertices(override_width, override_height) + return True + return False +
--- a/pytouhou/opengl/texture.py +++ b/pytouhou/opengl/texture.py @@ -33,5 +33,8 @@ def load_texture(archive, anim): glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) + return texture, width, height
--- a/stageviewer.py +++ b/stageviewer.py @@ -11,6 +11,8 @@ from itertools import chain import pygame from pytouhou.formats.pbg3 import PBG3 +from pytouhou.formats.std import Stage +from pytouhou.formats.anm0 import Animations from pytouhou.game.background import Background from pytouhou.opengl.texture import load_texture @@ -36,8 +38,6 @@ def main(path, stage_num): glEnable(GL_FOG) glHint(GL_FOG_HINT, GL_NICEST) glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glEnableClientState(GL_VERTEX_ARRAY) glEnableClientState(GL_TEXTURE_COORD_ARRAY) @@ -45,7 +45,9 @@ def main(path, stage_num): # Load data with open(path, 'rb') as file: archive = PBG3.read(file) - background = Background(archive, stage_num) + stage = Stage.read(BytesIO(archive.extract('stage%d.std' % stage_num)), stage_num) + background_anim = Animations.read(BytesIO(archive.extract('stg%dbg.anm' % stage_num))) + background = Background(stage, background_anim) texture = load_texture(archive, background.anim) print(background.stage.name)