def fade(*args):
            assert args and len(args) % 4 == 0
            for i in range(0, len(args), 4):
                in_t, in_fade, out_t, out_fade = args[i:i + 4]
                if in_fade == 0:
                    if t < in_t:
                        return 0
                elif in_fade < 0:
                    in_fade = -in_fade
                    if t < in_t - in_fade:
                        return 0
                    if t < in_t:
                        return util.lerp(t, in_t - in_fade, in_t, 0, 1)
                else:
                    if t < in_t:
                        return 0
                    if t < in_t + in_fade:
                        return util.lerp(t, in_t, in_t + in_fade, 0, 1)

                if out_fade == 0:
                    if t < out_t:
                        return 1
                elif out_fade < 0:
                    out_fade = -out_fade
                    if t < out_t - out_fade:
                        return 1
                    if t < out_t:
                        return util.lerp(t, out_t - out_fade, out_t, 1, 0)
                else:
                    if t < out_t:
                        return 1
                    if t < out_t + out_fade:
                        return util.lerp(t, out_t, out_t + out_fade, 1, 0)
            return 0
Esempio n. 2
0
    def generate(self, x, y, freq, hash_table, unit_vectors):
        xi, xf = splitfloat.split_float(x)
        yi, yf = splitfloat.split_float(y)

        xim = xi % freq
        xjm = (xi + 1) % freq
        yim = yi % freq
        yjm = (yi + 1) % freq

        aa = hash_table.hash(hash_table.hash(xim) + yim)
        ab = hash_table.hash(hash_table.hash(xim) + yjm)
        ba = hash_table.hash(hash_table.hash(xjm) + yim)
        bb = hash_table.hash(hash_table.hash(xjm) + yjm)

        aav = unit_vectors[aa]
        abv = unit_vectors[ab]
        bav = unit_vectors[ba]
        bbv = unit_vectors[bb]
        aap = (xf, yf)
        abp = (xf, yf - 1)
        bap = (xf - 1, yf)
        bbp = (xf - 1, yf - 1)

        noise = util.lerp(
            util.lerp(grad(aav, aap), grad(bav, bap), util.fade(xf)),
            util.lerp(grad(abv, abp), grad(bbv, bbp), util.fade(xf)),
            util.fade(yf))

        return bind(noise, 0, 1)
        def blip(center, strength, hue, saturation, lightness):
            if strength == 0:
                return
            hue %= 1

            radius = util.lerp(strength, 0, 1, 0, 1.75, clip=True)
            brightness = util.lerp(strength, 0, 1, 0, 1.0, clip=True)

            grad = QtGui.QRadialGradient(0.5, 0.5, 0.5)
            grad.setCoordinateMode(QtGui.QGradient.ObjectBoundingMode)
            grad.setColorAt(
                0.0,
                QtGui.QColor.fromHsvF(hue, saturation * 0.3, lightness,
                                      brightness))
            grad.setColorAt(
                0.2,
                QtGui.QColor.fromHsvF(hue, saturation, lightness,
                                      brightness * 0.8))
            grad.setColorAt(1.0, QtCore.Qt.transparent)
            painter.setBrush(QtGui.QBrush(grad))
            painter.setPen(QtCore.Qt.NoPen)

            painter.drawEllipse(
                QtCore.QRectF(center[0] - radius, center[1] - radius,
                              radius * 2, radius * 2))
Esempio n. 4
0
    def hatch(self, lines, angle):

        radius = math.sqrt(2 * math.pow(self.scale, 2))
        box = Polygon(self.pos, 4, radius)
        box.rotate(angle)
        corners = box.computeVertices()
        hatches = []

        for i in range(1, lines + 1):
            frac = i / lines
            start = util.lerp(corners[0], corners[1], frac)
            end = util.lerp(corners[3], corners[2], frac)
            hits = []
            vertices = self.computeVertices()
            for k in range(len(vertices)):
                a = vertices[k]
                b = vertices[(k + 1) % len(vertices)]
                cross = util.segmentIntersect(start, end, a, b)
                if cross is not None:
                    hits.append(cross)
            #hits.sort(key=lambda p: util.dist(start, p))
            if len(hits) > 2:
                #print(hits)
                del hits[0]
            if len(hits) > 1:
                hatches.append([hits[0], hits[1]])
        return hatches
Esempio n. 5
0
    def tick(self):
        super().tick()

        if self.mouse_on():
            self.length = lerp(self.length, self.width, get_lerp_friction(self.display.fps))
        else:
            if self.length < 1:
                self.length = 0
            else:
                self.length = lerp(self.length, 0, get_lerp_friction(self.display.fps))
Esempio n. 6
0
 def mousePressEvent(self, event):
     if self.viewer.on_scrub is not None:
         time_idx = int(event.pos().x())
         time = util.lerp(time_idx, 0, self.viewer.frame_count, 0,
                          self.viewer.duration)
         self.viewer.on_scrub(time)
         self.viewer._update_time_line(time)
Esempio n. 7
0
    def set_spectrogram(self, spec, spec_freqs, frame_rate):
        self.spec = spec
        self.spec_freqs = spec_freqs
        self.frame_rate = frame_rate
        self.frame_count = self.spec.shape[0]
        self.duration = self.frame_count / self.frame_rate

        img = util.lerp(self.spec, 0, 1, 0, 0xFF, clip=True).astype(np.uint8)
        img = np.repeat(img[:, :, np.newaxis], 4, 2)
        img = img.transpose(1, 0, 2)
        self.spec_img = QtGui.QImage(img.tobytes(), img.shape[1], img.shape[0],
                                     QtGui.QImage.Format_RGB32)
        self.spec_img.save(os.path.join(os.path.dirname(__file__), 'spec.png'))
        self.spec_pm = QtGui.QPixmap.fromImage(self.spec_img)

        self.spec_pm_item = SpectrogramViewer.SpecGraphicsItem(
            self.spec_pm, self, self.scene)

        self.time_line = self.scene.addLine(0,
                                            0,
                                            0,
                                            self.spec_img.height(),
                                            pen=QtGui.QPen(
                                                QtGui.QColor.fromHsvF(0, 1, 1),
                                                1.5))
    def evaluate(self, model, dataset, nsteps=None):
        structure_image = self.load_image(self.opt.input_structure_image)
        texture_image = self.load_image(self.opt.input_texture_image)
        os.makedirs(self.output_dir(), exist_ok=True)

        model(sample_image=structure_image, command="fix_noise")
        structure_code, source_texture_code = model(structure_image,
                                                    command="encode")
        _, target_texture_code = model(texture_image, command="encode")

        alphas = self.opt.texture_mix_alphas
        for alpha in alphas:
            texture_code = util.lerp(source_texture_code, target_texture_code,
                                     alpha)

            output_image = model(structure_code,
                                 texture_code,
                                 command="decode")
            output_image = transforms.ToPILImage()(
                (output_image[0].clamp(-1.0, 1.0) + 1.0) * 0.5)

            output_name = "%s_%s_%.2f.png" % (
                os.path.splitext(
                    os.path.basename(self.opt.input_structure_image))[0],
                os.path.splitext(os.path.basename(
                    self.opt.input_texture_image))[0], alpha)

            output_path = os.path.join(self.output_dir(), output_name)

            output_image.save(output_path)
            print("Saved at " + output_path)

        return {}
