Exemple #1
0
    def render_command_list(self, list, buffer):
        """
        Renders the output of a command list to the output buffer.
        Commands are rendered in FIFO overlap style.  Run the list through
        filter_and_sort_commands() beforehand.
        If the output buffer is not zero (black) at a command's target,
        the output will be additively blended according to the blend_state
        (0.0 = 100% original, 1.0 = 100% new)
        """
        for command in list:
            color = command.get_color()
            if isinstance(command, SetAll):
                buffer[:, :] = color

            elif isinstance(command, SetStrand):
                strand = command.get_strand()
                start, end = BufferUtils.get_strand_extents(strand)
                buffer[start:end] = color

            elif isinstance(command, SetFixture):
                strand = command.get_strand()
                fixture = command.get_address()
                start = BufferUtils.logical_to_index((strand, fixture, 0))
                end = start + self._scene.fixture(strand, fixture).pixels
                buffer[start:end] = color

            elif isinstance(command, SetPixel):
                strand = command.get_strand()
                fixture = command.get_address()
                offset = command.get_pixel()
                pixel = BufferUtils.logical_to_index((strand, fixture, offset))
                buffer[pixel] = color
Exemple #2
0
    def get_pixel_neighbors(self, index):
        """
        Returns a list of pixel addresses that are adjacent to the given address.
        """

        neighbors = self._pixel_neighbors_cache.get(index, None)

        if neighbors is None:
            neighbors = []
            strand, address, pixel = BufferUtils.index_to_logical(index)
            f = self.fixture(strand, address)
            neighbors = [BufferUtils.logical_to_index((strand, address, p)) for p in f.pixel_neighbors(pixel)]

            if (pixel == 0) or (pixel == f.pixels - 1):
                # If this pixel is on the end of a fixture, consider the neighboring fixtures
                loc = 'end'
                if pixel == 0:
                    loc = 'start'

                logical_neighbors = self.get_colliding_fixtures(strand, address, loc)
                neighbors += [BufferUtils.logical_to_index(n) for n in logical_neighbors]

            self._pixel_neighbors_cache[index] = neighbors

        return neighbors
Exemple #3
0
    def render_command_list(self, list, buffer):
        """
        Renders the output of a command list to the output buffer.
        Commands are rendered in FIFO overlap style.  Run the list through
        filter_and_sort_commands() beforehand.
        If the output buffer is not zero (black) at a command's target,
        the output will be additively blended according to the blend_state
        (0.0 = 100% original, 1.0 = 100% new)
        """
        for command in list:
            color = command.get_color()
            if isinstance(command, SetAll):
                buffer[:,:] = color

            elif isinstance(command, SetStrand):
                strand = command.get_strand()
                start, end = BufferUtils.get_strand_extents(strand)
                buffer[start:end] = color

            elif isinstance(command, SetFixture):
                strand = command.get_strand()
                fixture = command.get_address()
                start = BufferUtils.logical_to_index((strand, fixture, 0))
                end = start + self._scene.fixture(strand, fixture).pixels
                buffer[start:end] = color

            elif isinstance(command, SetPixel):
                strand = command.get_strand()
                fixture = command.get_address()
                offset = command.get_pixel()
                pixel = BufferUtils.logical_to_index((strand, fixture, offset))
                buffer[pixel] = color
Exemple #4
0
    def get_pixel_neighbors(self, index):
        """
        Returns a list of pixel addresses that are adjacent to the given address.
        """

        neighbors = self._pixel_neighbors_cache.get(index, None)

        if neighbors is None:
            neighbors = []
            strand, address, pixel = BufferUtils.index_to_logical(index)
            f = self.fixture(strand, address)
            neighbors = [
                BufferUtils.logical_to_index((strand, address, p))
                for p in f.pixel_neighbors(pixel)
            ]

            if (pixel == 0) or (pixel == f.pixels - 1):
                # If this pixel is on the end of a fixture, consider the neighboring fixtures
                loc = 'end'
                if pixel == 0:
                    loc = 'start'

                logical_neighbors = self.get_colliding_fixtures(
                    strand, address, loc)
                neighbors += [
                    BufferUtils.logical_to_index(n) for n in logical_neighbors
                ]

            self._pixel_neighbors_cache[index] = neighbors

        return neighbors
