Example #1
0
 def sweep_collision(self, collidee, v, debug=False):
     """
     self (collider) moving by v, collidee stationery
     based on http://bit.ly/3grWzs
     """
     u_0 = [2, 2, 2]
     u_1 = [1, 1, 1]
     for i in xrange(3):
         if fops.lte(self.maxs[i], collidee.mins[i]) and fops.gt(v[i], 0):
             d = collidee.mins[i] - self.maxs[i]
             u_0[i] = d / v[i]
         elif fops.lte(collidee.maxs[i], self.mins[i]) and fops.lt(v[i], 0):
             d = collidee.maxs[i] - self.mins[i]
             u_0[i] = d / v[i]
         elif not (fops.lte(self.maxs[i], collidee.mins[i])
                   or fops.gte(self.mins[i], collidee.maxs[i])):
             u_0[i] = 0
         if fops.gte(collidee.maxs[i], self.mins[i]) and fops.gt(v[i], 0):
             d = collidee.maxs[i] - self.mins[i]
             u_1[i] = d / v[i]
         elif fops.gte(self.maxs[i], collidee.mins[i]) and fops.lt(v[i], 0):
             d = collidee.mins[i] - self.maxs[i]
             u_1[i] = d / v[i]
     u0 = max(u_0)
     if u0 == 2 or fops.gte(u0, 1.0):
         col = False
     else:
         col = fops.lte(u0, min(u_1))
     return col, u0
Example #2
0
 def sweep_collision(self, collidee, v, debug=False):
     """
     self (collider) moving by v, collidee stationery
     based on http://bit.ly/3grWzs
     """
     u_0 = [2, 2, 2]
     u_1 = [1, 1, 1]
     for i in xrange(3):
         if fops.lte(self.maxs[i], collidee.mins[i]) and fops.gt(v[i], 0):
             d = collidee.mins[i] - self.maxs[i]
             u_0[i] = d / v[i]
         elif fops.lte(collidee.maxs[i], self.mins[i]) and fops.lt(v[i], 0):
             d = collidee.maxs[i] - self.mins[i]
             u_0[i] = d / v[i]
         elif not(fops.lte(self.maxs[i], collidee.mins[i]) or fops.gte(self.mins[i], collidee.maxs[i])):
             u_0[i] = 0
         if fops.gte(collidee.maxs[i], self.mins[i]) and fops.gt(v[i], 0):
             d = collidee.maxs[i] - self.mins[i]
             u_1[i] = d / v[i]
         elif fops.gte(self.maxs[i], collidee.mins[i]) and fops.lt(v[i], 0):
             d = collidee.mins[i] - self.maxs[i]
             u_1[i] = d / v[i]
     u0 = max(u_0)
     if u0 == 2 or fops.gte(u0, 1.0):
         col = False
     else:
         col = fops.lte(u0, min(u_1))
     return col, u0
Example #3
0
 def calculate_axis_offset(self, collidee, d, axis):
     for i in xrange(3):
         if i == axis:
             continue
         if fops.lte(self.maxs[i], collidee.mins[i]) or \
                 fops.gte(self.mins[i], collidee.maxs[i]):
             return d
     if d < 0 and fops.lte(collidee.maxs[axis], self.mins[axis]):
         dout = collidee.maxs[axis] - self.mins[axis]
         if fops.gt(dout, d):
             d = dout
     elif d > 0 and fops.gte(collidee.mins[axis], self.maxs[axis]):
         dout = collidee.mins[axis] - self.maxs[axis]
         if fops.lt(dout, d):
             d = dout
     return d
Example #4
0
 def collides_on_axes(self, bb, x=False, y=False, z=False):
     if not (x or y or z):
         raise Exception("axes not set in collides_on_axes")
     if x:
         if fops.lte(self.max_x, bb.min_x) or \
                 fops.gte(self.min_x, bb.max_x):
             return False
     if y:
         if fops.lte(self.max_y, bb.min_y) or \
                 fops.gte(self.min_y, bb.max_y):
             return False
     if z:
         if fops.lte(self.max_z, bb.min_z) or \
                 fops.gte(self.min_z, bb.max_z):
             return False
     return True
Example #5
0
 def calculate_axis_offset(self, collidee, d, axis):
     for i in xrange(3):
         if i == axis:
             continue
         if fops.lte(self.maxs[i], collidee.mins[i]) or \
                 fops.gte(self.mins[i], collidee.maxs[i]):
             return d
     if d < 0 and fops.lte(collidee.maxs[axis], self.mins[axis]):
         dout = collidee.maxs[axis] - self.mins[axis]
         if fops.gt(dout, d):
             d = dout
     elif d > 0 and fops.gte(collidee.mins[axis], self.maxs[axis]):
         dout = collidee.mins[axis] - self.maxs[axis]
         if fops.lt(dout, d):
             d = dout
     return d