def value_from_spec(arg_spec):
    'return a generator based on variable specification'
    # interval / range
    if arg_spec[0] == '[':
        v = arg_spec[1:-1].split(',')
        return lerp(float(v[0]), float(v[1]), random())
    # set
    elif arg_spec[0] == '(':
        v = arg_spec[1:-1].split(',')
        # note: we assume sets are composed of ints
        return int(choice(v))
    # time
    elif arg_spec[0] == 't':
        return random_time()
    # frequency
    elif arg_spec[0] == 'f':
        # is there a modifier?
        if len(arg_spec) > 1:
            if arg_spec[1] == 'd':  # difference
                return abs(random_freq() - random_freq())
            elif arg_spec[1] == 'r':  # reciprocal
                return 1. / random_freq()
            else:
                # in case we missed something
                print('Unexpected freq modifier: ' + arg[1])
                return 0
        return random_freq()
    # wavetable
    elif arg_spec[0] == 'w':
        return choice(wavetables)
    return random()
Esempio n. 10
0
 def lerp_param(self, param_name, t):
     """
     A common pattern I use for defining parameters is specifying
     parameters as (initial, final) pairs and then interpolating them
     This is a shortcut for looking up the parameter and interpolating
     """
     param = self.params[param_name]
     return util.lerp(param, t)
Esempio n. 11
0
 def hoverMoveEvent(self, event):
     time_idx = int(event.pos().x())
     freq_idx = int(event.pos().y())
     value = self.viewer.spec[time_idx, freq_idx]
     time = util.lerp(time_idx, 0, self.viewer.frame_count, 0,
                      self.viewer.duration)
     freq = self.viewer.spec_freqs[freq_idx]
     self.viewer.value_label.setText(
         '{:.4g} Hz at {:.3f} secs: {:.3f}'.format(freq, time, value))
Esempio n. 12
0
    def position(self, v):
        """
        Position on the helix:

        x = cos(phi(v))
        y = sin(phi(v))
        z = z(v)

        phi(v) = lerp(angles, v)
        z(v) = lerp(heights, v)
        """
        # The height is a linear interpolation of the two heights
        z = util.lerp(self.heights, v)

        # For x and y, the angle gets lerp-ed
        phi = util.lerp(self.angles, v)
        x = math.cos(phi)
        y = math.sin(phi)
        return Vector((x, y, z))
Esempio n. 13
0
 def spec_peak(min_freq, max_freq):
     from_idx = int(
         np.floor(np.interp(min_freq, self.spec_freqs, self.spec_idxs)))
     to_idx = int(
         np.ceil(np.interp(max_freq, self.spec_freqs, self.spec_idxs)))
     spec_range = spec[from_idx:to_idx]
     peak_idx = np.argmax(spec_range) + from_idx
     peak_val = spec[peak_idx]
     peak_freq = np.interp(peak_idx, self.spec_idxs, self.spec_freqs)
     return np.array(
         [util.lerp(peak_freq, min_freq, max_freq, 0, 1), peak_val])
Esempio n. 14
0
def random_freq():
    x, i = 0, 0
    # rejection sampling, with a watchdog
    while i < 64:
        # sample a random point
        x, y = random(), random()
        # if that point is below the distribution curve, the sample is accepted
        if (y < distribution(x)):
            break
        i = i + 1
    return lerp(1, 6000, x)
Esempio n. 15
0
 def apply(self,
           img,
           img_features=None,
           specified_parameter=None,
           high_res=None):
     assert (img_features is None) ^ (specified_parameter is None)
     if img_features is not None:
         filter_features, mask_parameters = self.extract_parameters(
             img_features)
         filter_parameters = self.filter_param_regressor(filter_features)
     else:
         assert not self.use_masking()
         filter_parameters = specified_parameter
         mask_parameters = tf.zeros(shape=(1,
                                           self.get_num_mask_parameters()),
                                    dtype=np.float32)
     if high_res is not None:
         # working on high res...
         pass
     debug_info = {}
     # We only debug the first image of this batch
     if self.debug_info_batched():
         debug_info['filter_parameters'] = filter_parameters
     else:
         debug_info['filter_parameters'] = filter_parameters[0]
     self.mask_parameters = mask_parameters
     self.mask = self.get_mask(img, mask_parameters)
     debug_info['mask'] = self.mask[0]
     low_res_output = lerp(img, self.process(img, filter_parameters),
                           self.mask)
     if high_res is not None:
         if self.no_high_res():
             high_res_output = high_res
         else:
             self.high_res_mask = self.get_mask(high_res, mask_parameters)
             high_res_output = lerp(
                 high_res, self.process(high_res, filter_parameters),
                 self.high_res_mask)
     else:
         high_res_output = None
     return low_res_output, high_res_output, debug_info
Esempio n. 16
0
    def tick(self):
        self.click_area.tick()

        friction = get_lerp_friction(self.display.fps)
        if self.inserting:
            self.string += self.keyboard_buffer.regurgitate_string()
            if (backspace := self.keyboard_buffer.regurgitate_backspace()) > 0:
                self.string = self.string[:-backspace]
            self.underline_length = lerp(self.underline_length, self.width, friction)
            if self.key_manager.is_start_key(K_ESCAPE) \
                    or self.key_manager.is_start_key(K_RETURN) \
                    or self.key_manager.is_start_key(K_KP_ENTER) \
                    or not self.click_area.mouse_on() and self.mouse_manager.end_left:
                if self.string_test is not None and not self.string_test(self.string):
                    self.string = self.pre_edited_string
                else:
                    self.inserting = False
