Merge pull request #535 from PhilipRosedale/master

Everyone is now looking where they are mousing!  (myeyesareuphere.com)
This commit is contained in:
Andrzej Kapolka 2013-06-13 16:21:14 -07:00
commit 4b3ab2d8d5
6 changed files with 54 additions and 111 deletions

View file

@ -303,6 +303,8 @@ void Application::paintGL() {
glEnable(GL_LINE_SMOOTH);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float headCameraScale = _serialHeadSensor.active ? _headCameraPitchYawScale : 1.0f;
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
_myCamera.setTightness (100.0f);
_myCamera.setTargetPosition(_myAvatar.getUprightHeadPosition());
@ -318,11 +320,11 @@ void Application::paintGL() {
} else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
_myCamera.setTightness(0.0f); // In first person, camera follows head exactly without delay
_myCamera.setTargetPosition(_myAvatar.getUprightHeadPosition());
_myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation(_headCameraPitchYawScale));
_myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation(headCameraScale));
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
_myCamera.setTargetPosition(_myAvatar.getUprightHeadPosition());
_myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation(_headCameraPitchYawScale));
_myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation(headCameraScale));
}
// Update camera position
@ -1449,6 +1451,10 @@ void Application::update(float deltaTime) {
// tell my avatar the posiion and direction of the ray projected ino the world based on the mouse position
_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);
// If we are dragging on a voxel, add thrust according to the amount the mouse is dragging
const float VOXEL_GRAB_THRUST = 5.0f;
@ -2038,11 +2044,15 @@ void Application::displaySide(Camera& whichCamera) {
avatar->init();
}
avatar->render(false, _renderAvatarBalls->isChecked());
avatar->setDisplayingLookatVectors(_renderLookatOn->isChecked());
}
}
agentList->unlock();
// Render my own Avatar
// Render my own Avatar
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
_myAvatar.getHead().setLookAtPosition(_myCamera.getPosition());
}
_myAvatar.render(_lookingInMirror->isChecked(), _renderAvatarBalls->isChecked());
_myAvatar.setDisplayingLookatVectors(_renderLookatOn->isChecked());
}

View file

@ -616,15 +616,6 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
}
}
// set head lookat position
if (!_owningAgent) {
if (_interactingOther) {
_head.setLookAtPosition(_interactingOther->calculateAverageEyePosition());
} else {
_head.setLookAtPosition(glm::vec3(0.0f, 0.0f, 0.0f)); // 0,0,0 represents NOT looking at anything
}
}
_head.setBodyRotation (glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll));
_head.setPosition(_bodyBall[ BODY_BALL_HEAD_BASE ].position);
_head.setScale (_bodyBall[ BODY_BALL_HEAD_BASE ].radius);

View file

