WorldViz User Forum

WorldViz User Forum (https://forum.worldviz.com/index.php)
-   Vizard (https://forum.worldviz.com/forumdisplay.php?f=17)
-   -   Blindfolding screen, asking for input, unblindfolding. (https://forum.worldviz.com/showthread.php?t=4875)

saajaja 11-12-2013 05:18 PM

Blindfolding screen, asking for input, unblindfolding.
 
Hello, and thank you for reading. Here is what I am trying to do:

1. Turn the screen black.
2. Display a popup dialog which asks for an input.
3. Turn the world back on.

Here is some code that should do that when you press the spacebar:

Code:

import viz
import vizinput
import vizact

piazza = viz.add('piazza.osgb')
viz.go()

def getInput():
        # Blindfold. This isn't working.
        viz.MainScene.visible(0,viz.WORLD)
        viz.clearcolor(viz.SKYBLUE)

        # Ask for input
        input = ''
        while input == '':
                input = vizinput.input('Input something.')

        # Unblindfold
        viz.MainScene.visible(1,viz.WORLD)
        viz.clearcolor(viz.BLACK)
       
vizact.onkeydown(' ', getInput)

However, it does not do that. Instead, it does this:
1. Ask for input.

Help would be greatly appreciated. Thank you for reading.

Frank Verberne 11-13-2013 06:15 AM

Hi Saajaja,

The code below should do what you want. Note that the color of the screen will be skyblue instead of black (as stated in your question). Just change SKYBLUE to BLACK to change that. I think the problem is that the function you used immediately shows the input window, before drawing the scene again. By using the module viztask and schedule, you can make Vizard first draw one frame, and then do something else.

Code:

import viz
import vizinput
import vizact
import viztask

piazza = viz.add('piazza.osgb')
viz.go()

def getInput():
        # Blindfold.
        viz.MainScene.visible(0,viz.WORLD)
        viz.clearcolor(viz.SKYBLUE)
        yield viztask.waitFrame(1)
       
        # Ask for input
        input = ''
        while input == '':
                input = vizinput.input('Input something.')

        # Unblindfold.
        viz.MainScene.visible(1,viz.WORLD)
        viz.clearcolor(viz.BLACK)
        yield viztask.waitFrame(1)

def inputScreen():
        viztask.schedule(getInput)
       
vizact.onkeydown(' ', inputScreen)

Good luck!
Frank

saajaja 11-13-2013 02:44 PM

Thank you, Frank, that works great!

saajaja 11-13-2013 09:31 PM

Dear Frank,

I spoke too soon. Your code helped speed me in the right direction, but it had a semantic bug. Execution would continue before the actual input value was received. So if we wanted to actually do anything with the input string, we would end up doing weird stuff that we didn't want to do.

In order to make the program wait for an actual input to arrive from the user, I did some fancy signal stuff based on your code and the two balls example at the bottom of Task Basics.

Code:

import viz
import vizinput
import viztask

class test:
        def __init__(self):
                piazza = viz.add('piazza.osgb')
               
                self.input = 'initialized value'
                vizact.onkeydown(' ', self.getAndPrintInput)
                self.gotInputSignal = viztask.Signal()
               
                viz.go()

        def getInput(self):
                # Blindfold.
                viz.fogcolor(viz.GRAY)
                viz.fog(.2)
                yield viztask.waitFrame(1)
               
                # Ask for input
                self.input = vizinput.input('Input something.')
                self.gotInputSignal.send()
               
                # Unblindfold.
                viz.fog(0)
                yield viztask.waitFrame(1)
       
        def printInput(self):
                # Wait for an actual input to arrive.
                yield self.gotInputSignal.wait()
                print self.input
       
        def getAndPrintInput(self):
                viztask.schedule( self.getInput() )
                viztask.schedule( self.printInput() )

t = test()

I learned a lot today. Thank you for your support!

Frank Verberne 11-14-2013 04:18 AM

Hi Saajaja,

Seems like you already figured out how to solve your problem. However, a simpler solution seems like to yield a function, where you do something with the input. Everything that is in that function should be executed before showing the world again. Now, I just print the input and wait a few seconds, so you can see that everything in the function is executed before executing the rest of the code.
Code:

import viz
import vizinput
import vizact
import viztask

piazza = viz.add('piazza.osgb')
viz.go()

def printValue(value):
        print value
        viz.waitTime(4)
       
def getInput():
        # Blindfold.
        viz.MainScene.visible(0,viz.WORLD)
        viz.clearcolor(viz.SKYBLUE)
        yield viztask.waitFrame(1)
       
        # Ask for input
        input = ''
        while input == '':
                input = vizinput.input('Input something.')
       
        yield printValue(input)
        # Unblindfold.
        viz.MainScene.visible(1,viz.WORLD)
        viz.clearcolor(viz.BLACK)
        yield viztask.waitFrame(1)

def inputScreen():
        viztask.schedule(getInput)
       
vizact.onkeydown(' ', inputScreen)


saajaja 11-14-2013 08:08 AM

That's much better! Thank you very much, Frank.


All times are GMT -7. The time now is 03:46 PM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Copyright 2002-2023 WorldViz LLC