# HG changeset patch # User Thibaut Girka # Date 1312211842 -7200 # Node ID 787d2eb13c2d9ef93b1af1f924b2c8fd72933fce # Parent ffe0283c27de003e97637c47d37770e1562faf86 Add buggy stageviewer! diff --git a/pytouhou/utils/matrix.py b/pytouhou/utils/matrix.py new file mode 100644 --- /dev/null +++ b/pytouhou/utils/matrix.py @@ -0,0 +1,66 @@ +#TODO: find/learn to use a proper lib + +from math import sin, cos + +class Matrix(object): + def __init__(self): + self.data = [[0] * 4 for i in xrange(4)] + + + def mult(self, other_matrix): + result = Matrix() + for i in xrange(4): + for j in xrange(4): + result.data[i][j] = sum(self.data[i][a] * other_matrix.data[a][j] for a in xrange(4)) + return result + + + @classmethod + def get_translation_matrix(cls, x, y, z): + matrix = cls() + matrix.data[0][0] = 1 + matrix.data[1][1] = 1 + matrix.data[2][2] = 1 + matrix.data[3][3] = 1 + matrix.data[0][3] = x + matrix.data[1][3] = y + matrix.data[2][3] = z + return matrix + + + @classmethod + def get_scaling_matrix(cls, x, y, z): + matrix = cls() + matrix.data[0][0] = x + matrix.data[1][1] = y + matrix.data[2][2] = z + matrix.data[3][3] = 1 + return matrix + + + @classmethod + def get_rotation_matrix(cls, angle, axis): + """Only handles axis = x, y or z.""" + matrix = cls() + matrix.data[3][3] = 1 + if axis == 'x': + matrix.data[0][0] = 1 + matrix.data[1][1] = cos(angle) + matrix.data[1][2] = -sin(angle) + matrix.data[2][1] = sin(angle) + matrix.data[2][2] = cos(angle) + elif axis == 'y': + matrix.data[0][0] = cos(angle) + matrix.data[0][2] = sin(angle) + matrix.data[2][0] = -sin(angle) + matrix.data[2][2] = cos(angle) + matrix.data[1][1] = 1 + elif axis == 'z': + matrix.data[0][0] = cos(angle) + matrix.data[0][1] = -sin(angle) + matrix.data[1][0] = sin(angle) + matrix.data[1][1] = cos(angle) + matrix.data[2][2] = 1 + else: + raise Exception + return matrix diff --git a/stageviewer.py b/stageviewer.py new file mode 100644 --- /dev/null +++ b/stageviewer.py @@ -0,0 +1,251 @@ +#!/usr/bin/env python + +import sys +import os + +import struct +from math import degrees, radians +from io import BytesIO +from itertools import chain + +import pygame + +import OpenGL +OpenGL.FORWARD_COMPATIBLE_ONLY = True +from OpenGL.GL import * +from OpenGL.GLU import * + +from pytouhou.formats.pbg3 import PBG3 +from pytouhou.formats.std import Stage +from pytouhou.formats.anm0 import Animations + +from pytouhou.utils.matrix import Matrix + + +def load_texture(image, alpha_image=None): + textureSurface = pygame.image.load(image).convert_alpha() + + if alpha_image: + alphaSurface = pygame.image.load(alpha_image) + assert textureSurface.get_size() == alphaSurface.get_size() + for x in range(alphaSurface.get_width()): + for y in range(alphaSurface.get_height()): + r, g, b, a = textureSurface.get_at((x, y)) + color2 = alphaSurface.get_at((x, y)) + textureSurface.set_at((x, y), (r, g, b, color2[0])) + + textureData = pygame.image.tostring(textureSurface, 'RGBA', 1) + + width = textureSurface.get_width() + height = textureSurface.get_height() + + texture = glGenTextures(1) + glBindTexture(GL_TEXTURE_2D, texture) + + 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 + + + +def build_objects_faces(stage, anim): + objects_faces = [] + for i, obj in enumerate(stage.objects): + faces = [] + for script_index, x, y, z, width_override, height_override in obj.quads: + #TODO: move mof of it elsewhere + 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 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 = anim.sprites[struct.unpack(' frame and message_type == 0: + next_message = frame_num, message_type, data + break + + if frame < interpolation[2]: + truc = float(frame - interpolation[0]) / interpolation[1] + unknownx = old_unknownx + (next_unknownx - old_unknownx) * truc + dy = old_dy + (next_dy - old_dy) * truc + fov = old_fov + (next_fov - old_fov) * truc + else: + unknownx, dy, fov = next_unknownx, next_dy, next_fov + + x1, y1, z1 = struct.unpack('