Exemple #5
0
    def _spawn(self, current_strand, current_fixture, population):
        children = set()
        neighbors = self.pattern.scene().get_pixel_neighbors(self.loc)
        neighbors = [BufferUtils.index_to_logical(n) for n in neighbors]
        random.shuffle(neighbors)

        # Iterate over candidate pixels that aren't on the current fixture
        candidates = [
            n for n in neighbors if n[:2] != (current_strand, current_fixture)
        ]
        for candidate in candidates:
            child_index = BufferUtils.logical_to_index(candidate)
            if len(children) == 0:
                # Spawn at least one new dragon to replace the old one.  This first one skips the growth.
                dir = 1 if candidate[2] == 0 else -1
                child = _Dragon(self.pattern, child_index, dir,
                                self.pattern._current_time)
                child.growing = False
                child.alive = True
                children.add(child)
                population += 1
            elif (population < self.pattern.parameter('pop-limit').get()
                  and random.random() <
                  self.pattern.parameter('birth-rate').get()):
                # Randomly spawn new dragons
                dir = 1 if candidate[2] == 0 else -1
                child = _Dragon(self.pattern, child_index, dir,
                                self.pattern._current_time)
                children.add(child)
                population += 1

        return children
Exemple #6
0
    def warmup(self):
        """
        Warms up caches
        """
        log.info("Warming up scene caches...")
        fh = self.fixture_hierarchy()
        for strand in fh:
            for fixture in fh[strand]:
                self.get_colliding_fixtures(strand, fixture)
                for pixel in range(self.fixture(strand, fixture).pixels):
                    index = BufferUtils.logical_to_index((strand, fixture, pixel))
                    neighbors = self.get_pixel_neighbors(index)
                    self.get_pixel_location(index)
                    for neighbor in neighbors:
                        self.get_pixel_distance(index, neighbor)
        self.get_fixture_bounding_box()
        self.get_intersection_points()
        self.get_all_pixels_logical()
        self._tree = spatial.KDTree(self.get_all_pixel_locations())

        locations = self.get_all_pixel_locations()
        self.pixelDistances = np.empty([len(locations), len(locations)])

        for pixel in range(len(locations)):
            cx, cy = locations[pixel]
            x,y = (locations - (cx, cy)).T
            pixel_distances = np.sqrt(np.square(x) + np.square(y))
            self.pixelDistances[pixel] = pixel_distances

        log.info("Done")
Exemple #7
0
    def warmup(self):
        """
        Warms up caches
        """
        log.info("Warming up scene caches...")
        fh = self.fixture_hierarchy()
        for strand in fh:
            for fixture in fh[strand]:
                self.get_colliding_fixtures(strand, fixture)
                for pixel in range(self.fixture(strand, fixture).pixels):
                    index = BufferUtils.logical_to_index(
                        (strand, fixture, pixel))
                    neighbors = self.get_pixel_neighbors(index)
                    self.get_pixel_location(index)
                    for neighbor in neighbors:
                        self.get_pixel_distance(index, neighbor)
        self.get_fixture_bounding_box()
        self.get_intersection_points()
        self.get_all_pixels_logical()
        self._tree = spatial.KDTree(self.get_all_pixel_locations())

        locations = self.get_all_pixel_locations()
        self.pixelDistances = np.empty([len(locations), len(locations)])

        for pixel in range(len(locations)):
            cx, cy = locations[pixel]
            x, y = (locations - (cx, cy)).T
            pixel_distances = np.sqrt(np.square(x) + np.square(y))
            self.pixelDistances[pixel] = pixel_distances

        log.info("Done")
Exemple #8
0
    def get_fixture_bounding_box(self):
        """
        Returns the bounding box containing all fixtures in the scene
        Return value is a tuple of (xmin, ymin, xmax, ymax)
        """
        xmin = 999999
        xmax = -999999
        ymin = 999999
        ymax = -999999

        fh = self.fixture_hierarchy()
        for strand in fh:
            for fixture in fh[strand]:
                for pixel in range(self.fixture(strand, fixture).pixels):
                    x, y = self.get_pixel_location(
                        BufferUtils.logical_to_index((strand, fixture, pixel)))
                    if x < xmin:
                        xmin = x
                    if x > xmax:
                        xmax = x
                    if y < ymin:
                        ymin = y
                    if y > ymax:
                        ymax = y

        return (xmin, ymin, xmax, ymax)
Exemple #9
0
    def get_fixture_bounding_box(self):
        """
        Returns the bounding box containing all fixtures in the scene
        Return value is a tuple of (xmin, ymin, xmax, ymax)
        """
        xmin = 999999
        xmax = -999999
        ymin = 999999
        ymax = -999999

        fh = self.fixture_hierarchy()
        for strand in fh:
            for fixture in fh[strand]:
                for pixel in range(self.fixture(strand, fixture).pixels):
                    x, y = self.get_pixel_location(BufferUtils.logical_to_index((strand, fixture, pixel)))
                    if x < xmin:
                        xmin = x
                    if x > xmax:
                        xmax = x
                    if y < ymin:
                        ymin = y
                    if y > ymax:
                        ymax = y

        return (xmin, ymin, xmax, ymax)
