Example #1
0
 def on_mouse_press(self, mouse):
     x0, y0 = self.absolute_position()  # Can be nested in other layers.
     step = 1.0 / max(self.steps, 1)
     # Calculate relative value from the slider handle position.
     # The inner width is a bit smaller to accomodate for the slider handle.
     # Clamp the relative value to the nearest step.
     self._t = (mouse.x - x0 - self.height * 0.5) / float(self.width - self.height)
     self._t = self._t - self._t % step + step
     self._t = clamp(self._t, 0.0, 1.0)
     self.on_action()
Example #2
0
 def on_mouse_press(self, mouse):
     x0, y0 = self.absolute_position() # Can be nested in other layers.
     step = 1.0 / max(self.steps, 1)
     # Calculate relative value from the slider handle position.
     # The inner width is a bit smaller to accomodate for the slider handle.
     # Clamp the relative value to the nearest step.
     self._t = (mouse.x-x0-self.height*0.5) / float(self.width-self.height)
     self._t = self._t - self._t % step + step 
     self._t = clamp(self._t, 0.0, 1.0)
     self.on_action()
Example #3
0
 def _set_value(self, value):
     self._t = clamp(float(value - self.min) / (self.max - self.min or -1), 0.0, 1.0)
Example #4
0
def draw(canvas):
    global headset
    global dimmer
    global images
    global samples
    global particles
    global attractor
    global ZOOM, ATTRACT, SPAWN, DIM, delay
    global MUTE
    
    glEnable(GL_DITHER)
    
    background(0)
    #image(abspath("g","bg.png"), 0, 0, width=canvas.width, height=canvas.height)
    image(abspath("g","bg-light.png"), 0, 0, width=canvas.width, height=canvas.height, alpha=0.9)
    
    if canvas.key.code == SPACE:
        MUTE = not MUTE

    # Poll the headset.
    # Is alpha above average? => attraction.
    # Is valence above average? => spawn feelies.
    headset.update(buffer=1024)
    ATTRACT = False
    ATTRACT = delay > 0
    ATTRACT = ATTRACT or SHIFT in canvas.key.modifiers
    if canvas.key.code == SHIFT:
        ATTRACT = True
    if len(headset.alpha[0]) > 0 and headset.alpha[0][-1][0] > headset.alpha[0][-1][1] * 1.0:
        ATTRACT = True
        delay = 10 # Delay before repulsing to counter small alpha fluctuation.
    elif delay > 0:
        delay -= 1
    SPAWN = False
    SPAWN = CTRL in canvas.key.modifiers
    if canvas.key.code == CTRL:
        SPAWN = True
    if len(headset.valence) > 0 and headset.valence[-1][0] > headset.valence[-1][1]:
        SPAWN = True
    
    # In mute mode, ignore triggering alpha and valence.
    if MUTE:
        ATTRACT = SPAWN = False
        delay = 0
    
    # Dimmer sends a value over UDP that drops to 0 when relaxed.
    # It can be used to dim ambient lighting using a domotica module.
    m = 0.0025
    if ATTRACT:
        DIM = clamp(DIM-m, 0.0, 1.0)
    else:
        DIM = clamp(DIM+m, 0.0, 1.0)
    if DIM < 0.8 and dimmer is not None:
        dimmer.send("%.2f" % (DIM * 100))
    
    # Valence controls the balance between high and low ambient.
    v = headset.valence.slope # -1.0 => +1.0
    v = 0.0
    dx = 1.0 - v
    dy = 1.0 + v
    # Mouse changes the volume of low and high ambient sound.
    #dx = canvas.mouse.relative_x
    #dy = canvas.mouse.relative_y
    samples["ambient_lo"].play(volume=0.7 * dx)
    samples["ambient_hi"].play(volume=0.7 * dy)

    if canvas.key.code == ALT:
        text("%.2f FPS" % canvas.profiler.framerate, canvas.width-80, 15, align=RIGHT, fill=[1,1,1,0.75])

    if canvas.frame / 20 % 2 == 0:
        fill(1,1,1, 0.75)
        fontsize(9)
        if len(headset.alpha[0]) > 0:
            ellipse(canvas.width-18, 19.5, 7, 7, fill=[1,1,1,1])
        if ATTRACT or SPAWN:
            ellipse(15, 19.5, 7, 7, fill=[1,0,0,1])
        if ATTRACT and SPAWN:
            text(" RELAXATION + AROUSAL", 20, 15)
        elif ATTRACT:
            text(" RELAXATION", 20, 15)
        elif SPAWN:
            text(" AROUSAL", 20, 15)
        elif MUTE:
            text(" READY", 20, 15)

    # Zoom out as the attractor grows larger.
    # Integrate the zoom scale to make the transition smoother.
    d = (1.25 - len(attractor.particles) * 0.05)
    if ZOOM > -0.15 and ZOOM > d:
        ZOOM -= 0.0025
    if ZOOM < +1.25 and ZOOM < d:
        ZOOM += 0.0025   
    dx = 0.5 * ZOOM * canvas.width
    dy = 0.5 * ZOOM * canvas.height
    translate(-dx, -dy)
    scale(1.0 + ZOOM)

    for p in list(particles):
        d = distance(p.x, p.y, attractor.x, attractor.y)
        t = d / canvas.width * 2
        p.update()
        # When valence is low, unattached feelie particles fade away.
        if SPAWN is False:
            if p.parent is None and p.type == FEELIE:
                p.alpha -= 0.04
                p.alpha = max(p.alpha, 0)
                if p.alpha == 0:
                    # Remove hidden feelies, so we have a chance to see new ones.
                    particles.remove(p)
        # Check if a particle falls within the attraction radius:
        # If so, attract it when alpha is above average.
        if ATTRACT is True:
            if p.parent is None and p.frames >= 0 and p.alpha >= 0.25:
                if d < min(210, p.radius + attractor.radius * attractor.gravity):
                    attractor.append(p)
                    samples["attract"].play().volume = 0.75
        p.draw(blur=t, alpha=(1-t))
                    
    # Repulse when alpha drops below average.
    # Press mouse to repulse attracted particles.
    if ATTRACT is False:
        if random() > 0.5:
            if len(attractor.particles) > 0:
                attractor.remove(attractor.particles[0])
                samples["repulse"].play()
                
    # When valence is high, feelie particles appear.
    if SPAWN is True: 
        if random() > 0.5:
            if len(particles) < 80:
                p = Particle(x = choice((-30, canvas.width+30)),
                             y = -30,
                         image = choice([images["flower%i.png"%i] for i in range(2,6+1)], bias=0.25),
                        radius = 15 + random(20),
                        bounds = (-65, -65, canvas.width+65, canvas.height+65),
                         speed = 3.5,
                          type = FEELIE)
                if p.image._src[0].endswith("flower3.png"):
                    p.radius = 20 + random(20)
                if p.image._src[0].endswith("flower4.png"):
                    p.radius = 15 + random(10)
                if p.image._src[0].endswith("flower5.png"):
                    p.radius = 15
                if p.image._src[0].endswith("flower6.png"):
                    p.radius = 10 + random(5)
                particles.append(p)

    attractor.update()
    attractor.draw_halo()
    attractor.draw()
