Merge pull request #642 from LionTurtle/master

Make lookAtVectors lock on other avatar's eyes if the mouse is over the other avatar's head.
This commit is contained in:
ZappoMan 2013-07-11 10:51:26 -07:00
commit a1eed4e597
6 changed files with 56 additions and 4 deletions

View file

@ -1734,6 +1734,22 @@ void Application::init() {
const float MAX_AVATAR_EDIT_VELOCITY = 1.0f;
const float MAX_VOXEL_EDIT_DISTANCE = 20.0f;
const float HEAD_SPHERE_RADIUS = 0.07;
bool Application::isLookingAtOtherAvatar(glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection, glm::vec3& eyePosition) {
NodeList* nodeList = NodeList::getInstance();
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
Avatar* avatar = (Avatar *) node->getLinkedData();
glm::vec3 headPosition = avatar->getHead().getPosition();
if (rayIntersectsSphere(mouseRayOrigin, mouseRayDirection, headPosition, HEAD_SPHERE_RADIUS)) {
eyePosition = avatar->getHead().getEyeLevelPosition();
return true;
}
}
}
return false;
}
void Application::update(float deltaTime) {
// Use Transmitter Hand to move hand if connected, else use mouse
@ -1761,8 +1777,15 @@ void Application::update(float deltaTime) {
_myAvatar.setMouseRay(mouseRayOrigin, mouseRayDirection);
// Set where I am looking based on my mouse ray (so that other people can see)
glm::vec3 myLookAtFromMouse(mouseRayOrigin + mouseRayDirection);
_myAvatar.getHead().setLookAtPosition(myLookAtFromMouse);
glm::vec3 eyePosition;
if (isLookingAtOtherAvatar(mouseRayOrigin, mouseRayDirection, eyePosition)) {
// If the mouse is over another avatar's head...
glm::vec3 myLookAtFromMouse(eyePosition);
_myAvatar.getHead().setLookAtPosition(myLookAtFromMouse);
} else {
glm::vec3 myLookAtFromMouse(mouseRayOrigin + mouseRayDirection);
_myAvatar.getHead().setLookAtPosition(myLookAtFromMouse);
}
// If we are dragging on a voxel, add thrust according to the amount the mouse is dragging
const float VOXEL_GRAB_THRUST = 0.0f;
@ -1998,6 +2021,17 @@ void Application::updateAvatar(float deltaTime) {
_headMouseY = max(_headMouseY, 0);
_headMouseY = min(_headMouseY, _glWidget->height());
// Set lookAtPosition if an avatar is at the center of the screen
glm::vec3 screenCenterRayOrigin, screenCenterRayDirection;
_viewFrustum.computePickRay(0.5, 0.5, screenCenterRayOrigin, screenCenterRayDirection);
glm::vec3 eyePosition;
if (isLookingAtOtherAvatar(screenCenterRayOrigin, screenCenterRayDirection, eyePosition)) {
glm::vec3 myLookAtFromMouse(eyePosition);
_myAvatar.getHead().setLookAtPosition(myLookAtFromMouse);
}
}
if (OculusManager::isConnected()) {

View file

@ -181,6 +181,7 @@ private:
void init();
void update(float deltaTime);
bool isLookingAtOtherAvatar(glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection, glm::vec3& eyePosition);
void updateAvatar(float deltaTime);
void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum);

View file

@ -54,6 +54,7 @@ Head::Head(Avatar* owningAvatar) :
_rotation(0.0f, 0.0f, 0.0f),
_leftEyePosition(0.0f, 0.0f, 0.0f),
_rightEyePosition(0.0f, 0.0f, 0.0f),
_eyeLevelPosition(0.0f, 0.0f, 0.0f),
_leftEyeBrowPosition(0.0f, 0.0f, 0.0f),
_rightEyeBrowPosition(0.0f, 0.0f, 0.0f),
_leftEarPosition(0.0f, 0.0f, 0.0f),
@ -268,6 +269,8 @@ void Head::calculateGeometry() {
+ up * _scale * EYE_UP_OFFSET
+ front * _scale * EYE_FRONT_OFFSET;
_eyeLevelPosition = _position + up * _scale * EYE_UP_OFFSET;
//calculate the eyebrow positions
_leftEyeBrowPosition = _leftEyePosition;
_rightEyeBrowPosition = _rightEyePosition;

View file

@ -53,7 +53,8 @@ public:
glm::quat getOrientation() const;
glm::quat getCameraOrientation () const;
glm::vec3 getPosition() const { return _position; }
glm::vec3 getPosition() const { return _position; }
const glm::vec3& getEyeLevelPosition() const { return _eyeLevelPosition; }
glm::vec3 getRightDirection() const { return getOrientation() * IDENTITY_RIGHT; }
glm::vec3 getUpDirection () const { return getOrientation() * IDENTITY_UP; }
glm::vec3 getFrontDirection() const { return getOrientation() * IDENTITY_FRONT; }
@ -88,7 +89,8 @@ private:
glm::vec3 _position;
glm::vec3 _rotation;
glm::vec3 _leftEyePosition;
glm::vec3 _rightEyePosition;
glm::vec3 _rightEyePosition;
glm::vec3 _eyeLevelPosition;
glm::vec3 _leftEyeBrowPosition;
glm::vec3 _rightEyeBrowPosition;
glm::vec3 _leftEarPosition;

View file

@ -537,3 +537,13 @@ float loadSetting(QSettings* settings, const char* name, float defaultValue) {
}
return value;
}
bool rayIntersectsSphere(glm::vec3& rayStarting, glm::vec3& rayNormalizedDirection, glm::vec3& sphereCenter, double sphereRadius) {
glm::vec3 vecFromRayToSphereCenter = sphereCenter - rayStarting;
double projection = glm::dot(vecFromRayToSphereCenter, rayNormalizedDirection);
double shortestDistance = sqrt(glm::dot(vecFromRayToSphereCenter, vecFromRayToSphereCenter) - projection * projection);
if (shortestDistance <= sphereRadius) {
return true;
}
return false;
}

View file

@ -71,4 +71,6 @@ void runTimingTests();
float loadSetting(QSettings* settings, const char* name, float defaultValue);
bool rayIntersectsSphere(glm::vec3& rayStarting, glm::vec3& rayNormalizedDirection, glm::vec3& sphereCenter, double sphereRadius);
#endif