mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 14:54:29 +02:00
working on lookat (eye contact)
This commit is contained in:
parent
7117e4a76c
commit
f53b49c496
7 changed files with 193 additions and 162 deletions
|
@ -293,7 +293,9 @@ bool Avatar::getIsNearInteractingOther() {
|
||||||
void Avatar::simulate(float deltaTime) {
|
void Avatar::simulate(float deltaTime) {
|
||||||
|
|
||||||
//figure out if the mouse cursor is over any body spheres...
|
//figure out if the mouse cursor is over any body spheres...
|
||||||
checkForMouseRayTouching();
|
if (_isMine) {
|
||||||
|
checkForMouseRayTouching();
|
||||||
|
}
|
||||||
|
|
||||||
// update balls
|
// update balls
|
||||||
if (_balls) { _balls->simulate(deltaTime); }
|
if (_balls) { _balls->simulate(deltaTime); }
|
||||||
|
@ -519,6 +521,9 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_interactingOther) {
|
if (_interactingOther) {
|
||||||
|
|
||||||
|
_head.setLookatPosition( _interactingOther->getSpringyHeadPosition());
|
||||||
|
|
||||||
_avatarTouch.setYourBodyPosition(_interactingOther->_position);
|
_avatarTouch.setYourBodyPosition(_interactingOther->_position);
|
||||||
_avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition);
|
_avatarTouch.setYourHandPosition(_interactingOther->_joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].springyPosition);
|
||||||
_avatarTouch.setYourHandState (_interactingOther->_handState);
|
_avatarTouch.setYourHandState (_interactingOther->_handState);
|
||||||
|
@ -592,115 +597,6 @@ void Avatar::updateHandMovementAndTouching(float deltaTime) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::updateHead(float deltaTime) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Decay head back to center if turned on
|
|
||||||
if (_isMine && _returnHeadToCenter) {
|
|
||||||
// Decay back toward center
|
|
||||||
_headPitch *= (1.0f - DECAY * _head.returnSpringScale * 2 * deltaTime);
|
|
||||||
_headYaw *= (1.0f - DECAY * _head.returnSpringScale * 2 * deltaTime);
|
|
||||||
_headRoll *= (1.0f - DECAY * _head.returnSpringScale * 2 * deltaTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
// For invensense gyro, decay only slightly when roughly centered
|
|
||||||
if (_isMine) {
|
|
||||||
const float RETURN_RANGE = 15.0;
|
|
||||||
const float RETURN_STRENGTH = 2.0;
|
|
||||||
if (fabs(_headPitch) < RETURN_RANGE) { _headPitch *= (1.0f - RETURN_STRENGTH * deltaTime); }
|
|
||||||
if (fabs(_headYaw) < RETURN_RANGE) { _headYaw *= (1.0f - RETURN_STRENGTH * deltaTime); }
|
|
||||||
if (fabs(_headRoll) < RETURN_RANGE) { _headRoll *= (1.0f - RETURN_STRENGTH * deltaTime); }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_head.noise) {
|
|
||||||
// Move toward new target
|
|
||||||
_headPitch += (_head.pitchTarget - _headPitch) * 10 * deltaTime; // (1.f - DECAY*deltaTime)*Pitch + ;
|
|
||||||
_headYaw += (_head.yawTarget - _headYaw ) * 10 * deltaTime; // (1.f - DECAY*deltaTime);
|
|
||||||
_headRoll *= 1.f - (DECAY * deltaTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
_head.leanForward *= (1.f - DECAY * 30 * deltaTime);
|
|
||||||
_head.leanSideways *= (1.f - DECAY * 30 * deltaTime);
|
|
||||||
|
|
||||||
// Update where the avatar's eyes are
|
|
||||||
//
|
|
||||||
// First, decide if we are making eye contact or not
|
|
||||||
if (randFloat() < 0.005) {
|
|
||||||
_head.eyeContact = !_head.eyeContact;
|
|
||||||
_head.eyeContact = 1;
|
|
||||||
if (!_head.eyeContact) {
|
|
||||||
// If we just stopped making eye contact,move the eyes markedly away
|
|
||||||
_head.eyeballPitch[0] = _head.eyeballPitch[1] = _head.eyeballPitch[0] + 5.0 + (randFloat() - 0.5) * 10;
|
|
||||||
_head.eyeballYaw [0] = _head.eyeballYaw [1] = _head.eyeballYaw [0] + 5.0 + (randFloat() - 0.5) * 5;
|
|
||||||
} else {
|
|
||||||
// If now making eye contact, turn head to look right at viewer
|
|
||||||
SetNewHeadTarget(0,0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const float DEGREES_BETWEEN_VIEWER_EYES = 3;
|
|
||||||
const float DEGREES_TO_VIEWER_MOUTH = 7;
|
|
||||||
|
|
||||||
if (_head.eyeContact) {
|
|
||||||
// Should we pick a new eye contact target?
|
|
||||||
if (randFloat() < 0.01) {
|
|
||||||
// Choose where to look next
|
|
||||||
if (randFloat() < 0.1) {
|
|
||||||
_head.eyeContactTarget = MOUTH;
|
|
||||||
} else {
|
|
||||||
if (randFloat() < 0.5) _head.eyeContactTarget = LEFT_EYE; else _head.eyeContactTarget = RIGHT_EYE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Set eyeball pitch and yaw to make contact
|
|
||||||
float eye_target_yaw_adjust = 0;
|
|
||||||
float eye_target_pitch_adjust = 0;
|
|
||||||
if (_head.eyeContactTarget == LEFT_EYE) eye_target_yaw_adjust = DEGREES_BETWEEN_VIEWER_EYES;
|
|
||||||
if (_head.eyeContactTarget == RIGHT_EYE) eye_target_yaw_adjust = -DEGREES_BETWEEN_VIEWER_EYES;
|
|
||||||
if (_head.eyeContactTarget == MOUTH) eye_target_pitch_adjust = DEGREES_TO_VIEWER_MOUTH;
|
|
||||||
|
|
||||||
_head.eyeballPitch[0] = _head.eyeballPitch[1] = -_headPitch + eye_target_pitch_adjust;
|
|
||||||
_head.eyeballYaw[0] = _head.eyeballYaw[1] = -_headYaw + eye_target_yaw_adjust;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_head.noise)
|
|
||||||
{
|
|
||||||
_headPitch += (randFloat() - 0.5) * 0.2 * _head.noiseEnvelope;
|
|
||||||
_headYaw += (randFloat() - 0.5) * 0.3 *_head.noiseEnvelope;
|
|
||||||
//PupilSize += (randFloat() - 0.5) * 0.001*NoiseEnvelope;
|
|
||||||
|
|
||||||
if (randFloat() < 0.005) _head.mouthWidth = MouthWidthChoices[rand()%3];
|
|
||||||
|
|
||||||
if (!_head.eyeContact) {
|
|
||||||
if (randFloat() < 0.01) _head.eyeballPitch[0] = _head.eyeballPitch[1] = (randFloat() - 0.5) * 20;
|
|
||||||
if (randFloat() < 0.01) _head.eyeballYaw[0] = _head.eyeballYaw[1] = (randFloat()- 0.5) * 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((randFloat() < 0.005) && (fabs(_head.pitchTarget - _headPitch) < 1.0) && (fabs(_head.yawTarget - _headYaw) < 1.0)) {
|
|
||||||
SetNewHeadTarget((randFloat()-0.5) * 20.0, (randFloat()-0.5) * 45.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0) {
|
|
||||||
|
|
||||||
// Pick new target
|
|
||||||
_head.pitchTarget = (randFloat() - 0.5) * 45;
|
|
||||||
_head.yawTarget = (randFloat() - 0.5) * 22;
|
|
||||||
}
|
|
||||||
if (randFloat() < 0.01)
|
|
||||||
{
|
|
||||||
_head.eyebrowPitch[0] = _head.eyebrowPitch[1] = BrowPitchAngle[rand()%3];
|
|
||||||
_head.eyebrowRoll [0] = _head.eyebrowRoll[1] = BrowRollAngle[rand()%5];
|
|
||||||
_head.eyebrowRoll [1] *=-1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update audio trailing average for rendering facial animations
|
|
||||||
const float AUDIO_AVERAGING_SECS = 0.05;
|
|
||||||
_head.averageLoudness = (1.f - deltaTime / AUDIO_AVERAGING_SECS) * _head.averageLoudness +
|
|
||||||
(deltaTime / AUDIO_AVERAGING_SECS) * _audioLoudness;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
float Avatar::getHeight() {
|
float Avatar::getHeight() {
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,9 +195,6 @@ private:
|
||||||
glm::vec3 _mouseRayDirection;
|
glm::vec3 _mouseRayDirection;
|
||||||
glm::vec3 _cameraPosition;
|
glm::vec3 _cameraPosition;
|
||||||
|
|
||||||
//AvatarJointID _jointTouched;
|
|
||||||
|
|
||||||
|
|
||||||
// private methods...
|
// private methods...
|
||||||
void initializeSkeleton();
|
void initializeSkeleton();
|
||||||
void updateSkeleton();
|
void updateSkeleton();
|
||||||
|
@ -205,7 +202,6 @@ private:
|
||||||
void updateBodySprings( float deltaTime );
|
void updateBodySprings( float deltaTime );
|
||||||
void calculateBoneLengths();
|
void calculateBoneLengths();
|
||||||
void readSensors();
|
void readSensors();
|
||||||
void updateHead( float deltaTime );
|
|
||||||
void updateHandMovementAndTouching(float deltaTime);
|
void updateHandMovementAndTouching(float deltaTime);
|
||||||
void updateAvatarCollisions(float deltaTime);
|
void updateAvatarCollisions(float deltaTime);
|
||||||
void updateCollisionWithSphere( glm::vec3 position, float radius, float deltaTime );
|
void updateCollisionWithSphere( glm::vec3 position, float radius, float deltaTime );
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Head.h"
|
#include "Head.h"
|
||||||
|
#include "Util.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
#include <lodepng.h>
|
#include <lodepng.h>
|
||||||
|
@ -15,6 +16,8 @@ using namespace std;
|
||||||
|
|
||||||
const float HEAD_MOTION_DECAY = 0.1;
|
const float HEAD_MOTION_DECAY = 0.1;
|
||||||
|
|
||||||
|
const bool TESTING_LOOKAT = false;
|
||||||
|
|
||||||
|
|
||||||
float _browColor [] = {210.0/255.0, 105.0/255.0, 30.0/255.0};
|
float _browColor [] = {210.0/255.0, 105.0/255.0, 30.0/255.0};
|
||||||
float _mouthColor[] = {1, 0, 0};
|
float _mouthColor[] = {1, 0, 0};
|
||||||
|
@ -49,6 +52,7 @@ void Head::initialize() {
|
||||||
audioLoudness = 0.0;
|
audioLoudness = 0.0;
|
||||||
skinColor = glm::vec3(0.0f, 0.0f, 0.0f);
|
skinColor = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
position = glm::vec3(0.0f, 0.0f, 0.0f);
|
position = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
lookatPosition = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
yaw = 0.0f;
|
yaw = 0.0f;
|
||||||
pitch = 0.0f;
|
pitch = 0.0f;
|
||||||
roll = 0.0f;
|
roll = 0.0f;
|
||||||
|
@ -219,11 +223,21 @@ void Head::simulate(float deltaTime, bool isMine) {
|
||||||
const float AUDIO_AVERAGING_SECS = 0.05;
|
const float AUDIO_AVERAGING_SECS = 0.05;
|
||||||
averageLoudness = (1.f - deltaTime / AUDIO_AVERAGING_SECS) * averageLoudness +
|
averageLoudness = (1.f - deltaTime / AUDIO_AVERAGING_SECS) * averageLoudness +
|
||||||
(deltaTime / AUDIO_AVERAGING_SECS) * audioLoudness;
|
(deltaTime / AUDIO_AVERAGING_SECS) * audioLoudness;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Head::setLookatPosition(glm::vec3 l) {
|
||||||
|
lookatPosition = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Head::render(bool lookingInMirror, float bodyYaw) {
|
void Head::render(bool lookingInMirror, float bodyYaw) {
|
||||||
|
|
||||||
|
|
||||||
|
//float a = angleBetween( &position, &position);
|
||||||
|
|
||||||
int side = 0;
|
int side = 0;
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
@ -236,11 +250,11 @@ void Head::render(bool lookingInMirror, float bodyYaw) {
|
||||||
glScalef(scale, scale, scale);
|
glScalef(scale, scale, scale);
|
||||||
|
|
||||||
if (lookingInMirror) {
|
if (lookingInMirror) {
|
||||||
glRotatef(bodyYaw - yaw, 0, 1, 0);
|
glRotatef(bodyYaw - yaw, 0, 1, 0);
|
||||||
glRotatef(pitch, 1, 0, 0);
|
glRotatef(pitch, 1, 0, 0);
|
||||||
glRotatef(-roll, 0, 0, 1);
|
glRotatef(-roll, 0, 0, 1);
|
||||||
} else {
|
} else {
|
||||||
glRotatef(bodyYaw + yaw, 0, 1, 0);
|
glRotatef(bodyYaw + yaw, 0, 1, 0);
|
||||||
glRotatef(pitch, 1, 0, 0);
|
glRotatef(pitch, 1, 0, 0);
|
||||||
glRotatef(roll, 0, 0, 1);
|
glRotatef(roll, 0, 0, 1);
|
||||||
}
|
}
|
||||||
|
@ -290,24 +304,37 @@ void Head::render(bool lookingInMirror, float bodyYaw) {
|
||||||
|
|
||||||
// Mouth
|
// Mouth
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(0,-0.35,0.75);
|
glTranslatef(0,-0.35,0.75);
|
||||||
glColor3f(0,0,0);
|
glColor3f(0,0,0);
|
||||||
|
|
||||||
glRotatef(mouthPitch, 1, 0, 0);
|
glRotatef(mouthPitch, 1, 0, 0);
|
||||||
glRotatef(mouthYaw, 0, 0, 1);
|
glRotatef(mouthYaw, 0, 0, 1);
|
||||||
|
|
||||||
if (averageLoudness > 1.f) {
|
if (averageLoudness > 1.f) {
|
||||||
glScalef(mouthWidth * (.7f + sqrt(averageLoudness) /60.f),
|
glScalef(mouthWidth * (.7f + sqrt(averageLoudness) /60.f),
|
||||||
mouthHeight * (1.f + sqrt(averageLoudness) /30.f), 1);
|
mouthHeight * (1.f + sqrt(averageLoudness) /30.f), 1);
|
||||||
} else {
|
} else {
|
||||||
glScalef(mouthWidth, mouthHeight, 1);
|
glScalef(mouthWidth, mouthHeight, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
glutSolidCube(0.5);
|
glutSolidCube(0.5);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
glTranslatef(0, 1.0, 0);
|
renderEyeBalls();
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
if (TESTING_LOOKAT) {
|
||||||
|
//the irises are special - they have the ability to look at specific targets in the world (code still not finished yet)
|
||||||
|
renderIrises(bodyYaw + yaw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Head::renderEyeBalls() {
|
||||||
|
|
||||||
|
glTranslatef(0, 1.0, 0);
|
||||||
|
|
||||||
glTranslatef(-interPupilDistance/2.0,-0.68,0.7);
|
glTranslatef(-interPupilDistance/2.0,-0.68,0.7);
|
||||||
// Right Eye
|
// Right Eye
|
||||||
|
@ -322,30 +349,33 @@ void Head::render(bool lookingInMirror, float bodyYaw) {
|
||||||
}
|
}
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
// Right Pupil
|
if (!TESTING_LOOKAT) {
|
||||||
if (sphere == NULL) {
|
// Right Pupil
|
||||||
sphere = gluNewQuadric();
|
if (sphere == NULL) {
|
||||||
gluQuadricTexture(sphere, GL_TRUE);
|
sphere = gluNewQuadric();
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
gluQuadricTexture(sphere, GL_TRUE);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
gluQuadricOrientation(sphere, GLU_OUTSIDE);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iris_texture_width, iris_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &iris_texture[0]);
|
gluQuadricOrientation(sphere, GLU_OUTSIDE);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iris_texture_width, iris_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &iris_texture[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
{
|
||||||
|
glRotatef(eyeballPitch[1], 1, 0, 0);
|
||||||
|
glRotatef(eyeballYaw[1] + yaw + pupilConverge, 0, 1, 0);
|
||||||
|
glTranslatef(0,0,.35);
|
||||||
|
glRotatef(-75,1,0,0);
|
||||||
|
glScalef(1.0, 0.4, 1.0);
|
||||||
|
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
gluSphere(sphere, pupilSize, 15, 15);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
glPushMatrix();
|
|
||||||
{
|
|
||||||
glRotatef(eyeballPitch[1], 1, 0, 0);
|
|
||||||
glRotatef(eyeballYaw[1] + yaw + pupilConverge, 0, 1, 0);
|
|
||||||
glTranslatef(0,0,.35);
|
|
||||||
glRotatef(-75,1,0,0);
|
|
||||||
glScalef(1.0, 0.4, 1.0);
|
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
gluSphere(sphere, pupilSize, 15, 15);
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
}
|
|
||||||
|
|
||||||
glPopMatrix();
|
|
||||||
// Left Eye
|
// Left Eye
|
||||||
glColor3fv(_eyeColor);
|
glColor3fv(_eyeColor);
|
||||||
glTranslatef(interPupilDistance, 0, 0);
|
glTranslatef(interPupilDistance, 0, 0);
|
||||||
|
@ -357,21 +387,111 @@ void Head::render(bool lookingInMirror, float bodyYaw) {
|
||||||
glutSolidSphere(0.25, 30, 30);
|
glutSolidSphere(0.25, 30, 30);
|
||||||
}
|
}
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
// Left Pupil
|
|
||||||
|
if (!TESTING_LOOKAT) {
|
||||||
|
// Left Pupil
|
||||||
|
glPushMatrix();
|
||||||
|
{
|
||||||
|
glRotatef(eyeballPitch[0], 1, 0, 0);
|
||||||
|
glRotatef(eyeballYaw[0] + yaw - pupilConverge, 0, 1, 0);
|
||||||
|
glTranslatef(0, 0, .35);
|
||||||
|
glRotatef(-75, 1, 0, 0);
|
||||||
|
glScalef(1.0, 0.4, 1.0);
|
||||||
|
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
gluSphere(sphere, pupilSize, 15, 15);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------
|
||||||
|
// the code below is still in the prototyping stages....
|
||||||
|
//---------------------------------------------------------
|
||||||
|
void Head::renderIrises(float yaw) {
|
||||||
|
Orientation orientation;
|
||||||
|
orientation.setToPitchYawRoll( pitch, yaw, roll);
|
||||||
|
|
||||||
|
// Render lines originating from the eyes and converging on the lookatPosition
|
||||||
|
float rightShift = scale * 0.22f;
|
||||||
|
float upShift = scale * 0.38f;
|
||||||
|
float frontShift = scale * 0.9f;
|
||||||
|
|
||||||
|
glm::vec3 leftEyePosition = position + orientation.getRight() * rightShift
|
||||||
|
+ orientation.getUp () * upShift
|
||||||
|
+ orientation.getFront() * frontShift;
|
||||||
|
glm::vec3 rightEyePosition = position - orientation.getRight() * rightShift
|
||||||
|
+ orientation.getUp () * upShift
|
||||||
|
+ orientation.getFront() * frontShift;
|
||||||
|
|
||||||
|
debugRenderLookatVectors(leftEyePosition, rightEyePosition, lookatPosition);
|
||||||
|
|
||||||
|
glColor3fv(_eyeColor);
|
||||||
|
|
||||||
|
if (sphere == NULL) {
|
||||||
|
sphere = gluNewQuadric();
|
||||||
|
gluQuadricTexture(sphere, GL_TRUE);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
gluQuadricOrientation(sphere, GLU_OUTSIDE);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iris_texture_width, iris_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &iris_texture[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//render left iris
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
{
|
{
|
||||||
glRotatef(eyeballPitch[0], 1, 0, 0);
|
glTranslatef(leftEyePosition.x, leftEyePosition.y, leftEyePosition.z);
|
||||||
glRotatef(eyeballYaw[0] + yaw - pupilConverge, 0, 1, 0);
|
glm::vec3 targetLookatAxis = glm::normalize(lookatPosition - leftEyePosition);
|
||||||
glTranslatef(0, 0, .35);
|
|
||||||
glRotatef(-75, 1, 0, 0);
|
|
||||||
glScalef(1.0, 0.4, 1.0);
|
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
glPushMatrix();
|
||||||
gluSphere(sphere, pupilSize, 15, 15);
|
glm::vec3 pitchRotationAxis = glm::cross(targetLookatAxis, orientation.getRight());
|
||||||
glDisable(GL_TEXTURE_2D);
|
glm::vec3 yawRotationAxis = glm::cross(targetLookatAxis, orientation.getUp());
|
||||||
|
|
||||||
|
glRotatef(90.0f, yawRotationAxis.x, yawRotationAxis.y, yawRotationAxis.z);
|
||||||
|
glRotatef(90.0f, pitchRotationAxis.x, pitchRotationAxis.y, pitchRotationAxis.z);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
gluSphere(sphere, 0.01, 15, 15);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
|
//render right iris
|
||||||
|
glPushMatrix();
|
||||||
|
{
|
||||||
|
glTranslatef(rightEyePosition.x, rightEyePosition.y, rightEyePosition.z);
|
||||||
|
glm::vec3 targetLookatAxis = glm::normalize(lookatPosition - rightEyePosition);
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
glm::vec3 pitchRotationAxis = glm::cross(targetLookatAxis, orientation.getRight());
|
||||||
|
glm::vec3 yawRotationAxis = glm::cross(targetLookatAxis, orientation.getUp());
|
||||||
|
|
||||||
|
glRotatef(90.0f, yawRotationAxis.x, yawRotationAxis.y, yawRotationAxis.z);
|
||||||
|
glRotatef(90.0f, pitchRotationAxis.x, pitchRotationAxis.y, pitchRotationAxis.z);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
gluSphere(sphere, 0.01, 15, 15);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Head::debugRenderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) {
|
||||||
|
|
||||||
|
glColor3f(0.0f, 0.0f, 0.0f);
|
||||||
|
glLineWidth(3.0);
|
||||||
|
glBegin(GL_LINE_STRIP);
|
||||||
|
glVertex3f(leftEyePosition.x, leftEyePosition.y, leftEyePosition.z);
|
||||||
|
glVertex3f(lookatPosition.x, lookatPosition.y, lookatPosition.z);
|
||||||
|
glEnd();
|
||||||
|
glBegin(GL_LINE_STRIP);
|
||||||
|
glVertex3f(rightEyePosition.x, rightEyePosition.y, rightEyePosition.z);
|
||||||
|
glVertex3f(lookatPosition.x, lookatPosition.y, lookatPosition.z);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
#include "InterfaceConfig.h"
|
#include "InterfaceConfig.h"
|
||||||
#include "SerialInterface.h"
|
#include "SerialInterface.h"
|
||||||
|
#include "Orientation.h"
|
||||||
|
|
||||||
enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH};
|
enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH};
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@ public:
|
||||||
void render(bool lookingInMirror, float bodyYaw);
|
void render(bool lookingInMirror, float bodyYaw);
|
||||||
void setNewTarget(float, float);
|
void setNewTarget(float, float);
|
||||||
void setSpringScale(float s) { returnSpringScale = s; }
|
void setSpringScale(float s) { returnSpringScale = s; }
|
||||||
|
void setLookatPosition(glm::vec3 lookatPosition);
|
||||||
|
|
||||||
// Do you want head to try to return to center (depends on interface detected)
|
// Do you want head to try to return to center (depends on interface detected)
|
||||||
void setReturnToCenter(bool r) { returnHeadToCenter = r; }
|
void setReturnToCenter(bool r) { returnHeadToCenter = r; }
|
||||||
|
@ -43,6 +45,7 @@ public:
|
||||||
glm::vec3 skinColor;
|
glm::vec3 skinColor;
|
||||||
glm::vec3 position;
|
glm::vec3 position;
|
||||||
glm::vec3 rotation;
|
glm::vec3 rotation;
|
||||||
|
glm::vec3 lookatPosition;
|
||||||
float yaw;
|
float yaw;
|
||||||
float pitch;
|
float pitch;
|
||||||
float roll;
|
float roll;
|
||||||
|
@ -85,6 +88,12 @@ public:
|
||||||
|
|
||||||
// Strength of return springs
|
// Strength of return springs
|
||||||
float returnSpringScale;
|
float returnSpringScale;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void renderEyeBalls();
|
||||||
|
void renderIrises(float yaw);
|
||||||
|
void debugRenderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1059,6 +1059,7 @@ void display(void)
|
||||||
myCamera.setTargetRotation(myAvatar.getBodyYaw() + myAvatar.getHeadYaw(), -myAvatar.getHeadPitch(), myAvatar.getHeadRoll());
|
myCamera.setTargetRotation(myAvatar.getBodyYaw() + myAvatar.getHeadYaw(), -myAvatar.getHeadPitch(), myAvatar.getHeadRoll());
|
||||||
|
|
||||||
} else if (myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
} else if (myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||||
|
myCamera.setTightness (100.0f);
|
||||||
myCamera.setTargetPosition(myAvatar.getSpringyHeadPosition());
|
myCamera.setTargetPosition(myAvatar.getSpringyHeadPosition());
|
||||||
myCamera.setTargetRotation(myAvatar.getBodyYaw() - 180.0f, 0.0f, 0.0f);
|
myCamera.setTargetRotation(myAvatar.getBodyYaw() - 180.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
@ -1086,7 +1087,6 @@ void display(void)
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// Note: whichCamera is used to pick between the normal camera myCamera for our
|
// Note: whichCamera is used to pick between the normal camera myCamera for our
|
||||||
// main camera, vs, an alternate camera. The alternate camera we support right now
|
// main camera, vs, an alternate camera. The alternate camera we support right now
|
||||||
// is the viewFrustumOffsetCamera. But theoretically, we could use this same mechanism
|
// is the viewFrustumOffsetCamera. But theoretically, we could use this same mechanism
|
||||||
|
|
|
@ -25,6 +25,15 @@ void Orientation::setToIdentity() {
|
||||||
front = glm::vec3(IDENTITY_FRONT);
|
front = glm::vec3(IDENTITY_FRONT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Orientation::setToPitchYawRoll(float p, float y, float r) {
|
||||||
|
|
||||||
|
setToIdentity();
|
||||||
|
pitch(p);
|
||||||
|
yaw (y);
|
||||||
|
roll (r);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Orientation::set(Orientation o) {
|
void Orientation::set(Orientation o) {
|
||||||
|
|
||||||
quat = o.quat;
|
quat = o.quat;
|
||||||
|
|
|
@ -22,6 +22,7 @@ public:
|
||||||
Orientation();
|
Orientation();
|
||||||
|
|
||||||
void set(Orientation);
|
void set(Orientation);
|
||||||
|
void setToPitchYawRoll(float p, float y, float r);
|
||||||
void setToIdentity();
|
void setToIdentity();
|
||||||
|
|
||||||
void pitch(float p);
|
void pitch(float p);
|
||||||
|
|
Loading…
Reference in a new issue