Example #5
0
 def _set_value(self, value):
     self._t = clamp(float(value-self.min) / (self.max-self.min or -1), 0.0, 1.0)
Example #6
0
def draw(canvas):
    global headset
    global dimmer
    global images
    global samples
    global particles
    global attractor
    global ZOOM, ATTRACT, SPAWN, DIM, delay
    global MUTE

    glEnable(GL_DITHER)

    background(0)
    #image(abspath("g","bg.png"), 0, 0, width=canvas.width, height=canvas.height)
    image(abspath("g", "bg-light.png"),
          0,
          0,
          width=canvas.width,
          height=canvas.height,
          alpha=0.9)

    if canvas.key.code == SPACE:
        MUTE = not MUTE

    # Poll the headset.
    # Is alpha above average? => attraction.
    # Is valence above average? => spawn feelies.
    headset.update(buffer=1024)
    ATTRACT = False
    ATTRACT = delay > 0
    ATTRACT = ATTRACT or SHIFT in canvas.key.modifiers
    if canvas.key.code == SHIFT:
        ATTRACT = True
    if len(headset.alpha[0]
           ) > 0 and headset.alpha[0][-1][0] > headset.alpha[0][-1][1] * 1.0:
        ATTRACT = True
        delay = 10  # Delay before repulsing to counter small alpha fluctuation.
    elif delay > 0:
        delay -= 1
    SPAWN = False
    SPAWN = CTRL in canvas.key.modifiers
    if canvas.key.code == CTRL:
        SPAWN = True
    if len(headset.valence
           ) > 0 and headset.valence[-1][0] > headset.valence[-1][1]:
        SPAWN = True

    # In mute mode, ignore triggering alpha and valence.
    if MUTE:
        ATTRACT = SPAWN = False
        delay = 0

    # Dimmer sends a value over UDP that drops to 0 when relaxed.
    # It can be used to dim ambient lighting using a domotica module.
    m = 0.0025
    if ATTRACT:
        DIM = clamp(DIM - m, 0.0, 1.0)
    else:
        DIM = clamp(DIM + m, 0.0, 1.0)
    if DIM < 0.8 and dimmer is not None:
        dimmer.send("%.2f" % (DIM * 100))

    # Valence controls the balance between high and low ambient.
    v = headset.valence.slope  # -1.0 => +1.0
    v = 0.0
    dx = 1.0 - v
    dy = 1.0 + v
    # Mouse changes the volume of low and high ambient sound.
    #dx = canvas.mouse.relative_x
    #dy = canvas.mouse.relative_y
    samples["ambient_lo"].play(volume=0.7 * dx)
    samples["ambient_hi"].play(volume=0.7 * dy)

    if canvas.key.code == ALT:
        text("%.2f FPS" % canvas.profiler.framerate,
             canvas.width - 80,
             15,
             align=RIGHT,
             fill=[1, 1, 1, 0.75])

    if canvas.frame / 20 % 2 == 0:
        fill(1, 1, 1, 0.75)
        fontsize(9)
        if len(headset.alpha[0]) > 0:
            ellipse(canvas.width - 18, 19.5, 7, 7, fill=[1, 1, 1, 1])
        if ATTRACT or SPAWN:
            ellipse(15, 19.5, 7, 7, fill=[1, 0, 0, 1])
        if ATTRACT and SPAWN:
            text(" RELAXATION + AROUSAL", 20, 15)
        elif ATTRACT:
            text(" RELAXATION", 20, 15)
        elif SPAWN:
            text(" AROUSAL", 20, 15)
        elif MUTE:
            text(" READY", 20, 15)

    # Zoom out as the attractor grows larger.
    # Integrate the zoom scale to make the transition smoother.
    d = (1.25 - len(attractor.particles) * 0.05)
    if ZOOM > -0.15 and ZOOM > d:
        ZOOM -= 0.0025
    if ZOOM < +1.25 and ZOOM < d:
        ZOOM += 0.0025
    dx = 0.5 * ZOOM * canvas.width
    dy = 0.5 * ZOOM * canvas.height
    translate(-dx, -dy)
    scale(1.0 + ZOOM)

    for p in list(particles):
        d = distance(p.x, p.y, attractor.x, attractor.y)
        t = d / canvas.width * 2
        p.update()
        # When valence is low, unattached feelie particles fade away.
        if SPAWN is False:
            if p.parent is None and p.type == FEELIE:
                p.alpha -= 0.04
                p.alpha = max(p.alpha, 0)
                if p.alpha == 0:
                    # Remove hidden feelies, so we have a chance to see new ones.
                    particles.remove(p)
        # Check if a particle falls within the attraction radius:
        # If so, attract it when alpha is above average.
        if ATTRACT is True:
            if p.parent is None and p.frames >= 0 and p.alpha >= 0.25:
                if d < min(210,
                           p.radius + attractor.radius * attractor.gravity):
                    attractor.append(p)
                    samples["attract"].play().volume = 0.75
        p.draw(blur=t, alpha=(1 - t))

    # Repulse when alpha drops below average.
    # Press mouse to repulse attracted particles.
    if ATTRACT is False:
        if random() > 0.5:
            if len(attractor.particles) > 0:
                attractor.remove(attractor.particles[0])
                samples["repulse"].play()

    # When valence is high, feelie particles appear.
    if SPAWN is True:
        if random() > 0.5:
            if len(particles) < 80:
                p = Particle(
                    x=choice((-30, canvas.width + 30)),
                    y=-30,
                    image=choice(
                        [images["flower%i.png" % i] for i in range(2, 6 + 1)],
                        bias=0.25),
                    radius=15 + random(20),
                    bounds=(-65, -65, canvas.width + 65, canvas.height + 65),
                    speed=3.5,
                    type=FEELIE)
                if p.image._src[0].endswith("flower3.png"):
                    p.radius = 20 + random(20)
                if p.image._src[0].endswith("flower4.png"):
                    p.radius = 15 + random(10)
                if p.image._src[0].endswith("flower5.png"):
                    p.radius = 15
                if p.image._src[0].endswith("flower6.png"):
                    p.radius = 10 + random(5)
                particles.append(p)

    attractor.update()
    attractor.draw_halo()
    attractor.draw()