Esempio n. 17
0
    def update(self, delta):
        super(Block, self).update(delta)

        self.icon.update(delta)

        if self.state == 'move':
            self.position = util.lerp(self.start_position, self.target,
                                      self.state_time)

            self.state_time += 2 * delta

            if self.state_time >= 1:
                self.set_state('wait')
        elif self.state == 'remove':
            self.position[1] += delta * 64
            if self.state_time >= 1:
                self.is_active = False

            self.state_time += delta
Esempio n. 18
0
    def handle_move_frame(self):
        frame = self.frame_meta['frame']
        frames = self.frame_meta['frames']
        start = self.frame_meta['start']
        end = self.frame_meta['end']

        if frame == len(frames):
            self.end_move()

            if self.is_bot() and self.moving:
                self.draw_path = self.draw_path[1:] if len(
                    self.draw_path) > 1 else []
            if not self.moves.empty():
                self.move(self.moves.pop())
        elif self.moving and start and end:
            self.loc = lerp(frame, frames, start, end)
            self.frame_meta['frame'] += 1
        else:
            if not self.moves.empty():
                self.move(self.moves.pop())
Esempio n. 19
0
	def update(self, dt, entity_manager):
		scroller = self.sys_man.parent.scroller
		pairs = entity_manager.pairs_for_type(PlayerInput)
		for e_id, pi in pairs:
			pos = entity_manager.component_for_entity(e_id, Position)
			new_x = util.lerp(pos.x, scroller.restricted_fx, 0.6)
			new_y = util.lerp(pos.y, scroller.restricted_fy, 0.6)
			
			if new_x < pos.x - 50:
				new_x = util.lerp(new_x, pos.x - 50, 0.5)
			elif new_x > pos.x + 50:
				new_x = util.lerp(new_x, pos.x + 50, 0.5)
				
			if new_y < pos.y - 50:
				new_y = util.lerp(new_y, pos.y - 50, 0.5)
			elif new_y > pos.y + 50:
				new_y = util.lerp(new_y, pos.y + 50, 0.5)
			
			scroller.set_focus(new_x, new_y)
		
		
		
					
Esempio n. 20
0
            self.string += self.keyboard_buffer.regurgitate_string()
            if (backspace := self.keyboard_buffer.regurgitate_backspace()) > 0:
                self.string = self.string[:-backspace]
            self.underline_length = lerp(self.underline_length, self.width, friction)
            if self.key_manager.is_start_key(K_ESCAPE) \
                    or self.key_manager.is_start_key(K_RETURN) \
                    or self.key_manager.is_start_key(K_KP_ENTER) \
                    or not self.click_area.mouse_on() and self.mouse_manager.end_left:
                if self.string_test is not None and not self.string_test(self.string):
                    self.string = self.pre_edited_string
                else:
                    self.inserting = False
        else:
            if self.underline_length < 1:
                self.underline_length = 0
            else:
                self.underline_length = lerp(self.underline_length, 0, friction)

        if self.previous_string != self.string:
            self.refresh_surface()

        self.previous_string = self.string

    def render(self, surface: Surface):
        surface.blit(self.surface, (self.x, self.y))
        if self.underline_length:
            draw.line(surface, self.text_format.color,
                      (self.x, self.y + self.text_format.size),
                      (self.x + self.underline_length, self.y + self.text_format.size))
        self.click_area.render(surface)
Esempio n. 21
0
def kick_off(agent):
    ball = agent.info.ball
    car = agent.info.my_car
    t = distance_2d(ball.position, car.position) / 2200
    batmobile_resting = 18.65
    robbies_constant = (ball.position - vec3(0, 0, 92.75 - batmobile_resting) -
                        car.position - car.velocity * t) * 2 * t**-2
    robbies_boost_constant = dot(normalize(xy(
        car.forward())), normalize(
            xy(robbies_constant))) > (0.3 if car.on_ground else 0.1)
    """"Module that performs the kickoffs"""
    if agent.kickoffStart == "Diagonal":
        if agent.step is Step.Drive:
            agent.drive.step(agent.info.time_delta)
            agent.controls = agent.drive.controls
            if agent.drive.finished:
                ball_location = ball.position + vec3(
                    0, -sign(agent.team) * 500, 0)
                target = car.position + 250 * normalize(ball_location -
                                                        car.position)
                agent.drive = Drive(car)
                agent.drive.target = target
                agent.drive.speed = 2400
                agent.step = Step.Drive_1
        if agent.step is Step.Drive_1:
            agent.drive.step(agent.info.time_delta)
            agent.controls = agent.drive.controls
            if agent.drive.finished:
                target = vec3(
                    dot(
                        rotation(
                            math.radians(-sign(agent.info.team) *
                                         sign(car.position[0]) * 60)),
                        vec2(car.forward())) * 10000)
                preorientation = dot(
                    axis_to_rotation(
                        vec3(
                            0, 0,
                            math.radians(-sign(agent.info.team) *
                                         -sign(car.position[0]) * 30))),
                    car.orientation)
                setup_first_dodge(agent, 0.05, 0.3, target, preorientation)
        elif agent.step is Step.Dodge_1:
            agent.timer += agent.info.time_delta
            if agent.timer > 0.8:
                lerp_var = lerp(
                    normalize(robbies_constant),
                    normalize(ball.position -
                              vec3(0, 0, 92.75 - batmobile_resting) -
                              car.position), 0.8)
                agent.turn.target = look_at(lerp_var, vec3(0, 0, 1))
                agent.turn.step(agent.info.time_delta)
                agent.controls = agent.turn.controls
                if car.on_ground:
                    agent.time = 0
                    agent.set_state = True
                    agent.step = Step.Shooting
            else:
                agent.dodge.step(agent.info.time_delta)
                agent.controls = agent.dodge.controls
            agent.controls.boost = robbies_boost_constant
    elif agent.kickoffStart == "Center":
        if agent.step is Step.Drive:
            agent.drive.step(agent.info.time_delta)
            agent.controls = agent.drive.controls
            if agent.drive.finished:
                target = vec3(
                    dot(rotation(math.radians(-65)), vec2(car.forward())) *
                    10000)
                preorientation = dot(
                    axis_to_rotation(vec3(0, 0, math.radians(45))),
                    car.orientation)
                setup_first_dodge(agent, 0.05, 0.4, target, preorientation)
        elif agent.step is Step.Dodge_1:
            agent.timer += agent.info.time_delta
            if agent.timer > 0.8:
                agent.turn.target = look_at(xy(ball.position - car.position),
                                            vec3(0, 0, 1))
                agent.turn.step(agent.info.time_delta)
                agent.controls = agent.turn.controls
                set_steer(agent)
            else:
                agent.dodge.step(agent.info.time_delta)
                agent.controls = agent.dodge.controls
            agent.controls.boost = robbies_boost_constant
        elif agent.step is Step.Steer:
            agent.drive.step(agent.info.time_delta)
            agent.controls = agent.drive.controls
            if distance_2d(car.position, ball.position) < 800:
                agent.step = Step.Dodge_2
                agent.dodge = Dodge(car)
                agent.dodge.duration = 0.075
                agent.dodge.target = ball.position
        elif agent.step is Step.Dodge_2:
            agent.dodge.step(agent.info.time_delta)
            agent.controls = agent.dodge.controls
            if agent.dodge.finished and car.on_ground:
                agent.time = 0
                agent.set_state = True
                agent.step = Step.Shooting
    elif agent.kickoffStart == "offCenter":
        if agent.step is Step.Drive:
            agent.drive.step(agent.info.time_delta)
            agent.controls = agent.drive.controls
            if distance_2d(car.position, agent.drive.target) < 650:
                target = vec3(
                    dot(
                        rotation(
                            math.radians(-sign(agent.info.team) *
                                         -sign(car.position[0]) * 100)),
                        vec2(car.forward())) * 10000)
                preorientation = dot(
                    axis_to_rotation(
                        vec3(
                            0, 0,
                            math.radians(-sign(agent.info.team) *
                                         sign(car.position[0]) * 30))),
                    car.orientation)
                print("PYTHON: ", agent.info.my_car.position)
                print(
                    "PYTHON: ",
                    math.radians(-sign(agent.info.team) *
                                 -sign(car.position[0]) * 100))
                setup_first_dodge(agent, 0.05, 0.4, target, preorientation)
        elif agent.step is Step.Dodge_1:
            agent.timer += agent.info.time_delta
            if agent.timer > 0.8:
                lerp_var = lerp(
                    normalize(robbies_constant),
                    normalize(ball.position -
                              vec3(0, 0, 92.75 - batmobile_resting) -
                              car.position), 0.25)
                agent.turn.target = look_at(lerp_var, vec3(0, 0, 1))
                agent.turn.step(agent.info.time_delta)
                agent.controls = agent.turn.controls
                set_steer(agent)
            else:
                agent.dodge.step(agent.info.time_delta)
                agent.controls = agent.dodge.controls
            agent.controls.boost = robbies_boost_constant
        elif agent.step is Step.Steer:
            agent.drive.step(agent.info.time_delta)
            agent.controls = agent.drive.controls
            if distance_2d(ball.position, car.position) < 800:
                agent.step = Step.Dodge_2
                agent.dodge = Dodge(car)
                agent.dodge.duration = 0.075
                agent.dodge.target = ball.position
        elif agent.step is Step.Dodge_2:
            agent.dodge.step(agent.info.time_delta)
            agent.controls = agent.dodge.controls
            if agent.dodge.finished and car.on_ground:
                agent.time = 0
                agent.set_state = True
                agent.step = Step.Shooting
