Remove Avatar::_head, use AvatarData::_headData

This commit is contained in:
Andrew Meadows 2014-02-18 17:41:46 -08:00
parent c134b8de5b
commit 4010f3ab3f
8 changed files with 98 additions and 93 deletions

View file

@ -450,22 +450,22 @@ void Application::paintGL() {
_myCamera.setUpShift(0.0f); _myCamera.setUpShift(0.0f);
_myCamera.setDistance(0.0f); _myCamera.setDistance(0.0f);
_myCamera.setTightness(0.0f); // Camera is directly connected to head without smoothing _myCamera.setTightness(0.0f); // Camera is directly connected to head without smoothing
_myCamera.setTargetPosition(_myAvatar->getHead().calculateAverageEyePosition()); _myCamera.setTargetPosition(_myAvatar->getHead()->calculateAverageEyePosition());
_myCamera.setTargetRotation(_myAvatar->getHead().getOrientation()); _myCamera.setTargetRotation(_myAvatar->getHead()->getOrientation());
} 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 (untweaked) head exactly without delay _myCamera.setTightness(0.0f); // In first person, camera follows (untweaked) head exactly without delay
_myCamera.setTargetPosition(_myAvatar->getHead().calculateAverageEyePosition()); _myCamera.setTargetPosition(_myAvatar->getHead()->calculateAverageEyePosition());
_myCamera.setTargetRotation(_myAvatar->getHead().getCameraOrientation()); _myCamera.setTargetRotation(_myAvatar->getHead()->getCameraOrientation());
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
_myCamera.setTightness(0.0f); // Camera is directly connected to head without smoothing _myCamera.setTightness(0.0f); // Camera is directly connected to head without smoothing
_myCamera.setTargetPosition(_myAvatar->getUprightHeadPosition()); _myCamera.setTargetPosition(_myAvatar->getUprightHeadPosition());
_myCamera.setTargetRotation(_myAvatar->getHead().getCameraOrientation()); _myCamera.setTargetRotation(_myAvatar->getHead()->getCameraOrientation());
} else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
_myCamera.setTightness(0.0f); _myCamera.setTightness(0.0f);
float headHeight = _myAvatar->getHead().calculateAverageEyePosition().y - _myAvatar->getPosition().y; float headHeight = _myAvatar->getHead()->calculateAverageEyePosition().y - _myAvatar->getPosition().y;
_myCamera.setDistance(MIRROR_FULLSCREEN_DISTANCE * _myAvatar->getScale()); _myCamera.setDistance(MIRROR_FULLSCREEN_DISTANCE * _myAvatar->getScale());
_myCamera.setTargetPosition(_myAvatar->getPosition() + glm::vec3(0, headHeight, 0)); _myCamera.setTargetPosition(_myAvatar->getPosition() + glm::vec3(0, headHeight, 0));
_myCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PIf, 0.0f))); _myCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PIf, 0.0f)));
@ -529,14 +529,14 @@ void Application::paintGL() {
_mirrorCamera.setTargetPosition(_myAvatar->getChestPosition()); _mirrorCamera.setTargetPosition(_myAvatar->getChestPosition());
} else { // HEAD zoom level } else { // HEAD zoom level
_mirrorCamera.setDistance(MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale()); _mirrorCamera.setDistance(MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale());
if (_myAvatar->getSkeletonModel().isActive() && _myAvatar->getHead().getFaceModel().isActive()) { if (_myAvatar->getSkeletonModel().isActive() && _myAvatar->getHead()->getFaceModel().isActive()) {
// as a hack until we have a better way of dealing with coordinate precision issues, reposition the // as a hack until we have a better way of dealing with coordinate precision issues, reposition the
// face/body so that the average eye position lies at the origin // face/body so that the average eye position lies at the origin
eyeRelativeCamera = true; eyeRelativeCamera = true;
_mirrorCamera.setTargetPosition(glm::vec3()); _mirrorCamera.setTargetPosition(glm::vec3());
} else { } else {
_mirrorCamera.setTargetPosition(_myAvatar->getHead().calculateAverageEyePosition()); _mirrorCamera.setTargetPosition(_myAvatar->getHead()->calculateAverageEyePosition());
} }
} }
@ -558,26 +558,26 @@ void Application::paintGL() {
if (eyeRelativeCamera) { if (eyeRelativeCamera) {
// save absolute translations // save absolute translations
glm::vec3 absoluteSkeletonTranslation = _myAvatar->getSkeletonModel().getTranslation(); glm::vec3 absoluteSkeletonTranslation = _myAvatar->getSkeletonModel().getTranslation();
glm::vec3 absoluteFaceTranslation = _myAvatar->getHead().getFaceModel().getTranslation(); glm::vec3 absoluteFaceTranslation = _myAvatar->getHead()->getFaceModel().getTranslation();
// get the eye positions relative to the neck and use them to set the face translation // get the eye positions relative to the neck and use them to set the face translation
glm::vec3 leftEyePosition, rightEyePosition; glm::vec3 leftEyePosition, rightEyePosition;
_myAvatar->getHead().getFaceModel().setTranslation(glm::vec3()); _myAvatar->getHead()->getFaceModel().setTranslation(glm::vec3());
_myAvatar->getHead().getFaceModel().getEyePositions(leftEyePosition, rightEyePosition); _myAvatar->getHead()->getFaceModel().getEyePositions(leftEyePosition, rightEyePosition);
_myAvatar->getHead().getFaceModel().setTranslation((leftEyePosition + rightEyePosition) * -0.5f); _myAvatar->getHead()->getFaceModel().setTranslation((leftEyePosition + rightEyePosition) * -0.5f);
// get the neck position relative to the body and use it to set the skeleton translation // get the neck position relative to the body and use it to set the skeleton translation
glm::vec3 neckPosition; glm::vec3 neckPosition;
_myAvatar->getSkeletonModel().setTranslation(glm::vec3()); _myAvatar->getSkeletonModel().setTranslation(glm::vec3());
_myAvatar->getSkeletonModel().getNeckPosition(neckPosition); _myAvatar->getSkeletonModel().getNeckPosition(neckPosition);
_myAvatar->getSkeletonModel().setTranslation(_myAvatar->getHead().getFaceModel().getTranslation() - _myAvatar->getSkeletonModel().setTranslation(_myAvatar->getHead()->getFaceModel().getTranslation() -
neckPosition); neckPosition);
displaySide(_mirrorCamera, true); displaySide(_mirrorCamera, true);
// restore absolute translations // restore absolute translations
_myAvatar->getSkeletonModel().setTranslation(absoluteSkeletonTranslation); _myAvatar->getSkeletonModel().setTranslation(absoluteSkeletonTranslation);
_myAvatar->getHead().getFaceModel().setTranslation(absoluteFaceTranslation); _myAvatar->getHead()->getFaceModel().setTranslation(absoluteFaceTranslation);
} else { } else {
displaySide(_mirrorCamera, true); displaySide(_mirrorCamera, true);
} }
@ -1975,8 +1975,8 @@ const float MAX_VOXEL_EDIT_DISTANCE = 50.0f;
const float HEAD_SPHERE_RADIUS = 0.07f; const float HEAD_SPHERE_RADIUS = 0.07f;
bool Application::isLookingAtMyAvatar(Avatar* avatar) { bool Application::isLookingAtMyAvatar(Avatar* avatar) {
glm::vec3 theirLookat = avatar->getHead().getLookAtPosition(); glm::vec3 theirLookat = avatar->getHead()->getLookAtPosition();
glm::vec3 myHeadPosition = _myAvatar->getHead().getPosition(); glm::vec3 myHeadPosition = _myAvatar->getHead()->getPosition();
if (pointInSphere(theirLookat, myHeadPosition, HEAD_SPHERE_RADIUS * _myAvatar->getScale())) { if (pointInSphere(theirLookat, myHeadPosition, HEAD_SPHERE_RADIUS * _myAvatar->getScale())) {
return true; return true;
@ -2037,7 +2037,7 @@ void Application::updateFaceshift() {
// Copy angular velocity if measured by faceshift, to the head // Copy angular velocity if measured by faceshift, to the head
if (_faceshift.isActive()) { if (_faceshift.isActive()) {
_myAvatar->getHead().setAngularVelocity(_faceshift.getHeadAngularVelocity()); _myAvatar->getHead()->setAngularVelocity(_faceshift.getHeadAngularVelocity());
} }
} }
@ -2054,7 +2054,7 @@ void Application::updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot) {
float distance = TREE_SCALE; float distance = TREE_SCALE;
if (_myAvatar->getLookAtTargetAvatar()) { if (_myAvatar->getLookAtTargetAvatar()) {
distance = glm::distance(_mouseRayOrigin, distance = glm::distance(_mouseRayOrigin,
static_cast<Avatar*>(_myAvatar->getLookAtTargetAvatar())->getHead().calculateAverageEyePosition()); static_cast<Avatar*>(_myAvatar->getLookAtTargetAvatar())->getHead()->calculateAverageEyePosition());
} else if (_isHoverVoxel) { } else if (_isHoverVoxel) {
distance = glm::distance(_mouseRayOrigin, getMouseVoxelWorldCoordinates(_hoverVoxel)); distance = glm::distance(_mouseRayOrigin, getMouseVoxelWorldCoordinates(_hoverVoxel));
@ -2063,14 +2063,14 @@ void Application::updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot) {
} }
if (_faceshift.isActive()) { if (_faceshift.isActive()) {
// deflect using Faceshift gaze data // deflect using Faceshift gaze data
glm::vec3 origin = _myAvatar->getHead().calculateAverageEyePosition(); glm::vec3 origin = _myAvatar->getHead()->calculateAverageEyePosition();
float pitchSign = (_myCamera.getMode() == CAMERA_MODE_MIRROR) ? -1.0f : 1.0f; float pitchSign = (_myCamera.getMode() == CAMERA_MODE_MIRROR) ? -1.0f : 1.0f;
float deflection = Menu::getInstance()->getFaceshiftEyeDeflection(); float deflection = Menu::getInstance()->getFaceshiftEyeDeflection();
lookAtSpot = origin + _myCamera.getRotation() * glm::quat(glm::radians(glm::vec3( lookAtSpot = origin + _myCamera.getRotation() * glm::quat(glm::radians(glm::vec3(
_faceshift.getEstimatedEyePitch() * pitchSign * deflection, _faceshift.getEstimatedEyeYaw() * deflection, 0.0f))) * _faceshift.getEstimatedEyePitch() * pitchSign * deflection, _faceshift.getEstimatedEyeYaw() * deflection, 0.0f))) *
glm::inverse(_myCamera.getRotation()) * (lookAtSpot - origin); glm::inverse(_myCamera.getRotation()) * (lookAtSpot - origin);
} }
_myAvatar->getHead().setLookAtPosition(lookAtSpot); _myAvatar->getHead()->setLookAtPosition(lookAtSpot);
} }
void Application::updateHoverVoxels(float deltaTime, float& distance, BoxFace& face) { void Application::updateHoverVoxels(float deltaTime, float& distance, BoxFace& face) {

View file

@ -467,8 +467,8 @@ void Audio::handleAudioInput() {
if (audioMixer && audioMixer->getActiveSocket()) { if (audioMixer && audioMixer->getActiveSocket()) {
MyAvatar* interfaceAvatar = Application::getInstance()->getAvatar(); MyAvatar* interfaceAvatar = Application::getInstance()->getAvatar();
glm::vec3 headPosition = interfaceAvatar->getHead().getPosition(); glm::vec3 headPosition = interfaceAvatar->getHead()->getPosition();
glm::quat headOrientation = interfaceAvatar->getHead().getOrientation(); glm::quat headOrientation = interfaceAvatar->getHead()->getOrientation();
// we need the amount of bytes in the buffer + 1 for type // we need the amount of bytes in the buffer + 1 for type
// + 12 for 3 floats for position + float for bearing + 1 attenuation byte // + 12 for 3 floats for position + float for bearing + 1 attenuation byte

View file

@ -773,7 +773,7 @@ void Menu::editPreferences() {
QFormLayout* form = new QFormLayout(); QFormLayout* form = new QFormLayout();
layout->addLayout(form, 1); layout->addLayout(form, 1);
QString faceURLString = applicationInstance->getAvatar()->getHead().getFaceModel().getURL().toString(); QString faceURLString = applicationInstance->getAvatar()->getHead()->getFaceModel().getURL().toString();
QLineEdit* faceURLEdit = new QLineEdit(faceURLString); QLineEdit* faceURLEdit = new QLineEdit(faceURLString);
faceURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); faceURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH);
faceURLEdit->setPlaceholderText(DEFAULT_HEAD_MODEL_URL.toString()); faceURLEdit->setPlaceholderText(DEFAULT_HEAD_MODEL_URL.toString());
@ -786,7 +786,7 @@ void Menu::editPreferences() {
form->addRow("Skeleton URL:", skeletonURLEdit); form->addRow("Skeleton URL:", skeletonURLEdit);
QSlider* pupilDilation = new QSlider(Qt::Horizontal); QSlider* pupilDilation = new QSlider(Qt::Horizontal);
pupilDilation->setValue(applicationInstance->getAvatar()->getHead().getPupilDilation() * pupilDilation->maximum()); pupilDilation->setValue(applicationInstance->getAvatar()->getHead()->getPupilDilation() * pupilDilation->maximum());
form->addRow("Pupil Dilation:", pupilDilation); form->addRow("Pupil Dilation:", pupilDilation);
QSlider* faceshiftEyeDeflection = new QSlider(Qt::Horizontal); QSlider* faceshiftEyeDeflection = new QSlider(Qt::Horizontal);
@ -862,7 +862,7 @@ void Menu::editPreferences() {
applicationInstance->getAvatar()->sendIdentityPacket(); applicationInstance->getAvatar()->sendIdentityPacket();
} }
applicationInstance->getAvatar()->getHead().setPupilDilation(pupilDilation->value() / (float)pupilDilation->maximum()); applicationInstance->getAvatar()->getHead()->setPupilDilation(pupilDilation->value() / (float)pupilDilation->maximum());
_maxVoxels = maxVoxels->value(); _maxVoxels = maxVoxels->value();
applicationInstance->getVoxels()->setMaxVoxels(_maxVoxels); applicationInstance->getVoxels()->setMaxVoxels(_maxVoxels);

View file

@ -59,7 +59,6 @@ const float CHAT_MESSAGE_HEIGHT = 0.1f;
Avatar::Avatar() : Avatar::Avatar() :
AvatarData(), AvatarData(),
_head(this),
_skeletonModel(this), _skeletonModel(this),
_bodyYawDelta(0.0f), _bodyYawDelta(0.0f),
_mode(AVATAR_MODE_STANDING), _mode(AVATAR_MODE_STANDING),
@ -80,16 +79,15 @@ Avatar::Avatar() :
moveToThread(Application::getInstance()->thread()); moveToThread(Application::getInstance()->thread());
// give the pointer to our head to inherited _headData variable from AvatarData // give the pointer to our head to inherited _headData variable from AvatarData
_headData = &_head; _headData = static_cast<HeadData*>(new Head(this));
_handData = static_cast<HandData*>(new Hand(this)); _handData = static_cast<HandData*>(new Hand(this));
} }
Avatar::~Avatar() { Avatar::~Avatar() {
_headData = NULL;
} }
void Avatar::init() { void Avatar::init() {
_head.init(); getHead()->init();
getHand()->init(); getHand()->init();
_skeletonModel.init(); _skeletonModel.init();
_initialized = true; _initialized = true;
@ -115,14 +113,15 @@ void Avatar::simulate(float deltaTime) {
getHand()->simulate(deltaTime, false); getHand()->simulate(deltaTime, false);
_skeletonModel.simulate(deltaTime); _skeletonModel.simulate(deltaTime);
_head.setBodyRotation(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)); Head* head = getHead();
head->setBodyRotation(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll));
glm::vec3 headPosition; glm::vec3 headPosition;
if (!_skeletonModel.getHeadPosition(headPosition)) { if (!_skeletonModel.getHeadPosition(headPosition)) {
headPosition = _position; headPosition = _position;
} }
_head.setPosition(headPosition); head->setPosition(headPosition);
_head.setScale(_scale); head->setScale(_scale);
_head.simulate(deltaTime, false); getHead()->simulate(deltaTime, false);
// use speed and angular velocity to determine walking vs. standing // use speed and angular velocity to determine walking vs. standing
if (_speed + fabs(_bodyYawDelta) > 0.2) { if (_speed + fabs(_bodyYawDelta) > 0.2) {
@ -162,7 +161,7 @@ void Avatar::render(bool forceRenderHead) {
_skeletonModel.renderCollisionProxies(0.7f); _skeletonModel.renderCollisionProxies(0.7f);
} }
if (Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionProxies)) { if (Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionProxies)) {
_head.getFaceModel().renderCollisionProxies(0.7f); getHead()->getFaceModel().renderCollisionProxies(0.7f);
} }
if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) {
renderBody(forceRenderHead); renderBody(forceRenderHead);
@ -171,7 +170,7 @@ void Avatar::render(bool forceRenderHead) {
// render sphere when far away // render sphere when far away
const float MAX_ANGLE = 10.f; const float MAX_ANGLE = 10.f;
float height = getHeight(); float height = getHeight();
glm::vec3 delta = height * (_head.getCameraOrientation() * IDENTITY_UP) / 2.f; glm::vec3 delta = height * (getHead()->getCameraOrientation() * IDENTITY_UP) / 2.f;
float angle = abs(angleBetween(toTarget + delta, toTarget - delta)); float angle = abs(angleBetween(toTarget + delta, toTarget - delta));
if (angle < MAX_ANGLE) { if (angle < MAX_ANGLE) {
@ -179,7 +178,7 @@ void Avatar::render(bool forceRenderHead) {
glPushMatrix(); glPushMatrix();
glTranslatef(_position.x, _position.y, _position.z); glTranslatef(_position.x, _position.y, _position.z);
glScalef(height / 2.f, height / 2.f, height / 2.f); glScalef(height / 2.f, height / 2.f, height / 2.f);
glutSolidSphere(1.2f + _head.getAverageLoudness() * .0005f, 20, 20); glutSolidSphere(1.2f + getHead()->getAverageLoudness() * .0005f, 20, 20);
glPopMatrix(); glPopMatrix();
} }
} }
@ -193,7 +192,7 @@ void Avatar::render(bool forceRenderHead) {
} }
glPushMatrix(); glPushMatrix();
glm::vec3 chatPosition = getHead().getEyePosition() + getBodyUpDirection() * CHAT_MESSAGE_HEIGHT * _scale; glm::vec3 chatPosition = getHead()->getEyePosition() + getBodyUpDirection() * CHAT_MESSAGE_HEIGHT * _scale;
glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z); glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z);
glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation(); glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation();
glm::vec3 chatAxis = glm::axis(chatRotation); glm::vec3 chatAxis = glm::axis(chatRotation);
@ -250,7 +249,7 @@ void Avatar::renderBody(bool forceRenderHead) {
//printf("Render other at %.3f, %.2f, %.2f\n", pos.x, pos.y, pos.z); //printf("Render other at %.3f, %.2f, %.2f\n", pos.x, pos.y, pos.z);
_skeletonModel.render(1.0f); _skeletonModel.render(1.0f);
if (forceRenderHead) { if (forceRenderHead) {
_head.render(1.0f); getHead()->render(1.0f);
} }
getHand()->render(false); getHand()->render(false);
} }
@ -261,7 +260,7 @@ bool Avatar::findRayIntersection(const glm::vec3& origin, const glm::vec3& direc
if (_skeletonModel.findRayIntersection(origin, direction, modelDistance)) { if (_skeletonModel.findRayIntersection(origin, direction, modelDistance)) {
minDistance = qMin(minDistance, modelDistance); minDistance = qMin(minDistance, modelDistance);
} }
if (_head.getFaceModel().findRayIntersection(origin, direction, modelDistance)) { if (getHead()->getFaceModel().findRayIntersection(origin, direction, modelDistance)) {
minDistance = qMin(minDistance, modelDistance); minDistance = qMin(minDistance, modelDistance);
} }
if (minDistance < FLT_MAX) { if (minDistance < FLT_MAX) {
@ -276,7 +275,7 @@ bool Avatar::findSphereCollisions(const glm::vec3& penetratorCenter, float penet
// Temporarily disabling collisions against the skeleton because the collision proxies up // Temporarily disabling collisions against the skeleton because the collision proxies up
// near the neck are bad and prevent the hand from hitting the face. // near the neck are bad and prevent the hand from hitting the face.
//return _skeletonModel.findSphereCollisions(penetratorCenter, penetratorRadius, collisions, 1.0f, skeletonSkipIndex); //return _skeletonModel.findSphereCollisions(penetratorCenter, penetratorRadius, collisions, 1.0f, skeletonSkipIndex);
return _head.getFaceModel().findSphereCollisions(penetratorCenter, penetratorRadius, collisions); return getHead()->getFaceModel().findSphereCollisions(penetratorCenter, penetratorRadius, collisions);
} }
bool Avatar::findParticleCollisions(const glm::vec3& particleCenter, float particleRadius, CollisionList& collisions) { bool Avatar::findParticleCollisions(const glm::vec3& particleCenter, float particleRadius, CollisionList& collisions) {
@ -355,7 +354,7 @@ bool Avatar::findParticleCollisions(const glm::vec3& particleCenter, float parti
void Avatar::setFaceModelURL(const QUrl &faceModelURL) { void Avatar::setFaceModelURL(const QUrl &faceModelURL) {
AvatarData::setFaceModelURL(faceModelURL); AvatarData::setFaceModelURL(faceModelURL);
const QUrl DEFAULT_FACE_MODEL_URL = QUrl::fromLocalFile("resources/meshes/defaultAvatar_head.fst"); const QUrl DEFAULT_FACE_MODEL_URL = QUrl::fromLocalFile("resources/meshes/defaultAvatar_head.fst");
_head.getFaceModel().setURL(_faceModelURL, DEFAULT_FACE_MODEL_URL); getHead()->getFaceModel().setURL(_faceModelURL, DEFAULT_FACE_MODEL_URL);
} }
void Avatar::setSkeletonModelURL(const QUrl &skeletonModelURL) { void Avatar::setSkeletonModelURL(const QUrl &skeletonModelURL) {
@ -466,7 +465,7 @@ bool Avatar::collisionWouldMoveAvatar(CollisionInfo& collision) const {
return false; return false;
//return _skeletonModel.collisionHitsMoveableJoint(collision); //return _skeletonModel.collisionHitsMoveableJoint(collision);
} }
if (model == &(_head.getFaceModel())) { if (model == &(getHead()->getFaceModel())) {
// ATM we always handle MODEL_COLLISIONS against the face. // ATM we always handle MODEL_COLLISIONS against the face.
return true; return true;
} }
@ -479,8 +478,8 @@ void Avatar::applyCollision(CollisionInfo& collision) {
} }
// TODO: make skeleton also respond to collisions // TODO: make skeleton also respond to collisions
Model* model = static_cast<Model*>(collision._data); Model* model = static_cast<Model*>(collision._data);
if (model == &(_head.getFaceModel())) { if (model == &(getHead()->getFaceModel())) {
_head.applyCollision(collision); getHead()->applyCollision(collision);
} }
} }
@ -489,6 +488,6 @@ float Avatar::getPelvisFloatingHeight() const {
} }
float Avatar::getPelvisToHeadLength() const { float Avatar::getPelvisToHeadLength() const {
return glm::distance(_position, _head.getPosition()); return glm::distance(_position, getHead()->getPosition());
} }

View file

@ -74,7 +74,7 @@ public:
void render(bool forceRenderHead); void render(bool forceRenderHead);
//setters //setters
void setDisplayingLookatVectors(bool displayingLookatVectors) { _head.setRenderLookatVectors(displayingLookatVectors); } void setDisplayingLookatVectors(bool displayingLookatVectors) { getHead()->setRenderLookatVectors(displayingLookatVectors); }
void setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction); void setMouseRay(const glm::vec3 &origin, const glm::vec3 &direction);
//getters //getters
@ -83,7 +83,8 @@ public:
glm::vec3 getChestPosition() const; glm::vec3 getChestPosition() const;
float getScale() const { return _scale; } float getScale() const { return _scale; }
const glm::vec3& getVelocity() const { return _velocity; } const glm::vec3& getVelocity() const { return _velocity; }
Head& getHead() { return _head; } const Head* getHead() const { return static_cast<const Head*>(_headData); }
Head* getHead() { return static_cast<Head*>(_headData); }
Hand* getHand() { return static_cast<Hand*>(_handData); } Hand* getHand() { return static_cast<Hand*>(_handData); }
glm::quat getWorldAlignedOrientation() const; glm::quat getWorldAlignedOrientation() const;
@ -129,8 +130,6 @@ public slots:
void updateCollisionFlags(); void updateCollisionFlags();
protected: protected:
Head _head;
//Hand _hand;
SkeletonModel _skeletonModel; SkeletonModel _skeletonModel;
float _bodyYawDelta; float _bodyYawDelta;
AvatarMode _mode; AvatarMode _mode;

View file

@ -72,7 +72,7 @@ void MyAvatar::reset() {
// TODO? resurrect headMouse stuff? // TODO? resurrect headMouse stuff?
//_headMouseX = _glWidget->width() / 2; //_headMouseX = _glWidget->width() / 2;
//_headMouseY = _glWidget->height() / 2; //_headMouseY = _glWidget->height() / 2;
_head.reset(); getHead()->reset();
getHand()->reset(); getHand()->reset();
setVelocity(glm::vec3(0,0,0)); setVelocity(glm::vec3(0,0,0));
@ -130,19 +130,20 @@ void MyAvatar::update(float deltaTime) {
//_headMouseY = glm::clamp(_headMouseY, 0, _glWidget->height()); //_headMouseY = glm::clamp(_headMouseY, 0, _glWidget->height());
} }
Head* head = getHead();
if (OculusManager::isConnected()) { if (OculusManager::isConnected()) {
float yaw, pitch, roll; float yaw, pitch, roll;
OculusManager::getEulerAngles(yaw, pitch, roll); OculusManager::getEulerAngles(yaw, pitch, roll);
_head.setYaw(yaw); head->setYaw(yaw);
_head.setPitch(pitch); head->setPitch(pitch);
_head.setRoll(roll); head->setRoll(roll);
} }
// Get audio loudness data from audio input device // Get audio loudness data from audio input device
Audio* audio = Application::getInstance()->getAudio(); Audio* audio = Application::getInstance()->getAudio();
_head.setAudioLoudness(audio->getLastInputLoudness()); head->setAudioLoudness(audio->getLastInputLoudness());
_head.setAudioAverageLoudness(audio->getAudioAverageInputLoudness()); head->setAudioAverageLoudness(audio->getAudioAverageInputLoudness());
if (Menu::getInstance()->isOptionChecked(MenuOption::Gravity)) { if (Menu::getInstance()->isOptionChecked(MenuOption::Gravity)) {
setGravity(Application::getInstance()->getEnvironment()->getGravity(getPosition())); setGravity(Application::getInstance()->getEnvironment()->getGravity(getPosition()));
@ -266,7 +267,7 @@ void MyAvatar::simulate(float deltaTime) {
if (!Application::getInstance()->getFaceshift()->isActive() && OculusManager::isConnected() && if (!Application::getInstance()->getFaceshift()->isActive() && OculusManager::isConnected() &&
fabsf(forwardAcceleration) > OCULUS_ACCELERATION_PULL_THRESHOLD && fabsf(forwardAcceleration) > OCULUS_ACCELERATION_PULL_THRESHOLD &&
fabs(_head.getYaw()) > OCULUS_YAW_OFFSET_THRESHOLD) { fabs(getHead()->getYaw()) > OCULUS_YAW_OFFSET_THRESHOLD) {
// if we're wearing the oculus // if we're wearing the oculus
// and this acceleration is above the pull threshold // and this acceleration is above the pull threshold
@ -276,7 +277,7 @@ void MyAvatar::simulate(float deltaTime) {
_bodyYaw = getAbsoluteHeadYaw(); _bodyYaw = getAbsoluteHeadYaw();
// set the head yaw to zero for this draw // set the head yaw to zero for this draw
_head.setYaw(0); getHead()->setYaw(0);
// correct the oculus yaw offset // correct the oculus yaw offset
OculusManager::updateYawOffset(); OculusManager::updateYawOffset();
@ -316,15 +317,18 @@ void MyAvatar::simulate(float deltaTime) {
// update avatar skeleton and simulate hand and head // update avatar skeleton and simulate hand and head
getHand()->collideAgainstOurself(); getHand()->collideAgainstOurself();
getHand()->simulate(deltaTime, true); getHand()->simulate(deltaTime, true);
_skeletonModel.simulate(deltaTime); _skeletonModel.simulate(deltaTime);
_head.setBodyRotation(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll));
Head* head = getHead();
head->setBodyRotation(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll));
glm::vec3 headPosition; glm::vec3 headPosition;
if (!_skeletonModel.getHeadPosition(headPosition)) { if (!_skeletonModel.getHeadPosition(headPosition)) {
headPosition = _position; headPosition = _position;
} }
_head.setPosition(headPosition); head->setPosition(headPosition);
_head.setScale(_scale); head->setScale(_scale);
_head.simulate(deltaTime, true); head->simulate(deltaTime, true);
// Zero thrust out now that we've added it to velocity in this frame // Zero thrust out now that we've added it to velocity in this frame
_thrust = glm::vec3(0, 0, 0); _thrust = glm::vec3(0, 0, 0);
@ -338,6 +342,8 @@ void MyAvatar::updateFromGyros(float deltaTime) {
Faceshift* faceshift = Application::getInstance()->getFaceshift(); Faceshift* faceshift = Application::getInstance()->getFaceshift();
glm::vec3 estimatedPosition, estimatedRotation; glm::vec3 estimatedPosition, estimatedRotation;
Head* head = getHead();
if (faceshift->isActive()) { if (faceshift->isActive()) {
estimatedPosition = faceshift->getHeadTranslation(); estimatedPosition = faceshift->getHeadTranslation();
estimatedRotation = safeEulerAngles(faceshift->getHeadRotation()); estimatedRotation = safeEulerAngles(faceshift->getHeadRotation());
@ -359,10 +365,10 @@ void MyAvatar::updateFromGyros(float deltaTime) {
// restore rotation, lean to neutral positions // restore rotation, lean to neutral positions
const float RESTORE_PERIOD = 1.f; // seconds const float RESTORE_PERIOD = 1.f; // seconds
float restorePercentage = glm::clamp(deltaTime/RESTORE_PERIOD, 0.f, 1.f); float restorePercentage = glm::clamp(deltaTime/RESTORE_PERIOD, 0.f, 1.f);
_head.setYaw(glm::mix(_head.getYaw(), 0.0f, restorePercentage)); head->setYaw(glm::mix(head->getYaw(), 0.0f, restorePercentage));
_head.setRoll(glm::mix(_head.getRoll(), 0.0f, restorePercentage)); head->setRoll(glm::mix(head->getRoll(), 0.0f, restorePercentage));
_head.setLeanSideways(glm::mix(_head.getLeanSideways(), 0.0f, restorePercentage)); head->setLeanSideways(glm::mix(head->getLeanSideways(), 0.0f, restorePercentage));
_head.setLeanForward(glm::mix(_head.getLeanForward(), 0.0f, restorePercentage)); head->setLeanForward(glm::mix(head->getLeanForward(), 0.0f, restorePercentage));
return; return;
} }
@ -371,17 +377,17 @@ void MyAvatar::updateFromGyros(float deltaTime) {
const float AVATAR_HEAD_PITCH_MAGNIFY = 1.0f; const float AVATAR_HEAD_PITCH_MAGNIFY = 1.0f;
const float AVATAR_HEAD_YAW_MAGNIFY = 1.0f; const float AVATAR_HEAD_YAW_MAGNIFY = 1.0f;
const float AVATAR_HEAD_ROLL_MAGNIFY = 1.0f; const float AVATAR_HEAD_ROLL_MAGNIFY = 1.0f;
_head.tweakPitch(estimatedRotation.x * AVATAR_HEAD_PITCH_MAGNIFY); head->tweakPitch(estimatedRotation.x * AVATAR_HEAD_PITCH_MAGNIFY);
_head.tweakYaw(estimatedRotation.y * AVATAR_HEAD_YAW_MAGNIFY); head->tweakYaw(estimatedRotation.y * AVATAR_HEAD_YAW_MAGNIFY);
_head.tweakRoll(estimatedRotation.z * AVATAR_HEAD_ROLL_MAGNIFY); head->tweakRoll(estimatedRotation.z * AVATAR_HEAD_ROLL_MAGNIFY);
// Update torso lean distance based on accelerometer data // Update torso lean distance based on accelerometer data
const float TORSO_LENGTH = 0.5f; const float TORSO_LENGTH = 0.5f;
glm::vec3 relativePosition = estimatedPosition - glm::vec3(0.0f, -TORSO_LENGTH, 0.0f); glm::vec3 relativePosition = estimatedPosition - glm::vec3(0.0f, -TORSO_LENGTH, 0.0f);
const float MAX_LEAN = 45.0f; const float MAX_LEAN = 45.0f;
_head.setLeanSideways(glm::clamp(glm::degrees(atanf(relativePosition.x * _leanScale / TORSO_LENGTH)), head->setLeanSideways(glm::clamp(glm::degrees(atanf(relativePosition.x * _leanScale / TORSO_LENGTH)),
-MAX_LEAN, MAX_LEAN)); -MAX_LEAN, MAX_LEAN));
_head.setLeanForward(glm::clamp(glm::degrees(atanf(relativePosition.z * _leanScale / TORSO_LENGTH)), head->setLeanForward(glm::clamp(glm::degrees(atanf(relativePosition.z * _leanScale / TORSO_LENGTH)),
-MAX_LEAN, MAX_LEAN)); -MAX_LEAN, MAX_LEAN));
// if Faceshift drive is enabled, set the avatar drive based on the head position // if Faceshift drive is enabled, set the avatar drive based on the head position
@ -390,11 +396,11 @@ void MyAvatar::updateFromGyros(float deltaTime) {
} }
// Move with Lean by applying thrust proportional to leaning // Move with Lean by applying thrust proportional to leaning
glm::quat orientation = _head.getCameraOrientation(); glm::quat orientation = head->getCameraOrientation();
glm::vec3 front = orientation * IDENTITY_FRONT; glm::vec3 front = orientation * IDENTITY_FRONT;
glm::vec3 right = orientation * IDENTITY_RIGHT; glm::vec3 right = orientation * IDENTITY_RIGHT;
float leanForward = _head.getLeanForward(); float leanForward = head->getLeanForward();
float leanSideways = _head.getLeanSideways(); float leanSideways = head->getLeanSideways();
// Degrees of 'dead zone' when leaning, and amount of acceleration to apply to lean angle // Degrees of 'dead zone' when leaning, and amount of acceleration to apply to lean angle
const float LEAN_FWD_DEAD_ZONE = 15.f; const float LEAN_FWD_DEAD_ZONE = 15.f;
@ -425,7 +431,7 @@ static TextRenderer* textRenderer() {
void MyAvatar::renderDebugBodyPoints() { void MyAvatar::renderDebugBodyPoints() {
glm::vec3 torsoPosition(getPosition()); glm::vec3 torsoPosition(getPosition());
glm::vec3 headPosition(getHead().getEyePosition()); glm::vec3 headPosition(getHead()->getEyePosition());
float torsoToHead = glm::length(headPosition - torsoPosition); float torsoToHead = glm::length(headPosition - torsoPosition);
glm::vec3 position; glm::vec3 position;
printf("head-above-torso %.2f, scale = %0.2f\n", torsoToHead, getScale()); printf("head-above-torso %.2f, scale = %0.2f\n", torsoToHead, getScale());
@ -471,7 +477,7 @@ void MyAvatar::render(bool forceRenderHead) {
} }
glPushMatrix(); glPushMatrix();
glm::vec3 chatPosition = getHead().getEyePosition() + getBodyUpDirection() * CHAT_MESSAGE_HEIGHT * _scale; glm::vec3 chatPosition = getHead()->getEyePosition() + getBodyUpDirection() * CHAT_MESSAGE_HEIGHT * _scale;
glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z); glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z);
glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation(); glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation();
glm::vec3 chatAxis = glm::axis(chatRotation); glm::vec3 chatAxis = glm::axis(chatRotation);
@ -581,13 +587,13 @@ void MyAvatar::saveData(QSettings* settings) {
settings->setValue("bodyPitch", _bodyPitch); settings->setValue("bodyPitch", _bodyPitch);
settings->setValue("bodyRoll", _bodyRoll); settings->setValue("bodyRoll", _bodyRoll);
settings->setValue("headPitch", _head.getPitch()); settings->setValue("headPitch", getHead()->getPitch());
settings->setValue("position_x", _position.x); settings->setValue("position_x", _position.x);
settings->setValue("position_y", _position.y); settings->setValue("position_y", _position.y);
settings->setValue("position_z", _position.z); settings->setValue("position_z", _position.z);
settings->setValue("pupilDilation", _head.getPupilDilation()); settings->setValue("pupilDilation", getHead()->getPupilDilation());
settings->setValue("leanScale", _leanScale); settings->setValue("leanScale", _leanScale);
settings->setValue("scale", _targetScale); settings->setValue("scale", _targetScale);
@ -606,13 +612,13 @@ void MyAvatar::loadData(QSettings* settings) {
_bodyPitch = loadSetting(settings, "bodyPitch", 0.0f); _bodyPitch = loadSetting(settings, "bodyPitch", 0.0f);
_bodyRoll = loadSetting(settings, "bodyRoll", 0.0f); _bodyRoll = loadSetting(settings, "bodyRoll", 0.0f);
_head.setPitch(loadSetting(settings, "headPitch", 0.0f)); getHead()->setPitch(loadSetting(settings, "headPitch", 0.0f));
_position.x = loadSetting(settings, "position_x", 0.0f); _position.x = loadSetting(settings, "position_x", 0.0f);
_position.y = loadSetting(settings, "position_y", 0.0f); _position.y = loadSetting(settings, "position_y", 0.0f);
_position.z = loadSetting(settings, "position_z", 0.0f); _position.z = loadSetting(settings, "position_z", 0.0f);
_head.setPupilDilation(loadSetting(settings, "pupilDilation", 0.0f)); getHead()->setPupilDilation(loadSetting(settings, "pupilDilation", 0.0f));
_leanScale = loadSetting(settings, "leanScale", 0.05f); _leanScale = loadSetting(settings, "leanScale", 0.05f);
_targetScale = loadSetting(settings, "scale", 1.0f); _targetScale = loadSetting(settings, "scale", 1.0f);
@ -647,9 +653,9 @@ void MyAvatar::orbit(const glm::vec3& position, int deltaX, int deltaY) {
setOrientation(orientation); setOrientation(orientation);
// then vertically // then vertically
float oldPitch = _head.getPitch(); float oldPitch = getHead()->getPitch();
_head.setPitch(oldPitch + deltaY * -ANGULAR_SCALE); getHead()->setPitch(oldPitch + deltaY * -ANGULAR_SCALE);
rotation = glm::angleAxis(_head.getPitch() - oldPitch, orientation * IDENTITY_RIGHT); rotation = glm::angleAxis(getHead()->getPitch() - oldPitch, orientation * IDENTITY_RIGHT);
setPosition(position + rotation * (getPosition() - position)); setPosition(position + rotation * (getPosition() - position));
} }
@ -669,8 +675,8 @@ void MyAvatar::updateLookAtTargetAvatar(glm::vec3 &eyePosition) {
float distance; float distance;
if (avatar->findRayIntersection(mouseOrigin, mouseDirection, distance)) { if (avatar->findRayIntersection(mouseOrigin, mouseDirection, distance)) {
// rescale to compensate for head embiggening // rescale to compensate for head embiggening
eyePosition = (avatar->getHead().calculateAverageEyePosition() - avatar->getHead().getScalePivot()) * eyePosition = (avatar->getHead()->calculateAverageEyePosition() - avatar->getHead()->getScalePivot()) *
(avatar->getScale() / avatar->getHead().getScale()) + avatar->getHead().getScalePivot(); (avatar->getScale() / avatar->getHead()->getScale()) + avatar->getHead()->getScalePivot();
_lookAtTargetAvatar = avatarPointer; _lookAtTargetAvatar = avatarPointer;
return; return;
} }
@ -684,7 +690,8 @@ void MyAvatar::clearLookAtTargetAvatar() {
} }
float MyAvatar::getAbsoluteHeadYaw() const { float MyAvatar::getAbsoluteHeadYaw() const {
return glm::yaw(_head.getOrientation()); const Head* head = static_cast<const Head*>(_headData);
return glm::yaw(head->getOrientation());
} }
glm::vec3 MyAvatar::getUprightHeadPosition() const { glm::vec3 MyAvatar::getUprightHeadPosition() const {
@ -698,8 +705,8 @@ void MyAvatar::renderBody(bool forceRenderHead) {
// Render head so long as the camera isn't inside it // Render head so long as the camera isn't inside it
const float RENDER_HEAD_CUTOFF_DISTANCE = 0.10f; const float RENDER_HEAD_CUTOFF_DISTANCE = 0.10f;
Camera* myCamera = Application::getInstance()->getCamera(); Camera* myCamera = Application::getInstance()->getCamera();
if (forceRenderHead || (glm::length(myCamera->getPosition() - _head.calculateAverageEyePosition()) > RENDER_HEAD_CUTOFF_DISTANCE)) { if (forceRenderHead || (glm::length(myCamera->getPosition() - getHead()->calculateAverageEyePosition()) > RENDER_HEAD_CUTOFF_DISTANCE)) {
_head.render(1.0f); getHead()->render(1.0f);
} }
getHand()->render(true); getHand()->render(true);
} }
@ -708,7 +715,7 @@ void MyAvatar::updateThrust(float deltaTime) {
// //
// Gather thrust information from keyboard and sensors to apply to avatar motion // Gather thrust information from keyboard and sensors to apply to avatar motion
// //
glm::quat orientation = getHead().getCameraOrientation(); glm::quat orientation = getHead()->getCameraOrientation();
glm::vec3 front = orientation * IDENTITY_FRONT; glm::vec3 front = orientation * IDENTITY_FRONT;
glm::vec3 right = orientation * IDENTITY_RIGHT; glm::vec3 right = orientation * IDENTITY_RIGHT;
glm::vec3 up = orientation * IDENTITY_UP; glm::vec3 up = orientation * IDENTITY_UP;
@ -729,7 +736,7 @@ void MyAvatar::updateThrust(float deltaTime) {
_thrust -= _driveKeys[DOWN] * _scale * THRUST_MAG_DOWN * _thrustMultiplier * deltaTime * up; _thrust -= _driveKeys[DOWN] * _scale * THRUST_MAG_DOWN * _thrustMultiplier * deltaTime * up;
_bodyYawDelta -= _driveKeys[ROT_RIGHT] * YAW_MAG * deltaTime; _bodyYawDelta -= _driveKeys[ROT_RIGHT] * YAW_MAG * deltaTime;
_bodyYawDelta += _driveKeys[ROT_LEFT] * YAW_MAG * deltaTime; _bodyYawDelta += _driveKeys[ROT_LEFT] * YAW_MAG * deltaTime;
_head.setPitch(_head.getPitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_MAG * deltaTime); getHead()->setPitch(getHead()->getPitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_MAG * deltaTime);
// If thrust keys are being held down, slowly increase thrust to allow reaching great speeds // If thrust keys are being held down, slowly increase thrust to allow reaching great speeds
if (_driveKeys[FWD] || _driveKeys[BACK] || _driveKeys[RIGHT] || _driveKeys[LEFT] || _driveKeys[UP] || _driveKeys[DOWN]) { if (_driveKeys[FWD] || _driveKeys[BACK] || _driveKeys[RIGHT] || _driveKeys[LEFT] || _driveKeys[UP] || _driveKeys[DOWN]) {
@ -1112,7 +1119,7 @@ void MyAvatar::updateChatCircle(float deltaTime) {
void MyAvatar::setGravity(glm::vec3 gravity) { void MyAvatar::setGravity(glm::vec3 gravity) {
_gravity = gravity; _gravity = gravity;
_head.setGravity(_gravity); getHead()->setGravity(_gravity);
// use the gravity to determine the new world up direction, if possible // use the gravity to determine the new world up direction, if possible
float gravityLength = glm::length(gravity); float gravityLength = glm::length(gravity);

View file

@ -181,8 +181,8 @@ void SkeletonModel::maybeUpdateLeanRotation(const JointState& parentState, const
glm::mat3 axes = glm::mat3_cast(_rotation); glm::mat3 axes = glm::mat3_cast(_rotation);
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) * glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) *
joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation))); joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation)));
state.rotation = glm::angleAxis(-_owningAvatar->getHead().getLeanSideways(), glm::normalize(inverse * axes[2])) * state.rotation = glm::angleAxis(-_owningAvatar->getHead()->getLeanSideways(), glm::normalize(inverse * axes[2])) *
glm::angleAxis(-_owningAvatar->getHead().getLeanForward(), glm::normalize(inverse * axes[0])) * joint.rotation; glm::angleAxis(-_owningAvatar->getHead()->getLeanForward(), glm::normalize(inverse * axes[0])) * joint.rotation;
} }
void SkeletonModel::stretchArm(int jointIndex, const glm::vec3& position) { void SkeletonModel::stretchArm(int jointIndex, const glm::vec3& position) {

View file

@ -64,7 +64,7 @@ void Snapshot::saveSnapshot(QGLWidget* widget, Profile* profile, Avatar* avatar)
QImage shot = widget->grabFrameBuffer(); QImage shot = widget->grabFrameBuffer();
glm::vec3 location = avatar->getPosition(); glm::vec3 location = avatar->getPosition();
glm::quat orientation = avatar->getHead().getOrientation(); glm::quat orientation = avatar->getHead()->getOrientation();
// add metadata // add metadata
shot.setText(LOCATION_X, QString::number(location.x)); shot.setText(LOCATION_X, QString::number(location.x));