Exemple #10
0
    def get_all_pixels(self):
        """
        Returns a list of all pixels in buffer address format (strand, offset)
        """
        if self._all_pixels_raw is None:
            all_pixels = []
            for s, a, p in self.get_all_pixels_logical():
                #pxs.append(BufferUtils.get_buffer_address((s, a, p), scene=self))
                all_pixels.append(BufferUtils.logical_to_index((s, a, p), scene=self))
            all_pixels = sorted(all_pixels)
            self._all_pixels_raw = all_pixels

        return self._all_pixels_raw
Exemple #11
0
    def get_all_pixels(self):
        """
        Returns a list of all pixels in buffer address format (strand, offset)
        """
        if self._all_pixels_raw is None:
            all_pixels = []
            for s, a, p in self.get_all_pixels_logical():
                #pxs.append(BufferUtils.get_buffer_address((s, a, p), scene=self))
                all_pixels.append(
                    BufferUtils.logical_to_index((s, a, p), scene=self))
            all_pixels = sorted(all_pixels)
            self._all_pixels_raw = all_pixels

        return self._all_pixels_raw
Exemple #12
0
 def warmup(self):
     """
     Warms up caches
     """
     log.info("Warming up scene caches...")
     fh = self.fixture_hierarchy()
     for strand in fh:
         for fixture in fh[strand]:
             self.get_colliding_fixtures(strand, fixture)
             for pixel in range(self.fixture(strand, fixture).pixels):
                 index = BufferUtils.logical_to_index((strand, fixture, pixel))
                 neighbors = self.get_pixel_neighbors(index)
                 self.get_pixel_location(index)
                 for neighbor in neighbors:
                     self.get_pixel_distance(index, neighbor)
     self.get_fixture_bounding_box()
     self.get_intersection_points()
     self.get_all_pixels_logical()
     #self.get_all_pixels()
     #self.get_all_pixel_locations()
     log.info("Done")
Exemple #13
0
    def render(self, out):
        # Spontaneous birth: Rare after startup
        if (len(self._dragons) < self.parameter('pop-limit').get()
            ) and random.random() < self.parameter('birth-rate').get():
            strand = random.randint(0, BufferUtils.num_strands - 1)
            fixture = random.randint(
                0,
                BufferUtils.strand_num_fixtures(strand) - 1)
            address = BufferUtils.logical_to_index((strand, fixture, 0))
            if address not in [d.loc for d in self._dragons]:
                self._dragons.add(_Dragon(self, address, 1,
                                          self._current_time))

        # Dragon life cycle
        to_add = set()
        to_remove = set()
        population = len(self._dragons)
        for dragon in self._dragons:
            population += dragon.render(to_add, to_remove, population)

        self._dragons = (self._dragons | to_add) - to_remove

        # Draw tails
        tails_to_remove = []
        for loc, time, fader in self._tails:
            if (self._current_time -
                    time) > self.parameter('tail-persist').get():
                if (loc, time, fader) in self._tails:
                    tails_to_remove.append((loc, time, fader))
                self.setPixelHLS(self._buffer, loc, (0, 0, 0))
            else:
                progress = (self._current_time -
                            time) / self.parameter('tail-persist').get()
                self.setPixelHLS(self._buffer, loc,
                                 fader.get_color(progress * self._fader_steps))
        for tail in tails_to_remove:
            self._tails.remove(tail)

        np.copyto(out, self._buffer)
Exemple #14
0
 def warmup(self):
     """
     Warms up caches
     """
     log.info("Warming up scene caches...")
     fh = self.fixture_hierarchy()
     for strand in fh:
         for fixture in fh[strand]:
             self.get_colliding_fixtures(strand, fixture)
             for pixel in range(self.fixture(strand, fixture).pixels):
                 index = BufferUtils.logical_to_index(
                     (strand, fixture, pixel))
                 neighbors = self.get_pixel_neighbors(index)
                 self.get_pixel_location(index)
                 for neighbor in neighbors:
                     self.get_pixel_distance(index, neighbor)
     self.get_fixture_bounding_box()
     self.get_intersection_points()
     self.get_all_pixels_logical()
     #self.get_all_pixels()
     #self.get_all_pixel_locations()
     log.info("Done")