Esempio n. 22
0
def random_time():
    return lerp(0.01, 2, random())
Esempio n. 23
0
def read(omo_input, debug_bones=[], debug_bone_ids={}):
  f = util.open_mixed(omo_input)
  assert f.read(4) == b'OMO '

  has_unk = False

  _,_,_,_, \
  channel_count, frame_count, frame_entry_size, \
  channel_data_offset, fixed_data_offset, frame_data_offset = struct.unpack('>HHIHHHHIII', f.read(28))

  util.log('{:d} channels, {:d} frames ({:04x}), offsets: channels {:08x}, fixed {:08x}, frames {:08x}' \
    .format(channel_count, frame_count, frame_entry_size, channel_data_offset, fixed_data_offset, frame_data_offset), level=util.LOG_VERBOSE)

  # channel table. each channel is an animation for a single bone
  channels = []
  
  f.seek(channel_data_offset)
  for i in range(channel_count):
    data = f.read(16)
    flags, bone_id, fixed_offset, frame_offset = struct.unpack('>IIII', data)

    # read flags into booleans
    attribs = {}
    for flag, flag_name in OMO_entry_flags:
      attribs[flag_name] = flags & flag == flag

    util.log('Channel {:d} - flags: {:08x}, bone UID: {:08x}, fixed {:08x}, frame {:08x}' \
      .format(i, flags, bone_id, fixed_offset, frame_offset), level=util.LOG_VERBOSE)
    util.log(attribs, level=util.LOG_VERBOSE)

    if bone_id not in debug_bone_ids:
      print('Ignoring channel', i, bone_id)
      continue

    channel_pos = f.tell() # return here later to read next channel(s)
    channel_frames = [{}]

    # init lerp values in this scope
    inter_scale_start = inter_scale_diff = \
    inter_rotation_start = inter_rotation_diff = \
    inter_translation_start = inter_translation_diff = False

    # read fixed data into frame 0 and calculate lerp values
    f.seek(fixed_data_offset + fixed_offset)

    if attribs['has_scale']:
      if attribs['is_scale_fixed']:
        channel_frames[0]['scl'] = util.readvec3(f)
        print(debug_bones[debug_bone_ids[bone_id]]['name'], 'Scale fixed', [format(f, '.2f') for f in channel_frames[0]['scl']])

      elif attribs['is_scale_inter']:
        inter_scale_start = util.readvec3(f)
        inter_scale_end = util.readvec3(f)
        inter_scale_diff = np.subtract(inter_scale_end, inter_scale_start)
        print(debug_bones[debug_bone_ids[bone_id]]['name'], 'Scale lerp start', [format(f, '.2f') for f in inter_scale_start])
        print(debug_bones[debug_bone_ids[bone_id]]['name'], 'Scale lerp end  ', [format(f, '.2f') for f in inter_scale_end])

    if attribs['has_rotation']:
      if attribs['is_rotation_fixed']:
        rotation = util.readvec3(f)
        channel_frames[0]['rot'] = util.quaternion_from_euler(*rotation, 'sxyz')
        print(debug_bones[debug_bone_ids[bone_id]]['name'], 'Rotation fixed', [format(f, '.2f') for f in rotation])
      elif attribs['is_rotation_quat']:
        channel_frames[0]['rot'] = util.readvec4(f)
        print(debug_bones[debug_bone_ids[bone_id]]['name'], 'Rotation quat', [format(f, '.2f') for f in channel_frames[0]['rot']])
      elif attribs['is_rotation_euler']:
        inter_rotation_start = util.readvec3(f)
        inter_rotation_end = util.readvec3(f)
        print(debug_bones[debug_bone_ids[bone_id]]['name'], 'Rotation lerp start', [format(f, '.2f') for f in inter_rotation_start])
        print(debug_bones[debug_bone_ids[bone_id]]['name'], 'Rotation lerp end  ', [format(f, '.2f') for f in inter_rotation_end])
        inter_rotation_diff = np.subtract(inter_rotation_end, inter_rotation_start)

    if attribs['has_translation']:
      if attribs['is_translation_fixed']:
        channel_frames[0]['pos'] = util.readvec3(f)
        print(debug_bones[debug_bone_ids[bone_id]]['name'], 'Translation fixed', [format(f, '.2f') for f in channel_frames[0]['pos']])
      elif attribs['is_translation_inter']:
        inter_translation_start = util.readvec3(f)
        inter_translation_end = util.readvec3(f)
        inter_translation_diff = np.subtract(inter_translation_end, inter_translation_start)
        print(debug_bones[debug_bone_ids[bone_id]]['name'], 'Translation lerp start', [format(f, '.2f') for f in inter_translation_start])
        print(debug_bones[debug_bone_ids[bone_id]]['name'], 'Translation lerp end  ', [format(f, '.2f') for f in inter_translation_end])

    # read frame data
    for j in range(0, frame_count):
      f.seek(frame_data_offset + (j * frame_entry_size) + frame_offset)
      frame = {}

      if attribs['has_scale'] and attribs['is_scale_inter'] and not attribs['is_scale_fixed']:
        mults = util.readmults(f, 3)
        frame['scl'] = util.lerp(inter_scale_start, inter_scale_diff, mults)
        print(debug_bones[debug_bone_ids[bone_id]]['name'], 'F', j, 'Scale lerp', [format(m, '.2f') for m in mults])
      
      if attribs['has_rotation'] and not attribs['is_rotation_fixed']:
        if attribs['is_rotation_quat']:
          mult = util.readmults(f, 1)
          print(debug_bones[debug_bone_ids[bone_id]]['name'], 'F', j, 'Rotation quat', [format(m, '.2f') for m in mult])
          has_unk = True

        elif attribs['is_rotation_euler']:
          mults = util.readmults(f, 3)
          rotation = util.lerp(inter_rotation_start, inter_rotation_diff, mults)
          quat = util.quaternion_from_euler(*reversed(rotation), 'sxyz')
          frame['rot'] = quat
          print(debug_bones[debug_bone_ids[bone_id]]['name'], 'F', j, 'Rotation lerp', [format(m, '.2f') for m in mults])

        elif attribs['is_rotation_frame']:
          mults = util.readmults(f, 4)
          print(debug_bones[debug_bone_ids[bone_id]]['name'], 'F', j, 'Rotation frame', [format(m, '.2f') for m in mults])
          has_unk = True

      if attribs['has_translation'] and not attribs['is_translation_fixed']:
        if attribs['is_translation_inter']:
          mults = util.readmults(f, 3)
          frame['pos'] = util.lerp(inter_translation_start, inter_translation_diff, mults)
          print(debug_bones[debug_bone_ids[bone_id]]['name'], 'F', j, 'Translation lerp', [format(m, '.2f') for m in mults])

        elif attribs['is_translation_frame']:
          frame['pos'] = util.readvec3(f)
          print(debug_bones[debug_bone_ids[bone_id]]['name'], 'F', j, 'Translation frame', frame['pos'])

      if len(frame.keys()) > 0:
        util.log('Channel {:d} Frame {:d}:'.format(i, j), frame, level=util.LOG_DEBUG)
        channel_frames.append(frame)

    channels.append({
      'flags': flags,
      'bone': bone_id,
      'frames': channel_frames
    })
    # return to channel index
    f.seek(channel_pos)

  return {
    'frame_count': frame_count,
    'channels': channels,
    'unknown': has_unk
  }
