mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 15:50:37 +02:00
Merge branch 'master' of github.com:worklist/hifi
This commit is contained in:
commit
51b431aa81
8 changed files with 150 additions and 145 deletions
21
interface/resources/shaders/iris.frag
Normal file
21
interface/resources/shaders/iris.frag
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
//
|
||||||
|
// iris.frag
|
||||||
|
// fragment shader
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 6/13/13.
|
||||||
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
// the iris texture
|
||||||
|
uniform sampler2D texture;
|
||||||
|
|
||||||
|
// the interpolated normal
|
||||||
|
varying vec4 normal;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
float specular = max(0.0, dot(normalize(gl_LightSource[0].position + vec4(0.0, 0.0, 1.0, 0.0)), normalize(normal)));
|
||||||
|
gl_FragColor = vec4(gl_Color.rgb * texture2D(texture, gl_TexCoord[0].st).rgb +
|
||||||
|
pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 1.0);
|
||||||
|
}
|
20
interface/resources/shaders/iris.vert
Normal file
20
interface/resources/shaders/iris.vert
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
//
|
||||||
|
// iris.vert
|
||||||
|
// vertex shader
|
||||||
|
//
|
||||||
|
// Created by Andrzej Kapolka on 6/13/13.
|
||||||
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
// the interpolated normal
|
||||||
|
varying vec4 normal;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
|
||||||
|
gl_FrontColor = gl_Color * (gl_LightModel.ambient + gl_LightSource[0].ambient +
|
||||||
|
gl_LightSource[0].diffuse * max(0.0, dot(normal, gl_LightSource[0].position)));
|
||||||
|
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||||
|
gl_Position = ftransform();
|
||||||
|
}
|
|
@ -303,6 +303,8 @@ void Application::paintGL() {
|
||||||
glEnable(GL_LINE_SMOOTH);
|
glEnable(GL_LINE_SMOOTH);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
float headCameraScale = _serialHeadSensor.active ? _headCameraPitchYawScale : 1.0f;
|
||||||
|
|
||||||
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||||
_myCamera.setTightness (100.0f);
|
_myCamera.setTightness (100.0f);
|
||||||
_myCamera.setTargetPosition(_myAvatar.getUprightHeadPosition());
|
_myCamera.setTargetPosition(_myAvatar.getUprightHeadPosition());
|
||||||
|
@ -318,11 +320,11 @@ void Application::paintGL() {
|
||||||
} else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
|
} else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
|
||||||
_myCamera.setTightness(0.0f); // In first person, camera follows head exactly without delay
|
_myCamera.setTightness(0.0f); // In first person, camera follows head exactly without delay
|
||||||
_myCamera.setTargetPosition(_myAvatar.getUprightHeadPosition());
|
_myCamera.setTargetPosition(_myAvatar.getUprightHeadPosition());
|
||||||
_myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation(_headCameraPitchYawScale));
|
_myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation(headCameraScale));
|
||||||
|
|
||||||
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
||||||
_myCamera.setTargetPosition(_myAvatar.getUprightHeadPosition());
|
_myCamera.setTargetPosition(_myAvatar.getUprightHeadPosition());
|
||||||
_myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation(_headCameraPitchYawScale));
|
_myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation(headCameraScale));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update camera position
|
// 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
|
// tell my avatar the posiion and direction of the ray projected ino the world based on the mouse position
|
||||||
_myAvatar.setMouseRay(mouseRayOrigin, mouseRayDirection);
|
_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
|
// If we are dragging on a voxel, add thrust according to the amount the mouse is dragging
|
||||||
const float VOXEL_GRAB_THRUST = 5.0f;
|
const float VOXEL_GRAB_THRUST = 5.0f;
|
||||||
|
@ -2038,11 +2044,15 @@ void Application::displaySide(Camera& whichCamera) {
|
||||||
avatar->init();
|
avatar->init();
|
||||||
}
|
}
|
||||||
avatar->render(false, _renderAvatarBalls->isChecked());
|
avatar->render(false, _renderAvatarBalls->isChecked());
|
||||||
|
avatar->setDisplayingLookatVectors(_renderLookatOn->isChecked());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
agentList->unlock();
|
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.render(_lookingInMirror->isChecked(), _renderAvatarBalls->isChecked());
|
||||||
_myAvatar.setDisplayingLookatVectors(_renderLookatOn->isChecked());
|
_myAvatar.setDisplayingLookatVectors(_renderLookatOn->isChecked());
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,6 +271,7 @@ Avatar::~Avatar() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::init() {
|
void Avatar::init() {
|
||||||
|
_head.init();
|
||||||
_voxels.init();
|
_voxels.init();
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
@ -615,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.setBodyRotation (glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll));
|
||||||
_head.setPosition(_bodyBall[ BODY_BALL_HEAD_BASE ].position);
|
_head.setPosition(_bodyBall[ BODY_BALL_HEAD_BASE ].position);
|
||||||
_head.setScale (_bodyBall[ BODY_BALL_HEAD_BASE ].radius);
|
_head.setScale (_bodyBall[ BODY_BALL_HEAD_BASE ].radius);
|
||||||
|
|
|
@ -5,13 +5,16 @@
|
||||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
|
||||||
#include <glm/gtx/quaternion.hpp>
|
#include <glm/gtx/quaternion.hpp>
|
||||||
|
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
#include <AgentList.h>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "Avatar.h"
|
#include "Avatar.h"
|
||||||
#include "Head.h"
|
#include "Head.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
#include <vector>
|
#include "renderer/ProgramObject.h"
|
||||||
#include <lodepng.h>
|
|
||||||
#include <AgentList.h>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -36,9 +39,8 @@ const float IRIS_RADIUS = 0.007;
|
||||||
const float IRIS_PROTRUSION = 0.0145f;
|
const float IRIS_PROTRUSION = 0.0145f;
|
||||||
const char IRIS_TEXTURE_FILENAME[] = "resources/images/iris.png";
|
const char IRIS_TEXTURE_FILENAME[] = "resources/images/iris.png";
|
||||||
|
|
||||||
unsigned int IRIS_TEXTURE_WIDTH = 768;
|
ProgramObject* Head::_irisProgram = 0;
|
||||||
unsigned int IRIS_TEXTURE_HEIGHT = 498;
|
GLuint Head::_irisTextureID;
|
||||||
vector<unsigned char> irisTexture;
|
|
||||||
|
|
||||||
Head::Head(Avatar* owningAvatar) :
|
Head::Head(Avatar* owningAvatar) :
|
||||||
HeadData((AvatarData*)owningAvatar),
|
HeadData((AvatarData*)owningAvatar),
|
||||||
|
@ -57,7 +59,6 @@ Head::Head(Avatar* owningAvatar) :
|
||||||
_mouthPosition(0.0f, 0.0f, 0.0f),
|
_mouthPosition(0.0f, 0.0f, 0.0f),
|
||||||
_scale(1.0f),
|
_scale(1.0f),
|
||||||
_browAudioLift(0.0f),
|
_browAudioLift(0.0f),
|
||||||
_lookingAtSomething(false),
|
|
||||||
_gravity(0.0f, -1.0f, 0.0f),
|
_gravity(0.0f, -1.0f, 0.0f),
|
||||||
_lastLoudness(0.0f),
|
_lastLoudness(0.0f),
|
||||||
_averageLoudness(0.0f),
|
_averageLoudness(0.0f),
|
||||||
|
@ -67,13 +68,35 @@ Head::Head(Avatar* owningAvatar) :
|
||||||
_lookingInMirror(false),
|
_lookingInMirror(false),
|
||||||
_renderLookatVectors(false),
|
_renderLookatVectors(false),
|
||||||
_mohawkTriangleFan(NULL),
|
_mohawkTriangleFan(NULL),
|
||||||
_mohawkColors(NULL)
|
_mohawkColors(NULL),
|
||||||
|
_saccade(0.0f, 0.0f, 0.0f),
|
||||||
|
_saccadeTarget(0.0f, 0.0f, 0.0f)
|
||||||
{
|
{
|
||||||
if (USING_PHYSICAL_MOHAWK) {
|
if (USING_PHYSICAL_MOHAWK) {
|
||||||
resetHairPhysics();
|
resetHairPhysics();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Head::init() {
|
||||||
|
if (_irisProgram == 0) {
|
||||||
|
switchToResourcesParentIfRequired();
|
||||||
|
_irisProgram = new ProgramObject();
|
||||||
|
_irisProgram->addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/iris.vert");
|
||||||
|
_irisProgram->addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/iris.frag");
|
||||||
|
_irisProgram->link();
|
||||||
|
|
||||||
|
_irisProgram->setUniformValue("texture", 0);
|
||||||
|
|
||||||
|
QImage image = QImage(IRIS_TEXTURE_FILENAME).convertToFormat(QImage::Format_RGB888);
|
||||||
|
|
||||||
|
glGenTextures(1, &_irisTextureID);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, _irisTextureID);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image.constBits());
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Head::reset() {
|
void Head::reset() {
|
||||||
_yaw = _pitch = _roll = 0.0f;
|
_yaw = _pitch = _roll = 0.0f;
|
||||||
_leanForward = _leanSideways = 0.0f;
|
_leanForward = _leanSideways = 0.0f;
|
||||||
|
@ -102,32 +125,19 @@ void Head::resetHairPhysics() {
|
||||||
|
|
||||||
|
|
||||||
void Head::simulate(float deltaTime, bool isMine) {
|
void Head::simulate(float deltaTime, bool isMine) {
|
||||||
|
|
||||||
const float HEAD_MOTION_DECAY = 0.00;
|
|
||||||
|
|
||||||
/*
|
// Update eye saccades
|
||||||
// Decay head back to center if turned on
|
const float AVERAGE_MICROSACCADE_INTERVAL = 0.50f;
|
||||||
if (isMine && _returnHeadToCenter) {
|
const float AVERAGE_SACCADE_INTERVAL = 4.0f;
|
||||||
|
const float MICROSACCADE_MAGNITUDE = 0.002f;
|
||||||
|
const float SACCADE_MAGNITUDE = 0.04;
|
||||||
|
|
||||||
// Decay rotation back toward center
|
if (randFloat() < deltaTime / AVERAGE_MICROSACCADE_INTERVAL) {
|
||||||
_pitch *= (1.0f - HEAD_MOTION_DECAY * _returnSpringScale * deltaTime);
|
_saccadeTarget = MICROSACCADE_MAGNITUDE * randVector();
|
||||||
_yaw *= (1.0f - HEAD_MOTION_DECAY * _returnSpringScale * deltaTime);
|
} else if (randFloat() < deltaTime / AVERAGE_SACCADE_INTERVAL) {
|
||||||
_roll *= (1.0f - HEAD_MOTION_DECAY * _returnSpringScale * deltaTime);
|
_saccadeTarget = SACCADE_MAGNITUDE * randVector();
|
||||||
}
|
}
|
||||||
|
_saccade += (_saccadeTarget - _saccade) * 0.50f;
|
||||||
// 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);
|
|
||||||
|
|
||||||
// Update audio trailing average for rendering facial animations
|
// Update audio trailing average for rendering facial animations
|
||||||
const float AUDIO_AVERAGING_SECS = 0.05;
|
const float AUDIO_AVERAGING_SECS = 0.05;
|
||||||
|
@ -148,30 +158,13 @@ void Head::simulate(float deltaTime, bool isMine) {
|
||||||
|
|
||||||
_browAudioLift *= 0.7f;
|
_browAudioLift *= 0.7f;
|
||||||
|
|
||||||
// based on the nature of the lookat position, determine if the eyes can look / are looking at it.
|
// based on the nature of the lookat position, determine if the eyes can look / are looking at it.
|
||||||
determineIfLookingAtSomething();
|
|
||||||
|
|
||||||
if (USING_PHYSICAL_MOHAWK) {
|
if (USING_PHYSICAL_MOHAWK) {
|
||||||
updateHairPhysics(deltaTime);
|
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() {
|
void Head::calculateGeometry() {
|
||||||
//generate orientation directions
|
//generate orientation directions
|
||||||
glm::quat orientation = getOrientation();
|
glm::quat orientation = getOrientation();
|
||||||
|
@ -218,9 +211,9 @@ void Head::render(bool lookingInMirror, float alpha) {
|
||||||
renderEyeBalls();
|
renderEyeBalls();
|
||||||
renderEars();
|
renderEars();
|
||||||
renderMouth();
|
renderMouth();
|
||||||
renderEyeBrows();
|
renderEyeBrows();
|
||||||
|
|
||||||
if (_renderLookatVectors && _lookingAtSomething) {
|
if (_renderLookatVectors) {
|
||||||
renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition);
|
renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -469,22 +462,11 @@ void Head::renderEyeBrows() {
|
||||||
|
|
||||||
void Head::renderEyeBalls() {
|
void Head::renderEyeBalls() {
|
||||||
|
|
||||||
if (::irisTexture.size() == 0) {
|
// setup the texture to be used on each iris
|
||||||
switchToResourcesParentIfRequired();
|
|
||||||
unsigned error = lodepng::decode(::irisTexture, IRIS_TEXTURE_WIDTH, IRIS_TEXTURE_HEIGHT, IRIS_TEXTURE_FILENAME);
|
|
||||||
if (error != 0) {
|
|
||||||
printLog("error %u: %s\n", error, lodepng_error_text(error));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup the texutre to be used on each iris
|
|
||||||
GLUquadric* irisQuadric = gluNewQuadric();
|
GLUquadric* irisQuadric = gluNewQuadric();
|
||||||
gluQuadricTexture(irisQuadric, GL_TRUE);
|
gluQuadricTexture(irisQuadric, GL_TRUE);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
||||||
gluQuadricOrientation(irisQuadric, GLU_OUTSIDE);
|
gluQuadricOrientation(irisQuadric, GLU_OUTSIDE);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, IRIS_TEXTURE_WIDTH, IRIS_TEXTURE_HEIGHT,
|
|
||||||
0, GL_RGBA, GL_UNSIGNED_BYTE, &::irisTexture[0]);
|
|
||||||
|
|
||||||
// render white ball of left eyeball
|
// render white ball of left eyeball
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
|
@ -493,45 +475,6 @@ void Head::renderEyeBalls() {
|
||||||
gluSphere(irisQuadric, EYEBALL_RADIUS, 30, 30);
|
gluSphere(irisQuadric, EYEBALL_RADIUS, 30, 30);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
glm::vec3 front = getFrontDirection();
|
|
||||||
|
|
||||||
// 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
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
gluSphere(irisQuadric, IRIS_RADIUS, 15, 15);
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
glPopMatrix();
|
|
||||||
}
|
|
||||||
glPopMatrix();
|
|
||||||
|
|
||||||
//render white ball of right eyeball
|
//render white ball of right eyeball
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glColor3fv(EYEBALL_COLOR);
|
glColor3fv(EYEBALL_COLOR);
|
||||||
|
@ -539,43 +482,50 @@ void Head::renderEyeBalls() {
|
||||||
gluSphere(irisQuadric, EYEBALL_RADIUS, 30, 30);
|
gluSphere(irisQuadric, EYEBALL_RADIUS, 30, 30);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
|
_irisProgram->bind();
|
||||||
|
glBindTexture(GL_TEXTURE_2D, _irisTextureID);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
glm::vec3 front = getFrontDirection();
|
||||||
|
|
||||||
|
// render left iris
|
||||||
|
glPushMatrix(); {
|
||||||
|
glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); //translate to eyeball position
|
||||||
|
glPushMatrix();
|
||||||
|
//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();
|
||||||
|
}
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
// render right iris
|
// render right iris
|
||||||
glPushMatrix(); {
|
glPushMatrix(); {
|
||||||
glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); //translate to eyeball position
|
glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); //translate to eyeball position
|
||||||
|
|
||||||
glPushMatrix();
|
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 towards the lookat position
|
||||||
|
glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition + _saccade - _rightEyePosition);
|
||||||
//rotate the eyeball to aim straight ahead
|
glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP);
|
||||||
glm::vec3 rotationAxisToHeadFront = glm::cross(front, IDENTITY_UP);
|
float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP);
|
||||||
float angleToHeadFront = 180.0f - angleBetween(front, IDENTITY_UP);
|
glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z);
|
||||||
glRotatef(angleToHeadFront, rotationAxisToHeadFront.x, rotationAxisToHeadFront.y, rotationAxisToHeadFront.z);
|
glRotatef(180.0f, 0.0f, 1.0f, 0.0f); //adjust roll to correct after previous rotations
|
||||||
|
glTranslatef( 0.0f, -IRIS_PROTRUSION, 0.0f);
|
||||||
//set the amount of roll (for correction after previous rotations)
|
glScalef( 1.0f, 0.5f, 1.0f); // flatten the iris
|
||||||
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
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
gluSphere(irisQuadric, IRIS_RADIUS, 15, 15);
|
gluSphere(irisQuadric, IRIS_RADIUS, 15, 15);
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_irisProgram->release();
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
// delete the iris quadric now that we're done with it
|
// delete the iris quadric now that we're done with it
|
||||||
gluDeleteQuadric(irisQuadric);
|
gluDeleteQuadric(irisQuadric);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
|
@ -26,11 +26,13 @@ enum eyeContactTargets
|
||||||
const int NUM_HAIR_TUFTS = 4;
|
const int NUM_HAIR_TUFTS = 4;
|
||||||
|
|
||||||
class Avatar;
|
class Avatar;
|
||||||
|
class ProgramObject;
|
||||||
|
|
||||||
class Head : public HeadData {
|
class Head : public HeadData {
|
||||||
public:
|
public:
|
||||||
Head(Avatar* owningAvatar);
|
Head(Avatar* owningAvatar);
|
||||||
|
|
||||||
|
void init();
|
||||||
void reset();
|
void reset();
|
||||||
void simulate(float deltaTime, bool isMine);
|
void simulate(float deltaTime, bool isMine);
|
||||||
void render(bool lookingInMirror, float alpha);
|
void render(bool lookingInMirror, float alpha);
|
||||||
|
@ -91,7 +93,6 @@ private:
|
||||||
glm::vec3 _mouthPosition;
|
glm::vec3 _mouthPosition;
|
||||||
float _scale;
|
float _scale;
|
||||||
float _browAudioLift;
|
float _browAudioLift;
|
||||||
bool _lookingAtSomething;
|
|
||||||
glm::vec3 _gravity;
|
glm::vec3 _gravity;
|
||||||
float _lastLoudness;
|
float _lastLoudness;
|
||||||
float _averageLoudness;
|
float _averageLoudness;
|
||||||
|
@ -103,6 +104,11 @@ private:
|
||||||
HairTuft _hairTuft[NUM_HAIR_TUFTS];
|
HairTuft _hairTuft[NUM_HAIR_TUFTS];
|
||||||
glm::vec3* _mohawkTriangleFan;
|
glm::vec3* _mohawkTriangleFan;
|
||||||
glm::vec3* _mohawkColors;
|
glm::vec3* _mohawkColors;
|
||||||
|
glm::vec3 _saccade;
|
||||||
|
glm::vec3 _saccadeTarget;
|
||||||
|
|
||||||
|
static ProgramObject* _irisProgram;
|
||||||
|
static GLuint _irisTextureID;
|
||||||
|
|
||||||
// private methods
|
// private methods
|
||||||
void createMohawk();
|
void createMohawk();
|
||||||
|
@ -113,7 +119,6 @@ private:
|
||||||
void renderMouth();
|
void renderMouth();
|
||||||
void renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition);
|
void renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition);
|
||||||
void calculateGeometry();
|
void calculateGeometry();
|
||||||
void determineIfLookingAtSomething();
|
|
||||||
void resetHairPhysics();
|
void resetHairPhysics();
|
||||||
void updateHairPhysics(float deltaTime);
|
void updateHairPhysics(float deltaTime);
|
||||||
};
|
};
|
||||||
|
|
|
@ -267,6 +267,11 @@ double diffclock(timeval *clock1,timeval *clock2)
|
||||||
return diffms;
|
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* textRenderer(int mono) {
|
||||||
static TextRenderer* monoRenderer = new TextRenderer(MONO_FONT_FAMILY);
|
static TextRenderer* monoRenderer = new TextRenderer(MONO_FONT_FAMILY);
|
||||||
static TextRenderer* proportionalRenderer = new TextRenderer(SANS_FONT_FAMILY, -1, -1, false, TextRenderer::SHADOW_EFFECT);
|
static TextRenderer* proportionalRenderer = new TextRenderer(SANS_FONT_FAMILY, -1, -1, false, TextRenderer::SHADOW_EFFECT);
|
||||||
|
|
|
@ -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 angle_to(glm::vec3 head_pos, glm::vec3 source_pos, float render_yaw, float head_yaw);
|
||||||
|
|
||||||
float randFloat();
|
float randFloat();
|
||||||
|
const glm::vec3 randVector();
|
||||||
|
|
||||||
void render_world_box();
|
void render_world_box();
|
||||||
int widthText(float scale, int mono, char const* string);
|
int widthText(float scale, int mono, char const* string);
|
||||||
float widthChar(float scale, int mono, char ch);
|
float widthChar(float scale, int mono, char ch);
|
||||||
|
|
Loading…
Reference in a new issue