Exemple #15
0
    def draw(self, dt):

        self._current_time += dt
        self._mass_destruction_countdown -= dt
    
        # Ensure that empty displays start up with some seeds
        p_birth = (1.0 - self._spontaneous_birth_probability) if self._population > 5 else 0.5

        # Spontaneous birth: Rare after startup
        if (self._population < self._population_limit) and random.random() + self.parameter('audio-onset-birth-boost').get() > p_birth:
            strand = random.randint(0, BufferUtils.num_strands - 1)
            fixture = random.randint(0, BufferUtils.strand_num_fixtures(strand) - 1)
            pixel = random.randint(0, BufferUtils.fixture_length(strand, fixture) - 1)
            address = BufferUtils.logical_to_index((strand, fixture, pixel))
            if address not in (self._growing + self._alive + self._dying + self._fading_out):
                self._growing.append(address)
                self._time[address] = self._current_time
                self._population += 1

        self._spread_boost *= self.parameter('audio-onset-spread-boost-echo').get()
        if self._mixer.is_onset():
            self._spread_boost += self.parameter('audio-onset-spread-boost').get()

        # Color growth
        for address in self._growing:
            neighbors = self.scene().get_pixel_neighbors(address)
            p, color = self._get_next_color(address, self._growth_time, self._current_time)
            if p >= 1.0:
                self._growing.remove(address)
                self._alive.append(address)
                self._time[address] = self._current_time
            self.setPixelHLS(address, color)

            # Spread
            spread_rate = self._spread_rate + self._spread_boost

            if (self._population < self._population_limit) and (random.random() < spread_rate * dt):
                for spread in neighbors:
                    if spread not in (self._growing + self._alive + self._dying + self._fading_out):
                        self._growing.append(spread)
                        self._time[spread] = self._current_time
                        self._population += 1

        # Lifetime
        for address in self._alive:
            neighbors = self.scene().get_pixel_neighbors(address)
            live_neighbors = [i for i in neighbors if i in self._alive]
            lt = self._life_time
            if len(neighbors) < 2:
                lt = self._isolated_life_time

            if len(live_neighbors) < 3 and ((self._current_time - self._time[address]) / lt) >= 1.0:
                self._alive.remove(address)
                self._dying.append(address)
                self._time[address] = self._current_time
                self._population -= 1

            self.setPixelHLS(address, self._alive_color)

            # Spread
            if (self._population < self._population_limit) and random.random() < self._birth_rate * dt:
                for spread in neighbors:
                    if spread not in (self._growing + self._alive + self._dying + self._fading_out):
                        self._growing.append(spread)
                        self._time[spread] = self._current_time
                        self._population += 1

        # Color decay
        for address in self._dying:
            p, color = self._get_next_color(address, self._death_time, self._current_time + self.parameter('audio-onset-death-boost').get())
            if p >= 1.0:
                self._dying.remove(address)
                self._fading_out.append(address)
                self._time[address] = self._current_time
            self.setPixelHLS(address, color)

        # Fade out
        for address in self._fading_out:
            p, color = self._get_next_color(address, self._fade_out_time, self._current_time + self.parameter('audio-onset-death-boost').get())
            if p >= 1.0:
                self._fading_out.remove(address)
            self.setPixelHLS(address, color)

        # Mass destruction
        if (self._population == self._population_limit) or \
                (self._population > self._mass_destruction_threshold and self._mass_destruction_countdown <= 0):
            for i in self._alive:
                if random.random() > 0.95:
                    self._alive.remove(i)
                    self._dying.append(i)
                    self._population -= 1
            for i in self._growing:
                if random.random() > 0.85:
                    self._growing.remove(i)
                    self._dying.append(i)
                    self._population -= 1
            self._mass_destruction_countdown = self.parameter('mass-destruction-time').get()
