Beispiel #1
0
Mickey::Mickey() : updateTimer(this), btnThread(this), state(STANDBY), 
  calDlg(), aplDlg(), recenterFlag(true), dw(NULL) 
{
  trans = new MickeyTransform();
  //QObject::connect(onOffSwitch, SIGNAL(activated()), this, SLOT(onOffSwitch_activated()));
  //QObject::connect(&lbtnSwitch, SIGNAL(activated()), &btnThread, SLOT(on_key_pressed()));
  QObject::connect(this, SIGNAL(mouseHotKey_activated(int, bool)), 
		   &btnThread, SLOT(on_mouseHotKey_activated(int, bool)));
  QObject::connect(&updateTimer, SIGNAL(timeout()), this, SLOT(updateTimer_activated()));
  QObject::connect(&aplDlg, SIGNAL(keep()), this, SLOT(keepSettings()));
  QObject::connect(&aplDlg, SIGNAL(revert()), this, SLOT(revertSettings()));

  QObject::connect(&calDlg, SIGNAL(recenterNow(bool)), this, SLOT(recenterNow(bool)));
  QObject::connect(&calDlg, SIGNAL(startCalibration()), this, SLOT(startCalibration()));
  QObject::connect(&calDlg, SIGNAL(finishCalibration()), this, SLOT(finishCalibration()));
  QObject::connect(&calDlg, SIGNAL(cancelCalibration(bool)), this, SLOT(cancelCalibration(bool)));
  
  if(!mouse.init()){
    exit(1);
  }
  dw = QApplication::desktop();
//  screenBBox = dw->screenGeometry();
  screenBBox = QRect(0, 0, dw->width(), dw->height());
  screenCenter = screenBBox.center();
  updateTimer.setSingleShot(false);
  updateTimer.setInterval(8);
  btnThread.start();
  linuxtrack_init((char *)"Mickey");
  changeState(TRACKING);
}
Beispiel #2
0
void MickeyCalibration::timeout()
{
  //std::cout<<"timer!"<<std::endl;
  --cntr;
  if(cntr == 0){
    switch(calState){
      case CENTER_ONLY:
        timer.stop();
        emit recenterNow(true);
        window()->hide();
        break;
      case CENTER:
        emit recenterNow(false);
        emit startCalibration();
        calState = CALIBRATE;
        cntr = GUI.getCalDelay();
        break;
      case CALIBRATE:
        timer.stop();
        emit finishCalibration();
        window()->hide();
        break;
    }
  }
    switch(calState){
      case CENTER:
      case CENTER_ONLY:
        ui.CalibrationText->setText(QString::fromUtf8("Please center your head and sight."));
        ui.FBString->setText(QString::fromUtf8("Center position will be recorded in %1 seconds...").arg(cntr));
        break;
      case CALIBRATE:
        ui.CalibrationText->setText(QString::fromUtf8("Please move your head to left/right and up/down extremes."));
        ui.FBString->setText(QString::fromUtf8("Calibration will end in %1 seconds...").arg(cntr));
        break;
    }
}
Beispiel #3
0
void DdeFaceTracker::decodePacket(const QByteArray& buffer) {
    _lastReceiveTimestamp = usecTimestampNow();

    if (buffer.size() > MIN_PACKET_SIZE) {
        bool isFiltering = Menu::getInstance()->isOptionChecked(MenuOption::VelocityFilter);

        Packet packet;
        int bytesToCopy = glm::min((int)sizeof(packet), buffer.size());
        memset(&packet.name, '\n', MAX_NAME_SIZE + 1);
        memcpy(&packet, buffer.data(), bytesToCopy);
        
        glm::vec3 translation;
        memcpy(&translation, packet.translation, sizeof(packet.translation));
        glm::quat rotation;
        memcpy(&rotation, &packet.rotation, sizeof(packet.rotation));
        if (_reset || (_lastMessageReceived == 0)) {
            memcpy(&_referenceTranslation, &translation, sizeof(glm::vec3));
            memcpy(&_referenceRotation, &rotation, sizeof(glm::quat));
            _reset = false;
        }

        // Compute relative translation
        float LEAN_DAMPING_FACTOR = 75.0f;
        translation -= _referenceTranslation;
        translation /= LEAN_DAMPING_FACTOR;
        translation.x *= -1;
        if (isFiltering) {
            glm::vec3 linearVelocity = (translation - _lastHeadTranslation) / _averageMessageTime;
            const float LINEAR_VELOCITY_FILTER_STRENGTH = 0.3f;
            float velocityFilter = glm::clamp(1.0f - glm::length(linearVelocity) *
                LINEAR_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
            _filteredHeadTranslation = velocityFilter * _filteredHeadTranslation + (1.0f - velocityFilter) * translation;
            _lastHeadTranslation = translation;
            _headTranslation = _filteredHeadTranslation;
        } else {
            _headTranslation = translation;
        }

        // Compute relative rotation
        rotation = glm::inverse(_referenceRotation) * rotation;
        if (isFiltering) {
            glm::quat r = rotation * glm::inverse(_headRotation);
            float theta = 2 * acos(r.w);
            glm::vec3 angularVelocity;
            if (theta > EPSILON) {
                float rMag = glm::length(glm::vec3(r.x, r.y, r.z));
                angularVelocity = theta / _averageMessageTime * glm::vec3(r.x, r.y, r.z) / rMag;
            } else {
                angularVelocity = glm::vec3(0, 0, 0);
            }
            const float ANGULAR_VELOCITY_FILTER_STRENGTH = 0.3f;
            _headRotation = safeMix(_headRotation, rotation, glm::clamp(glm::length(angularVelocity) *
                ANGULAR_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f));
        } else {
            _headRotation = rotation;
        }

        // Translate DDE coefficients to Faceshift compatible coefficients
        for (int i = 0; i < NUM_EXPRESSIONS; i++) {
            _coefficients[DDE_TO_FACESHIFT_MAPPING[i]] = packet.expressions[i];
        }

        // Calibration
        if (_isCalibrating) {
            addCalibrationDatum();
        }
        for (int i = 0; i < NUM_FACESHIFT_BLENDSHAPES; i++) {
            _coefficients[i] -= _coefficientAverages[i];
        }

        // Use BrowsU_C to control both brows' up and down
        float browUp = _coefficients[_browUpCenterIndex];
        if (isFiltering) {
            const float BROW_VELOCITY_FILTER_STRENGTH = 0.5f;
            float velocity = fabs(browUp - _lastBrowUp) / _averageMessageTime;
            float velocityFilter = glm::clamp(velocity * BROW_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
            _filteredBrowUp = velocityFilter * browUp + (1.0f - velocityFilter) * _filteredBrowUp;
            _lastBrowUp = browUp;
            browUp = _filteredBrowUp;
            _coefficients[_browUpCenterIndex] = browUp;
        }
        _coefficients[_browUpLeftIndex] = browUp;
        _coefficients[_browUpRightIndex] = browUp;
        _coefficients[_browDownLeftIndex] = -browUp;
        _coefficients[_browDownRightIndex] = -browUp;

        // Offset jaw open coefficient
        static const float JAW_OPEN_THRESHOLD = 0.1f;
        _coefficients[_jawOpenIndex] = _coefficients[_jawOpenIndex] - JAW_OPEN_THRESHOLD;

        // Offset smile coefficients
        static const float SMILE_THRESHOLD = 0.5f;
        _coefficients[_mouthSmileLeftIndex] = _coefficients[_mouthSmileLeftIndex] - SMILE_THRESHOLD;
        _coefficients[_mouthSmileRightIndex] = _coefficients[_mouthSmileRightIndex] - SMILE_THRESHOLD;

        // Velocity filter EyeBlink values
        const float DDE_EYEBLINK_SCALE = 3.0f;
        float eyeBlinks[] = { DDE_EYEBLINK_SCALE * _coefficients[_leftBlinkIndex], DDE_EYEBLINK_SCALE * _coefficients[_rightBlinkIndex] };
        if (isFiltering) {
            const float BLINK_VELOCITY_FILTER_STRENGTH = 0.3f;
            for (int i = 0; i < 2; i++) {
                float velocity = fabs(eyeBlinks[i] - _lastEyeBlinks[i]) / _averageMessageTime;
                float velocityFilter = glm::clamp(velocity * BLINK_VELOCITY_FILTER_STRENGTH, 0.0f, 1.0f);
                _filteredEyeBlinks[i] = velocityFilter * eyeBlinks[i] + (1.0f - velocityFilter) * _filteredEyeBlinks[i];
                _lastEyeBlinks[i] = eyeBlinks[i];
            }
        }

        // Finesse EyeBlink values
        float eyeCoefficients[2];
        if (Menu::getInstance()->isOptionChecked(MenuOption::BinaryEyelidControl)) {
            if (_eyeStates[0] == EYE_UNCONTROLLED) {
                _eyeStates[0] = EYE_OPEN;
                _eyeStates[1] = EYE_OPEN;
            }

            for (int i = 0; i < 2; i++) {
                // Scale EyeBlink values so that they can be used to control both EyeBlink and EyeOpen
                // -ve values control EyeOpen; +ve values control EyeBlink
                static const float EYE_CONTROL_THRESHOLD = 0.5f;  // Resting eye value
                eyeCoefficients[i] = (_filteredEyeBlinks[i] - EYE_CONTROL_THRESHOLD) / (1.0f - EYE_CONTROL_THRESHOLD);

                // Change to closing or opening states
                const float EYE_CONTROL_HYSTERISIS = 0.25f;
                float eyeClosingThreshold = getEyeClosingThreshold();
                float eyeOpeningThreshold = eyeClosingThreshold - EYE_CONTROL_HYSTERISIS;
                if ((_eyeStates[i] == EYE_OPEN || _eyeStates[i] == EYE_OPENING) && eyeCoefficients[i] > eyeClosingThreshold) {
                    _eyeStates[i] = EYE_CLOSING;
                } else if ((_eyeStates[i] == EYE_CLOSED || _eyeStates[i] == EYE_CLOSING)
                    && eyeCoefficients[i] < eyeOpeningThreshold) {
                    _eyeStates[i] = EYE_OPENING;
                }

                const float EYELID_MOVEMENT_RATE = 10.0f;  // units/second
                const float EYE_OPEN_SCALE = 0.2f;
                if (_eyeStates[i] == EYE_CLOSING) {
                    // Close eyelid until it's fully closed
                    float closingValue = _lastEyeCoefficients[i] + EYELID_MOVEMENT_RATE * _averageMessageTime;
                    if (closingValue >= 1.0) {
                        _eyeStates[i] = EYE_CLOSED;
                        eyeCoefficients[i] = 1.0;
                    } else {
                        eyeCoefficients[i] = closingValue;
                    }
                } else if (_eyeStates[i] == EYE_OPENING) {
                    // Open eyelid until it meets the current adjusted value
                    float openingValue = _lastEyeCoefficients[i] - EYELID_MOVEMENT_RATE * _averageMessageTime;
                    if (openingValue < eyeCoefficients[i] * EYE_OPEN_SCALE) {
                        _eyeStates[i] = EYE_OPEN;
                        eyeCoefficients[i] = eyeCoefficients[i] * EYE_OPEN_SCALE;
                    } else {
                        eyeCoefficients[i] = openingValue;
                    }
                } else  if (_eyeStates[i] == EYE_OPEN) {
                    // Reduce eyelid movement
                    eyeCoefficients[i] = eyeCoefficients[i] * EYE_OPEN_SCALE;
                } else if (_eyeStates[i] == EYE_CLOSED) {
                    // Keep eyelid fully closed
                    eyeCoefficients[i] = 1.0;
                }
            }

            if (_eyeStates[0] == EYE_OPEN && _eyeStates[1] == EYE_OPEN) {
                // Couple eyelids
                eyeCoefficients[0] = eyeCoefficients[1] = (eyeCoefficients[0] + eyeCoefficients[0]) / 2.0f;
            }

            _lastEyeCoefficients[0] = eyeCoefficients[0];
            _lastEyeCoefficients[1] = eyeCoefficients[1];
        } else {
            _eyeStates[0] = EYE_UNCONTROLLED;
            _eyeStates[1] = EYE_UNCONTROLLED;

            eyeCoefficients[0] = _filteredEyeBlinks[0];
            eyeCoefficients[1] = _filteredEyeBlinks[1];
        }

        // Use EyeBlink values to control both EyeBlink and EyeOpen
        if (eyeCoefficients[0] > 0) {
            _coefficients[_leftBlinkIndex] = eyeCoefficients[0];
            _coefficients[_leftEyeOpenIndex] = 0.0f;
        } else {
            _coefficients[_leftBlinkIndex] = 0.0f;
            _coefficients[_leftEyeOpenIndex] = -eyeCoefficients[0];
        }
        if (eyeCoefficients[1] > 0) {
            _coefficients[_rightBlinkIndex] = eyeCoefficients[1];
            _coefficients[_rightEyeOpenIndex] = 0.0f;
        } else {
            _coefficients[_rightBlinkIndex] = 0.0f;
            _coefficients[_rightEyeOpenIndex] = -eyeCoefficients[1];
        }

        // Scale all coefficients
        for (int i = 0; i < NUM_EXPRESSIONS; i++) {
            _blendshapeCoefficients[i]
                = glm::clamp(DDE_COEFFICIENT_SCALES[i] * _coefficients[i], 0.0f, 1.0f);
        }

        // Calculate average frame time
        const float FRAME_AVERAGING_FACTOR = 0.99f;
        quint64 usecsNow = usecTimestampNow();
        if (_lastMessageReceived != 0) {
            _averageMessageTime = FRAME_AVERAGING_FACTOR * _averageMessageTime 
                + (1.0f - FRAME_AVERAGING_FACTOR) * (float)(usecsNow - _lastMessageReceived) / 1000000.0f;
        }
        _lastMessageReceived = usecsNow;

        FaceTracker::countFrame();
        
    } else {
        qCWarning(interfaceapp) << "DDE Face Tracker: Decode error";
    }

    if (_isCalibrating && _calibrationCount > CALIBRATION_SAMPLES) {
        finishCalibration();
    }
}