Example #6
0
 def intersection_on_axes(self, bb, x=False, y=False, z=False, debug=False):
     if not (x or y or z):
         raise Exception("axes not set in collides_on_axes")
     truth = 0
     if x:
         truth += 1
     if y:
         truth += 1
     if z:
         truth += 1
     if truth != 2:
         raise Exception("set exactly two axes to True in collides_on_axes")
     if x:
         if fops.lte(self.max_x, bb.min_x) or \
                 fops.gte(self.min_x, bb.max_x):
             return None
         else:
             min_x = self.min_x if self.min_x > bb.min_x else bb.min_x
             max_x = self.max_x if self.max_x < bb.max_x else bb.max_x
     else:
         min_x = self.min_x
         max_x = self.max_x
     if y:
         if fops.lte(self.max_y, bb.min_y) or \
                 fops.gte(self.min_y, bb.max_y):
             return None
         else:
             min_y = self.min_y if self.min_y > bb.min_y else bb.min_y
             max_y = self.max_y if self.max_y < bb.max_y else bb.max_y
     else:
         min_y = self.min_y
         max_y = self.max_y
     if z:
         if fops.lte(self.max_z, bb.min_z) or \
                 fops.gte(self.min_z, bb.max_z):
             return None
         else:
             min_z = self.min_z if self.min_z > bb.min_z else bb.min_z
             max_z = self.max_z if self.max_z < bb.max_z else bb.max_z
     else:
         min_z = self.min_z
         max_z = self.max_z
     return AABB(min_x, min_y, min_z, max_x, max_y, max_z)
Example #7
0
    def sweep_collision(self, collidee, v, debug=False):
        """
        self moving by v, collidee stationery
        based on http://bit.ly/3grWzs
        """
        u_0 = [2, 2, 2]
        u_1 = [1, 1, 1]
        dists = [None, None, None]
        for i in xrange(3):
            if fops.lte(self.maxs[i], collidee.mins[i]) and fops.gt(v[i], 0):
                d = collidee.mins[i] - self.maxs[i]
                dists[i] = d
                u_0[i] = d / v[i]
            elif fops.lte(collidee.maxs[i], self.mins[i]) and fops.lt(v[i], 0):
                d = collidee.maxs[i] - self.mins[i]
                dists[i] = d
                u_0[i] = d / v[i]
            elif fops.eq(v[i], 0) and \
                    not(fops.lte(self.maxs[i], collidee.mins[i]) or
                        fops.gte(self.mins[i], collidee.maxs[i])):
                u_0[i] = 0
            elif not(fops.lte(self.maxs[i], collidee.mins[i]) or
                     fops.gte(self.mins[i], collidee.maxs[i])):
                u_0[i] = 0
            if fops.gte(collidee.maxs[i], self.mins[i]) and fops.gt(v[i], 0):
                d = collidee.maxs[i] - self.mins[i]
                u_1[i] = d / v[i]
            elif fops.gte(self.maxs[i], collidee.mins[i]) and fops.lt(v[i], 0):
                d = collidee.mins[i] - self.maxs[i]
                u_1[i] = d / v[i]

        if max(u_0) == 2:
            u0 = None
            col = False
        else:
            u0 = max(u_0)
            u1 = min(u_1)
            if fops.gte(u0, 1.0):
                col = False
            else:
                col = fops.lte(u0, u1)
        return col, u0
Example #8
0
 def collision_distance(self, collidee, axis=None, direction=None):
     for i in xrange(3):
         if i == axis:
             continue
         if fops.lte(self.maxs[i], collidee.mins[i]) or \
                 fops.gte(self.mins[i], collidee.maxs[i]):
             return None
     p = None
     if direction < 0:
         if fops.eq(self.mins[axis], collidee.maxs[axis]):
             p = 0
         elif fops.gt(self.mins[axis], collidee.maxs[axis]):
             p = self.mins[axis] - collidee.maxs[axis]
     else:
         if fops.eq(collidee.mins[axis], self.maxs[axis]):
             p = 0
         elif fops.gt(collidee.mins[axis], self.maxs[axis]):
             p = collidee.mins[axis] - self.maxs[axis]
     return p
Example #9
0
 def collision_distance(self, collidee, axis=None, direction=None):
     for i in xrange(3):
         if i == axis:
             continue
         if fops.lte(self.maxs[i], collidee.mins[i]) or \
                 fops.gte(self.mins[i], collidee.maxs[i]):
             return None
     p = None
     if direction < 0:
         if fops.eq(self.mins[axis], collidee.maxs[axis]):
             p = 0
         elif fops.gt(self.mins[axis], collidee.maxs[axis]):
             p = self.mins[axis] - collidee.maxs[axis]
     else:
         if fops.eq(collidee.mins[axis], self.maxs[axis]):
             p = 0
         elif fops.gt(collidee.mins[axis], self.maxs[axis]):
             p = collidee.mins[axis] - self.maxs[axis]
     return p
