# HG changeset patch # User Emmanuel Gil Peyrot # Date 1375868082 -7200 # Node ID cb5c68598ab0d88ea606a09863cb907842363d86 # Parent 878273a984c42a31c611d1c7017da77c97c58c41 Cythonize pytouhou.utils.maths and pytouhou.utils.vector. diff --git a/pytouhou/utils/maths.pxd b/pytouhou/utils/maths.pxd --- a/pytouhou/utils/maths.pxd +++ b/pytouhou/utils/maths.pxd @@ -1,4 +1,5 @@ -cpdef ortho_2d(left, right, bottom, top) -cpdef look_at(eye, center, up) -cpdef perspective(fovy, aspect, zNear, zFar) -cpdef setup_camera(dx, dy, dz) +from .matrix cimport Matrix + +cdef Matrix ortho_2d(float left, float right, float bottom, float top) +cdef Matrix perspective(float fovy, float aspect, float zNear, float zFar) +cdef Matrix setup_camera(float dx, float dy, float dz) diff --git a/pytouhou/utils/maths.pyx b/pytouhou/utils/maths.pyx --- a/pytouhou/utils/maths.pyx +++ b/pytouhou/utils/maths.pyx @@ -12,14 +12,16 @@ ## GNU General Public License for more details. ## -from math import radians -from libc.math cimport tan +from libc.math cimport tan, M_PI as pi -from .matrix cimport Matrix -from .vector import Vector, normalize, cross, dot +from .vector cimport Vector, normalize, cross, dot -cpdef ortho_2d(left, right, bottom, top): +cdef double radians(double degrees) nogil: + return degrees * pi / 180 + + +cdef Matrix ortho_2d(float left, float right, float bottom, float top): cdef float *data mat = Matrix() @@ -32,23 +34,19 @@ cpdef ortho_2d(left, right, bottom, top) return mat -cpdef look_at(eye, center, up): - eye = Vector(eye) - center = Vector(center) - up = Vector(up) - - f = normalize(center - eye) +cdef Matrix look_at(Vector eye, Vector center, Vector up): + f = normalize(center.sub(eye)) u = normalize(up) s = normalize(cross(f, u)) u = cross(s, f) - return Matrix([s[0], u[0], -f[0], 0, - s[1], u[1], -f[1], 0, - s[2], u[2], -f[2], 0, + return Matrix([s.x, u.x, -f.x, 0, + s.y, u.y, -f.y, 0, + s.z, u.z, -f.z, 0, -dot(s, eye), -dot(u, eye), dot(f, eye), 1]) -cpdef perspective(fovy, aspect, z_near, z_far): +cdef Matrix perspective(float fovy, float aspect, float z_near, float z_far): cdef float *data top = tan(radians(fovy / 2)) * z_near @@ -67,11 +65,11 @@ cpdef perspective(fovy, aspect, z_near, return mat -cpdef setup_camera(dx, dy, dz): +cdef Matrix setup_camera(float dx, float dy, float dz): # Some explanations on the magic constants: # 192. = 384. / 2. = width / 2. # 224. = 448. / 2. = height / 2. # 835.979370 = 224./math.tan(math.radians(15)) = (height/2.)/math.tan(math.radians(fov/2)) # This is so that objects on the (O, x, y) plane use pixel coordinates - return look_at((192., 224., - 835.979370 * dz), - (192. + dx, 224. - dy, 0.), (0., -1., 0.)) + return look_at(Vector(192., 224., - 835.979370 * dz), + Vector(192. + dx, 224. - dy, 0.), Vector(0., -1., 0.)) diff --git a/pytouhou/utils/vector.pxd b/pytouhou/utils/vector.pxd new file mode 100644 --- /dev/null +++ b/pytouhou/utils/vector.pxd @@ -0,0 +1,8 @@ +cdef class Vector: + cdef float x, y, z + + cdef Vector sub(self, Vector other) + +cdef Vector cross(Vector vec1, Vector vec2) +cdef float dot(Vector vec1, Vector vec2) +cdef Vector normalize(Vector vec) diff --git a/pytouhou/utils/vector.py b/pytouhou/utils/vector.pyx rename from pytouhou/utils/vector.py rename to pytouhou/utils/vector.pyx --- a/pytouhou/utils/vector.py +++ b/pytouhou/utils/vector.pyx @@ -12,32 +12,38 @@ ## GNU General Public License for more details. ## -from math import sqrt +from libc.math cimport sqrt -class Vector(list): - def __init__(self, data=None): - list.__init__(self, data or [0] * 3) - - - def __add__(self, other): - return Vector([a+b for a, b in zip(self, other)]) +cdef class Vector: + def __init__(self, float x, float y, float z): + self.x = x + self.y = y + self.z = z - def __sub__(self, other): - return Vector([a-b for a, b in zip(self, other)]) + cdef Vector sub(self, Vector other): + cdef float x, y, z + + x = self.x - other.x + y = self.y - other.y + z = self.z - other.z + + return Vector(x, y, z) -def cross(vec1, vec2): - return Vector([vec1[1] * vec2[2] - vec2[1] * vec1[2], - vec1[2] * vec2[0] - vec2[2] * vec1[0], - vec1[0] * vec2[1] - vec2[0] * vec1[1]]) +cdef Vector cross(Vector vec1, Vector vec2): + return Vector(vec1.y * vec2.z - vec2.y * vec1.z, + vec1.z * vec2.x - vec2.z * vec1.x, + vec1.x * vec2.y - vec2.x * vec1.y) -def dot(vec1, vec2): - return vec1[0] * vec2[0] + vec2[1] * vec1[1] + vec1[2] * vec2[2] +cdef float dot(Vector vec1, Vector vec2): + return vec1.x * vec2.x + vec2.y * vec1.y + vec1.z * vec2.z -def normalize(vec1): - normal = 1 / sqrt(vec1[0] * vec1[0] + vec1[1] * vec1[1] + vec1[2] * vec1[2]) - return Vector(x * normal for x in vec1) +cdef Vector normalize(Vector vec): + cdef float normal + + normal = 1 / sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z) + return Vector(vec.x * normal, vec.y * normal, vec.z * normal)