Exemple #16
0
    def draw(self, dt):

        self._current_time += dt
        
        # Spontaneous birth: Rare after startup
        if (len(self._dragons) < self.parameter('pop-limit').get()) and random.random() < self.parameter('birth-rate').get():
            strand = random.randint(0, BufferUtils.num_strands - 1)
            fixture = random.randint(0, BufferUtils.strand_num_fixtures(strand) - 1)
            address = BufferUtils.logical_to_index((strand, fixture, 0))
            if address not in [d.loc for d in self._dragons]:
                self._dragons.append(self.Dragon(address, 1, self._current_time))

        growth_rate = self.parameter('growth-rate').get()
        
        # Dragon life cycle
        for dragon in self._dragons:
            # Fade in
            if dragon.growing:
                p = (self._current_time - dragon.lifetime) / self.parameter('growth-time').get()
                if (p > 1):
                    p = 1.0
                color = self._growth_fader.get_color(p * self._fader_steps)
                if p >= 1.0:
                    dragon.growing = False
                    dragon.alive = True
                    dragon.lifetime = self._current_time

                self.setPixelHLS(dragon.loc, color)

            # Alive - can move or die
            if dragon.alive:

                dragon.growth += dt * growth_rate
                for times in range(int(dragon.growth)):
                    s, f, p = BufferUtils.index_to_logical(dragon.loc)
                    self.setPixelHLS(dragon.loc, (0, 0, 0))

                    if random.random() < dragon.growth:
                        dragon.growth -= 1
                    
                        # At a vertex: optionally spawn new dragons
                        if dragon.moving and (p == 0 or p == (self.scene().fixture(s, f).pixels - 1)):
                            neighbors = self.scene().get_pixel_neighbors(dragon.loc)
                            neighbors = [BufferUtils.index_to_logical(n) for n in neighbors]
                            random.shuffle(neighbors)

                            # Kill dragons that reach the end of a fixture
                            dragon.moving = False
                            if dragon in self._dragons:
                                self._dragons.remove(dragon)
                                
                            # Iterate over candidate pixels that aren't on the current fixture
                            num_children = 0
                            for candidate in [n for n in neighbors if n[1] != f]:
                                child_index = BufferUtils.logical_to_index(candidate)
                                if num_children == 0:
                                    # Spawn at least one new dragon to replace the old one.  This first one skips the growth.
                                    dir = 1 if candidate[2] == 0 else -1
                                    child = self.Dragon(child_index, dir, self._current_time)
                                    child.growing = False
                                    child.alive = True
                                    child.moving = False
                                    self._dragons.append(child)
                                    num_children += 1
                                elif (len(self._dragons) < self.parameter('pop-limit').get()):
                                    # Randomly spawn new dragons
                                    if random.random() < self.parameter('birth-rate').get():
                                        dir = 1 if candidate[2] == 0 else -1
                                        child = self.Dragon(child_index, dir, self._current_time)
                                        child.moving = False

                                        self._dragons.append(child)
                                        num_children += 1
                            break;
                        else:
                            # Move dragons along the fixture
                            self._tails.append((dragon.loc, self._current_time, self._tail_fader))
                            new_address = BufferUtils.logical_to_index((s, f, p + dragon.dir))
                            dragon.loc = new_address
                            dragon.moving = True
                            self.setPixelHLS(new_address, self._alive_color)

                    # Kill dragons that run into each other
                    if dragon in self._dragons:
                        colliding = [d for d in self._dragons if d != dragon and d.loc == dragon.loc]
                        if len(colliding) > 0:
                            #print "collision between", dragon, "and", colliding[0]
                            self._dragons.remove(dragon)
                            self._dragons.remove(colliding[0])
                            self._tails.append((dragon.loc, self._current_time, self._explode_fader))
                            neighbors = self.scene().get_pixel_neighbors(dragon.loc)
                            for neighbor in neighbors:
                                self._tails.append((neighbor, self._current_time, self._explode_fader))
                            break

        # Draw tails
        for loc, time, fader in self._tails:
            if (self._current_time - time) > self.parameter('tail-persist').get():
                if (loc, time, fader) in self._tails:
                    self._tails.remove((loc, time, fader))
                self.setPixelHLS(loc, (0, 0, 0))
            else:
                progress = (self._current_time - time) / self.parameter('tail-persist').get()
                self.setPixelHLS(loc, fader.get_color(progress * self._fader_steps))
