class MouseLogger(Element): """ Logs the position of the mouse, in a text file using the participant ID and timestamps that are synchronized with the rest of the timestamps from other events in the simulation """ def __init__(self, **kwargs): """ See the Element class to find out what attributes are available from scratch """ super(MouseLogger, self).__init__(**kwargs) self.mouseLog = Logger( self.baseTime, "run/mouseLog_%s.txt" % self.config.world.participantId) self.left = MouseButton.one() self.leftDown = False self.right = MouseButton.two() self.rightDown = False self.hideElement() def enterState(self): # super class enterState Element.enterState(self) #self.mouseLog.startLog() taskMgr.add(self.logMouseTask, "mouseLogTask_%s" % self.config.world.participantId) def exitState(self): # super class exitState taskMgr.remove("mouseLogTask_%s" % self.config.world.participantId) self.mouseLog.stopLog() Element.exitState(self) def logMouseTask(self, t): m = base.mouseWatcherNode if not m.hasMouse(): return t.cont try: self.mouseLog.logEvent("%f %f" % (m.getMouseX(), m.getMouseY())) if m.is_button_down(self.left): self.leftDown = True elif self.leftDown: self.mouseLog.logEvent("mouse1") self.leftDown = False if m.is_button_down(self.right): self.rightDown = True elif self.rightDown: self.mouseLog.logEvent("mouse2") self.rightDown = False except: self.mouseLog.logEvent("mouse outside of the window...") finally: return t.cont
class EventLogger(Element): """ """ def __init__(self, **kwargs): super(EventLogger, self).__init__(**kwargs) self.listener = DirectObject() # registering some events by hand self.listener.accept('crossHair',self.logEvent) uniqueFileName = self.config.logfile +"_"+ self.config.world.participantId + ".log" self.eventLog = Logger(self.baseTime, uniqueFileName, 'w') #self.eventLog.startLog() self.eventLog.logEvent('Event logger started\n') taskMgr.add( self.updateHooks, 'updateHooks' ) self.registeredEvents = messenger.getEvents() for e in self.registeredEvents: self.listener.accept(e, self.logEvent, [e]) self.hideElement() def logEvent(self, event=None, args=[]): if event == 'mouse1': args = base.mouseWatcherNode.getMouse() self.eventLog.logEvent("%s;%s\n"%(event,args)) def enterState(self): # super class enterState Element.enterState(self) def exitState(self): # super class exitState Element.exitState(self) taskMgr.remove( 'updateHooks' ) self.eventLog.logEvent('Event logger stopped\n') self.eventLog.closeLog() def updateHooks(self, task): # run every 100 ms task.delayTime = 0.1 newEvents = [x for x in messenger.getEvents() if x not in self.registeredEvents] for x in newEvents: #print "NEW EVENT" self.listener.accept(x, self.logEvent, [x]) self.registeredEvents.append(x) return task.cont
class EyeTrackerClient(Element): def __init__(self, **kwargs): """ Basic empty constructor for an EyeTracakerClient class :param kwargs: list :return: None """ if getattr(self, "defaults", None) is None: self.defaults = {} # setting logGaze before constructing Element, so it will # end up in self.config.logGaze == True self.defaults["logGaze"] = True # call Element constructor super(EyeTrackerClient, self).__init__(**kwargs) # this is not a visible element!!! self.hideElement() """ constructor for the EyeTracker class """ self.status = TRACKER_STATUS.DISCONNECTED # gazeData is a list of triplets (timeStamp, x, y) if (getattr(self.config, "smoothWindow", None) == None): self.config.smoothWindow = 5.0 else: self.config.smoothWindow = float(self.config.smoothWindow) self.gazeData = [(0, 0, 0)] * int(self.config.smoothWindow) self.smoothSampleXY = [0.0, 0.0] if self.config.logGaze: # one gaze log per participant self.gazeLogger = Logger(self.baseTime, "run/gazeData_" + self.config.world.participantId + ".log", mode='w') else: self.gazeLogger = Logger(self.baseTime, "noLog") #self.gazeLogger.startLog() # create a mutex for accessing the gazeData list self.gazeMutex = Mutex('gazeMutex') gazeTex = loader.loadTexture( 'Elements/Game/models/textures/outter_circle.png') gazeTex.setMinfilter(Texture.FTLinearMipmapLinear) gazeTex.setAnisotropicDegree(2) gazeNode = loader.loadModel("Elements/Game/models/plane") gazeNode.reparentTo(self.hudNP) gazeNode.setScale(0.1, 1.0, 0.1) gazeNode.setTransparency(1) gazeNode.setAlphaScale(0.1) gazeNode.setTexture(gazeTex) gazeNode.setPos(-1.7, 0, 0) self.gazeNode = gazeNode #w,h = map(float,(cam.screenWidth,cam.screenHeight)) self.normX = base.win.getXSize() / float( base.win.getYSize()) # self.config.world.getCamera().ratio self.hudNP.setBin('fixed', 10) def getLastSampleAndTime(self, smooth=False): """ Get last tracker sample, for now no smoothing or filter is applied :param smooth: Bool :return: (float,float) or None """ return None def toggleGaze(self): print "toggle!" if self.gazeNode.isHidden(): self.config.showGaze = True self.showGaze() else: self.config.showGaze = False self.hideGaze() def showGaze(self): self.gazeNode.show() def hideGaze(self): self.gazeNode.hide() def getLastSample(self, smooth=True): """ Get last tracker sample, for now no smoothing or filter is applied :param smooth: Bool :return: (float,float) or None """ value = (-1, -1) self.gazeMutex.acquire() if smooth: value = self.smoothSampleXY else: value = self.gazeData[-1][-2:] self.gazeMutex.release() return value def appendSample(self, timestamp, x, y): s = self.config.smoothWindow self.gazeMutex.acquire() self.gazeData.append((timestamp, x, y)) # discard oldest, add new. self.smoothSampleXY[0] += (-self.gazeData[-int(s + 1)][1] / s) + (x / s) self.smoothSampleXY[1] += (-self.gazeData[-int(s + 1)][2] / s) + (y / s) self.gazeMutex.release() def startTracking(self): pass def stopTracking(selfs): pass def startCalibration(self): pass def stopCalibration(self): pass def addCalibrationPoint(self, x, y): pass def removeCalibrationPoint(self, x, y): pass def connect(self): """ Implemented in subclass :return: """ pass def disconnect(self): """ Implemented in subclass :return: """ pass def enterState(self): super(EyeTrackerClient, self).enterState() self.gazeLogger.logEvent("INFO - Starting EyeTracker client\n") if not self.config.showGaze: self.gazeNode.hide() def exitState(self): self.gazeLogger.logEvent("INFO - Closing EyeTracker client\n") self.gazeLogger.stopLog() super(EyeTrackerClient, self).exitState()