X-Git-Url: https://git.yukkurigames.com/?p=python-bulletml.git;a=blobdiff_plain;f=bulletml%2F_collision.pyx;fp=bulletml%2F_collision.pyx;h=0000000000000000000000000000000000000000;hp=b05702213ca775d73079096d8b03a88005c53877;hb=eed0de88f98b23ecb25507b47a507e2791861334;hpb=382c381aa58db92e81145d49f193f79fdfa72450 diff --git a/bulletml/_collision.pyx b/bulletml/_collision.pyx deleted file mode 100644 index b057022..0000000 --- a/bulletml/_collision.pyx +++ /dev/null @@ -1,178 +0,0 @@ -"""Optimized collision detection functions.""" - -def overlaps(a, b): - """Return true if two circles are overlapping. - - Usually, you'll want to use the 'collides' method instead, but - this one can be useful for just checking to see if the player has - entered an area or hit a stationary oject. - - (This function is optimized.) - - """ - - cdef float ax - cdef float bx - cdef float ay - cdef float by - cdef float dx - cdef float dy - cdef float radius_a - cdef float radius_b - cdef float radius - - ax = a.x - bx = b.x - ay = a.y - by = b.y - - dx = ax - bx - dy = ay - by - - radius_a = getattr3(a, 'radius', 0.5) - radius_b = getattr3(b, 'radius', 0.5) - radius = radius_a + radius_b - - return dx * dx + dy * dy <= radius * radius - - -cdef int _collides(float xa, float xb, float ya, float yb, - float pxa, float pxb, float pya, float pyb, - float radius_a, float radius_b): - - """Check collision for two moving circles.""" - - cdef float dir_x - cdef float dir_y - - cdef float diff_x - cdef float diff_y - cdef float dist_x - cdef float dist_y - - cdef float dx - cdef float dy - cdef float t - - cdef float radius - - radius = radius_a + radius_b - - # Translate b's final position to be relative to a's start. - # And now, circle/line collision. - dir_x = pxa + (xb - xa) - pxb - dir_y = pya + (yb - ya) - pyb - - if (dir_x < 0.0001 and dir_x > -0.0001 - and dir_y < 0.0001 and dir_y > -0.0001): - # b did not move relative to a, so do point/circle. - dx = pxb - pxa - dy = pyb - pya - return dx * dx + dy * dy < radius * radius - - diff_x = pxa - pxb - diff_y = pya - pyb - - # dot(diff, dir) / dot(dir, dir) - t = (diff_x * dir_x + diff_y * dir_y) / (dir_x * dir_x + dir_y * dir_y) - if t < 0: - t = 0 - elif t > 1: - t = 1 - - dist_x = pxa - (pxb + dir_x * t) - dist_y = pya - (pyb + dir_y * t) - - # dist_sq < radius_sq - return dist_x * dist_x + dist_y * dist_y <= radius * radius - -def collides(a, b): - """Return true if the two moving circles collide. - - a and b should have the following attributes: - - x, y - required, current position - px, py - not required, defaults to x, y, previous frame position - radius - not required, defaults to 0.5 - - (This function is optimized.) - - """ - cdef float xa - cdef float xb - cdef float ya - cdef float yb - - cdef float pxa - cdef float pya - cdef float pxb - cdef float pyb - - cdef float radius_a - cdef float radius_b - - xa = a.x - xb = b.x - ya = a.y - yb = b.y - - radius_a = getattr3(a, 'radius', 0.5) - radius_b = getattr3(b, 'radius', 0.5) - - pxa = getattr3(a, 'px', xa) - pya = getattr3(a, 'py', ya) - pxb = getattr3(b, 'px', xb) - pyb = getattr3(b, 'py', yb) - - return _collides(xa, xb, ya, yb, pxa, pxb, pya, pyb, radius_a, radius_b) - -def collides_all(a, others): - """Filter the second argument to those that collide with the first. - - This is equivalent to filter(lambda o: collides(a, o), others), - but is much faster when the compiled extension is available (which - it is currently). - - """ - cdef float xa - cdef float xb - cdef float ya - cdef float yb - - cdef float pxa - cdef float pya - cdef float pxb - cdef float pyb - - cdef float radius_a - cdef float radius_b - - cdef list bs - cdef int length - - cdef list colliding - - cdef int coll - - colliding = [] - - xa = a.x - ya = a.y - radius_a = getattr3(a, 'radius', 0.5) - pxa = getattr3(a, 'px', xa) - pya = getattr3(a, 'py', ya) - - bs = list(others) - length = len(bs) - - for 0 <= i < length: - b = others[i] - xb = b.x - yb = b.y - radius_b = getattr3(b, 'radius', 0.5) - pxb = getattr3(b, 'px', xb) - pyb = getattr3(b, 'py', yb) - - if _collides(xa, xb, ya, yb, pxa, pxb, pya, pyb, radius_a, radius_b): - colliding.append(b) - return colliding