Exemple #17
0
    def draw(self, dt):

        self._current_time += dt
        self._mass_destruction_countdown -= dt

        # Ensure that empty displays start up with some seeds
        p_birth = (1.0 - self._spontaneous_birth_probability
                   ) if self._population > 5 else 0.5

        # Spontaneous birth: Rare after startup
        if (self._population < self._population_limit) and random.random(
        ) + self.parameter('audio-onset-birth-boost').get() > p_birth:
            strand = random.randint(0, BufferUtils.num_strands - 1)
            fixture = random.randint(
                0,
                BufferUtils.strand_num_fixtures(strand) - 1)
            pixel = random.randint(
                0,
                BufferUtils.fixture_length(strand, fixture) - 1)
            address = BufferUtils.logical_to_index((strand, fixture, pixel))
            if address not in (self._growing + self._alive + self._dying +
                               self._fading_out):
                self._growing.append(address)
                self._time[address] = self._current_time
                self._population += 1

        self._spread_boost *= self.parameter(
            'audio-onset-spread-boost-echo').get()
        if self._mixer.is_onset():
            self._spread_boost += self.parameter(
                'audio-onset-spread-boost').get()

        # Color growth
        for address in self._growing:
            neighbors = self.scene().get_pixel_neighbors(address)
            p, color = self._get_next_color(address, self._growth_time,
                                            self._current_time)
            if p >= 1.0:
                self._growing.remove(address)
                self._alive.append(address)
                self._time[address] = self._current_time
            self.setPixelHLS(address, color)

            # Spread
            spread_rate = self._spread_rate + self._spread_boost

            if (self._population < self._population_limit) and (
                    random.random() < spread_rate * dt):
                for spread in neighbors:
                    if spread not in (self._growing + self._alive +
                                      self._dying + self._fading_out):
                        self._growing.append(spread)
                        self._time[spread] = self._current_time
                        self._population += 1

        # Lifetime
        for address in self._alive:
            neighbors = self.scene().get_pixel_neighbors(address)
            live_neighbors = [i for i in neighbors if i in self._alive]
            lt = self._life_time
            if len(neighbors) < 2:
                lt = self._isolated_life_time

            if len(live_neighbors) < 3 and (
                (self._current_time - self._time[address]) / lt) >= 1.0:
                self._alive.remove(address)
                self._dying.append(address)
                self._time[address] = self._current_time
                self._population -= 1

            self.setPixelHLS(address, self._alive_color)

            # Spread
            if (self._population < self._population_limit
                ) and random.random() < self._birth_rate * dt:
                for spread in neighbors:
                    if spread not in (self._growing + self._alive +
                                      self._dying + self._fading_out):
                        self._growing.append(spread)
                        self._time[spread] = self._current_time
                        self._population += 1

        # Color decay
        for address in self._dying:
            p, color = self._get_next_color(
                address, self._death_time, self._current_time +
                self.parameter('audio-onset-death-boost').get())
            if p >= 1.0:
                self._dying.remove(address)
                self._fading_out.append(address)
                self._time[address] = self._current_time
            self.setPixelHLS(address, color)

        # Fade out
        for address in self._fading_out:
            p, color = self._get_next_color(
                address, self._fade_out_time, self._current_time +
                self.parameter('audio-onset-death-boost').get())
            if p >= 1.0:
                self._fading_out.remove(address)
            self.setPixelHLS(address, color)

        # Mass destruction
        if (self._population == self._population_limit) or \
                (self._population > self._mass_destruction_threshold and self._mass_destruction_countdown <= 0):
            for i in self._alive:
                if random.random() > 0.95:
                    self._alive.remove(i)
                    self._dying.append(i)
                    self._population -= 1
            for i in self._growing:
                if random.random() > 0.85:
                    self._growing.remove(i)
                    self._dying.append(i)
                    self._population -= 1
            self._mass_destruction_countdown = self.parameter(
                'mass-destruction-time').get()
Exemple #18
0
    def draw(self, dt):
        self._hue = (self._hue + (dt * 0.1)) % 1.0
        self.setAllHLS(self._hue, 0.2, 1.0)
        for strand in self._hierarchy:
            self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 0), scene=self.scene()), (0.33, 0.5, 1.0))

            if (strand & 0x8):
                self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 1), scene=self.scene()), (0.66, 0.9, 1.0))
            else:
                self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 1), scene=self.scene()), (0.0, 0.2, 0.0))
            if (strand & 0x4):
                self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 2), scene=self.scene()), (0.66, 0.9, 1.0))
            else:
                self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 2), scene=self.scene()), (0.0, 0.2, 0.0))
            if (strand & 0x2):
                self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 3), scene=self.scene()), (0.66, 0.9, 1.0))
            else:
                self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 3), scene=self.scene()), (0.0, 0.2, 0.0))
            if (strand & 0x1):
                self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 4), scene=self.scene()), (0.66, 0.9, 1.0))
            else:
                self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 4), scene=self.scene()), (0.0, 0.2, 0.0))

            for fixture in self._hierarchy[strand]:
                last_fixture_pixel = self._hierarchy[strand][fixture].pixels - 1
                self.setPixelHLS(BufferUtils.logical_to_index((strand, fixture, last_fixture_pixel), scene=self.scene()), (0.66, 0.5, 1.0))
                if fixture > 0:
                    self.setPixelHLS(BufferUtils.logical_to_index((strand, fixture, 0), scene=self.scene()), (0.15, 0.5, 1.0))

            last_fixture = len(self._hierarchy[strand].keys()) - 1
            last_pixel = self._hierarchy[strand][last_fixture].pixels - 1

            self.setPixelHLS(BufferUtils.logical_to_index((strand, last_fixture, last_pixel), scene=self.scene()), (0.0, 0.5, 1.0))
