diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 297194003e..0d2566ca64 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1651,9 +1651,9 @@ Avatar* Application::findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, con glm::vec3 headPosition = avatar->getHead().getPosition(); float distance; if (rayIntersectsSphere(mouseRayOrigin, mouseRayDirection, headPosition, - HEAD_SPHERE_RADIUS * avatar->getScale(), distance)) { + HEAD_SPHERE_RADIUS * avatar->getHead().getScale(), distance)) { eyePosition = avatar->getHead().getEyePosition(); - _lookatIndicatorScale = avatar->getScale(); + _lookatIndicatorScale = avatar->getHead().getScale(); _lookatOtherPosition = headPosition; nodeID = avatar->getOwningNode()->getNodeID(); return avatar; @@ -1794,8 +1794,8 @@ void Application::update(float deltaTime) { _faceshift.getEstimatedEyePitch(), _faceshift.getEstimatedEyeYaw(), 0.0f))) * glm::vec3(0.0f, 0.0f, -1.0f); } - updateLookatTargetAvatar(lookAtRayOrigin, lookAtRayDirection, lookAtSpot); - if (_lookatTargetAvatar) { + updateLookatTargetAvatar(mouseRayOrigin, mouseRayDirection, lookAtSpot); + if (_lookatTargetAvatar && !_faceshift.isActive()) { // If the mouse is over another avatar's head... _myAvatar.getHead().setLookAtPosition(lookAtSpot); } else if (_isHoverVoxel && !_faceshift.isActive()) { diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 762652217a..917e135e5e 100755 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -102,6 +102,8 @@ Avatar::Avatar(Node* owningNode) : _leadingAvatar(NULL), _voxels(this), _moving(false), + _hoverOnDuration(0.0f), + _hoverOffDuration(0.0f), _initialized(false), _handHoldingPosition(0.0f, 0.0f, 0.0f), _maxArmLength(0.0f), @@ -388,15 +390,27 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { } // head scale grows when avatar is looked at + const float BASE_MAX_SCALE = 3.0f; + float maxScale = BASE_MAX_SCALE * glm::distance(_position, Application::getInstance()->getCamera()->getPosition()); if (Application::getInstance()->getLookatTargetAvatar() == this) { - const float BASE_MAX_SCALE = 3.0f; - const float GROW_SPEED = 0.1f; - _head.setScale(min(BASE_MAX_SCALE * glm::distance(_position, Application::getInstance()->getCamera()->getPosition()), - _head.getScale() + deltaTime * GROW_SPEED)); + _hoverOnDuration += deltaTime; + _hoverOffDuration = 0.0f; + + const float GROW_DELAY = 1.0f; + const float GROW_RATE = 0.25f; + if (_hoverOnDuration > GROW_DELAY) { + _head.setScale(glm::mix(_head.getScale(), maxScale, GROW_RATE)); + } } else { - const float SHRINK_SPEED = 100.0f; - _head.setScale(max(_scale, _head.getScale() - deltaTime * SHRINK_SPEED)); + _hoverOnDuration = 0.0f; + _hoverOffDuration += deltaTime; + + const float SHRINK_DELAY = 1.0f; + const float SHRINK_RATE = 0.25f; + if (_hoverOffDuration > SHRINK_DELAY) { + _head.setScale(glm::mix(_head.getScale(), 1.0f, SHRINK_RATE)); + } } _head.setBodyRotation(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)); @@ -465,15 +479,16 @@ void Avatar::render(bool lookingInMirror, bool renderAvatarBalls) { renderDiskShadow(_position, glm::vec3(0.0f, 1.0f, 0.0f), _scale * 0.1f, 0.2f); { - // glow when moving - Glower glower(_moving ? 1.0f : 0.0f); + // glow when moving in the distance + glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition(); + const float GLOW_DISTANCE = 5.0f; + Glower glower(_moving && glm::length(toTarget) > GLOW_DISTANCE ? 1.0f : 0.0f); // render body renderBody(lookingInMirror, renderAvatarBalls); // render sphere when far away const float MAX_ANGLE = 10.f; - glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition(); glm::vec3 delta = _height * (_head.getCameraOrientation() * IDENTITY_UP) / 2.f; float angle = abs(angleBetween(toTarget + delta, toTarget - delta)); diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 4fd3f49880..1451abd180 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -222,6 +222,8 @@ protected: AvatarVoxelSystem _voxels; bool _moving; ///< set when position is changing + float _hoverOnDuration; + float _hoverOffDuration; // protected methods... glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } diff --git a/interface/src/avatar/BlendFace.cpp b/interface/src/avatar/BlendFace.cpp index 280dd6a5cc..ca49edd24b 100644 --- a/interface/src/avatar/BlendFace.cpp +++ b/interface/src/avatar/BlendFace.cpp @@ -191,6 +191,9 @@ bool BlendFace::render(float alpha) { glEnable(GL_TEXTURE_2D); glDisable(GL_COLOR_MATERIAL); + // the eye shader uses the color state even though color material is disabled + glColor4f(1.0f, 1.0f, 1.0f, alpha); + for (int i = 0; i < networkMeshes.size(); i++) { const NetworkMesh& networkMesh = networkMeshes.at(i); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, networkMesh.indexBufferID); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 74c39dfa4c..54080ae9ff 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -600,9 +600,6 @@ void MyAvatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) { return; } - // glow when moving - Glower glower(_moving ? 1.0f : 0.0f); - if (_head.getFace().isFullFrame()) { // Render the full-frame video float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, lookingInMirror); diff --git a/libraries/voxels/src/ViewFrustum.cpp b/libraries/voxels/src/ViewFrustum.cpp index b6249ad3ab..51d7639678 100644 --- a/libraries/voxels/src/ViewFrustum.cpp +++ b/libraries/voxels/src/ViewFrustum.cpp @@ -401,6 +401,10 @@ void ViewFrustum::computeOffAxisFrustum(float& left, float& right, float& bottom far = max(far, -corners[i].z); } + // make sure the near clip isn't too small to be valid + const float MIN_NEAR = 0.01f; + near = max(MIN_NEAR, near); + // get the near/far normal and use it to find the clip planes glm::vec4 normal = eyeMatrix * glm::vec4(0.0f, 0.0f, 1.0f, 0.0f); nearClipPlane = glm::vec4(-normal.x, -normal.y, -normal.z, glm::dot(normal, corners[0]));