Esempio n. 24
0
 def update(self, delta):
     super(Score, self).update(delta)
     
     self.display_score = int(util.lerp(self.display_score, game.score, 10 * delta))
     
     self.set_text("score: %i"%self.display_score, game.fonts['screen_large'])
Esempio n. 25
0
 def elapsed_time(self):
     return util.lerp(self.stream_pos, 0, self.sample_count, 0, self.duration)
Esempio n. 26
0
        controller.target_position = -1 if lowest_left else 1
        controller.move(0)
        ship_start_pos = ship.position[0]

    if curtime - last_bullet_spawned > 1:
        # Spawn a new bullet
        last_bullet_spawned = curtime
        n_shots += 1
        bullet_group.add(Bullet(ship.position[0]))

    # Update all the entities
    enemy_group.update(deltatime)
    ship_group.update(deltatime, keys)
    bullet_group.update(deltatime)

    ship.position[0] = lerp(ship_start_pos, controller.desired_position, (curtime - last_pred_time) / PREDICTION_TIME)

    # Check if any enemies have reached the bottom of the screen
    for enemy in enemy_group:
        if enemy.rect.bottom > screen_rect[1]:
            enemy.kill()
            n_deaths += 1

    # Check if an enemy has collided with a bullet
    collisions = pygame.sprite.groupcollide(bullet_group, enemy_group, True, True)
    for k, v in collisions.items():
        n_hits += 1
        score += int(round(10 * (screen_rect[1] - k.rect.center[1]) / screen_rect[1] + 1))

    # Check if a bullet has gone beyond the lowest enemy
    lowest_enemy = max(e.rect.center[1] for e in enemy_group) if enemy_group else 0
Esempio n. 27
0
 def _update_time_line(self, time):
     self.time_line.setX(
         util.lerp(time, 0, self.duration, 0, self.spec_img.width()))
Esempio n. 28
0
def update_const(const, lerp_factor):
	new_value = value_from_spec(const.spec)
	if isinstance(new_value, float):
		new_value = lerp(new_value, const.value, lerp_factor)
	return const._replace(value=new_value)
