def forceTexture(self, quality):
     if (quality < 0 or quality >= len(self.textures)):
         printOut("Warning, trying to set invalid quality: %s" % quality, 0)
         return
     self.model.setTexture(self.textures[quality], 1)
     self.currentQ = quality
     return
    def onBrowserEvent(self, eventType, eventName, trackerInfo):
        """ this method will be called in one of the Panda3d threads, in which is "safe"
            to call tobii sdk functions.
            trackerInfo is of EyetrackerInfo class """

        # testing some properties, not necesary during normal usage.
        properties = [
            'product_id', 'given_name', 'model', 'generation',
            'firmware_version', 'status', 'factory_info'
        ]
        printOut("Eye tracker event", 0, 'eyetracker')
        for p in properties:
            _p = getattr(trackerInfo, p, None)
            printOut("%s: %s" % (p, str(_p)), 0, 'eyetracker')

        # Tobii SDK
        # if we found an eye-tracker, connect straight away to it.
        if (not self.simul):
            tobii.sdk.eyetracker.Eyetracker.create_async(
                self.mainLoopThread, trackerInfo,
                lambda error, eyetracker: taskMgr.doMethodLater(
                    self.onEyeTrackerCreated,
                    "onEyeTrackerCreated",
                    extraArgs=[error, eyetracker, trackerInfo]))
        else:
            # dummy call for testing
            self.onEyeTrackerCreated(None, 'tracker', 'trackerInfo')
