diff options
-rw-r--r-- | DecayEvent.py | 2 | ||||
-rw-r--r-- | LayoutEngine.py | 12 | ||||
-rw-r--r-- | Light.py | 51 | ||||
-rw-r--r-- | LightStrip.py | 42 | ||||
-rw-r--r-- | LightSystem.py | 30 | ||||
-rw-r--r-- | Pixel.py | 29 | ||||
-rw-r--r-- | PixelEvent.py | 2 | ||||
-rw-r--r-- | PixelStrip.py | 26 | ||||
-rw-r--r-- | PygameRenderer.py | 2 | ||||
-rw-r--r-- | Screen.py | 4 | ||||
-rw-r--r-- | StepEvent.py | 2 | ||||
-rw-r--r-- | Util.py | 2 | ||||
-rw-r--r-- | gfxdemo.py | 82 |
13 files changed, 36 insertions, 250 deletions
diff --git a/DecayEvent.py b/DecayEvent.py index def4284..4dbe3cd 100644 --- a/DecayEvent.py +++ b/DecayEvent.py @@ -4,7 +4,7 @@ class DecayEvent(PixelEvent): def initEvent(self): self.validateArgs('DecayEvent.params') self['Coefficient'] = abs(self['Coefficient']) - def lightState(self,timeDelay): + def state(self,timeDelay): if self['DecayType'] == 'Exponential': decay = math.exp(timeDelay*-1*self['Coefficient']) if self['DecayType'] == 'Proportional': diff --git a/LayoutEngine.py b/LayoutEngine.py index 6d7cdd5..153167e 100644 --- a/LayoutEngine.py +++ b/LayoutEngine.py @@ -8,20 +8,20 @@ class LayoutEngine(SmootCoreObject): def layoutFunc(self, lastLocation): #Must be defined by inheriting class. #Returns tuple pair (x,y) pass - def getLightLocations(self): #returns a complete list of locations of lights + def getPixelLocations(self): #returns a complete list of locations of Pixels #for a strip locations = [self.argDict['originLocation']] - for lightIndex in range(self['numLights']-1): #-1 because origin + for pixelIndex in range(self['numPixels']-1): #-1 because origin #already exists newLocation = self.layoutFunc(locations[-1]) if newLocation == None: raise Exception('Location cannot be null. layoutFunc not \ defined or improperly defined.') if Util.dist(newLocation, locations[-1]) > \ - self['lightToLightSpacing']: - raise Exception('Illegal light location. Distance \ - between adjacent lights must be less than \ - lightToLightSpacing.') + self['pixelToPixelSpacing']: + raise Exception('Illegal pixel location. Distance \ + between adjacent pixels must be less than \ + pixelToPixelSpacing.') locations.append(newLocation) return locations def initLayout(self): diff --git a/Light.py b/Light.py deleted file mode 100644 index f6a73e8..0000000 --- a/Light.py +++ /dev/null @@ -1,51 +0,0 @@ -import Util -import pdb -from StepEvent import StepEvent -#Light keeps a cue of events (LightEvent objects). Every time is state is -#requested, it processes all the members of its cue. If a member returns none, -#it is removed from the queue. Otherwise, its value added to the lights color -#weighted by z-index. -class Light: - radius = 2 - lightOn = False - timeOff = -1 - def __init__(self, location, color): - self.location = location - self.color = color - self.events = {} - def turnOn(self): - self.lightOn = True - def turnOnFor(self, time): - event = StepEvent.generate(time, (255,0,255)) #TODO: Move color to - self.processInput(event, 0) - #arg - def processInput(self,lightEvent,zindex): #consider migrating arg to dict - self.events[Util.time()] = (zindex, lightEvent) - def turnOff(self): - self.lightOn = False - def lightState(self): - deadEvents = [] - currentTime = Util.time() - resultingColor = (0,0,0) - for eventTime in self.events: #TODO: right color weighting code - (zindex,event) = self.events[eventTime] - eventResult = event.lightState(currentTime-eventTime) - if eventResult != None: - resultingColor = Util.combineColors(eventResult, resultingColor) - print resultingColor - else: - deadEvents.append(eventTime) - [self.events.pop(event) for event in deadEvents] - if sum(resultingColor) > 0: - print resultingColor - return tuple(resultingColor) - def isLightOn(self): - if self.timeOff == -1: - return self.lightOn - else: - return Util.time() < self.timeOff - def flip(self): - self.lightOn = not self.lightOn - def __str__(self): - return 'Loc: ' + str(self.location) - diff --git a/LightStrip.py b/LightStrip.py deleted file mode 100644 index 7314e42..0000000 --- a/LightStrip.py +++ /dev/null @@ -1,42 +0,0 @@ -from Light import Light -from StepEvent import StepEvent -import pygame -import math -import Util -import pdb -#Python class representing a single light strip (usually 50 lights) -class PixelStrip: - def __init__(self, layoutEngine): - self.initStrip(layoutEngine) - self.argDict = layoutEngine.getStripArgs() - def initStrip(self, layoutEngine): - lightLocations = layoutEngine.getLightLocations() - self.lights = [Light(l, (0,0,0)) for l in lightLocations] - def __iter__(self): - return self.lights.__iter__() - def render(self, surface): - [l.render(surface) for l in self.lights] - #step - def allOn(self, time): - [l.turnOnFor(time) for l in self.lights] - def turnOnLight(self,light, dist): - if(dist < 12): - light.turnOnFor(300) - def respond(self, responseInfo): - print 'PixelEvent', responseInfo - location = responseInfo[Util.location] - if not 'PixelEvent' in responseInfo: - if 'Color' in responseInfo: - color = responseInfo['Color'] - else: - raise Exception('Need Color. Probably') - responseInfo['PixelEvent'] = StepEvent.generate(300, color) - (dist, light) = self.getLightNearest(location) - light.processInput(responseInfo['PixelEvent'], 0) #TODO: z-index - - def getLightNearest(self, location): - dists = [(Util.dist(location, light.location), light) for light in self.lights] - dists.sort() - return dists[0] - #just for now. - diff --git a/LightSystem.py b/LightSystem.py deleted file mode 100644 index e00c4c0..0000000 --- a/LightSystem.py +++ /dev/null @@ -1,30 +0,0 @@ -from Light import Light -from LightStrip import LightStrip -import itertools -class Screen: - def __init__(self): - self.responseQueue = [] - self.lightStrips = [] - def addStrip(self, lS): - self.lightStrips.append(lS) - def render(self, surface): - [lS.render(surface) for lS in self.lightStrips] - def allOn(self): - [lS.allOn(-1) for lS in self.lightStrips] - #increment time -- This processes all queued responses. Responses generated - #during this period are added to the queue that will be processed on the next - #time step. - def __iter__(self): #the iterator of all our light strips chained togther - return itertools.chain(*[strip.__iter__() for strip in self.lightStrips]) - def timeStep(self): - tempQueue = list(self.responseQueue) - self.responseQueue = [] - for response in tempQueue: - self.processResponse(response) - def respond(self, responseInfo): - print responseInfo - self.responseQueue.append(responseInfo) - def processResponse(self, responseInfo): #we need to make a new dict for - #each to prevent interference - [strip.respond(dict(responseInfo)) for strip in self.lightStrips] - @@ -1,35 +1,35 @@ import Util import pdb from StepEvent import StepEvent -#Light keeps a cue of events (LightEvent objects). Every time is state is +#Pixel keeps a queue of events (PixelEvent objects) (actually a dictionary +#keyed by event time). Every time is state is #requested, it processes all the members of its cue. If a member returns none, -#it is removed from the queue. Otherwise, its value added to the lights color +#it is removed from the queue. Otherwise, its value added to the Pixels color #weighted by z-index. -class Light: +class Pixel: radius = 2 - lightOn = False timeOff = -1 def __init__(self, location, color): self.location = location self.color = color self.events = {} def turnOn(self): - self.lightOn = True + self.turnOnFor(-1) def turnOnFor(self, time): event = StepEvent.generate(time, (255,0,255)) #TODO: Move color to self.processInput(event, 0) #arg - def processInput(self,lightEvent,zindex): #consider migrating arg to dict - self.events[Util.time()] = (zindex, lightEvent) - def turnOff(self): - self.lightOn = False - def lightState(self): + def processInput(self,pixelEvent,zindex): #consider migrating arg to dict + self.events[Util.time()] = (zindex, pixelEvent) + def clearAllEvents(self): + self.events = {} + def state(self): deadEvents = [] currentTime = Util.time() resultingColor = (0,0,0) for eventTime in self.events: #TODO: right color weighting code (zindex,event) = self.events[eventTime] - eventResult = event.lightState(currentTime-eventTime) + eventResult = event.state(currentTime-eventTime) if eventResult != None: resultingColor = Util.combineColors(eventResult, resultingColor) print resultingColor @@ -39,13 +39,6 @@ class Light: if sum(resultingColor) > 0: print resultingColor return tuple(resultingColor) - def isLightOn(self): - if self.timeOff == -1: - return self.lightOn - else: - return Util.time() < self.timeOff - def flip(self): - self.lightOn = not self.lightOn def __str__(self): return 'Loc: ' + str(self.location) diff --git a/PixelEvent.py b/PixelEvent.py index 2c3fa66..a932e23 100644 --- a/PixelEvent.py +++ b/PixelEvent.py @@ -8,6 +8,6 @@ class PixelEvent(SmootCoreObject): self.initEvent() def initEvent(self): pass - def lightState(self,timeDelay): + def state(self,timeDelay): pass diff --git a/PixelStrip.py b/PixelStrip.py index 7314e42..7be9528 100644 --- a/PixelStrip.py +++ b/PixelStrip.py @@ -1,27 +1,25 @@ -from Light import Light +from Pixel import Pixel from StepEvent import StepEvent import pygame import math import Util import pdb -#Python class representing a single light strip (usually 50 lights) +#Python class representing a single Pixel strip (usually 50 Pixels) class PixelStrip: def __init__(self, layoutEngine): self.initStrip(layoutEngine) self.argDict = layoutEngine.getStripArgs() def initStrip(self, layoutEngine): - lightLocations = layoutEngine.getLightLocations() - self.lights = [Light(l, (0,0,0)) for l in lightLocations] + pixelLocations = layoutEngine.getPixelLocations() + self.pixels = [Pixel(l, (0,0,0)) for l in pixelLocations] def __iter__(self): - return self.lights.__iter__() + return self.pixels.__iter__() def render(self, surface): - [l.render(surface) for l in self.lights] + [l.render(surface) for l in self.pixels] #step def allOn(self, time): - [l.turnOnFor(time) for l in self.lights] - def turnOnLight(self,light, dist): - if(dist < 12): - light.turnOnFor(300) + [l.turnOnFor(time) for l in self.pixels] #TODO: add test-on method to + #pixels def respond(self, responseInfo): print 'PixelEvent', responseInfo location = responseInfo[Util.location] @@ -31,11 +29,11 @@ class PixelStrip: else: raise Exception('Need Color. Probably') responseInfo['PixelEvent'] = StepEvent.generate(300, color) - (dist, light) = self.getLightNearest(location) - light.processInput(responseInfo['PixelEvent'], 0) #TODO: z-index + (dist, pixel) = self.getPixelNearest(location) + pixel.processInput(responseInfo['PixelEvent'], 0) #TODO: z-index - def getLightNearest(self, location): - dists = [(Util.dist(location, light.location), light) for light in self.lights] + def getPixelNearest(self, location): + dists = [(Util.dist(location, pixel.location), pixel) for pixel in self.pixels] dists.sort() return dists[0] #just for now. diff --git a/PygameRenderer.py b/PygameRenderer.py index fb157a4..81740c7 100644 --- a/PygameRenderer.py +++ b/PygameRenderer.py @@ -13,7 +13,7 @@ class PygameRenderer(Renderer): self.background.fill(Color('Black')) #print 'drawing color:',light.color for light in lightSystem: - pygame.draw.circle(self.background, light.lightState(), light.location, \ + pygame.draw.circle(self.background, light.state(), light.location, \ light.radius) self.screen.blit(self.background, (0,0)) @@ -1,4 +1,4 @@ -from Light import Light +from Pixel import Pixel from PixelStrip import PixelStrip import itertools class Screen: @@ -11,7 +11,7 @@ class Screen: [lS.render(surface) for lS in self.pixelStrips] def allOn(self): [lS.allOn(-1) for lS in self.pixelStrips] - def __iter__(self): #the iterator of all our light strips chained togther + def __iter__(self): #the iterator of all our pixel strips chained togther return itertools.chain(*[strip.__iter__() for strip in self.pixelStrips]) #increment time -- This processes all queued responses. Responses generated #during this period are added to the queue that will be processed on the next diff --git a/StepEvent.py b/StepEvent.py index e28f0b7..aca933b 100644 --- a/StepEvent.py +++ b/StepEvent.py @@ -2,7 +2,7 @@ from PixelEvent import PixelEvent class StepEvent(PixelEvent): def initEvent(self): self.validateArgs('StepEvent.params') - def lightState(self,timeDelay): + def state(self,timeDelay): if timeDelay < self['LightTime'] or self['LightTime'] == -1: return self['Color'] else: @@ -61,7 +61,7 @@ def getConnectedSocket(ip,port): def composePixelStripData(pixelStrip): packet = bytearray() for light in pixelStrip: - color = light.lightState() + color = light.state() for channel in color: #skip the last value, its an #alpha value packet.append(struct.pack('B', channel)) diff --git a/gfxdemo.py b/gfxdemo.py deleted file mode 100644 index 7e242ae..0000000 --- a/gfxdemo.py +++ /dev/null @@ -1,82 +0,0 @@ -import os, sys, random, Util -import pygame -import math -from Light import Light -from LightStrip import LightStrip -from LightSystem import LightSystem -from pygame.locals import * -spacing = 4 -vspacing = 12 -def dist(l1, l2): - return math.sqrt(sum([(l1[i]-l2[i])**2 for i in range(len(l1))])) -def colorAdd(c1, c2): - if(c1 == None): - return c2 - if(c2 == None): - return c1 - c = [min(c1[i]+c2[i], 255) for i in range(4)] - return Color(*c) -pygame.color.add = colorAdd -class BouncyLightSystem(LightSystem): - def respond(self, responseInfo): - location = responseInfo['location'] - data = responseInfo['data'] - if(location[0] < 0): - data = 'right' - if(location[0] > self.length): - data = 'left' - if(data == None): - data = 'right' - if data == 'right': - change = 20 - else: - change = -20 - responseInfo['location'] = (location[0]+change, location[1]) - responseInfo['data'] = data - LightSystem.respond(self,responseInfo) -class BouncyLightSystemMultiple(BouncyLightSystem): - def respondToInput(self, inputDict): - if sum(inputDict['mouse']) % 2 == 0: - color = Color('Blue') - else: - color = Color('Red') - LightSystem.respond(self, {'location':inputDict['mouse'],'data': 'right', - 'color': color}) -class DyingLightSystem(LightSystem): - def respond(self, inputDict): - if 'responsesLeft' in inputDict: - inputDict['responsesLeft'] -= 1 - -class ExplodeLightSystem(LightSystem): - def respond(self, location, data): - if data['responsesLeft'] != 0: - data['responsesLeft'] -= 1 - for i in range(data['responsesLeft']): - LightSystem.respond(self, (location[0]+random.randint(-50,50), - location[1]+random.randint(-5,5)), dict(data)) - def respondToInput(self, inputDict): - LightSystem.respond(self, inputDict['mouse'], {'responsesLeft':5}) -pygame.init() -screen = pygame.display.set_mode((1300,50)) -background = pygame.Surface(screen.get_size()) -background = background.convert() -background.fill(Color('Black')) -clock = pygame.time.Clock() -l = BouncyLightSystemMultiple(1300, 50) -#l.respond((0, 25), None) -#l.allOn() -while 1: - for event in pygame.event.get(): - if event.type is MOUSEBUTTONDOWN: - l.respondToInput({'mouse': pygame.mouse.get_pos()}) - clock.tick(10) - background.fill(Color('Black')) - l.render(background) - - screen.blit(background, (0,0)) - pygame.display.flip() - l.timeStep() - - - - |