Esempio n. 29
0
def anim(dt):
    global spriteKartu, t, label, noAnim
    # if(noAnim == 1):
    #     done = True
    #     for i in range(4):
    #         if(t < durasiAnim1*fps):
    #             done = False
    #             xLama, yLama = spriteKartu[i].x, spriteKartu[i].y
    #             xBaru, yBaru = w/5 * (i+1), h/2
    #             spriteKartu[i].update(x=lerp(t,xLama,xBaru-xLama,durasiAnim1*fps),y=lerp(t,yLama,yBaru-yLama,durasiAnim1*fps))
    #             t += 1
    #     if(done):
    #         noAnim = 2
    # elif(noAnim == 2):
    #     label = []
    #     for i in range(4):
    #         ang = angka[i]
    #         label.append(pyglet.text.Label(str(ang),
    #                                 font_name='Times New Roman',
    #                                 font_size=36,
    #                                 x=w/5 * (i+1), y=h/2 - 100,
    #                                 anchor_x='center', anchor_y='center'))
    #     noAnim = 3
    for i in range(4):
        if (noAnim == (i + 1)):
            if (t < durasiAnim1 * fps):
                xLama, yLama = spriteKartu[i].x, spriteKartu[i].y
                xBaru, yBaru = w / 5 * (i + 1), h / 2 + 100
                spriteKartu[i].update(x=lerp(t, xLama, xBaru - xLama,
                                             durasiAnim1 * fps),
                                      y=lerp(t, yLama, yBaru - yLama,
                                             durasiAnim1 * fps))
                t += 1
            if (t >= durasiAnim1 * fps * 1 / 2):
                label.append(
                    pyglet.text.Label(str(angka[i]),
                                      font_name='Times New Roman',
                                      font_size=36,
                                      x=w / 10 * 2 * (i + 1),
                                      y=h / 2 - 100,
                                      anchor_x='center',
                                      anchor_y='center'))
                if (noAnim < 4):
                    label.append(
                        pyglet.text.Label(str(solusi[i]),
                                          font_name='Times New Roman',
                                          font_size=36,
                                          x=w / 10 * (2 * (i + 1) + 1),
                                          y=h / 2 - 100,
                                          anchor_x='center',
                                          anchor_y='center'))
                elif (noAnim == 4):
                    label.append(
                        pyglet.text.Label('=',
                                          font_name='Times New Roman',
                                          font_size=36,
                                          x=w / 10 * (2 * (i + 1) + 1),
                                          y=h / 2 - 100,
                                          anchor_x='center',
                                          anchor_y='center'))
                t = 0
                noAnim = i + 2
    if (noAnim == 5):
        hasil = str(angka[0]) + solusi[0] + str(angka[1]) + solusi[1] + str(
            angka[2]) + solusi[2] + str(angka[3])
        hasil = eval(hasil)
        label.append(
            pyglet.text.Label(str(hasil),
                              font_name='Times New Roman',
                              font_size=36,
                              x=w / 2,
                              y=h / 2 - 150,
                              anchor_x='center',
                              anchor_y='center'))
Esempio n. 30
0
 def skip_to(self, time):
     self.stream_pos = int(util.lerp(time, 0, self.duration, 0, self.sample_count))
