def simulate_landing(self): pos = vec3(self.car.position) vel = vec3(self.car.velocity) grav = vec3(0, 0, -650) self.trajectory = [vec3(pos)] self.landing = False collision_normal: Optional[vec3] = None dt = 1 / 60 simulation_duration = 0.8 for i in range(int(simulation_duration / dt)): pos += vel * dt vel += grav * dt if norm(vel) > 2300: vel = normalize(vel) * 2300 self.trajectory.append(vec3(pos)) collision_sphere = sphere(pos, 50) collision_ray = Field.collide(collision_sphere) collision_normal = collision_ray.direction if (norm(collision_normal) > 0.0 or pos[2] < 0) and i > 20: self.landing = True self.landing_pos = pos break if self.landing: u = collision_normal f = normalize(vel - dot(vel, u) * u) l = normalize(cross(u, f)) self.aerial_turn.target = three_vec3_to_mat3(f, l, u) else: target_direction = normalize( normalize(self.car.velocity) - vec3(0, 0, 3)) self.aerial_turn.target = look_at(target_direction, vec3(0, 0, 1))
def simulate(self): ball_prediction = self.get_ball_prediction_struct() duration_estimate = math.floor( get_time_at_height(self.game.ball.location[2], 0.2) * 10) / 10 for i in range(6): car = Car(self.game.my_car) ball = Ball(self.game.ball) batmobile = obb() batmobile.half_width = vec3(64.4098892211914, 42.335182189941406, 14.697200775146484) batmobile.center = car.location + dot(car.rotation, vec3(9.01, 0, 12.09)) batmobile.orientation = car.rotation dodge = Dodge(car) dodge.duration = duration_estimate + i / 60 dodge.target = ball.location for j in range(round(60 * dodge.duration)): dodge.target = ball.location dodge.step(1 / 60) car.step(dodge.controls, 1 / 60) prediction_slice = ball_prediction.slices[j] physics = prediction_slice.physics ball_location = vec3(physics.location.x, physics.location.y, physics.location.z) dodge.target = ball_location batmobile.center = car.location + dot(car.rotation, vec3(9.01, 0, 12.09)) batmobile.orientation = car.rotation if intersect(sphere(ball_location, 93.15), batmobile) and abs( ball_location[2] - car.location[2] ) < 25 and car.location[2] < ball_location[2]: return True, j / 60, ball_location return False, None, None
def simulate_landing(self): dummy = Car(self.car) self.trajectory = [vec3(dummy.position)] self.landing = False collision_normal: Optional[vec3] = None dt = 1 / 60 simulation_duration = 0.8 for i in range(int(simulation_duration / dt)): dummy.step(Input(), dt) self.trajectory.append(vec3(dummy.position)) collision_sphere = sphere(dummy.position, 50) collision_ray = Field.collide(collision_sphere) collision_normal = collision_ray.direction if (norm(collision_normal) > 0.0 or dummy.position[2] < 0) and i > 20: self.landing = True self.landing_pos = dummy.position break if self.landing: u = collision_normal f = normalize(dummy.velocity - dot(dummy.velocity, u) * u) l = normalize(cross(u, f)) self.aerial_turn.target = mat3(f[0], l[0], u[0], f[1], l[1], u[1], f[2], l[2], u[2]) else: target_direction = normalize( normalize(self.car.velocity) - vec3(0, 0, 3)) self.aerial_turn.target = look_at(target_direction, vec3(0, 0, 1))
def intercept_predicate(self, car: Car, ball: Ball): if ball.position[2] > 200 or abs( ball.position[1]) > Arena.size[1] - 400: return False contact_ray = Field.collide( sphere(ball.position, self.max_distance_from_wall)) return norm(contact_ray.start) > 0 and abs( dot(ball.velocity, contact_ray.direction)) < 150
def intercept_predicate(self, car: Car, ball: Ball): # max_height = align(car, ball, self.target) * 60 + self.max_base_height max_height = 300 contact_ray = Field.collide(sphere(ball.position, max_height)) return (norm(contact_ray.direction) > 0 and ball.position[2] < max_height + 50 and (Arena.inside(ball.position, 100) or distance(ball, self.target) < 1000) and abs(car.position[0]) < Arena.size[0] - 300)
def dodge_succesfull(self, car, ball_location, dodge): batmobile = obb() batmobile.half_width = vec3(64.4098892211914, 42.335182189941406, 14.697200775146484) batmobile.center = car.position + dot(car.orientation, vec3(9.01, 0, 12.09)) batmobile.orientation = car.orientation ball = sphere(ball_location, 93.15) b_local = dot(ball.center - batmobile.center, batmobile.orientation) closest_local = vec3( min(max(b_local[0], -batmobile.half_width[0]), batmobile.half_width[0]), min(max(b_local[1], -batmobile.half_width[1]), batmobile.half_width[1]), min(max(b_local[2], -batmobile.half_width[2]), batmobile.half_width[2])) hit_location = dot(batmobile.orientation, closest_local) + batmobile.center if norm(hit_location - ball.center) > ball.radius: return None # if abs(ball_location[2] - hit_location[2]) < 25 and hit_location[2] < ball_location[2]: if abs(ball_location[2] - hit_location[2]) < 25: if closest_local[0] > 35 and -12 < closest_local[2] < 12: hit_check = True else: print("local: ", closest_local) hit_check = True else: hit_check = False # Seems to work without angle_check. No clue why though angle_car_simulation = angle_between(car.orientation, self.info.my_car.orientation) angle_simulation_target = angle_between(car.orientation, dodge.preorientation) angle_check = angle_simulation_target < angle_car_simulation or angle_simulation_target < 0.1 return hit_check