Exemple #19
0
    def draw(self, dt):
        self._hue = (self._hue + (dt * 0.1)) % 1.0
        self.setAllHLS(self._hue, 0.2, 1.0)
        for strand in self._heirarchy:
            self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 0), scene=self.scene()), (0.33, 0.5, 1.0))

            if (strand & 0x8):
                self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 1), scene=self.scene()), (0.66, 0.9, 1.0))
            else:
                self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 1), scene=self.scene()), (0.0, 0.2, 0.0))
            if (strand & 0x4):
                self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 2), scene=self.scene()), (0.66, 0.9, 1.0))
            else:
                self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 2), scene=self.scene()), (0.0, 0.2, 0.0))
            if (strand & 0x2):
                self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 3), scene=self.scene()), (0.66, 0.9, 1.0))
            else:
                self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 3), scene=self.scene()), (0.0, 0.2, 0.0))
            if (strand & 0x1):
                self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 4), scene=self.scene()), (0.66, 0.9, 1.0))
            else:
                self.setPixelHLS(BufferUtils.logical_to_index((strand, 0, 4), scene=self.scene()), (0.0, 0.2, 0.0))

            for fixture in self._heirarchy[strand]:
                last_fixture_pixel = self._heirarchy[strand][fixture].pixels - 1
                self.setPixelHLS(BufferUtils.logical_to_index((strand, fixture, last_fixture_pixel), scene=self.scene()), (0.66, 0.5, 1.0))
                if fixture > 0:
                    self.setPixelHLS(BufferUtils.logical_to_index((strand, fixture, 0), scene=self.scene()), (0.15, 0.5, 1.0))

            last_fixture = len(self._heirarchy[strand].keys()) - 1
            last_pixel = self._heirarchy[strand][last_fixture].pixels - 1

            self.setPixelHLS(BufferUtils.logical_to_index((strand, last_fixture, last_pixel), scene=self.scene()), (0.0, 0.5, 1.0))
Exemple #20
0
    def render(self, to_add, to_remove, population):
        pop_delta = 0

        # Fade in
        if self.growing:
            p = (self.pattern._current_time -
                 self.lifetime) / self.pattern.parameter('growth-time').get()
            if (p > 1):
                p = 1.0
            color = self.pattern._growth_fader.get_color(
                p * self.pattern._fader_steps)
            if p >= 1.0:
                self.growing = False
                self.alive = True
                self.lifetime = self.pattern._current_time

            self.pattern.setPixelHLS(self.pattern._buffer, self.loc, color)

        # Alive - can move or die
        if not self.alive:
            return pop_delta

        for times in range(int(self.growth)):
            s, f, p = BufferUtils.index_to_logical(self.loc)
            self.pattern.setPixelHLS(self.pattern._buffer, self.loc, (0, 0, 0))

            if random.random() < self.growth:
                self.growth -= 1

                if ((self.dir == -1 and p == 0) or
                    (self.dir == 1 and p
                     == (self.pattern.scene().fixture(s, f).pixels - 1))):
                    # At a vertex: kill dragons that reach the end of a fixture
                    # and optionally spawn new dragons
                    self.pattern._tails.append(
                        (self.loc, self.pattern._current_time,
                         self.pattern._tail_fader))
                    to_remove.add(self)
                    pop_delta -= 1
                    spawned = self._spawn(s, f, population + pop_delta)
                    to_add |= spawned
                    pop_delta += len(spawned)
                    break
                else:
                    # Move dragons along the fixture
                    self.pattern._tails.append(
                        (self.loc, self.pattern._current_time,
                         self.pattern._tail_fader))
                    new_address = BufferUtils.logical_to_index(
                        (s, f, p + self.dir))
                    self.loc = new_address
                    self.pattern.setPixelHLS(self.pattern._buffer, new_address,
                                             self.pattern._alive_color)

            # Kill dragons that run into each other
            if self not in to_remove:
                others = (self.pattern._dragons | to_add) - to_remove
                colliding = [
                    d for d in others if d != self and d.loc == self.loc
                ]
                if len(colliding) > 0:
                    #print "collision between", self, "and", colliding[0]
                    to_remove.add(self)
                    pop_delta -= 1
                    for other in colliding:
                        to_remove.add(other)
                        pop_delta -= 1
                    self.pattern._tails.append(
                        (self.loc, self.pattern._current_time,
                         self.pattern._explode_fader))
                    neighbors = self.pattern.scene().get_pixel_neighbors(
                        self.loc)
                    for neighbor in neighbors:
                        self.pattern._tails.append(
                            (neighbor, self.pattern._current_time,
                             self.pattern._explode_fader))
                    break

        return pop_delta