@ -59,7 +59,6 @@ Head::Head(Avatar* owningAvatar) :
_mouthPosition(0.0f, 0.0f, 0.0f),
_scale(1.0f),
_browAudioLift(0.0f),
_lookingAtSomething(false),
_gravity(0.0f, -1.0f, 0.0f),
_lastLoudness(0.0f),
_averageLoudness(0.0f),
@ -69,7 +68,9 @@ Head::Head(Avatar* owningAvatar) :
_lookingInMirror(false),
_renderLookatVectors(false),
_mohawkTriangleFan(NULL),
_mohawkColors(NULL)
_mohawkColors(NULL),
_saccade(0.0f, 0.0f, 0.0f),
_saccadeTarget(0.0f, 0.0f, 0.0f)
{
if (USING_PHYSICAL_MOHAWK) {
resetHairPhysics();
@ -124,32 +125,19 @@ void Head::resetHairPhysics() {
void Head::simulate(float deltaTime, bool isMine) {
const float HEAD_MOTION_DECAY = 0.00;
/*
// Decay head back to center if turned on
if (isMine && _returnHeadToCenter) {
// Update eye saccades
const float AVERAGE_MICROSACCADE_INTERVAL = 0.50f;
const float AVERAGE_SACCADE_INTERVAL = 4.0f;
const float MICROSACCADE_MAGNITUDE = 0.002f;
const float SACCADE_MAGNITUDE = 0.04;
// Decay rotation back toward center
_pitch *= (1.0f - HEAD_MOTION_DECAY * _returnSpringScale * deltaTime);
_yaw *= (1.0f - HEAD_MOTION_DECAY * _returnSpringScale * deltaTime);
_roll *= (1.0f - HEAD_MOTION_DECAY * _returnSpringScale * deltaTime);
if (randFloat() < deltaTime / AVERAGE_MICROSACCADE_INTERVAL) {
_saccadeTarget = MICROSACCADE_MAGNITUDE * randVector();
} else if (randFloat() < deltaTime / AVERAGE_SACCADE_INTERVAL) {
_saccadeTarget = SACCADE_MAGNITUDE * randVector();
}
// For invensense gyro, decay only slightly when near center (until we add fusion)
if (isMine) {
const float RETURN_RANGE = 15.0;
const float RETURN_STRENGTH = 0.5;
if (fabs(_pitch) < RETURN_RANGE) { _pitch *= (1.0f - RETURN_STRENGTH * deltaTime); }
if (fabs(_yaw ) < RETURN_RANGE) { _yaw *= (1.0f - RETURN_STRENGTH * deltaTime); }
if (fabs(_roll ) < RETURN_RANGE) { _roll *= (1.0f - RETURN_STRENGTH * deltaTime); }
}
*/
// decay lean
_leanForward *= (1.f - HEAD_MOTION_DECAY * 30 * deltaTime);
_leanSideways *= (1.f - HEAD_MOTION_DECAY * 30 * deltaTime);
_saccade += (_saccadeTarget - _saccade) * 0.50f;
// Update audio trailing average for rendering facial animations
const float AUDIO_AVERAGING_SECS = 0.05;
@ -170,30 +158,13 @@ void Head::simulate(float deltaTime, bool isMine) {
_browAudioLift *= 0.7f;
// based on the nature of the lookat position, determine if the eyes can look / are looking at it.
determineIfLookingAtSomething();
// based on the nature of the lookat position, determine if the eyes can look / are looking at it.
if (USING_PHYSICAL_MOHAWK) {
updateHairPhysics(deltaTime);
}
}
void Head::determineIfLookingAtSomething() {
if ( fabs(_lookAtPosition.x + _lookAtPosition.y + _lookAtPosition.z) == 0.0 ) { // a lookatPosition of 0,0,0 signifies NOT looking
_lookingAtSomething = false;
} else {
glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - calculateAverageEyePosition());
float dot = glm::dot(targetLookatAxis, getFrontDirection());
if (dot < MINIMUM_EYE_ROTATION_DOT) { // too far off from center for the eyes to rotate
_lookingAtSomething = false;
} else {
_lookingAtSomething = true;
}
}
}
void Head::calculateGeometry() {
//generate orientation directions
glm::quat orientation = getOrientation();
@ -240,9 +211,9 @@ void Head::render(bool lookingInMirror, float alpha) {
renderEyeBalls();
renderEars();
renderMouth();
renderEyeBrows();
renderEyeBrows();
if (_renderLookatVectors && _lookingAtSomething) {
if (_renderLookatVectors) {
renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition);
}
}
@ -520,33 +491,15 @@ void Head::renderEyeBalls() {
// render left iris
glPushMatrix(); {
glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); //translate to eyeball position
glPushMatrix();
if (_lookingAtSomething) {
//rotate the eyeball to aim towards the lookat position
glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - _leftEyePosition); // the lookat direction
glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP);
float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP);
glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z);
glRotatef(180.0, 0.0f, 1.0f, 0.0f); //adjust roll to correct after previous rotations
} else {
//rotate the eyeball to aim straight ahead
glm::vec3 rotationAxisToHeadFront = glm::cross(front, IDENTITY_UP);
float angleToHeadFront = 180.0f - angleBetween(front, IDENTITY_UP);
glRotatef(angleToHeadFront, rotationAxisToHeadFront.x, rotationAxisToHeadFront.y, rotationAxisToHeadFront.z);
//set the amount of roll (for correction after previous rotations)
float rollRotation = angleBetween(front, IDENTITY_FRONT);
float dot = glm::dot(front, -IDENTITY_RIGHT);
if ( dot < 0.0f ) { rollRotation = -rollRotation; }
glRotatef(rollRotation, 0.0f, 1.0f, 0.0f); //roll the iris or correct roll about the lookat vector
}
glTranslatef( 0.0f, -IRIS_PROTRUSION, 0.0f);//push the iris out a bit (otherwise - inside of eyeball!)
glScalef( 1.0f, 0.5f, 1.0f); // flatten the iris
//rotate the eyeball to aim towards the lookat position
glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition + _saccade - _leftEyePosition);
glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP);
float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP);
glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z);
glRotatef(180.0, 0.0f, 1.0f, 0.0f); //adjust roll to correct after previous rotations
glTranslatef( 0.0f, -IRIS_PROTRUSION, 0.0f);
glScalef( 1.0f, 0.5f, 1.0f); // flatten the iris
gluSphere(irisQuadric, IRIS_RADIUS, 15, 15);
glPopMatrix();
}
@ -555,34 +508,16 @@ void Head::renderEyeBalls() {
// render right iris
glPushMatrix(); {
glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); //translate to eyeball position
glPushMatrix();
if (_lookingAtSomething) {
//rotate the eyeball to aim towards the lookat position
glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - _rightEyePosition);
glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP);
float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP);
glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z);
glRotatef(180.0f, 0.0f, 1.0f, 0.0f); //adjust roll to correct after previous rotations
} else {
//rotate the eyeball to aim straight ahead
glm::vec3 rotationAxisToHeadFront = glm::cross(front, IDENTITY_UP);
float angleToHeadFront = 180.0f - angleBetween(front, IDENTITY_UP);
glRotatef(angleToHeadFront, rotationAxisToHeadFront.x, rotationAxisToHeadFront.y, rotationAxisToHeadFront.z);
//set the amount of roll (for correction after previous rotations)
float rollRotation = angleBetween(front, IDENTITY_FRONT);
float dot = glm::dot(front, -IDENTITY_RIGHT);
if ( dot < 0.0f ) { rollRotation = -rollRotation; }
glRotatef(rollRotation, 0.0f, 1.0f, 0.0f); //roll the iris or correct roll about the lookat vector
}
glTranslatef( 0.0f, -IRIS_PROTRUSION, 0.0f);//push the iris out a bit (otherwise - inside of eyeball!)
glScalef( 1.0f, 0.5f, 1.0f); // flatten the iris
//rotate the eyeball to aim towards the lookat position
glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition + _saccade - _rightEyePosition);
glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP);
float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP);
glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z);
glRotatef(180.0f, 0.0f, 1.0f, 0.0f); //adjust roll to correct after previous rotations
glTranslatef( 0.0f, -IRIS_PROTRUSION, 0.0f);
glScalef( 1.0f, 0.5f, 1.0f); // flatten the iris
gluSphere(irisQuadric, IRIS_RADIUS, 15, 15);
glPopMatrix();
}

