Example #1
0
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 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()