15
|
1 from struct import unpack
|
|
2
|
|
3 from pytouhou.utils.matrix import Matrix
|
|
4
|
|
5 class Sprite(object):
|
|
6 def __init__(self, anm, script_index):
|
|
7 self.anm = anm
|
|
8 self.script_index = script_index
|
|
9 self.texcoords = (0, 0, 0, 0) # x, y, width, height
|
|
10 self.mirrored = False
|
|
11 self.rescale = (1., 1.)
|
|
12 self.rotations_3d = (0., 0., 0.)
|
|
13 self.corner_relative_placement = False
|
|
14 self._uvs = []
|
|
15 self._vertices = []
|
|
16
|
|
17
|
|
18 def update_uvs_vertices(self, override_width=0, override_height=0):
|
|
19 vertmat = Matrix()
|
|
20 vertmat.data[0][0] = -.5
|
|
21 vertmat.data[1][0] = -.5
|
|
22
|
|
23 vertmat.data[0][1] = .5
|
|
24 vertmat.data[1][1] = -.5
|
|
25
|
|
26 vertmat.data[0][2] = .5
|
|
27 vertmat.data[1][2] = .5
|
|
28
|
|
29 vertmat.data[0][3] = -.5
|
|
30 vertmat.data[1][3] = .5
|
|
31
|
|
32 for i in range(4):
|
|
33 vertmat.data[2][i] = 0.
|
|
34 vertmat.data[3][i] = 1.
|
|
35
|
|
36 tx, ty, tw, th = self.texcoords
|
|
37 sx, sy = self.rescale
|
|
38 width = override_width or (tw * sx)
|
|
39 height = override_height or (th * sy)
|
|
40
|
|
41 transform = Matrix.get_scaling_matrix(width, height, 1.)
|
|
42 if self.mirrored:
|
|
43 transform = Matrix.get_scaling_matrix(-1., 1., 1.).mult(transform)
|
|
44 if self.rotations_3d != (0., 0., 0.):
|
|
45 rx, ry, rz = self.rotations_3d
|
|
46 transform = Matrix.get_rotation_matrix(-rx, 'x').mult(transform)
|
|
47 transform = Matrix.get_rotation_matrix(ry, 'y').mult(transform)
|
|
48 transform = Matrix.get_rotation_matrix(-rz, 'z').mult(transform) #TODO: minus, really?
|
|
49 if self.corner_relative_placement: # Reposition
|
|
50 transform = Matrix.get_translation_matrix(width / 2., height / 2., 0.).mult(transform)
|
|
51 vertmat = transform.mult(vertmat)
|
|
52
|
|
53 uvs = [(tx / self.anm.size[0], 1. - (ty / self.anm.size[1])),
|
|
54 ((tx + tw) / self.anm.size[0], 1. - (ty / self.anm.size[1])),
|
|
55 ((tx + tw) / self.anm.size[0], 1. - ((ty + th) / self.anm.size[1])),
|
|
56 (tx / self.anm.size[0], 1. - ((ty + th) / self.anm.size[1]))]
|
|
57
|
|
58 vertices = []
|
|
59 for i in xrange(4):
|
|
60 w = vertmat.data[3][i]
|
|
61 vertices.append((vertmat.data[0][i] / w,
|
|
62 vertmat.data[1][i] / w,
|
|
63 vertmat.data[2][i] / w))
|
|
64
|
|
65 self._uvs, self._vertices = uvs, vertices
|
|
66
|
|
67
|
|
68
|
|
69 def update(self, frame, override_width=0, override_height=0):
|
|
70 properties = {}
|
|
71 for time, instr_type, data in self.anm.scripts[self.script_index]:
|
|
72 if time == frame:
|
|
73 if instr_type == 15: #Return
|
|
74 break
|
|
75 else:
|
|
76 properties[instr_type] = data
|
|
77 if properties:
|
|
78 if 1 in properties:
|
|
79 self.texcoords = self.anm.sprites[unpack('<I', properties[1])[0]]
|
|
80 del properties[1]
|
|
81 if 2 in properties:
|
|
82 self.rescale = unpack('<ff', properties[2])
|
|
83 del properties[2]
|
|
84 if 7 in properties:
|
|
85 self.mirrored = True #TODO
|
|
86 del properties[7]
|
|
87 if 9 in properties:
|
|
88 self.rotations_3d = unpack('<fff', properties[9])
|
|
89 del properties[9]
|
|
90 if 23 in properties:
|
|
91 self.corner_relative_placement = True #TODO
|
|
92 del properties[23]
|
|
93 if properties:
|
|
94 print('Leftover properties: %r' % properties) #TODO
|
|
95 self.update_uvs_vertices(override_width, override_height)
|
|
96 return True
|
|
97 return False
|
|
98
|