diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index abf16248c2..517d062494 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -661,21 +661,22 @@ void Head::renderEyeBalls() { glm::vec3 front = orientation * IDENTITY_FRONT; // render left iris + glm::quat leftIrisRotation; glPushMatrix(); { glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); //translate to eyeball position //rotate the eyeball to aim towards the lookat position glm::vec3 targetLookatVector = _lookAtPosition + _saccade - _leftEyePosition; - glm::quat rotation = rotationBetween(front, targetLookatVector) * orientation; - glm::vec3 rotationAxis = glm::axis(rotation); - glRotatef(glm::angle(rotation), rotationAxis.x, rotationAxis.y, rotationAxis.z); + leftIrisRotation = rotationBetween(front, targetLookatVector) * orientation; + glm::vec3 rotationAxis = glm::axis(leftIrisRotation); + glRotatef(glm::angle(leftIrisRotation), rotationAxis.x, rotationAxis.y, rotationAxis.z); glTranslatef(0.0f, 0.0f, -_scale * IRIS_PROTRUSION); glScalef(_scale * IRIS_RADIUS * 2.0f, _scale * IRIS_RADIUS * 2.0f, _scale * IRIS_RADIUS); // flatten the iris // this ugliness is simply to invert the model transform and get the eye position in model space - _irisProgram.setUniform(_eyePositionLocation, (glm::inverse(rotation) * + _irisProgram.setUniform(_eyePositionLocation, (glm::inverse(leftIrisRotation) * (Application::getInstance()->getCamera()->getPosition() - _leftEyePosition) + glm::vec3(0.0f, 0.0f, _scale * IRIS_PROTRUSION)) * glm::vec3(1.0f / (_scale * IRIS_RADIUS * 2.0f), 1.0f / (_scale * IRIS_RADIUS * 2.0f), 1.0f / (_scale * IRIS_RADIUS))); @@ -685,21 +686,22 @@ void Head::renderEyeBalls() { glPopMatrix(); // render right iris + glm::quat rightIrisRotation; glPushMatrix(); { glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); //translate to eyeball position //rotate the eyeball to aim towards the lookat position glm::vec3 targetLookatVector = _lookAtPosition + _saccade - _rightEyePosition; - glm::quat rotation = rotationBetween(front, targetLookatVector) * orientation; - glm::vec3 rotationAxis = glm::axis(rotation); - glRotatef(glm::angle(rotation), rotationAxis.x, rotationAxis.y, rotationAxis.z); + rightIrisRotation = rotationBetween(front, targetLookatVector) * orientation; + glm::vec3 rotationAxis = glm::axis(rightIrisRotation); + glRotatef(glm::angle(rightIrisRotation), rotationAxis.x, rotationAxis.y, rotationAxis.z); glTranslatef(0.0f, 0.0f, -_scale * IRIS_PROTRUSION); glScalef(_scale * IRIS_RADIUS * 2.0f, _scale * IRIS_RADIUS * 2.0f, _scale * IRIS_RADIUS); // flatten the iris // this ugliness is simply to invert the model transform and get the eye position in model space - _irisProgram.setUniform(_eyePositionLocation, (glm::inverse(rotation) * + _irisProgram.setUniform(_eyePositionLocation, (glm::inverse(rightIrisRotation) * (Application::getInstance()->getCamera()->getPosition() - _rightEyePosition) + glm::vec3(0.0f, 0.0f, _scale * IRIS_PROTRUSION)) * glm::vec3(1.0f / (_scale * IRIS_RADIUS * 2.0f), 1.0f / (_scale * IRIS_RADIUS * 2.0f), 1.0f / (_scale * IRIS_RADIUS))); @@ -718,12 +720,13 @@ void Head::renderEyeBalls() { // left eyelid glPushMatrix(); { glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); //translate to eyeball position - glm::vec3 rotationAxis = glm::axis(orientation); - glRotatef(glm::angle(orientation), rotationAxis.x, rotationAxis.y, rotationAxis.z); + glm::vec3 rotationAxis = glm::axis(leftIrisRotation); + glRotatef(glm::angle(leftIrisRotation), rotationAxis.x, rotationAxis.y, rotationAxis.z); glScalef(_scale * EYELID_RADIUS, _scale * EYELID_RADIUS, _scale * EYELID_RADIUS); - glRotatef(-40 - 50 * _leftEyeBlink, 1, 0, 0); + float angle = -67.5f - 50.0f * _leftEyeBlink; + glRotatef(angle, 1, 0, 0); Application::getInstance()->getGeometryCache()->renderHemisphere(15, 10); - glRotatef(180 * _leftEyeBlink, 1, 0, 0); + glRotatef(glm::mix(-angle, 180.0f, _leftEyeBlink), 1, 0, 0); Application::getInstance()->getGeometryCache()->renderHemisphere(15, 10); } glPopMatrix(); @@ -731,12 +734,13 @@ void Head::renderEyeBalls() { // right eyelid glPushMatrix(); { glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); //translate to eyeball position - glm::vec3 rotationAxis = glm::axis(orientation); - glRotatef(glm::angle(orientation), rotationAxis.x, rotationAxis.y, rotationAxis.z); + glm::vec3 rotationAxis = glm::axis(rightIrisRotation); + glRotatef(glm::angle(rightIrisRotation), rotationAxis.x, rotationAxis.y, rotationAxis.z); glScalef(_scale * EYELID_RADIUS, _scale * EYELID_RADIUS, _scale * EYELID_RADIUS); - glRotatef(-40 - 50 * _rightEyeBlink, 1, 0, 0); + float angle = -67.5f - 50.0f * _rightEyeBlink; + glRotatef(angle, 1, 0, 0); Application::getInstance()->getGeometryCache()->renderHemisphere(15, 10); - glRotatef(180 * _rightEyeBlink, 1, 0, 0); + glRotatef(glm::mix(-angle, 180.0f, _rightEyeBlink), 1, 0, 0); Application::getInstance()->getGeometryCache()->renderHemisphere(15, 10); } glPopMatrix(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4b7f64cb6f..0dcfe32236 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -347,14 +347,19 @@ void MyAvatar::updateFromGyrosAndOrWebcam(bool gyroLook, } else if (webcam->isActive()) { estimatedRotation = webcam->getEstimatedRotation(); - } else if (_leadingAvatar) { - _head.getFace().clearFrame(); - return; - } else { - _head.setMousePitch(pitchFromTouch); - _head.setPitch(pitchFromTouch); + if (!_leadingAvatar) { + _head.setMousePitch(pitchFromTouch); + _head.setPitch(pitchFromTouch); + } _head.getFace().clearFrame(); + + // restore rotation, lean to neutral positions + const float RESTORE_RATE = 0.05f; + _head.setYaw(glm::mix(_head.getYaw(), 0.0f, RESTORE_RATE)); + _head.setRoll(glm::mix(_head.getRoll(), 0.0f, RESTORE_RATE)); + _head.setLeanSideways(glm::mix(_head.getLeanSideways(), 0.0f, RESTORE_RATE)); + _head.setLeanForward(glm::mix(_head.getLeanForward(), 0.0f, RESTORE_RATE)); return; } _head.setMousePitch(pitchFromTouch); diff --git a/interface/src/devices/Faceshift.cpp b/interface/src/devices/Faceshift.cpp index 399369cdd3..991a406cc7 100644 --- a/interface/src/devices/Faceshift.cpp +++ b/interface/src/devices/Faceshift.cpp @@ -73,6 +73,7 @@ void Faceshift::connectSocket() { const quint16 FACESHIFT_PORT = 33433; _socket.connectToHost("localhost", FACESHIFT_PORT); + _tracking = false; } } @@ -102,7 +103,7 @@ void Faceshift::readFromSocket() { switch (msg->id()) { case fsMsg::MSG_OUT_TRACKING_STATE: { const fsTrackingData& data = static_cast(msg.get())->tracking_data(); - if (data.m_trackingSuccessful) { + if ((_tracking = data.m_trackingSuccessful)) { _headRotation = glm::quat(data.m_headRotation.w, -data.m_headRotation.x, data.m_headRotation.y, -data.m_headRotation.z); const float TRANSLATION_SCALE = 0.02f; diff --git a/interface/src/devices/Faceshift.h b/interface/src/devices/Faceshift.h index 408513e5d7..586f336c04 100644 --- a/interface/src/devices/Faceshift.h +++ b/interface/src/devices/Faceshift.h @@ -24,7 +24,7 @@ public: Faceshift(); - bool isActive() const { return _socket.state() == QAbstractSocket::ConnectedState; } + bool isActive() const { return _socket.state() == QAbstractSocket::ConnectedState && _tracking; } const glm::quat& getHeadRotation() const { return _headRotation; } const glm::vec3& getHeadTranslation() const { return _headTranslation; } @@ -66,6 +66,7 @@ private: QTcpSocket _socket; fs::fsBinaryStream _stream; bool _enabled; + bool _tracking; glm::quat _headRotation; glm::vec3 _headTranslation;