Exemple #3
0
    def __init__(self, **kwargs):
        """
        Class constructor
        """
        # build basic element  
        super(ImageRating,self).__init__(**kwargs)

        return
        sx, sz = getattr(self.config,'tuple_scale',[1.0,1.0])
        self.imageNodes=[]
        self.hiddenNodes=[]

        tempNodes=[]

        # pick a random image to start
        self.current = random.randint(0, len(self.imageNodes))
        # load images for the test
        try:
            for arg in self.config.tuple_imageStrArgs:
                finalName = getattr(self.config,"file imageNameStr") % arg
                tempNodes.append(OnscreenImage(image=finalName,
                                               scale=Vec3(sx, 1.0, sz)))
                tempNodes[-1].setTransparency(TransparencyAttrib.MAlpha)
                tempNodes[-1].hide()
                tempNodes[-1].setName(finalName)
                tempNodes[-1].reparentTo(self.hudNP)

            self.imageNodes = zip(tempNodes, self.config.tuple_imageAnswers)

        except Exception,e:
            printOut("Fatal error, could not load texture file",0)
            printOut(str(e), 0)
            self.config.world.quit()
 def onEyeTrackerCreated(self, error, tracker, trackerInfo):
     if error:
         printOut(
             " Connection to %s failed because of an exception: %s" %
             (eyetracker_info, error), 2)
         return False
     self.tracker = tracker
     return True
 def unregKey(self, key):
     try:
         del(self.data[key])
         self._keysOrder.remove(key)
         self.msn.ignore(key)
         return True
     except Exception, e:
         printOut("Error unregistering key %s" % key, 0)
         print e
         return False
    def setupGUI(self):
        """ Builds the GUI based on the YAML description """
        # read title or set to a default value
        settings = getattr(self.config, "settings", None)
        if settings is None:
            printOut("Missing settings attribute for UserQuestionnaire", 1)
            self.world.quit()

        if getattr(self.config, "questions", None) is None:
            printOut("No questions set, add them to the config file", 1)
            self.world.quit()

        # background colour
        colour = getattr(self.config.settings, "background", [0.2,0.2,0.2,1])

        frameSize = (-self.config.world.camera.ratio,
                     self.config.world.camera.ratio,
                      -1.0,  1.0)

        # DirectFrame that will contain the GUI
        self.myFrame = DirectFrame(parent=self.hudNP,
                                   frameColor=colour,
                                   frameSize=frameSize,
                                   pos=(0,0,0))

        title = getattr(self.config.settings, "title", "Please answer the following questions:")
        self.label = OnscreenText(text = title,
                             pos = (0,0.9), #frameSize[3] - scale*1.5 ),
                             scale = 0.07, #scale * 1.5,
                             fg=(1.0,1.0,1.0,1.0),  #labelColour,
                             align = TextNode.ACenter, mayChange = 1)

        self.label.reparentTo(self.myFrame)

        self.questionNode = OnscreenText(text="question here!",
                             pos = (-1,0.5), #frameSize[3] - scale*1.5 ),
                             scale = 0.07, #scale * 1.5,
                             fg=(1.0,1.0,1.0,1.0),  #labelColour,
                             wordwrap = 30,
                             align = TextNode.ALeft, mayChange = 1)

        self.questionNode.reparentTo(self.myFrame)

        self.answerNode = NodePath("answerNP")
        self.answerNode.reparentTo(self.myFrame)


        self.answersGuiNodes = {}

        self.questionsText = {}

        for q in self.config.questions:
            self.setupQuestions(q)
        self.currQuestion = 0
        self.setupButtons()
    def exitState(self):
        # print "leaving state FullScreenImage"
        if (self.i_count):
            self.i_count -= 1
            print self.i_count
            if (self.i_count == 0):
                printOut("Sending event 'NoMoreImages' from exitState of %s"
                    % self.config.name, 2)
                messenger.send('NoMoreImages',['NoMoreImages'])

        Element.exitState(self)
        self.unregisterKeys()
    def __init__(self, **kwargs):
        """
        Class constructor
        """
        # build basic element
        super(DataForm, self).__init__(**kwargs)
        printOut("Element for DataForm constructed", 1)
        # the config is loaded by Element automatically into self.config
        self.setupGUI()
        printOut("DataForm GUI constructed", 1)

        # in this dictionary we will keep the inputs from the form.
        self.userInput = {}
 def removeCalibPoint(self, point):
     printOut("Removing calibration point %d,%d" % (point[0], point[1]), 0)
     if (not self.simul):
         p = Point2D()
         p.x, p.y = point[0], point[1]
         self.tracker.RemoveCalibrationPoint(
             p, lambda error, r: taskMgr.doMethodLater(
                 self.onCalPointRemoved,
                 "calPointRemoved",
                 extraArgs=[error, r, p]))
     # testing purposes
     else:
         self.onCalPointRemoved(None, 'r', p)
     return False
    def registerKey(self, key, registrant, callback,
                    comment="", once=False,  arguments=[], display=True):
        """ registers a key with the messenger, to call a callback with
        arguments when something happens,
        it also remembers the order in which keys has been added, and if display is True
        it will show the key when the help is shown (using key h)"""
        try:
            if key in self.data:
                printOut("Key %s from: '%s', has been already registered" %
                         (key, registrant), 0)
                printOut("The key is registered under: %s" % str(self.data[key]), 0)
                printOut("Change your binding, ignoring for now")
                return False

            if once:
                self.msn.acceptOnce(key, callback, arguments)
            else:
                self.msn.accept(key, callback, arguments)

            self.data[key] = (registrant, callback, comment, display)
            self._keysOrder.append(key)
            printOut("Registering key: %s to callback %s for %s" %
                     (key, str(callback), registrant) + "with args:" + str(arguments), 2)
            return True
        except Exception, e:
            print e
            return False
    def finishedPreFall(self):
        # dissapear!
        printOut(
            "Node position: %f,%f,%f" %
            (self.node.getX(), self.node.getY(), self.node.getZ()), 0)
        printOut("Node scale: %f" % (self.node.getScale()[0]), 0)
        fadeOut = LerpFunctionInterval(self.node.setAlphaScale,
                                       toData=0.0,
                                       fromData=1.0,
                                       duration=1.0)
        fadeOut.start()

        self.fallInterval2 = self.genFallDownInterval(2.0,
                                                      self.groundHeight - 5)
        self.fallInterval2.setDoneEvent("lastBitFall_" + self.name)
        self.acceptOnce("lastBitFall_" + self.name, self.lastBitFall)
        self.fallInterval2.start()
        self.swingSeq.pause()
    def __init__(self, **kwargs):
        """
        Class constructor
        """
        # call Element constructor with configuration arguments
        super(UserQuestionnaire, self).__init__(**kwargs)
        printOut("Element for User Questionnaire constructed", 1)

        # build UI
        self.setupGUI()

        # create a simple service that can be queried in different ways,
        # pass (serverName, serviceName, callback)
        # TODO
        # self.createService('userdata0','UserData', self.getUserData)
        # printOut("Service userdata0 for dataform created",1)

        # in this dictionary we will keep the inputs from the form.
        self.answers = {}
    def setupGUI(self):
        """ Builds the GUI based on the JSON description """
        # stores the GUI labels
        self.guiLabels = []
        # stores ALL the widgets in order of focus (even if they cannot get focus)
        self.focusOrder = []
        # DirectFrame that will contain the GUI
        self.myFrame = None

        # frame to hold the form (left, right, bottom, top)
        # Find out window dimensions
        ratio = self.config.world.camera.ratio
        frameSize = (-ratio, ratio, -1.0, 1.0)
        # centered
        pos = (0, 1.0, 0)
        # background colour
        try:
            colour = self.config.color_background
        except:
            colour = self.colours['dark_grey']

        # guiLabels colour
        labelColour = getattr(self.config.settings, 'color_label',
                              (1.0, 1.0, 1.0, 1.0))
        # global scale of the frame
        scale = self.config.settings.scale
        # canvas with scrolling capabilities
        self.myFrame = DirectScrolledFrame(
            canvasSize=(frameSize[0], frameSize[1], 50 * frameSize[2],
                        frameSize[3]),
            frameColor=colour,
            frameSize=frameSize,
            pos=pos)
        # reparent the frame to the hudNP so we can hide it easily
        self.myFrame.reparentTo(self.hudNP)

        # read title or set to a default value
        title = getattr(self.config.settings, "title", "Introduce your data")

        # title of the frame
        label = OnscreenText(text=title,
                             pos=(0, frameSize[3] - scale * 2.5),
                             scale=scale * 1.5,
                             fg=labelColour,
                             align=TextNode.ACenter,
                             mayChange=1)
        label.reparentTo(self.myFrame.getCanvas())

        # max length in characters of a label (will split in lines if bigger)
        maxLabel = self.config.settings.maxlabel
        maxwidth = 0
        # position of the first label and widget
        lastYpos = frameSize[3] - scale * 4

        for count, i in enumerate(self.config.input):

            # create label in several lines up to 15 chars
            # split the string in several lines up to 15 chars
            printOut("Creating element: %s" % i.label, 2)
            splitWords = splitString(str(i.label) + ':', maxLabel)
            for s in splitWords:
                lastYpos -= 1.1 * scale
                label2 = OnscreenText(text=s,
                                      pos=(0, lastYpos),
                                      scale=scale,
                                      fg=labelColour,
                                      align=TextNode.ARight,
                                      mayChange=1)
                bounds = label2.getTightBounds()
                width = abs(bounds[0][0] - bounds[1][1])
                if (width > maxwidth): maxwidth = width
                label2.reparentTo(self.myFrame.getCanvas())
                self.guiLabels.append(label2)

            # for each label, create a widget matching the YAML
            widgetYpos = lastYpos
            if (str(i.type) == 'TextEntry'):
                widget = DirectEntry(text="",
                                     scale=scale,
                                     cursorKeys=1,
                                     command=self.setText,
                                     extraArgs=[],
                                     pos=(0.05, 1, widgetYpos),
                                     numLines=1,
                                     focus=0)
            elif (str(i.type) == 'Option'):
                widget = DirectOptionMenu(text="options",
                                          scale=1.05 * scale,
                                          items=i.tuple_values,
                                          popupMarkerBorder=(1, 0),
                                          initialitem=0,
                                          command=self.optionMenu,
                                          extraArgs=[],
                                          pos=(0.05, 1, widgetYpos),
                                          text_scale=(0.7, 0.7),
                                          text_pos=(0.3, 0.1))

            elif (str(i.type) == 'TickBox'):
                widget = DirectCheckButton(text="",
                                           scale=scale,
                                           command=self.tickBoxClicked,
                                           extraArgs=[],
                                           pos=(scale + 0.04, 1,
                                                widgetYpos + scale / 3.0))
                widget.clicked = getattr(i, 'default', False)

            # order of creation
            widget['extraArgs'] = [widget]
            self.focusOrder.append(widget)
            widget.reparentTo(self.myFrame.getCanvas())
            # distance to next widget
            lastYpos -= scale

        # adjust X position based on the largest word
        for l in self.guiLabels:
            #adjust X position
            l.setX(frameSize[0] + maxwidth + 0.05)
        for w in self.focusOrder:
            w.setX(w['pos'][0] + frameSize[0] + maxwidth + 0.10)

        # add a button to save the values and advance from the FORM (exit this state)
        lastYpos -= 2 * scale
        pad0 = (0.9, 0.7)
        #self.saveButton = DirectButton( parent = self.myFrame,
        #                            text="Save", pad=pad0, scale=0.05,
        #                            pos=(frameSize[1] - 10*0.05, 0, lastYpos), command=self.savePressed
        #                            )
        #self.finishButton = DirectButton ( parent = self.myFrame,
        #        text="Finish", pad=pad0, scale=0.05,
        #        pos=(frameSize[1] - 5*0.05,0,lastYpos), command=self.finishPressed
        #        )
        #self.finishButton["state"] = DGG.DISABLED
        #self.clearButton = DirectButton ( parent = self.myFrame,
        #        text="Clear", pad=pad0, scale=0.05,
        #        pos=(frameSize[1] - 15*0.05,0,lastYpos), command=self.clearButton
        #        )
        self.nextButton = DirectButton(parent=self.myFrame,
                                       text="Next",
                                       pad=pad0,
                                       scale=0.05,
                                       pos=(frameSize[1] - 10 * 0.05, 0, -0.9),
                                       command=self.nextPressed)
        # resize canvas to fit in height
        self.myFrame['canvasSize'] = (frameSize[0], frameSize[1], lastYpos,
                                      frameSize[3])
    def saveInputs(self):
        """
        Saves all the information from the form. If the JSON describing the
        form specifies datatypes for the inputs, then a conversion is performed,
        otherwise the value is saved a string. TickBox is always boolean.
        """
        # Internal comment:
        # self.config.input has the same order as self.guiLabels and self.focusOrder
        # self.focusOrder is a list with each widget (with or without focus!)
        # Use datatype specified in the JSON to convert the values, if no datatype
        # is specified, assume string

        for i, w in zip(self.config.input, self.focusOrder):
            datatypes = ('int', 'float', 'str', 'bool')

            if (i.type == 'TickBox'):
                # my custom attribute, added in the event handler!
                self.userInput[i.label] = w.clicked
            else:
                """TextEntry or Option"""
                if (i.type == "TextEntry"):
                    value = w.get(plain=True)
                else:
                    value = w.get()
                try:
                    t = i.datatype
                    if (t in datatypes):
                        evaluate = "%s(%s)" % (t, value)
                        printOut("Evaluating expresion: %s" % evaluate, 1)
                        value = eval(evaluate)
                except AttributeError:
                    printOut(
                        "No datatype defined for %s, assuming string" %
                        i.label, 1)
                except:
                    printOut("Invalid conversion from String to %s" % (t), 1)
                    pass
                self.userInput[i.label] = value

        # open file to save user input
        s = self.config.settings
        filename = "%s/%s_%s.txt" % (s.outfiledir, s.outfileprefix,
                                     self.config.world.participantId)
        try:
            # write comma separated values
            out = open(filename, 'w')
            # header
            out.write("# participant id, ")
            for (k, v) in self.userInput.items():
                out.write("%s," % k)
            out.write("\n")
            # values
            out.write("%s," % self.config.world.participantId)
            for (k, v) in self.userInput.items():
                out.write("%s," % v)

            out.close()
        except Exception, e:
            printOut(str(e), 0)
            printOut(
                "Fatal error trying to generate file with user information.",
                0)
            self.config.world.quit()