View file

@ -93,7 +93,6 @@ private:
glm::vec3 _mouthPosition;
float _scale;
float _browAudioLift;
bool _lookingAtSomething;
glm::vec3 _gravity;
float _lastLoudness;
float _averageLoudness;
@ -105,6 +104,8 @@ private:
HairTuft _hairTuft[NUM_HAIR_TUFTS];
glm::vec3* _mohawkTriangleFan;
glm::vec3* _mohawkColors;
glm::vec3 _saccade;
glm::vec3 _saccadeTarget;
static ProgramObject* _irisProgram;
static GLuint _irisTextureID;
@ -118,7 +119,6 @@ private:
void renderMouth();
void renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition);
void calculateGeometry();
void determineIfLookingAtSomething();
void resetHairPhysics();
void updateHairPhysics(float deltaTime);
};

View file

@ -267,6 +267,11 @@ double diffclock(timeval *clock1,timeval *clock2)
return diffms;
}
// Return a random vector of average length 1
const glm::vec3 randVector() {
return glm::vec3(randFloat() - 0.5f, randFloat() - 0.5f, randFloat() - 0.5f) * 2.f;
}
static TextRenderer* textRenderer(int mono) {
static TextRenderer* monoRenderer = new TextRenderer(MONO_FONT_FAMILY);
static TextRenderer* proportionalRenderer = new TextRenderer(SANS_FONT_FAMILY, -1, -1, false, TextRenderer::SHADOW_EFFECT);

View file

@ -32,6 +32,8 @@ float azimuth_to(glm::vec3 head_pos, glm::vec3 source_pos);
float angle_to(glm::vec3 head_pos, glm::vec3 source_pos, float render_yaw, float head_yaw);
float randFloat();
const glm::vec3 randVector();
void render_world_box();
int widthText(float scale, int mono, char const* string);
float widthChar(float scale, int mono, char ch);