Exemple #21
0
    def draw(self, dt):

        self._current_time += dt

        # Spontaneous birth: Rare after startup
        if (len(self._dragons) < self.parameter('pop-limit').get()
            ) and random.random() < self.parameter('birth-rate').get():
            address = BufferUtils.logical_to_index(
                (random.randint(0, self._max_strand - 1),
                 random.randint(0, self._max_fixture - 1), 0))
            if address not in [d.loc for d in self._dragons]:
                self._dragons.append(
                    self.Dragon(address, 1, self._current_time))

        growth_rate = self.parameter('growth-rate').get()

        # Dragon life cycle
        for dragon in self._dragons:
            # Fade in
            if dragon.growing:
                p = (self._current_time -
                     dragon.lifetime) / self.parameter('growth-time').get()
                if (p > 1):
                    p = 1.0
                color = self._growth_fader.get_color(p * self._fader_steps)
                if p >= 1.0:
                    dragon.growing = False
                    dragon.alive = True
                    dragon.lifetime = self._current_time

                self.setPixelHLS(dragon.loc, color)

            # Alive - can move or die
            if dragon.alive:

                dragon.growth += dt * growth_rate
                for times in range(int(dragon.growth)):
                    s, f, p = BufferUtils.index_to_logical(dragon.loc)
                    self.setPixelHLS(dragon.loc, (0, 0, 0))

                    if random.random() < dragon.growth:
                        dragon.growth -= 1

                        # At a vertex: optionally spawn new dragons
                        if dragon.moving and (p == 0 or p == (
                                self.scene().fixture(s, f).pixels - 1)):
                            neighbors = self.scene().get_pixel_neighbors(
                                dragon.loc)
                            neighbors = [
                                BufferUtils.index_to_logical(n)
                                for n in neighbors
                            ]
                            random.shuffle(neighbors)

                            # Kill dragons that reach the end of a fixture
                            dragon.moving = False
                            if dragon in self._dragons:
                                self._dragons.remove(dragon)

                            # Iterate over candidate pixels that aren't on the current fixture
                            num_children = 0
                            for candidate in [
                                    n for n in neighbors if n[1] != f
                            ]:
                                child_index = BufferUtils.logical_to_index(
                                    candidate)
                                if num_children == 0:
                                    # Spawn at least one new dragon to replace the old one.  This first one skips the growth.
                                    dir = 1 if candidate[2] == 0 else -1
                                    child = self.Dragon(
                                        child_index, dir, self._current_time)
                                    child.growing = False
                                    child.alive = True
                                    child.moving = False
                                    self._dragons.append(child)
                                    num_children += 1
                                elif (len(self._dragons) <
                                      self.parameter('pop-limit').get()):
                                    # Randomly spawn new dragons
                                    if random.random() < self.parameter(
                                            'birth-rate').get():
                                        dir = 1 if candidate[2] == 0 else -1
                                        child = self.Dragon(
                                            child_index, dir,
                                            self._current_time)
                                        child.moving = False

                                        self._dragons.append(child)
                                        num_children += 1
                            break
                        else:
                            # Move dragons along the fixture
                            self._tails.append((dragon.loc, self._current_time,
                                                self._tail_fader))
                            new_address = BufferUtils.logical_to_index(
                                (s, f, p + dragon.dir))
                            dragon.loc = new_address
                            dragon.moving = True
                            self.setPixelHLS(new_address, self._alive_color)

                    # Kill dragons that run into each other
                    if dragon in self._dragons:
                        colliding = [
                            d for d in self._dragons
                            if d != dragon and d.loc == dragon.loc
                        ]
                        if len(colliding) > 0:
                            #print "collision between", dragon, "and", colliding[0]
                            self._dragons.remove(dragon)
                            self._dragons.remove(colliding[0])
                            self._tails.append((dragon.loc, self._current_time,
                                                self._explode_fader))
                            neighbors = self.scene().get_pixel_neighbors(
                                dragon.loc)
                            for neighbor in neighbors:
                                self._tails.append(
                                    (neighbor, self._current_time,
                                     self._explode_fader))
                            break

        # Draw tails
        for loc, time, fader in self._tails:
            if (self._current_time -
                    time) > self.parameter('tail-persist').get():
                if (loc, time, fader) in self._tails:
                    self._tails.remove((loc, time, fader))
                self.setPixelHLS(loc, (0, 0, 0))
            else:
                progress = (self._current_time -
                            time) / self.parameter('tail-persist').get()
                self.setPixelHLS(loc,
                                 fader.get_color(progress * self._fader_steps))