Exemple #15
0
    def __init__(self, world = None, name = "",
                 textureName = None, conf = None, collisions=True):
        # grab a reference to the class!, to use
        # class attributes, this is python :|
        cls = self.__class__

        if (world is None or textureName is None or
            conf is None):
            printOut("Bad call to create parachutes",0)
            sys.quit()

        self.name = name
        self.game = world
        self.posGen = world.posGen
        self.speed = conf.speed
        self.changeStep = conf.blendtype.blendfunction
        self.collisions = collisions

        self.forced = False
        self.falling = False
        # self.textures = {}
        # load textures for this model, unless it was loaded
        # before. All textures go to a class attribute.

        if (textureName not in cls.texDict):
            t = loader.loadTexture(textureName)
            t.setWrapU(Texture.WMClamp)
            t.setWrapV(Texture.WMClamp)
            t.setMinfilter(Texture.FTLinearMipmapLinear)
            t.setAnisotropicDegree(2)
            #self.textures[int(tex.level)] = t
            self.texture = t
            cls.texDict[textureName] = t
        else:
            self.texture = cls.texDict[textureName]
            #self.textures[int(tex.level)] = cls.texDict[tex.name]
        # when set to True, it will change it's resolution
        # depending on delay, immediately or after it gets
        # a new position.
        #self.delayLodChange  = True
        #self.lowerResolution = False
        #self.nextLod = 0

        self.isTarget = False

        # this is used when we don't wont bullets to hit him
        self.ignoreHit = False
        self.currentQ = 0

        # empty nodepath
        self.modelNP = NodePath("parachute_" + name)
        self.modelNP.setTransparency(1)

        # particle node to hold the particle system later.
        # self.particleNode = NodePath("dust_"+name)
        # self.particleNode.reparentTo(self.modelNP)

        # manual adjustments...
        # self.modelNP.setScale(self.game.rescaleFactor)

        # put the model anywhere hidden from the camera!!!
        self.modelNP.setPos(Vec3(-1000, 40, 0))

        # parachuteTex is a class attribute!
        if cls.parachuteTex is None:
            cls.parachuteTex = loader.loadTexture("PilotData/models/textures/para_tex.png")
            cls.parachuteTex.setMinfilter(Texture.FTLinearMipmapLinear)
            cls.parachuteTex.setAnisotropicDegree(2)

        self.paraModel = loader.loadModel("PilotData/models/para02.egg")
        self.paraModel.setScale(Vec3(0.3, 0.2, 0.2))
        self.paraModel.setPos(Vec3(0, 0.15, 1.2))

        # generate automatically UV coordinates:
        #self.paraModel.setTexGen(TextureStage.getDefault(), TexGenAttrib.MWorldPosition)
        #self.paraModel.setTexProjector(TextureStage.getDefault(), render, self.paraModel)

        # assign texture
        self.paraModel.setTexture(cls.parachuteTex)
        self.paraModel.reparentTo(self.modelNP)

        # parachute is a billboard
        self.model = loader.loadModel("Elements/Game/models/plane")
        # pos actual model below the modelNP
        # away from the view until it gets a random position.
        self.model.setPos(Vec3(0, 0, -0.5))
        #self.model.setBillboardAxis()
        self.model.setTransparency(1)
        # set texture with maximum quality.
        #self.model.setTexture(self.textures[self.currentQ], 1)
        self.model.setTexture(self.texture, 1)

        #self.game.replayLog.logEvent("Q:[\'"+self.config.name+"\',"+str(self.currentQ)+"]\n", 0.0)
        self.model.reparentTo(self.modelNP)

        if self.collisions:
            # add collision sphere to modelNP
            colSolid = CollisionSphere(0, 0, 0, 0.5)
            colNP = self.modelNP.attachNewNode(CollisionNode(self.name))
            colNP.setPos(0, 0 ,-0.5)
            colNP.setCollideMask(BitMask32(0x80))
            colNP.node().addSolid(colSolid)

            # react to event of collision events
            self.accept('hit-'+self.name, self.hit)
 def onCalibrationComputed(self, error, r):
     if error == 0x20000502:
         printOut("Error on calibration, not enough data: %s" % error, 0)
     else:
         printOut("Calibration done!", 0)
    def newPos(self, d=0, x=0, y=0, z=0, forced=False):
        self.forced = forced

        # check if need to lower the texture
        if (not self.forced and self.lowerResolution):
            self.setTexture(self.nextLod, 1)

        # swipe time
        self.node.show()
        self.time = 2.0
        self.maxangle = 30.0
        self.groundHeight = -35

        pos = Vec3(x, y, z)

        self.node.setPos(pos)
        self.maxHeight = self.node.getZ()

        swing0 = LerpFunc(self.swingTheThing,
                          fromData=0.0,
                          toData=1.0,
                          duration=self.time,
                          blendType='easeInOut',
                          name="right_" + self.name)
        swing1 = LerpFunc(self.swingTheThing,
                          fromData=1.0,
                          toData=0.0,
                          duration=self.time,
                          blendType='easeInOut',
                          name="left_" + self.name)
        self.swingSeq = Sequence(swing0, swing1)
        self.swingSeq.loop()
        if (not self.forced):
            self.swingSeq.setT(uniform(0, 1))

        # set fall time, interval and callback after fall
        adjustedDuration = (z - self.groundHeight) / self.speed
        printOut("Adjusted Duration of speed: %f" % adjustedDuration, 0)
        self.fallInterval = self.genFallDownInterval(adjustedDuration,
                                                     self.groundHeight)

        self.fallInterval.setDoneEvent("finishedPreFall_" + self.name)

        self.acceptOnce("finishedPreFall_" + self.name, self.finishedPreFall)

        # rotation setup, creates a simple swing, and then a callback to keep
        # swinging
        #try:
        #    self.rotation.finish()
        #except(AttributeError):
        #    pass

        # all this crap is to have a random rotation position
        angle = uniform(0, self.maxangle) - self.maxangle / 2.0
        self.node.setHpr(Vec3(0, 0, angle))
        #self.rot0 = LerpHprInterval(self.modelNP,
        #                           self.time - self.time *
        #                           abs((2 * angle) / self.maxangle),
        #                           Vec3(0, 0, self.maxangle / 2),
        #                           blendType='easeOut')
        #self.rot0.setDoneEvent("swing_" + self.config.name)
        #self.acceptOnce("swing_" + self.config.name, self.swing)

        # adjusts a bit the parachute so it looks exactly behind the robot when
        # the parachute is in one of either sides.
        paraModel = self.node.find("parachute")
        #paraModel.setX(self.node.getX() * 0.001)
        return 1
 def getTextKey(self, key):
     """for a given key, returns the comment that explains what it does"""
     printOut("getTextKey with %s" % key, 3)
     # keys are stored in a tuple like:  (registrant, callback, comment, display)
     return "Key %s: %s" % (key, self.data[key][2])