Merge branch 'master' of ssh://github.com/highfidelity/hifi into paddle-fixes

This commit is contained in:
Andrew Meadows 2014-01-17 11:26:04 -08:00
commit 48796231ef
27 changed files with 63 additions and 27082 deletions

View file

@ -137,8 +137,7 @@ void AvatarMixer::processDatagram(const QByteArray& dataByteArray, const HifiSoc
}
}
case PACKET_TYPE_KILL_NODE:
case PACKET_TYPE_AVATAR_URLS:
case PACKET_TYPE_AVATAR_FACE_VIDEO: {
case PACKET_TYPE_AVATAR_URLS: {
QUuid nodeUUID = QUuid::fromRfc4122(dataByteArray.mid(numBytesForPacketHeader((unsigned char*) dataByteArray.data()),
NUM_BYTES_RFC4122_UUID));
// let everyone else know about the update

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

View file

@ -1,17 +0,0 @@
#version 120
//
// face.frag
// fragment shader
//
// Created by Andrzej Kapolka on 7/12/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
// the color texture
uniform sampler2D colorTexture;
void main(void) {
// for now, just modulate color
gl_FragColor = gl_Color * texture2D(colorTexture, gl_TexCoord[0].st);
}

View file

@ -1,32 +0,0 @@
#version 120
//
// face.vert
// vertex shader
//
// Created by Andrzej Kapolka on 7/12/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
// the lower left texture coordinate
uniform vec2 texCoordCorner;
// the texture coordinate vector from left to right
uniform vec2 texCoordRight;
// the texture coordinate vector from bottom to the top
uniform vec2 texCoordUp;
// the depth texture
uniform sampler2D depthTexture;
void main(void) {
gl_TexCoord[0] = vec4(texCoordCorner + gl_Vertex.x * texCoordRight + gl_Vertex.y * texCoordUp, 0.0, 1.0);
float depth = texture2D(depthTexture, gl_TexCoord[0].st).r;
// set alpha to zero for invalid depth values
const float MIN_VISIBLE_DEPTH = 1.0 / 255.0;
const float MAX_VISIBLE_DEPTH = 254.0 / 255.0;
gl_FrontColor = vec4(1.0, 1.0, 1.0, step(MIN_VISIBLE_DEPTH, depth) * (1.0 - step(MAX_VISIBLE_DEPTH, depth)));
gl_Position = gl_ModelViewProjectionMatrix * vec4(0.5 - gl_Vertex.x, gl_Vertex.y - 0.5, depth - 0.5, 1.0);
}

View file

@ -1,83 +0,0 @@
#version 120
//
// face_textured.frag
// fragment shader
//
// Created by Andrzej Kapolka on 8/6/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
// the texture coordinate vector from left to right
uniform vec2 texCoordRight;
// the texture coordinate vector from bottom to the top
uniform vec2 texCoordUp;
// the permutation/normal texture
uniform sampler2D permutationNormalTexture;
// the depth texture
uniform sampler2D depthTexture;
// the position in model space
varying vec3 position;
// returns the gradient at a single corner of our sampling cube
vec3 grad(vec3 location) {
float p1 = texture2D(permutationNormalTexture, vec2(location.x / 256.0, 0.25)).r;
float p2 = texture2D(permutationNormalTexture, vec2(p1 + location.y / 256.0, 0.25)).r;
return texture2D(permutationNormalTexture, vec2(p2 + location.z / 256.0, 0.75)).xyz * 2.0 - vec3(1.0, 1.0, 1.0);
}
// returns the perlin noise value for the specified location
float perlin(vec3 location) {
vec3 floors = floor(location);
vec3 ceils = ceil(location);
vec3 fff = grad(floors);
vec3 ffc = grad(vec3(floors.x, floors.y, ceils.z));
vec3 fcf = grad(vec3(floors.x, ceils.y, floors.z));
vec3 fcc = grad(vec3(floors.x, ceils.y, ceils.z));
vec3 cff = grad(vec3(ceils.x, floors.y, floors.z));
vec3 cfc = grad(vec3(ceils.x, floors.y, ceils.z));
vec3 ccf = grad(vec3(ceils.x, ceils.y, floors.z));
vec3 ccc = grad(ceils);
vec3 ffracts = fract(location);
vec3 cfracts = ffracts - vec3(1.0, 1.0, 1.0);
vec3 params = ffracts*ffracts*(3.0 - 2.0*ffracts);
float fffv = dot(fff, ffracts);
float ffcv = dot(ffc, vec3(ffracts.x, ffracts.y, cfracts.z));
float fcfv = dot(fcf, vec3(ffracts.x, cfracts.y, ffracts.z));
float fccv = dot(fcc, vec3(ffracts.x, cfracts.y, cfracts.z));
float cffv = dot(cff, vec3(cfracts.x, ffracts.y, ffracts.z));
float cfcv = dot(cfc, vec3(cfracts.x, ffracts.y, cfracts.z));
float ccfv = dot(ccf, vec3(cfracts.x, cfracts.y, ffracts.z));
float cccv = dot(ccc, cfracts);
return mix(
mix(mix(fffv, cffv, params.x), mix(fcfv, ccfv, params.x), params.y),
mix(mix(ffcv, cfcv, params.x), mix(fccv, cccv, params.x), params.y),
params.z);
}
void main(void) {
// compute normal from adjacent depth values
float left = texture2D(depthTexture, gl_TexCoord[0].st - texCoordRight * 0.01).r;
float right = texture2D(depthTexture, gl_TexCoord[0].st + texCoordRight * 0.01).r;
float bottom = texture2D(depthTexture, gl_TexCoord[0].st - texCoordUp * 0.01).r;
float top = texture2D(depthTexture, gl_TexCoord[0].st + texCoordUp * 0.01).r;
vec3 normal = normalize(gl_NormalMatrix * vec3(left - right, top - bottom, -0.05));
// compute the specular component (sans exponent) based on the normal OpenGL lighting model
float specular = max(0.0, dot(normalize(gl_LightSource[0].position.xyz + vec3(0.0, 0.0, 1.0)), normal));
// the base color is a subtle marble texture produced by modulating the phase of a sine wave by perlin noise
vec3 color = mix(vec3(1.0, 1.0, 1.0), vec3(0.75, 0.75, 0.75),
sin(dot(position, vec3(25.0, 25.0, 25.0)) + 2.0 * perlin(position * 10.0)));
// standard lighting
gl_FragColor = vec4(color * ( gl_LightModel.ambient.rgb + /* gl_LightSource[0].ambient.rgb + */
gl_LightSource[0].diffuse.rgb * max(0.0, dot(normal, gl_LightSource[0].position.xyz))) +
pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, gl_Color.a);
}

View file

@ -1,38 +0,0 @@
#version 120
//
// face_textured.vert
// vertex shader
//
// Created by Andrzej Kapolka on 8/6/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
// the lower left texture coordinate
uniform vec2 texCoordCorner;
// the texture coordinate vector from left to right
uniform vec2 texCoordRight;
// the texture coordinate vector from bottom to the top
uniform vec2 texCoordUp;
// the depth texture
uniform sampler2D depthTexture;
// the position in model space
varying vec3 position;
void main(void) {
gl_TexCoord[0] = vec4(texCoordCorner + gl_Vertex.x * texCoordRight + gl_Vertex.y * texCoordUp, 0.0, 1.0);
float depth = texture2D(depthTexture, gl_TexCoord[0].st).r;
// store the model space vertex
position = gl_Vertex.xyz;
// set alpha to zero for invalid depth values
const float MIN_VISIBLE_DEPTH = 1.0 / 255.0;
const float MAX_VISIBLE_DEPTH = 254.0 / 255.0;
gl_FrontColor = vec4(1.0, 1.0, 1.0, step(MIN_VISIBLE_DEPTH, depth) * (1.0 - step(MAX_VISIBLE_DEPTH, depth)));
gl_Position = gl_ModelViewProjectionMatrix * vec4(0.5 - gl_Vertex.x, gl_Vertex.y - 0.5, depth - 0.5, 1.0);
}

View file

@ -1,24 +0,0 @@
#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) {
// compute the specular component (sans exponent) based on the normal OpenGL lighting model
float specular = max(0.0, dot(normalize(gl_LightSource[0].position + vec4(0.0, 0.0, 1.0, 0.0)), normalize(normal)));
// modulate texture by diffuse color and add specular contribution
gl_FragColor = gl_Color * texture2D(texture, gl_TexCoord[0].st) +
pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular;
}

View file

@ -1,36 +0,0 @@
#version 120
//
// iris.vert
// vertex shader
//
// Created by Andrzej Kapolka on 6/13/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
// the location of the eye in model space
uniform vec3 eyePosition;
// the interpolated normal
varying vec4 normal;
// the ratio of the indices of refraction
const float refractionEta = 0.75;
void main(void) {
// transform and store the normal for interpolation
normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0));
// compute standard diffuse lighting per-vertex
gl_FrontColor = vec4(gl_Color.rgb * (gl_LightModel.ambient.rgb + gl_LightSource[0].ambient.rgb +
gl_LightSource[0].diffuse.rgb * max(0.0, dot(normal, gl_LightSource[0].position))), gl_Color.a);
// compute the texture coordinate based on where refracted vector hits z=0 in model space
vec4 incidence = normalize(gl_Vertex - vec4(eyePosition, 1.0));
vec4 refracted = refract(incidence, normalize(vec4(gl_Normal, 0.0)), refractionEta);
gl_TexCoord[0] = (gl_Vertex - (gl_Vertex.z / refracted.z) * refracted) + vec4(0.5, 0.5, 0.0, 0.0);
// use standard pipeline transform
gl_Position = ftransform();
}