Example #10
0
 def collides(self, bb):
     for i in xrange(3):
         if fops.lte(self.maxs[i], bb.mins[i]) or fops.gte(self.mins[i], bb.maxs[i]):
             return False
     return True
Example #11
0
 def can_go_between(self, gs, update_to_bb_stand=False, debug=False):
     edge_cost = 0
     bb_stand = self.bb_stand
     other_bb_stand = gs.bb_stand
     if bb_stand.horizontal_distance(other_bb_stand) > config.HORIZONTAL_MOVE_DISTANCE_LIMIT:
         if debug:
             print 'horizontal distance too far', bb_stand.horizontal_distance(other_bb_stand)
         return False
     if fops.gt(bb_stand.min_y, other_bb_stand.min_y):
         if (bb_stand.min_y - other_bb_stand.min_y) > 3:
             return False
         elev = bb_stand.min_y - other_bb_stand.min_y
         elev_bb = other_bb_stand.extend_to(dy=elev)
         bb_from = bb_stand
         bb_to = other_bb_stand.offset(dy=elev)
     elif fops.lt(bb_stand.min_y, other_bb_stand.min_y):
         if fops.lte(bb_stand.grid_y + 2, other_bb_stand.min_y):
             if debug:
                 print 'over 2 high difference'
             return False
         elev = other_bb_stand.min_y - bb_stand.min_y
         in_water = self.grid.aabb_in_water(bb_stand)
         if in_water and \
                 other_bb_stand.grid_y > bb_stand.grid_y and \
                 fops.gt(other_bb_stand.min_y, other_bb_stand.grid_y) and \
                 not self.grid.aabb_in_water(bb_stand.shift(min_y=other_bb_stand.min_y)) and \
                 fops.gte(other_bb_stand.min_y - (bb_stand.grid_y + 1), config.MAX_WATER_JUMP_HEIGHT - 0.15):
             if debug:
                 print 'water cannot go'
             return False
         if self.grid.aabb_on_ladder(bb_stand) and \
                 other_bb_stand.grid_y > bb_stand.grid_y and \
                 fops.gt(other_bb_stand.min_y, other_bb_stand.grid_y) and \
                 not self.grid.aabb_on_ladder(bb_stand.shift(min_y=other_bb_stand.min_y)) and \
                 fops.gte(other_bb_stand.min_y - (bb_stand.grid_y + 1), config.MAX_VINE_JUMP_HEIGHT - 0.2):
             if debug:
                 print 'ladder cannot go'
             return False
         if fops.gt(elev, config.MAX_JUMP_HEIGHT) and not in_water:
             if debug:
                 print 'too high'
             return False
         if fops.lte(elev, config.MAX_STEP_HEIGHT):
             elev = config.MAX_STEP_HEIGHT
             aabbs = self.grid.aabbs_in(bb_stand.extend_to(0, elev, 0))
             for bb in aabbs:
                 elev = bb_stand.calculate_axis_offset(bb, elev, 1)
             if fops.lt(bb_stand.min_y + elev, other_bb_stand.min_y):
                 if debug:
                     print 'cannot make step'
                 return False
         elev_bb = bb_stand.extend_to(dy=elev)
         bb_from = bb_stand.offset(dy=elev)
         bb_to = other_bb_stand
     else:
         elev = 0
         elev_bb = None
         bb_from = bb_stand
         bb_to = other_bb_stand
     if elev_bb is not None:
         if self.grid.aabb_collides(elev_bb):
             if debug:
                 print 'elevation collision'
             return False
         if self.blocks_to_avoid(self.grid.blocks_in_aabb(elev_bb)):
             if debug:
                 print 'elevation hitting avoid block'
             return False
     if self.grid.collision_between(bb_from, bb_to, debug=debug):
         if debug:
             print 'horizontal collision'
         return False
     if self.blocks_to_avoid(self.grid.passing_blocks_between(bb_from, bb_to)):
         if debug:
             print 'hitting avoid block'
         return False
     edge_cost += config.COST_DIRECT * bb_from.horizontal_distance(bb_to)
     if not (fops.lte(elev, config.MAX_STEP_HEIGHT) and fops.gte(elev, -config.MAX_STEP_HEIGHT)):
         edge_cost += config.COST_FALL * \
             bb_from.horizontal_distance(bb_to)
         if elev < 0:
             edge_cost += config.COST_FALL * elev
         else:
             edge_cost += config.COST_JUMP
     self.edge_cost = edge_cost
     if update_to_bb_stand:
         gs.bb_stand = other_bb_stand
     return True
Example #12
0
 def collides(self, bb):
     for i in xrange(3):
         if fops.lte(self.maxs[i], bb.mins[i]) or fops.gte(
                 self.mins[i], bb.maxs[i]):
             return False
     return True