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')
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()
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])