View file

@ -1,34 +0,0 @@
#version 120
//
// skin_voxels.vert
// vertex shader
//
// Created by Andrzej Kapolka on 5/31/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
const int MAX_BONES = 32;
const int INDICES_PER_VERTEX = 4;
uniform mat4 boneMatrices[MAX_BONES];
attribute vec4 boneIndices;
attribute vec4 boneWeights;
void main(void) {
vec4 position = vec4(0.0, 0.0, 0.0, 0.0);
vec4 normal = vec4(0.0, 0.0, 0.0, 0.0);
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
mat4 boneMatrix = boneMatrices[int(boneIndices[i])];
float boneWeight = boneWeights[i];
position += boneMatrix * gl_Vertex * boneWeight;
normal += boneMatrix * vec4(gl_Normal, 0.0) * boneWeight;
}
position = gl_ModelViewProjectionMatrix * position;
normal = normalize(gl_ModelViewMatrix * normal);
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_Position = position;
}

View file

@ -1474,6 +1474,11 @@ void Application::setFullscreen(bool fullscreen) {
(_window->windowState() & ~Qt::WindowFullScreen));
}
void Application::setEnable3DTVMode(bool enable3DTVMode) {
resizeGL(_glWidget->width(),_glWidget->height());
}
void Application::setRenderVoxels(bool voxelRender) {
_voxelEditSender.setShouldSend(voxelRender);
if (!voxelRender) {
@ -2075,17 +2080,23 @@ void Application::updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot, glm::vec3&
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateMyAvatarLookAtPosition()");
const float FAR_AWAY_STARE = TREE_SCALE;
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
lookAtSpot = _myCamera.getPosition();
} else if (_mouseHidden) {
// if the mouse cursor is hidden, just look straight ahead
glm::vec3 rayOrigin, rayDirection;
_viewFrustum.computePickRay(0.5f, 0.5f, rayOrigin, rayDirection);
lookAtSpot = rayOrigin + rayDirection * FAR_AWAY_STARE;
} else if (!_lookatTargetAvatar) {
if (_isHoverVoxel) {
// Look at the hovered voxel
lookAtSpot = getMouseVoxelWorldCoordinates(_hoverVoxel);
} else {
// Just look in direction of the mouse ray
const float FAR_AWAY_STARE = TREE_SCALE;
// Just look in direction of the mouse ray
lookAtSpot = lookAtRayOrigin + lookAtRayDirection * FAR_AWAY_STARE;
}
}

View file

@ -232,6 +232,8 @@ private slots:
void terminate();
void setFullscreen(bool fullscreen);
void setEnable3DTVMode(bool enable3DTVMode);
void renderThrustAtVoxel(const glm::vec3& thrust);

View file

@ -297,7 +297,7 @@ void Audio::handleAudioInput() {
QByteArray inputByteArray = _inputDevice->readAll();
if (Menu::getInstance()->isOptionChecked(MenuOption::EchoLocalAudio)) {
if (Menu::getInstance()->isOptionChecked(MenuOption::EchoLocalAudio) && !_muted) {
// if this person wants local loopback add that to the locally injected audio
if (!_loopbackOutputDevice) {

View file

@ -232,7 +232,10 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FirstPerson, Qt::Key_P, true);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0, false);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0,
false,
appInstance,
SLOT(setEnable3DTVMode(bool)));
QMenu* avatarSizeMenu = viewMenu->addMenu("Avatar Size");

View file

@ -31,7 +31,6 @@
using namespace std;
const bool BALLS_ON = false;
const glm::vec3 DEFAULT_UP_DIRECTION(0.0f, 1.0f, 0.0f);
const float YAW_MAG = 500.0f;
const float MY_HAND_HOLDING_PULL = 0.2f;
@ -40,7 +39,6 @@ const float BODY_SPRING_DEFAULT_TIGHTNESS = 1000.0f;
const float BODY_SPRING_FORCE = 300.0f;
const float BODY_SPRING_DECAY = 16.0f;
const float COLLISION_RADIUS_SCALAR = 1.2f; // pertains to avatar-to-avatar collisions
const float COLLISION_BALL_FORCE = 200.0f; // pertains to avatar-to-avatar collisions
const float COLLISION_BODY_FORCE = 30.0f; // pertains to avatar-to-avatar collisions
const float HEAD_ROTATION_SCALE = 0.70f;
const float HEAD_ROLL_SCALE = 0.40f;
@ -56,8 +54,6 @@ const float LEAN_SENSITIVITY = 0.15f;
const float LEAN_MAX = 0.45f;
const float LEAN_AVERAGING = 10.0f;
const float HEAD_RATE_MAX = 50.f;
const float SKIN_COLOR[] = {1.0f, 0.84f, 0.66f};
const float DARK_SKIN_COLOR[] = {0.9f, 0.78f, 0.63f};
const int NUM_BODY_CONE_SIDES = 9;
const float CHAT_MESSAGE_SCALE = 0.0015f;
const float CHAT_MESSAGE_HEIGHT = 0.1f;
@ -82,7 +78,6 @@ Avatar::Avatar(Node* owningNode) :
_head(this),
_hand(this),
_skeletonModel(this),
_ballSpringsInitialized(false),
_bodyYawDelta(0.0f),
_mode(AVATAR_MODE_STANDING),
_velocity(0.0f, 0.0f, 0.0f),
@ -95,8 +90,7 @@ Avatar::Avatar(Node* owningNode) :
_mouseRayDirection(0.0f, 0.0f, 0.0f),
_isCollisionsOn(true),
_moving(false),
_initialized(false),
_handHoldingPosition(0.0f, 0.0f, 0.0f)
_initialized(false)
{
// we may have been created in the network thread, but we live in the main thread
moveToThread(Application::getInstance()->thread());
@ -155,7 +149,6 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
}
_head.setPosition(headPosition);
_head.setScale(_scale);
_head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2]));
_head.simulate(deltaTime, false);
// use speed and angular velocity to determine walking vs. standing
@ -275,20 +268,10 @@ void Avatar::renderBody(bool forceRenderHead) {
glm::vec3 pos = getPosition();
//printf("Render other at %.3f, %.2f, %.2f\n", pos.x, pos.y, pos.z);
_skeletonModel.render(1.0f);
_head.render(1.0f, false);
_head.render(1.0f);
_hand.render(false);
}
void Avatar::getSkinColors(glm::vec3& lighter, glm::vec3& darker) {
lighter = glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2]);
darker = glm::vec3(DARK_SKIN_COLOR[0], DARK_SKIN_COLOR[1], DARK_SKIN_COLOR[2]);
if (_head.getFaceModel().isActive()) {
lighter = glm::vec3(_head.getFaceModel().computeAverageColor());
const float SKIN_DARKENING = 0.9f;
darker = lighter * SKIN_DARKENING;
}
}
bool Avatar::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const {
float minDistance = FLT_MAX;
float modelDistance;
@ -461,7 +444,7 @@ void Avatar::resetSize() {
qDebug("Reseted scale to %f", _targetScale);
}
void Avatar::setScale(const float scale) {
void Avatar::setScale(float scale) {
_scale = scale;
if (_targetScale * (1.f - RESCALING_TOLERANCE) < _scale &&

View file

@ -26,65 +26,9 @@ static const float SCALING_RATIO = .05f;
static const float SMOOTHING_RATIO = .05f; // 0 < ratio < 1
static const float RESCALING_TOLERANCE = .02f;
const float BODY_BALL_RADIUS_PELVIS = 0.07f;
const float BODY_BALL_RADIUS_TORSO = 0.065f;
const float BODY_BALL_RADIUS_CHEST = 0.08f;
const float BODY_BALL_RADIUS_NECK_BASE = 0.03f;
const float BODY_BALL_RADIUS_HEAD_BASE = 0.07f;
const float BODY_BALL_RADIUS_LEFT_COLLAR = 0.04f;
const float BODY_BALL_RADIUS_LEFT_SHOULDER = 0.03f;
const float BODY_BALL_RADIUS_LEFT_ELBOW = 0.02f;
const float BODY_BALL_RADIUS_LEFT_WRIST = 0.02f;
const float BODY_BALL_RADIUS_LEFT_FINGERTIPS = 0.01f;
const float BODY_BALL_RADIUS_RIGHT_COLLAR = 0.04f;
const float BODY_BALL_RADIUS_RIGHT_SHOULDER = 0.03f;
const float BODY_BALL_RADIUS_RIGHT_ELBOW = 0.02f;
const float BODY_BALL_RADIUS_RIGHT_WRIST = 0.02f;
const float BODY_BALL_RADIUS_RIGHT_FINGERTIPS = 0.01f;
const float BODY_BALL_RADIUS_LEFT_HIP = 0.04f;
const float BODY_BALL_RADIUS_LEFT_MID_THIGH = 0.03f;
const float BODY_BALL_RADIUS_LEFT_KNEE = 0.025f;
const float BODY_BALL_RADIUS_LEFT_HEEL = 0.025f;
const float BODY_BALL_RADIUS_LEFT_TOES = 0.025f;
const float BODY_BALL_RADIUS_RIGHT_HIP = 0.04f;
const float BODY_BALL_RADIUS_RIGHT_KNEE = 0.025f;
const float BODY_BALL_RADIUS_RIGHT_HEEL = 0.025f;
const float BODY_BALL_RADIUS_RIGHT_TOES = 0.025f;
extern const bool usingBigSphereCollisionTest;
extern const float CHAT_MESSAGE_SCALE;
extern const float CHAT_MESSAGE_HEIGHT;
enum AvatarBodyBallID {
BODY_BALL_NULL = -1,
BODY_BALL_PELVIS,
BODY_BALL_TORSO,
BODY_BALL_CHEST,
BODY_BALL_NECK_BASE,
BODY_BALL_HEAD_BASE,
BODY_BALL_HEAD_TOP,
BODY_BALL_LEFT_COLLAR,
BODY_BALL_LEFT_SHOULDER,
BODY_BALL_LEFT_ELBOW,
BODY_BALL_LEFT_WRIST,
BODY_BALL_LEFT_FINGERTIPS,
BODY_BALL_RIGHT_COLLAR,
BODY_BALL_RIGHT_SHOULDER,
BODY_BALL_RIGHT_ELBOW,
BODY_BALL_RIGHT_WRIST,
BODY_BALL_RIGHT_FINGERTIPS,
BODY_BALL_LEFT_HIP,
BODY_BALL_LEFT_KNEE,
BODY_BALL_LEFT_HEEL,
BODY_BALL_LEFT_TOES,
BODY_BALL_RIGHT_HIP,
BODY_BALL_RIGHT_KNEE,
BODY_BALL_RIGHT_HEEL,
BODY_BALL_RIGHT_TOES,
NUM_AVATAR_BODY_BALLS
};
enum DriveKeys {
FWD = 0,
BACK,
@ -151,8 +95,6 @@ public:
glm::quat getOrientation() const;
glm::quat getWorldAlignedOrientation() const;
void getSkinColors(glm::vec3& lighter, glm::vec3& darker);
bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const;
/// Checks for penetration between the described sphere and the avatar.
@ -189,7 +131,6 @@ protected:
Head _head;
Hand _hand;
SkeletonModel _skeletonModel;
bool _ballSpringsInitialized;
float _bodyYawDelta;
AvatarMode _mode;
glm::vec3 _velocity;
@ -210,26 +151,17 @@ protected:
glm::vec3 getBodyUpDirection() const { return getOrientation() * IDENTITY_UP; }
glm::vec3 getBodyFrontDirection() const { return getOrientation() * IDENTITY_FRONT; }
glm::quat computeRotationFromBodyToWorldUp(float proportion = 1.0f) const;
void setScale(const float scale);
void setScale(float scale);
float getHeight() const;
float getPelvisFloatingHeight() const;
float getPelvisToHeadLength() const;
private:
// privatize copy constructor and assignment operator to avoid copying
Avatar(const Avatar&);
Avatar& operator= (const Avatar&);
bool _initialized;
glm::vec3 _handHoldingPosition;
// private methods...
glm::vec3 calculateAverageEyePosition() { return _head.calculateAverageEyePosition(); } // get the position smack-dab between the eyes (for lookat)
float getBallRenderAlpha(int ball, bool forceRenderHead) const;
void renderBody(bool forceRenderHead);
void initializeBodyBalls();
void resetBodyBalls();
};
#endif

View file

@ -65,7 +65,7 @@ void FaceModel::maybeUpdateNeckRotation(const JointState& parentState, const FBX
void FaceModel::maybeUpdateEyeRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) {
// likewise with the eye joints
glm::mat4 inverse = glm::inverse(parentState.transform *
glm::mat4 inverse = glm::inverse(parentState.transform * glm::translate(state.translation) *
joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation));
glm::vec3 front = glm::vec3(inverse * glm::vec4(_owningHead->getOrientation() * IDENTITY_FRONT, 0.0f));
glm::vec3 lookAt = glm::vec3(inverse * glm::vec4(_owningHead->getLookAtPosition() +

View file

@ -9,66 +9,26 @@
#include <NodeList.h>
#include "Application.h"
#include "Menu.h"
#include "Avatar.h"
#include "Head.h"
#include "Menu.h"
#include "Util.h"
#include "renderer/ProgramObject.h"
using namespace std;
const float EYE_RIGHT_OFFSET = 0.27f;
const float EYE_UP_OFFSET = 0.36f;
const float EYE_FRONT_OFFSET = 0.8f;
const float EAR_RIGHT_OFFSET = 1.0f;
const float MOUTH_UP_OFFSET = -0.3f;
const float HEAD_MOTION_DECAY = 0.1f;
const float MINIMUM_EYE_ROTATION_DOT = 0.5f; // based on a dot product: 1.0 is straight ahead, 0.0 is 90 degrees off
const float EYEBALL_RADIUS = 0.017f;
const float EYELID_RADIUS = 0.019f;
const float EYEBALL_COLOR[3] = { 0.9f, 0.9f, 0.8f };
const float HAIR_SPRING_FORCE = 15.0f;
const float HAIR_TORQUE_FORCE = 0.2f;
const float HAIR_GRAVITY_FORCE = 0.001f;
const float HAIR_DRAG = 10.0f;
const float HAIR_LENGTH = 0.09f;
const float HAIR_THICKNESS = 0.03f;
const float NOSE_LENGTH = 0.025f;
const float NOSE_WIDTH = 0.03f;
const float NOSE_HEIGHT = 0.034f;
const float NOSE_UP_OFFSET = -0.07f;
const float NOSE_UPTURN = 0.005f;
const float IRIS_RADIUS = 0.007f;
const float IRIS_PROTRUSION = 0.0145f;
const char IRIS_TEXTURE_FILENAME[] = "resources/images/iris.png";
ProgramObject Head::_irisProgram;
QSharedPointer<DilatableNetworkTexture> Head::_irisTexture;
int Head::_eyePositionLocation;
Head::Head(Avatar* owningAvatar) :
HeadData((AvatarData*)owningAvatar),
yawRate(0.0f),
_renderAlpha(0.0),
_returnHeadToCenter(false),
_skinColor(0.0f, 0.0f, 0.0f),
_position(0.0f, 0.0f, 0.0f),
_rotation(0.0f, 0.0f, 0.0f),
_leftEyePosition(0.0f, 0.0f, 0.0f),
_rightEyePosition(0.0f, 0.0f, 0.0f),
_eyePosition(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),
_rightEarPosition(0.0f, 0.0f, 0.0f),
_mouthPosition(0.0f, 0.0f, 0.0f),
_scale(1.0f),
_gravity(0.0f, -1.0f, 0.0f),
_lastLoudness(0.0f),
_audioAttack(0.0f),
_returnSpringScale(1.0f),
_bodyRotation(0.0f, 0.0f, 0.0f),
_angularVelocity(0,0,0),
_renderLookatVectors(false),
@ -87,18 +47,6 @@ Head::Head(Avatar* owningAvatar) :
}
void Head::init() {
if (!_irisProgram.isLinked()) {
switchToResourcesParentIfRequired();
_irisProgram.addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/iris.vert");
_irisProgram.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/iris.frag");
_irisProgram.link();
_irisProgram.setUniformValue("texture", 0);
_eyePositionLocation = _irisProgram.uniformLocation("eyePosition");
_irisTexture = Application::getInstance()->getTextureCache()->getTexture(QUrl::fromLocalFile(IRIS_TEXTURE_FILENAME),
false, true).staticCast<DilatableNetworkTexture>();
}
_faceModel.init();
}
@ -218,76 +166,15 @@ void Head::simulate(float deltaTime, bool isMine) {
_faceModel.simulate(deltaTime);
calculateGeometry();
// the blend face may have custom eye meshes
if (!_faceModel.getEyePositions(_leftEyePosition, _rightEyePosition)) {
_leftEyePosition = _rightEyePosition = getPosition();
}
_eyePosition = calculateAverageEyePosition();
}
void Head::calculateGeometry() {
//generate orientation directions
glm::quat orientation = getOrientation();
glm::vec3 right = orientation * IDENTITY_RIGHT;
glm::vec3 up = orientation * IDENTITY_UP;
glm::vec3 front = orientation * IDENTITY_FRONT;
float scale = _scale * BODY_BALL_RADIUS_HEAD_BASE;
//calculate the eye positions
_leftEyePosition = _position
- right * scale * EYE_RIGHT_OFFSET
+ up * scale * EYE_UP_OFFSET
+ front * scale * EYE_FRONT_OFFSET;
_rightEyePosition = _position
+ right * scale * EYE_RIGHT_OFFSET
+ up * scale * EYE_UP_OFFSET
+ front * scale * EYE_FRONT_OFFSET;
_eyePosition = _rightEyePosition - right * scale * EYE_RIGHT_OFFSET;
//calculate the eyebrow positions
_leftEyeBrowPosition = _leftEyePosition;
_rightEyeBrowPosition = _rightEyePosition;
//calculate the ear positions
_leftEarPosition = _position - right * scale * EAR_RIGHT_OFFSET;
_rightEarPosition = _position + right * scale * EAR_RIGHT_OFFSET;
//calculate the mouth position
_mouthPosition = _position + up * scale * MOUTH_UP_OFFSET + front * scale;
// calculate nose geometry
glm::vec3 noseBase = _position + front * 0.95f * scale + up * NOSE_UP_OFFSET * scale;
_nose.top = noseBase + up * _scale * NOSE_HEIGHT;
_nose.left = noseBase - right * _scale * NOSE_WIDTH * ONE_HALF;
_nose.right = noseBase + right * _scale * NOSE_WIDTH * ONE_HALF;
_nose.front = noseBase + front * _scale * NOSE_LENGTH
+ up * _scale * NOSE_UPTURN;
}
void Head::render(float alpha, bool renderAvatarBalls) {
_renderAlpha = alpha;
bool lookatVectorsVisible = _renderLookatVectors;
if (renderAvatarBalls) {
glEnable(GL_DEPTH_TEST);
glEnable(GL_RESCALE_NORMAL);
renderHeadSphere();
renderEyeBalls();
renderEars();
renderMouth();
renderNose();
renderEyeBrows();
} else {
lookatVectorsVisible &= _faceModel.render(alpha);
}
if (lookatVectorsVisible) {
void Head::render(float alpha) {
if (_faceModel.render(alpha) && _renderLookatVectors) {
renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition);
}
}
@ -325,301 +212,6 @@ glm::vec3 Head::getScalePivot() const {
return _faceModel.isActive() ? _faceModel.getTranslation() : _position;
}
void Head::renderHeadSphere() {
glPushMatrix();
glTranslatef(_position.x, _position.y, _position.z); //translate to head position
glScalef(_scale * BODY_BALL_RADIUS_HEAD_BASE,
_scale * BODY_BALL_RADIUS_HEAD_BASE,
_scale * BODY_BALL_RADIUS_HEAD_BASE); //scale to head size
glColor4f(_skinColor.x, _skinColor.y, _skinColor.z, _renderAlpha);
glutSolidSphere(1, 30, 30);
glPopMatrix();
}
void Head::renderEars() {
glPushMatrix();
glColor4f(_skinColor.x, _skinColor.y, _skinColor.z, _renderAlpha);
glTranslatef(_leftEarPosition.x, _leftEarPosition.y, _leftEarPosition.z);
glutSolidSphere(_scale * 0.02, 30, 30);
glPopMatrix();
glPushMatrix();
glColor4f(_skinColor.x, _skinColor.y, _skinColor.z, _renderAlpha);
glTranslatef(_rightEarPosition.x, _rightEarPosition.y, _rightEarPosition.z);
glutSolidSphere(_scale * 0.02, 30, 30);
glPopMatrix();
}
void Head::renderNose() {
glm::vec3 bridgeVector = _nose.front - _nose.top;
glm::vec3 leftvector = _nose.front - _nose.left;
glm::vec3 rightvector = _nose.front - _nose.right;
glm::vec3 leftNormal (glm::normalize(glm::cross(leftvector, bridgeVector)));
glm::vec3 rightNormal (glm::normalize(glm::cross(bridgeVector, rightvector )));
glm::vec3 bottomNormal(glm::normalize(glm::cross(rightvector, leftvector )));
glColor4f(_skinColor.x, _skinColor.y, _skinColor.z, _renderAlpha);
glBegin(GL_TRIANGLES);
glNormal3f(leftNormal.x, leftNormal.y, leftNormal.z);
glVertex3f(_nose.top.x, _nose.top.y, _nose.top.z );
glVertex3f(_nose.left.x, _nose.left.y, _nose.left.z );
glVertex3f(_nose.front.x, _nose.front.y, _nose.front.z );
glNormal3f(rightNormal.x, rightNormal.y, rightNormal.z);
glVertex3f(_nose.top.x, _nose.top.y, _nose.top.z );
glVertex3f(_nose.right.x, _nose.right.y, _nose.right.z );
glVertex3f(_nose.front.x, _nose.front.y, _nose.front.z );
glNormal3f(bottomNormal.x, bottomNormal.y, bottomNormal.z);
glVertex3f(_nose.left.x, _nose.left.y, _nose.left.z );
glVertex3f(_nose.right.x, _nose.right.y, _nose.right.z );
glVertex3f(_nose.front.x, _nose.front.y, _nose.front.z );
glEnd();
}
void Head::renderMouth() {
float s = sqrt(_averageLoudness);
glm::quat orientation = getOrientation();
glm::vec3 right = orientation * IDENTITY_RIGHT;
glm::vec3 up = orientation * IDENTITY_UP;
glm::vec3 front = orientation * IDENTITY_FRONT;
glm::vec3 r = right * _scale * BODY_BALL_RADIUS_HEAD_BASE * (0.30f + s * 0.0014f );
glm::vec3 u = up * _scale * BODY_BALL_RADIUS_HEAD_BASE * (0.05f + s * 0.0040f );
glm::vec3 f = front * _scale * BODY_BALL_RADIUS_HEAD_BASE * 0.09f;
glm::vec3 middle = _mouthPosition;
glm::vec3 leftCorner = _mouthPosition - r * 1.0f;
glm::vec3 rightCorner = _mouthPosition + r * 1.0f;
glm::vec3 leftTop = _mouthPosition - r * 0.4f + u * 0.7f + f;
glm::vec3 rightTop = _mouthPosition + r * 0.4f + u * 0.7f + f;
glm::vec3 leftBottom = _mouthPosition - r * 0.4f - u * 1.0f + f * 0.7f;
glm::vec3 rightBottom = _mouthPosition + r * 0.4f - u * 1.0f + f * 0.7f;
// constrain all mouth vertices to a sphere slightly larger than the head...
const float MOUTH_OFFSET_OFF_FACE = 0.003f;
float constrainedRadius = _scale * BODY_BALL_RADIUS_HEAD_BASE + MOUTH_OFFSET_OFF_FACE;
middle = _position + glm::normalize(middle - _position) * constrainedRadius;
leftCorner = _position + glm::normalize(leftCorner - _position) * constrainedRadius;
rightCorner = _position + glm::normalize(rightCorner - _position) * constrainedRadius;
leftTop = _position + glm::normalize(leftTop - _position) * constrainedRadius;
rightTop = _position + glm::normalize(rightTop - _position) * constrainedRadius;
leftBottom = _position + glm::normalize(leftBottom - _position) * constrainedRadius;
rightBottom = _position + glm::normalize(rightBottom - _position) * constrainedRadius;
glColor3f(0.2f, 0.0f, 0.0f);
glBegin(GL_TRIANGLES);
glVertex3f(leftCorner.x, leftCorner.y, leftCorner.z );
glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z );
glVertex3f(leftTop.x, leftTop.y, leftTop.z );
glVertex3f(leftTop.x, leftTop.y, leftTop.z );
glVertex3f(middle.x, middle.y, middle.z );
glVertex3f(rightTop.x, rightTop.y, rightTop.z );
glVertex3f(leftTop.x, leftTop.y, leftTop.z );
glVertex3f(middle.x, middle.y, middle.z );
glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z );
glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z );
glVertex3f(middle.x, middle.y, middle.z );
glVertex3f(rightBottom.x, rightBottom.y, rightBottom.z);
glVertex3f(rightTop.x, rightTop.y, rightTop.z );
glVertex3f(middle.x, middle.y, middle.z );
glVertex3f(rightBottom.x, rightBottom.y, rightBottom.z);
glVertex3f(rightTop.x, rightTop.y, rightTop.z );
glVertex3f(rightBottom.x, rightBottom.y, rightBottom.z);
glVertex3f(rightCorner.x, rightCorner.y, rightCorner.z);
glEnd();
}
void Head::renderEyeBrows() {
float height = _scale * BODY_BALL_RADIUS_HEAD_BASE * 0.3f + _browAudioLift;
float length = _scale * BODY_BALL_RADIUS_HEAD_BASE * 0.2f;
float width = _scale * BODY_BALL_RADIUS_HEAD_BASE * 0.07f;
glColor3f(0.3f, 0.25f, 0.2f);
glm::vec3 leftCorner = _leftEyePosition;
glm::vec3 rightCorner = _leftEyePosition;
glm::vec3 leftTop = _leftEyePosition;
glm::vec3 rightTop = _leftEyePosition;
glm::vec3 leftBottom = _leftEyePosition;
glm::vec3 rightBottom = _leftEyePosition;
glm::quat orientation = getOrientation();
glm::vec3 right = orientation * IDENTITY_RIGHT;
glm::vec3 up = orientation * IDENTITY_UP;
glm::vec3 front = orientation * IDENTITY_FRONT;
glm::vec3 r = right * length;
glm::vec3 u = up * height;
glm::vec3 t = up * (height + width);
glm::vec3 f = front * _scale * BODY_BALL_RADIUS_HEAD_BASE * -0.1f;
for (int i = 0; i < 2; i++) {
if ( i == 1 ) {
leftCorner = rightCorner = leftTop = rightTop = leftBottom = rightBottom = _rightEyePosition;
}
leftCorner -= r * 1.0f;
rightCorner += r * 1.0f;
leftTop -= r * 0.4f;
rightTop += r * 0.4f;
leftBottom -= r * 0.4f;
rightBottom += r * 0.4f;
leftCorner += u + f;
rightCorner += u + f;
leftTop += t + f;
rightTop += t + f;
leftBottom += u + f;
rightBottom += u + f;
glBegin(GL_TRIANGLES);
glVertex3f(leftCorner.x, leftCorner.y, leftCorner.z );
glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z );
glVertex3f(leftTop.x, leftTop.y, leftTop.z );
glVertex3f(leftTop.x, leftTop.y, leftTop.z );
glVertex3f(rightTop.x, rightTop.y, rightTop.z );
glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z );
glVertex3f(rightTop.x, rightTop.y, rightTop.z );
glVertex3f(leftBottom.x, leftBottom.y, leftBottom.z );
glVertex3f(rightBottom.x, rightBottom.y, rightBottom.z);
glVertex3f(rightTop.x, rightTop.y, rightTop.z );
glVertex3f(rightBottom.x, rightBottom.y, rightBottom.z);
glVertex3f(rightCorner.x, rightCorner.y, rightCorner.z);
glEnd();
}
}
void Head::renderEyeBalls() {
// render white ball of left eyeball
glPushMatrix();
glColor3fv(EYEBALL_COLOR);
glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z);
glutSolidSphere(_scale * EYEBALL_RADIUS, 30, 30);
glPopMatrix();
//render white ball of right eyeball
glPushMatrix();
glColor3fv(EYEBALL_COLOR);
glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z);
glutSolidSphere(_scale * EYEBALL_RADIUS, 30, 30);
glPopMatrix();
_irisProgram.bind();
_dilatedIrisTexture = _irisTexture->getDilatedTexture(_pupilDilation);
glBindTexture(GL_TEXTURE_2D, _dilatedIrisTexture->getID());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glEnable(GL_TEXTURE_2D);
// render left iris
glm::quat leftIrisRotation;
glPushMatrix(); {
glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); //translate to eyeball position
//rotate the eyeball to aim towards the lookat position
leftIrisRotation = getEyeRotation(_leftEyePosition);
glm::vec3 rotationAxis = glm::axis(leftIrisRotation);
glRotatef(glm::angle(leftIrisRotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
glTranslatef(0.0f, 0.0f, -_scale * IRIS_PROTRUSION);
glScalef(_scale * IRIS_RADIUS * 2.0f,
_scale * IRIS_RADIUS * 2.0f,
_scale * IRIS_RADIUS); // flatten the iris
// this ugliness is simply to invert the model transform and get the eye position in model space
_irisProgram.setUniform(_eyePositionLocation, (glm::inverse(leftIrisRotation) *
(Application::getInstance()->getCamera()->getPosition() - _leftEyePosition) +
glm::vec3(0.0f, 0.0f, _scale * IRIS_PROTRUSION)) * glm::vec3(1.0f / (_scale * IRIS_RADIUS * 2.0f),
1.0f / (_scale * IRIS_RADIUS * 2.0f), 1.0f / (_scale * IRIS_RADIUS)));
glutSolidSphere(0.5f, 15, 15);
}
glPopMatrix();
// render right iris
glm::quat rightIrisRotation;
glPushMatrix(); {
glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); //translate to eyeball position
//rotate the eyeball to aim towards the lookat position
rightIrisRotation = getEyeRotation(_rightEyePosition);
glm::vec3 rotationAxis = glm::axis(rightIrisRotation);
glRotatef(glm::angle(rightIrisRotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
glTranslatef(0.0f, 0.0f, -_scale * IRIS_PROTRUSION);
glScalef(_scale * IRIS_RADIUS * 2.0f,
_scale * IRIS_RADIUS * 2.0f,
_scale * IRIS_RADIUS); // flatten the iris
// this ugliness is simply to invert the model transform and get the eye position in model space
_irisProgram.setUniform(_eyePositionLocation, (glm::inverse(rightIrisRotation) *
(Application::getInstance()->getCamera()->getPosition() - _rightEyePosition) +
glm::vec3(0.0f, 0.0f, _scale * IRIS_PROTRUSION)) * glm::vec3(1.0f / (_scale * IRIS_RADIUS * 2.0f),
1.0f / (_scale * IRIS_RADIUS * 2.0f), 1.0f / (_scale * IRIS_RADIUS)));
glutSolidSphere(0.5f, 15, 15);
}
glPopMatrix();
_irisProgram.release();
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
glEnable(GL_RESCALE_NORMAL);
glColor4f(_skinColor.x, _skinColor.y, _skinColor.z, _renderAlpha);
// left eyelid
glPushMatrix(); {
glTranslatef(_leftEyePosition.x, _leftEyePosition.y, _leftEyePosition.z); //translate to eyeball position
glm::vec3 rotationAxis = glm::axis(leftIrisRotation);
glRotatef(glm::angle(leftIrisRotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
glScalef(_scale * EYELID_RADIUS, _scale * EYELID_RADIUS, _scale * EYELID_RADIUS);
float angle = -67.5f - 50.0f * _leftEyeBlink;
glRotatef(angle, 1, 0, 0);
Application::getInstance()->getGeometryCache()->renderHemisphere(15, 10);
glRotatef(glm::mix(-angle, 180.0f, max(0.0f, _leftEyeBlink)), 1, 0, 0);
Application::getInstance()->getGeometryCache()->renderHemisphere(15, 10);
}
glPopMatrix();
// right eyelid
glPushMatrix(); {
glTranslatef(_rightEyePosition.x, _rightEyePosition.y, _rightEyePosition.z); //translate to eyeball position
glm::vec3 rotationAxis = glm::axis(rightIrisRotation);
glRotatef(glm::angle(rightIrisRotation), rotationAxis.x, rotationAxis.y, rotationAxis.z);
glScalef(_scale * EYELID_RADIUS, _scale * EYELID_RADIUS, _scale * EYELID_RADIUS);
float angle = -67.5f - 50.0f * _rightEyeBlink;
glRotatef(angle, 1, 0, 0);
Application::getInstance()->getGeometryCache()->renderHemisphere(15, 10);
glRotatef(glm::mix(-angle, 180.0f, max(0.0f, _rightEyeBlink)), 1, 0, 0);
Application::getInstance()->getGeometryCache()->renderHemisphere(15, 10);
}
glPopMatrix();
glDisable(GL_RESCALE_NORMAL);
}
void Head::renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition) {
Application::getInstance()->getGlowEffect()->begin();

View file

@ -20,7 +20,6 @@
#include "FaceModel.h"
#include "InterfaceConfig.h"
#include "world.h"
#include "renderer/TextureCache.h"
enum eyeContactTargets {
LEFT_EYE,
@ -38,13 +37,11 @@ public:
void init();
void reset();
void simulate(float deltaTime, bool isMine);
void render(float alpha, bool renderAvatarBalls);
void render(float alpha);
void setScale(float scale);
void setPosition(glm::vec3 position) { _position = position; }
void setBodyRotation(glm::vec3 bodyRotation) { _bodyRotation = bodyRotation; }
void setGravity(glm::vec3 gravity) { _gravity = gravity; }
void setSkinColor(glm::vec3 skinColor) { _skinColor = skinColor; }
void setSpringScale(float returnSpringScale) { _returnSpringScale = returnSpringScale; }
void setAverageLoudness(float averageLoudness) { _averageLoudness = averageLoudness; }
void setReturnToCenter (bool returnHeadToCenter) { _returnHeadToCenter = returnHeadToCenter; }
void setRenderLookatVectors(bool onOff) { _renderLookatVectors = onOff; }
@ -59,7 +56,6 @@ public:
float getScale() const { return _scale; }
glm::vec3 getPosition() const { return _position; }
const glm::vec3& getSkinColor() const { return _skinColor; }
const glm::vec3& getEyePosition() const { return _eyePosition; }
const glm::vec3& getSaccade() const { return _saccade; }
glm::vec3 getRightDirection() const { return getOrientation() * IDENTITY_RIGHT; }
@ -85,36 +81,19 @@ private:
Head(const Head&);
Head& operator= (const Head&);
struct Nose {
glm::vec3 top;
glm::vec3 left;
glm::vec3 right;
glm::vec3 front;
};
float _renderAlpha;
bool _returnHeadToCenter;
glm::vec3 _skinColor;
glm::vec3 _position;
glm::vec3 _rotation;
glm::vec3 _leftEyePosition;
glm::vec3 _rightEyePosition;
glm::vec3 _eyePosition;
glm::vec3 _leftEyeBrowPosition;
glm::vec3 _rightEyeBrowPosition;
glm::vec3 _leftEarPosition;
glm::vec3 _rightEarPosition;
glm::vec3 _mouthPosition;
Nose _nose;
float _scale;
glm::vec3 _gravity;
float _lastLoudness;
float _audioAttack;
float _returnSpringScale; //strength of return springs
glm::vec3 _bodyRotation;
glm::vec3 _angularVelocity;
bool _renderLookatVectors;
//BendyLine _hairTuft[NUM_HAIR_TUFTS];
glm::vec3 _saccade;
glm::vec3 _saccadeTarget;
float _leftEyeBlinkVelocity;
@ -125,22 +104,9 @@ private:
float _cameraYaw;
bool _isCameraMoving;
FaceModel _faceModel;
QSharedPointer<Texture> _dilatedIrisTexture;
static ProgramObject _irisProgram;
static QSharedPointer<DilatableNetworkTexture> _irisTexture;
static int _eyePositionLocation;
// private methods
void renderHeadSphere();
void renderEyeBalls();
void renderEyeBrows();
void renderEars();
void renderNose();
void renderMouth();
void renderLookatVectors(glm::vec3 leftEyePosition, glm::vec3 rightEyePosition, glm::vec3 lookatPosition);
void calculateGeometry();
friend class FaceModel;
};

View file

@ -30,7 +30,6 @@ const glm::vec3 DEFAULT_UP_DIRECTION(0.0f, 1.0f, 0.0f);
const float YAW_MAG = 500.0f;
const float PITCH_MAG = 100.0f;
const float COLLISION_RADIUS_SCALAR = 1.2f; // pertains to avatar-to-avatar collisions
const float COLLISION_BALL_FORCE = 200.0f; // pertains to avatar-to-avatar collisions
const float COLLISION_BODY_FORCE = 30.0f; // pertains to avatar-to-avatar collisions
const float COLLISION_RADIUS_SCALE = 0.125f;
const float MOUSE_RAY_TOUCH_RANGE = 0.01f;
@ -181,29 +180,22 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) {
const float OCULUS_ACCELERATION_PULL_THRESHOLD = 1.0f;
const int OCULUS_YAW_OFFSET_THRESHOLD = 10;
if (!Application::getInstance()->getFaceshift()->isActive()) {
// Decay HeadPitch as a function of acceleration, so that you look straight ahead when
// you start moving, but don't do this with an HMD like the Oculus.
if (!OculusManager::isConnected()) {
if (forwardAcceleration > ACCELERATION_PULL_THRESHOLD) {
_head.setMousePitch(_head.getMousePitch() * qMax(0.0f,
(1.f - forwardAcceleration * ACCELERATION_PITCH_DECAY * deltaTime)));
}
} else if (fabsf(forwardAcceleration) > OCULUS_ACCELERATION_PULL_THRESHOLD
&& fabs(_head.getYaw()) > OCULUS_YAW_OFFSET_THRESHOLD) {
// if we're wearing the oculus
// and this acceleration is above the pull threshold
// and the head yaw if off the body by more than OCULUS_YAW_OFFSET_THRESHOLD
if (!Application::getInstance()->getFaceshift()->isActive() && OculusManager::isConnected() &&
fabsf(forwardAcceleration) > OCULUS_ACCELERATION_PULL_THRESHOLD &&
fabs(_head.getYaw()) > OCULUS_YAW_OFFSET_THRESHOLD) {
// if we're wearing the oculus
// and this acceleration is above the pull threshold
// and the head yaw if off the body by more than OCULUS_YAW_OFFSET_THRESHOLD
// match the body yaw to the oculus yaw
_bodyYaw = getAbsoluteHeadYaw();
// match the body yaw to the oculus yaw
_bodyYaw = getAbsoluteHeadYaw();
// set the head yaw to zero for this draw
_head.setYaw(0);
// set the head yaw to zero for this draw
_head.setYaw(0);
// correct the oculus yaw offset
OculusManager::updateYawOffset();
}
// correct the oculus yaw offset
OculusManager::updateYawOffset();
}
const float WALKING_SPEED_THRESHOLD = 0.2f;
@ -262,7 +254,6 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) {
}
_head.setPosition(headPosition);
_head.setScale(_scale);
_head.setSkinColor(glm::vec3(SKIN_COLOR[0], SKIN_COLOR[1], SKIN_COLOR[2]));
_head.simulate(deltaTime, true);
// Zero thrust out now that we've added it to velocity in this frame
@ -510,7 +501,7 @@ void MyAvatar::renderBody(bool forceRenderHead) {
const float RENDER_HEAD_CUTOFF_DISTANCE = 0.10f;
Camera* myCamera = Application::getInstance()->getCamera();
if (forceRenderHead || (glm::length(myCamera->getPosition() - _head.calculateAverageEyePosition()) > RENDER_HEAD_CUTOFF_DISTANCE)) {
_head.render(1.0f, false);
_head.render(1.0f);
}
_hand.render(true);
}

View file

@ -68,46 +68,6 @@ bool SkeletonModel::render(float alpha) {
return false;
}
// only render the balls and sticks if the skeleton has no meshes
if (_meshStates.isEmpty()) {
const FBXGeometry& geometry = _geometry->getFBXGeometry();
glm::vec3 skinColor, darkSkinColor;
_owningAvatar->getSkinColors(skinColor, darkSkinColor);
for (int i = 0; i < _jointStates.size(); i++) {
glPushMatrix();
glm::vec3 position;
getJointPosition(i, position);
Application::getInstance()->loadTranslatedViewMatrix(position);
glm::quat rotation;
getJointRotation(i, rotation);
glm::vec3 axis = glm::axis(rotation);
glRotatef(glm::angle(rotation), axis.x, axis.y, axis.z);
glColor4f(skinColor.r, skinColor.g, skinColor.b, alpha);
const float BALL_RADIUS = 0.005f;
const int BALL_SUBDIVISIONS = 10;
glutSolidSphere(BALL_RADIUS * _owningAvatar->getScale(), BALL_SUBDIVISIONS, BALL_SUBDIVISIONS);
glPopMatrix();
int parentIndex = geometry.joints[i].parentIndex;
if (parentIndex == -1) {
continue;
}
glColor4f(darkSkinColor.r, darkSkinColor.g, darkSkinColor.b, alpha);
glm::vec3 parentPosition;
getJointPosition(parentIndex, parentPosition);
const float STICK_RADIUS = BALL_RADIUS * 0.1f;
Avatar::renderJointConnectingCone(parentPosition, position, STICK_RADIUS * _owningAvatar->getScale(),
STICK_RADIUS * _owningAvatar->getScale());
}
}
Model::render(alpha);
if (Menu::getInstance()->isOptionChecked(MenuOption::CollisionProxies)) {

View file

@ -146,13 +146,6 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
// leap hand data
destinationBuffer += _handData->encodeRemoteData(destinationBuffer);
// skeleton joints
*destinationBuffer++ = (unsigned char)_joints.size();
for (vector<JointData>::iterator it = _joints.begin(); it != _joints.end(); it++) {
*destinationBuffer++ = (unsigned char)it->jointID;
destinationBuffer += packOrientationQuatToBytes(destinationBuffer, it->rotation);
}
return destinationBuffer - bufferStart;
}
@ -273,16 +266,6 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
// check passed, bytes match
sourceBuffer += _handData->decodeRemoteData(sourceBuffer);
}
// skeleton joints
if (sourceBuffer - startPosition < numBytes) {
// check passed, bytes match
_joints.resize(*sourceBuffer++);
for (vector<JointData>::iterator it = _joints.begin(); it != _joints.end(); it++) {
it->jointID = *sourceBuffer++;
sourceBuffer += unpackOrientationQuatFromBytes(sourceBuffer, it->rotation);
}
}
return sourceBuffer - startPosition;
}

View file

@ -60,8 +60,6 @@ enum KeyState
const glm::vec3 vec3Zero(0.0f);
class JointData;
class AvatarData : public NodeData {
Q_OBJECT
@ -161,8 +159,6 @@ protected:
bool _isChatCirclingEnabled;
std::vector<JointData> _joints;
HeadData* _headData;
HandData* _handData;
@ -172,11 +168,4 @@ private:
AvatarData& operator= (const AvatarData&);
};
class JointData {
public:
int jointID;
glm::quat rotation;
};
#endif /* defined(__hifi__AvatarData__) */

View file

@ -412,8 +412,8 @@ OctreeElement* OctreeElement::getChildAtIndex(int childIndex) const {
if (externalIndex < childCount && externalIndex >= 0) {
result = _children.external[externalIndex];
} else {
qDebug("getChildAtIndex() attempt to access external client out of bounds externalIndex=%d <<<<<<<<<< WARNING!!!
",externalIndex);
qDebug("getChildAtIndex() attempt to access external client out of "
"bounds externalIndex=%d <<<<<<<<<< WARNING!!!", externalIndex);
}
break;
}

View file

@ -674,9 +674,9 @@ void NodeList::pingPublicAndLocalSocketsForInactiveNode(Node* node) {
SharedNodePointer NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType,
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) {
NodeHash::iterator matchingNodeItem = _nodeHash.find(uuid);
if (matchingNodeItem == _nodeHash.end()) {
SharedNodePointer matchingNode = _nodeHash.value(uuid);
if (!matchingNode) {
// we didn't have this node, so add them
Node* newNode = new Node(uuid, nodeType, publicSocket, localSocket);
SharedNodePointer newNodeSharedPointer(newNode, &QObject::deleteLater);
@ -689,29 +689,28 @@ SharedNodePointer NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType,
return newNodeSharedPointer;
} else {
SharedNodePointer node = matchingNodeItem.value();
QMutexLocker(&node->getMutex());
QMutexLocker(&matchingNode->getMutex());
if (node->getType() == NODE_TYPE_AUDIO_MIXER ||
node->getType() == NODE_TYPE_VOXEL_SERVER ||
node->getType() == NODE_TYPE_METAVOXEL_SERVER) {
if (matchingNode->getType() == NODE_TYPE_AUDIO_MIXER ||
matchingNode->getType() == NODE_TYPE_VOXEL_SERVER ||
matchingNode->getType() == NODE_TYPE_METAVOXEL_SERVER) {
// until the Audio class also uses our nodeList, we need to update
// the lastRecvTimeUsecs for the audio mixer so it doesn't get killed and re-added continously
node->setLastHeardMicrostamp(usecTimestampNow());
matchingNode->setLastHeardMicrostamp(usecTimestampNow());
}
// check if we need to change this node's public or local sockets
if (publicSocket != node->getPublicSocket()) {
node->setPublicSocket(publicSocket);
qDebug() << "Public socket change for node" << *node;
if (publicSocket != matchingNode->getPublicSocket()) {
matchingNode->setPublicSocket(publicSocket);
qDebug() << "Public socket change for node" << *matchingNode;
}
if (localSocket != node->getLocalSocket()) {
node->setLocalSocket(localSocket);
qDebug() << "Local socket change for node" << *node;
if (localSocket != matchingNode->getLocalSocket()) {
matchingNode->setLocalSocket(localSocket);
qDebug() << "Local socket change for node" << *matchingNode;
}
// we had this node already, do nothing for now
return node;
return matchingNode;
}
}

View file

@ -20,13 +20,10 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) {
return 2;
case PACKET_TYPE_HEAD_DATA:
return 13;
return 14;
case PACKET_TYPE_AVATAR_URLS:
return 2;
case PACKET_TYPE_AVATAR_FACE_VIDEO:
return 2;
case PACKET_TYPE_OCTREE_STATS:
return 2;

View file

@ -26,7 +26,6 @@ const PACKET_TYPE PACKET_TYPE_MICROPHONE_AUDIO_NO_ECHO = 'M';
const PACKET_TYPE PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO = 'm';
const PACKET_TYPE PACKET_TYPE_BULK_AVATAR_DATA = 'X';
const PACKET_TYPE PACKET_TYPE_AVATAR_URLS = 'U';
const PACKET_TYPE PACKET_TYPE_AVATAR_FACE_VIDEO = 'F';
const PACKET_TYPE PACKET_TYPE_TRANSMITTER_DATA_V2 = 'T';
const PACKET_TYPE PACKET_TYPE_ENVIRONMENT_DATA = 'e';
const PACKET_TYPE PACKET_TYPE_DOMAIN_LIST_REQUEST = 'L';