Mercurial > touhou
comparison pytouhou/utils/matrix.pyx @ 523:6e3b3d5d4691
Make matrix a struct.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Wed, 18 Dec 2013 17:53:29 +0100 |
parents | 26c082870dcf |
children | db28538cd399 |
comparison
equal
deleted
inserted
replaced
522:e8496e5ba056 | 523:6e3b3d5d4691 |
---|---|
15 from libc.math cimport sin, cos | 15 from libc.math cimport sin, cos |
16 from libc.stdlib cimport malloc, free | 16 from libc.stdlib cimport malloc, free |
17 from libc.string cimport memcpy | 17 from libc.string cimport memcpy |
18 | 18 |
19 | 19 |
20 cdef float[16] identity | 20 cdef Matrix identity |
21 identity[:] = [1, 0, 0, 0, | 21 identity = Matrix(1, 0, 0, 0, |
22 0, 1, 0, 0, | 22 0, 1, 0, 0, |
23 0, 0, 1, 0, | 23 0, 0, 1, 0, |
24 0, 0, 0, 1] | 24 0, 0, 0, 1) |
25 | 25 |
26 | 26 |
27 cdef class Matrix: | 27 cdef Matrix *new_matrix(Matrix *data) nogil: |
28 def __init__(self, data=None): | 28 mat = <Matrix*> malloc(sizeof(Matrix)) |
29 if data is not None: | 29 memcpy(mat, data, sizeof(Matrix)) |
30 for i in xrange(16): | 30 return mat |
31 self.data[i] = data[i] | |
32 else: | |
33 memcpy(self.data, identity, 16 * sizeof(float)) | |
34 | 31 |
35 | 32 |
36 def __mul__(Matrix self, Matrix other): | 33 cdef Matrix *new_identity() nogil: |
37 cdef float *d1, *d2, *d3 | 34 return new_matrix(&identity) |
38 | |
39 out = Matrix() | |
40 d1 = self.data | |
41 d2 = other.data | |
42 d3 = out.data | |
43 for i in xrange(4): | |
44 for j in xrange(4): | |
45 d3[4*i+j] = 0 | |
46 for k in xrange(4): | |
47 d3[4*i+j] += d1[4*i+k] * d2[4*k+j] | |
48 return out | |
49 | 35 |
50 | 36 |
51 cdef void flip(self) nogil: | 37 cdef void mul(Matrix *mat1, Matrix *mat2) nogil: |
52 cdef float *data | 38 cdef float *d3 |
53 | 39 |
54 data = self.data | 40 out = <Matrix*> malloc(sizeof(Matrix)) |
55 for i in xrange(4): | 41 d1 = <float*>mat1 |
56 data[i] = -data[i] | 42 d2 = <float*>mat2 |
43 d3 = <float*>out | |
44 for i in xrange(4): | |
45 for j in xrange(4): | |
46 d3[4*i+j] = 0 | |
47 for k in xrange(4): | |
48 d3[4*i+j] += d1[4*i+k] * d2[4*k+j] | |
49 memcpy(mat1, out, sizeof(Matrix)) | |
50 free(out) | |
57 | 51 |
58 | 52 |
59 cdef void scale(self, float x, float y, float z) nogil: | 53 cdef void flip(Matrix *mat) nogil: |
60 cdef float *data, coordinate[3] | 54 data = <float*>mat |
61 | 55 for i in xrange(4): |
62 data = self.data | 56 data[i] = -data[i] |
63 coordinate[0] = x | |
64 coordinate[1] = y | |
65 coordinate[2] = z | |
66 | |
67 for i in xrange(3): | |
68 for j in xrange(4): | |
69 data[4*i+j] *= coordinate[i] | |
70 | 57 |
71 | 58 |
72 cdef void scale2d(self, float x, float y) nogil: | 59 cdef void scale(Matrix *mat, float x, float y, float z) nogil: |
73 cdef float *data | 60 cdef float coordinate[3] |
74 | 61 |
75 data = self.data | 62 data = <float*>mat |
76 for i in xrange(4): | 63 coordinate[0] = x |
77 data[ i] *= x | 64 coordinate[1] = y |
78 data[4+i] *= y | 65 coordinate[2] = z |
66 | |
67 for i in xrange(3): | |
68 for j in xrange(4): | |
69 data[4*i+j] *= coordinate[i] | |
79 | 70 |
80 | 71 |
81 cdef void translate(self, float x, float y, float z) nogil: | 72 cdef void scale2d(Matrix *mat, float x, float y) nogil: |
82 cdef float *data, coordinate[3], item[3] | 73 data = <float*>mat |
83 | 74 for i in xrange(4): |
84 data = self.data | 75 data[ i] *= x |
85 coordinate[0] = x | 76 data[4+i] *= y |
86 coordinate[1] = y | |
87 coordinate[2] = z | |
88 for i in xrange(3): | |
89 item[i] = data[12+i] * coordinate[i] | |
90 | |
91 for i in xrange(3): | |
92 for j in xrange(4): | |
93 data[4*i+j] += item[i] | |
94 | 77 |
95 | 78 |
96 cdef void rotate_x(self, float angle) nogil: | 79 cdef void translate(Matrix *mat, float x, float y, float z) nogil: |
97 cdef float cos_a, sin_a | 80 cdef float offset[3], item[3] |
98 cdef float lines[8], *data | |
99 | 81 |
100 data = self.data | 82 offset[0] = x |
101 cos_a = cos(angle) | 83 offset[1] = y |
102 sin_a = sin(angle) | 84 offset[2] = z |
103 for i in xrange(8): | 85 |
104 lines[i] = data[i+4] | 86 data = <float*>mat |
105 for i in xrange(4): | 87 for i in xrange(3): |
106 data[4+i] = cos_a * lines[i] - sin_a * lines[4+i] | 88 item[i] = data[12+i] * offset[i] |
107 data[8+i] = sin_a * lines[i] + cos_a * lines[4+i] | 89 |
90 for i in xrange(3): | |
91 for j in xrange(4): | |
92 data[4*i+j] += item[i] | |
108 | 93 |
109 | 94 |
110 cdef void rotate_y(self, float angle) nogil: | 95 cdef void translate2d(Matrix *mat, float x, float y) nogil: |
111 cdef float cos_a, sin_a | 96 translate(mat, x, y, 0) |
112 cdef float lines[8], *data | |
113 | |
114 data = self.data | |
115 cos_a = cos(angle) | |
116 sin_a = sin(angle) | |
117 for i in xrange(4): | |
118 lines[i] = data[i] | |
119 lines[i+4] = data[i+8] | |
120 for i in xrange(4): | |
121 data[ i] = cos_a * lines[i] + sin_a * lines[4+i] | |
122 data[8+i] = -sin_a * lines[i] + cos_a * lines[4+i] | |
123 | 97 |
124 | 98 |
125 cdef void rotate_z(self, float angle) nogil: | 99 cdef void rotate_x(Matrix *mat, float angle) nogil: |
126 cdef float cos_a, sin_a | 100 cdef float cos_a, sin_a |
127 cdef float lines[8], *data | 101 cdef float lines[8] |
128 | 102 |
129 data = self.data | 103 data = <float*>mat |
130 cos_a = cos(angle) | 104 cos_a = cos(angle) |
131 sin_a = sin(angle) | 105 sin_a = sin(angle) |
132 for i in xrange(8): | 106 for i in xrange(8): |
133 lines[i] = data[i] | 107 lines[i] = data[i+4] |
134 for i in xrange(4): | 108 for i in xrange(4): |
135 data[ i] = cos_a * lines[i] - sin_a * lines[4+i] | 109 data[4+i] = cos_a * lines[i] - sin_a * lines[4+i] |
136 data[4+i] = sin_a * lines[i] + cos_a * lines[4+i] | 110 data[8+i] = sin_a * lines[i] + cos_a * lines[4+i] |
111 | |
112 | |
113 cdef void rotate_y(Matrix *mat, float angle) nogil: | |
114 cdef float cos_a, sin_a | |
115 cdef float lines[8] | |
116 | |
117 data = <float*>mat | |
118 cos_a = cos(angle) | |
119 sin_a = sin(angle) | |
120 for i in xrange(4): | |
121 lines[i] = data[i] | |
122 lines[i+4] = data[i+8] | |
123 for i in xrange(4): | |
124 data[ i] = cos_a * lines[i] + sin_a * lines[4+i] | |
125 data[8+i] = -sin_a * lines[i] + cos_a * lines[4+i] | |
126 | |
127 | |
128 cdef void rotate_z(Matrix *mat, float angle) nogil: | |
129 cdef float cos_a, sin_a | |
130 cdef float lines[8] | |
131 | |
132 data = <float*>mat | |
133 cos_a = cos(angle) | |
134 sin_a = sin(angle) | |
135 for i in xrange(8): | |
136 lines[i] = data[i] | |
137 for i in xrange(4): | |
138 data[ i] = cos_a * lines[i] - sin_a * lines[4+i] | |
139 data[4+i] = sin_a * lines[i] + cos_a * lines[4+i] |