Esempio n. 31
0
    def get_frame(self, t):
        spec = _frame_interp(self.spec, self.frame_rate, t)
        spec_grad = _frame_interp(self.spec_grad, self.frame_rate, t)

        def spec_power(freq):
            return np.interp(freq, self.spec_freqs, spec)

        def spec_peak(min_freq, max_freq):
            from_idx = int(
                np.floor(np.interp(min_freq, self.spec_freqs, self.spec_idxs)))
            to_idx = int(
                np.ceil(np.interp(max_freq, self.spec_freqs, self.spec_idxs)))
            spec_range = spec[from_idx:to_idx]
            peak_idx = np.argmax(spec_range) + from_idx
            peak_val = spec[peak_idx]
            peak_freq = np.interp(peak_idx, self.spec_idxs, self.spec_freqs)
            return np.array(
                [util.lerp(peak_freq, min_freq, max_freq, 0, 1), peak_val])

        self.canvas.fill(0xFF000000)

        painter = QtGui.QPainter(self.canvas)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.translate(config.DISPLAY_SHAPE[0] / 2,
                          config.DISPLAY_SHAPE[1] / 2)

        # painter.scale(config.DISPLAY_SHAPE[0] / 2, config.DISPLAY_SHAPE[1] / 2)

        def blip(center, strength, hue, saturation, lightness):
            if strength == 0:
                return
            hue %= 1

            radius = util.lerp(strength, 0, 1, 0, 1.75, clip=True)
            brightness = util.lerp(strength, 0, 1, 0, 1.0, clip=True)

            grad = QtGui.QRadialGradient(0.5, 0.5, 0.5)
            grad.setCoordinateMode(QtGui.QGradient.ObjectBoundingMode)
            grad.setColorAt(
                0.0,
                QtGui.QColor.fromHsvF(hue, saturation * 0.3, lightness,
                                      brightness))
            grad.setColorAt(
                0.2,
                QtGui.QColor.fromHsvF(hue, saturation, lightness,
                                      brightness * 0.8))
            grad.setColorAt(1.0, QtCore.Qt.transparent)
            painter.setBrush(QtGui.QBrush(grad))
            painter.setPen(QtCore.Qt.NoPen)

            painter.drawEllipse(
                QtCore.QRectF(center[0] - radius, center[1] - radius,
                              radius * 2, radius * 2))

        def edge_glow(strength, hue, saturation, lightness):
            if strength == 0:
                return
            hue %= 1

            radius = 5.5
            brightness = util.lerp(strength, 0, 1, 0, 1.0, clip=True)

            grad = QtGui.QRadialGradient(0.5, 0.5, 0.5)
            grad.setCoordinateMode(QtGui.QGradient.ObjectBoundingMode)
            grad.setColorAt(0.0, QtCore.Qt.transparent)
            grad.setColorAt(0.6, QtCore.Qt.transparent)
            grad.setColorAt(
                0.8,
                QtGui.QColor.fromHsvF(hue, saturation, lightness,
                                      brightness * 0.8))
            grad.setColorAt(
                1.0,
                QtGui.QColor.fromHsvF(hue, saturation * 0.3, lightness,
                                      brightness))
            painter.setBrush(QtGui.QBrush(grad))
            painter.setPen(QtCore.Qt.NoPen)

            painter.drawEllipse(
                QtCore.QRectF(-radius, -radius, radius * 2, radius * 2))

        INTRO = 0.20
        BASS = 22.13
        LYRICS_1 = 41.36
        LYRICS_1_KEYBOARD = 63.22
        CHORUS_1 = 85.23
        LYRICS_2 = 107.23
        LYRICS_2_PERCUS = 118.25
        CHORUS_2 = 129.13
        GUITAR_SOLO = 151.12
        GUITAR_SOLO_KEYBOARD = 167.00
        CHORUS_3 = 185.12
        OUTRO = 207.29
        FADE = 226.27
        END = 265.86

        def fade(*args):
            assert args and len(args) % 4 == 0
            for i in range(0, len(args), 4):
                in_t, in_fade, out_t, out_fade = args[i:i + 4]
                if in_fade == 0:
                    if t < in_t:
                        return 0
                elif in_fade < 0:
                    in_fade = -in_fade
                    if t < in_t - in_fade:
                        return 0
                    if t < in_t:
                        return util.lerp(t, in_t - in_fade, in_t, 0, 1)
                else:
                    if t < in_t:
                        return 0
                    if t < in_t + in_fade:
                        return util.lerp(t, in_t, in_t + in_fade, 0, 1)

                if out_fade == 0:
                    if t < out_t:
                        return 1
                elif out_fade < 0:
                    out_fade = -out_fade
                    if t < out_t - out_fade:
                        return 1
                    if t < out_t:
                        return util.lerp(t, out_t - out_fade, out_t, 1, 0)
                else:
                    if t < out_t:
                        return 1
                    if t < out_t + out_fade:
                        return util.lerp(t, out_t, out_t + out_fade, 1, 0)
            return 0

        beat_power = util.lerp(spec_power(3920), 0.4, 0.5, 0, 1, clip=True) * fade(BASS, 0, LYRICS_1, 0) + \
            util.lerp(spec_power(3920), 0.39, 0.67, 0, 1, clip=True) * fade(OUTRO, 0, END, 0)
        bass_pos, bass_power = spec_peak(20, 174) * fade(
            BASS, 0, END, 0)  # TODO: try to get clearer variation in bass_pos
        lyric_pos, lyric_power = spec_peak(523.6, 774.4) * fade(
            LYRICS_1, 0.1, GUITAR_SOLO, -2.4, CHORUS_3, -1, OUTRO, -2.4)
        freckle_power = fade(45.5, -0.4, 47.1, -0.3)
        chorus_bg_pos, chorus_bg_power = spec_peak(1672, 2169) * fade(
            CHORUS_1, 0, LYRICS_2, -2.4, CHORUS_2, 0, GUITAR_SOLO, -2.4,
            CHORUS_3, -1, OUTRO, -2.4)

        self.lyric_pos_filter.update(lyric_pos)
        self.chorus_bg_pos_filter.update(chorus_bg_pos)

        edge_glow(
            chorus_bg_power,
            util.lerp(self.chorus_bg_pos_filter.value, 0, 1, 123, 50) / 360,
            0.80, 0.60)

        # KEYBOARD
        keyboard_blip_pos = [
            (-4, -4),
            (-4, 4),
            (4, 4),
            (4, -4),
        ]
        keyboard_blip_colors = [
            (146 / 360, 0.87, 1.00),
            (204 / 360, 0.91, 1.00),
            (218 / 360, 0.86, 0.91),
            (231 / 360, 0.86, 1.00),
        ]
        keyboard_note_offsets = [
            63.31,
            74.28,
            107.22,
            118.18,
            167.70,
            175.82,
        ]
        keyboard_note_timings = [
            (63.31, 0, 63.95, 0),
            (63.68, 0, 64.28, 0),
            (63.99, 0, 64.68, 0),
            (64.36, 0, 65.93, -0.5),
            (66.06, 0, 66.62, 0),
            (66.40, 0, 66.98, 0),
            (66.83, 0, 67.32, 0),
            (67.10, 0, 68.48, -0.5),
            (68.71, 0, 69.43, 0),
            (69.15, 0, 69.50, 0),
            (69.50, 0, 70.02, 0),
            (69.86, 0, 71.37, -0.5),
            (71.26, 0, 71.48, 0.5),
            (71.38, 0, 72.38, -0.5),
        ]
        keyboard_note_blip_indicies = [
            0,
            1,
            2,
            3,
            0,
            1,
            2,
            3,
            0,
            2,
            1,
            3,
            2,
            1,
        ]
        for offset in keyboard_note_offsets:
            for blip_index, timing in zip(keyboard_note_blip_indicies,
                                          keyboard_note_timings):
                base_offset = keyboard_note_offsets[0]
                timing = (timing[0] - base_offset + offset, timing[1],
                          timing[2] - base_offset + offset, timing[3])
                pos = keyboard_blip_pos[blip_index]
                color = keyboard_blip_colors[blip_index]
                blip(pos, fade(*timing), *color)

        # FRECKLES
        freckle_spacing = np.linspace(-2.5, 2.5, 3)
        for y in range(3):
            for x in range(3):
                if not (x == 1 and y == 1):
                    blip((freckle_spacing[x], freckle_spacing[y]),
                         freckle_power * 0.5, 200 / 360, 0.5, 1.0)

        painter.save()
        # painter.scale(util.lerp(t, 47.55, 49.20, 1, -1, clip=True) * util.lerp(t, 50.94, 51.93, 1, -1, clip=True), 1)
        painter.scale(1, 1)
        painter.rotate(util.lerp(t, 0, 20, 0, 360))
        painter.translate(0 + util.lerp(beat_power, 0, 1, 0, 1), 0)

        # BLIPS
        for ang, note, color in zip(
                np.linspace(0, 2 * np.pi, 4, endpoint=False),
            [
                (355.7, 0.65, 0.80),
                (671.0, 0.55, 0.78),
                # (805.1, 0.55, 0.84),
                (1048, 0.45, 0.67),
                (1183, 0.41, 0.59),
            ],
            [
                (146 / 360, 0.87, 1.00),
                (204 / 360, 0.91, 1.00),
                (218 / 360, 0.86, 0.91),
                (231 / 360, 0.86, 1.00),
            ]):
            r = 2.91
            note_power = util.lerp(
                spec_power(note[0]), note[1], note[2], 0, 1, clip=True) * fade(
                    INTRO, 0, LYRICS_1 - 2.84, 2)
            #GUITAR_SOLO, 0, CHORUS_3, 0)
            blip((r * np.cos(ang), r * np.sin(ang)), note_power, *color)

        # BASS
        blip((0, 0), bass_power,
             util.lerp(bass_pos, 0, 1, 380, 280) / 360, 0.85, 1)

        # LYRICS
        for ang in np.linspace(0, 2 * np.pi, 4, endpoint=False):
            ang += 2 * np.pi / 8
            # spin on verse starts
            ang -= 2 * np.pi / 2 * fade(52.33, 53.22 - 52.33, GUITAR_SOLO,
                                        0)**(1 / 2)
            ang -= 2 * np.pi / 2 * fade(63.00, 64.36 - 63.00, GUITAR_SOLO,
                                        0)**(1 / 2)
            ang -= 2 * np.pi / 2 * fade(73.99, 75.33 - 73.99, GUITAR_SOLO,
                                        0)**(1 / 2)
            ang -= 2 * np.pi / 2 * fade(107.21, 107.93 - 107.21, GUITAR_SOLO,
                                        0)**(1 / 2)
            ang -= 2 * np.pi / 2 * fade(118.24, 118.56 - 118.24, GUITAR_SOLO,
                                        0)**(1 / 2)
            r = util.lerp(self.lyric_pos_filter.value, 0, 1, 2, 4)
            blip((r * np.cos(ang), r * np.sin(ang)), lyric_power, 82 / 360,
                 0.40, 1)

        painter.restore()
        # GUITAR SOLO
        guitar_solo_note_offsets = [
            151.44,
            159.67,
            167.92,
            176.15,
        ]
        guitar_solo_note_timings = [
            151.44, 151.79, 152.13, 152.47, 152.83, 153.14, 153.34, 153.49,
            153.64, 154.19, 154.53, 154.87, 155.20, 155.56, 155.90, 156.07,
            156.41, 156.94, 157.25, 157.64, 157.96, 158.32, 158.65, 158.86,
            159.01, 159.27
        ]
        guitar_solo_note_pos = [
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            1,
            1,
            1,
            1,
            1,
            1,
            1,
            0,
            2,
            2,
            2,
            2,
            2,
            2,
            1,
            2,
            2,
            3,
        ]
        guitar_solo_blip_offsets = [
            -2.5,
            -1.5,
            1.5,
            2.5,
        ]
        guitar_solo_blip_colors = [
            (43 / 360, 0.84, 1.00),
            (37 / 360, 0.84, 0.91),
            (29 / 360, 0.79, 1.00),
            (20 / 360, 0.84, 0.91),
        ]
        for time_offset in guitar_solo_note_offsets:
            time_offset = time_offset - guitar_solo_note_offsets[0]
            for pos, timing in zip(guitar_solo_note_pos,
                                   guitar_solo_note_timings):
                timing += time_offset
                offset = guitar_solo_blip_offsets[pos]
                color = guitar_solo_blip_colors[pos]
                pos = (offset, util.lerp(t, timing, timing + 0.2, -4, 4))
                blip(pos, 1.0, *color)

        outro_lyrics_note_offsets = [
            211.80,
            220.02,
        ]
        outro_lyrics_note_timings = [
            211.80,
            212.52,
            213.17,
        ]
        outro_lyrics_note_pos = [
            0,
            2,
            1,
        ]
        outro_lyrics_blip_offsets = [
            -2.5,
            -1.5,
            2.5,
        ]
        outro_lyrics_blip_colors = [
            (43 / 360, 0.84, 1.00),
            (37 / 360, 0.84, 0.91),
            (29 / 360, 0.79, 1.00),
        ]
        for time_offset in outro_lyrics_note_offsets:
            time_offset = time_offset - outro_lyrics_note_offsets[0]
            for pos, timing in zip(outro_lyrics_note_pos,
                                   outro_lyrics_note_timings):
                timing += time_offset
                offset = outro_lyrics_blip_offsets[pos]
                color = outro_lyrics_blip_colors[pos]
                pos = (offset,
                       util.lerp(
                           util.lerp(t, timing, timing + 0.6, 0, 1,
                                     clip=True)**(1 / 2), 0, 1, 4, -1.5))
                blip(pos, fade(timing, 0, timing + 0.6, -0.4), *color)

        painter.end()

        ptr = self.canvas.constBits()
        ptr.setsize(self.canvas.byteCount())

        pixels = np.array(ptr).reshape(config.DISPLAY_SHAPE[1],
                                       config.DISPLAY_SHAPE[0],
                                       4)[:, :, -2:-5:-1].transpose(1, 0, 2)
        return pixels
Esempio n. 32
0
def compute_river_network(points, neighbors, heights, land,
                          directional_inertia, default_water_level,
                          evaporation_rate):
    num_points = len(points)

    # The normalized vector between points i and j
    def unit_delta(i, j):
        delta = points[j] - points[i]
        return delta / np.linalg.norm(delta)

    # Initialize river priority queue with all edges between non-land points to
    # land points. Each entry is a tuple of (priority, (i, j, river direction))
    q = []
    roots = set()
    for i in range(num_points):
        if land[i]: continue
        is_root = True
        for j in neighbors[i]:
            if not land[j]: continue
            is_root = True
            heapq.heappush(q, (-1.0, (i, j, unit_delta(i, j))))
        if is_root: roots.add(i)

    # Compute the map of each node to its downstream node.
    downstream = [None] * num_points

    while len(q) > 0:
        (_, (i, j, direction)) = heapq.heappop(q)

        # Assign i as being downstream of j, assuming such a point doesn't
        # already exist.
        if downstream[j] is not None: continue
        downstream[j] = i

        # Go through each neighbor of upstream point j.
        for k in neighbors[j]:
            # Ignore neighbors that are lower than the current point, or who already
            # have an assigned downstream point.
            if (heights[k] < heights[j] or downstream[k] is not None
                    or not land[k]):
                continue

            # Edges that are aligned with the current direction vector are
            # prioritized.
            neighbor_direction = unit_delta(j, k)
            priority = -np.dot(direction, neighbor_direction)

            # Add new edge to queue.
            weighted_direction = util.lerp(neighbor_direction, direction,
                                           directional_inertia)
            heapq.heappush(q, (priority, (j, k, weighted_direction)))

    # Compute the mapping of each node to its upstream nodes.
    upstream = [set() for _ in range(num_points)]
    for i, j in enumerate(downstream):
        if j is not None: upstream[j].add(i)

    # Compute the water volume for each node.
    volume = [None] * num_points

    def compute_volume(i):
        if volume[i] is not None: return
        v = default_water_level
        for j in upstream[i]:
            compute_volume(j)
            v += volume[j]
        volume[i] = v * (1 - evaporation_rate)

    for i in range(0, num_points):
        compute_volume(i)

    return (upstream, downstream, volume)