mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
78 lines
3 KiB
C++
78 lines
3 KiB
C++
//
|
|
// FaceModel.cpp
|
|
// interface
|
|
//
|
|
// Created by Andrzej Kapolka on 9/16/13.
|
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
|
//
|
|
|
|
#include <glm/gtx/transform.hpp>
|
|
|
|
#include "Avatar.h"
|
|
#include "FaceModel.h"
|
|
#include "Head.h"
|
|
#include "Menu.h"
|
|
|
|
FaceModel::FaceModel(Head* owningHead) :
|
|
_owningHead(owningHead)
|
|
{
|
|
}
|
|
|
|
void FaceModel::simulate(float deltaTime) {
|
|
if (!isActive()) {
|
|
Model::simulate(deltaTime);
|
|
return;
|
|
}
|
|
Avatar* owningAvatar = static_cast<Avatar*>(_owningHead->_owningAvatar);
|
|
glm::vec3 neckPosition;
|
|
if (!owningAvatar->getSkeletonModel().getNeckPosition(neckPosition)) {
|
|
neckPosition = owningAvatar->getPosition();
|
|
}
|
|
setTranslation(neckPosition);
|
|
glm::quat neckRotation;
|
|
if (!owningAvatar->getSkeletonModel().getNeckRotation(neckRotation)) {
|
|
neckRotation = owningAvatar->getOrientation();
|
|
}
|
|
setRotation(neckRotation);
|
|
const float MODEL_SCALE = 0.0006f;
|
|
setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningHead->getScale() * MODEL_SCALE);
|
|
setOffset(-_geometry->getFBXGeometry().neckPivot);
|
|
|
|
setPupilDilation(_owningHead->getPupilDilation());
|
|
setBlendshapeCoefficients(_owningHead->getBlendshapeCoefficients());
|
|
|
|
Model::simulate(deltaTime);
|
|
}
|
|
|
|
bool FaceModel::render(float alpha) {
|
|
if (!Model::render(alpha)) {
|
|
return false;
|
|
}
|
|
if (Menu::getInstance()->isOptionChecked(MenuOption::CollisionProxies)) {
|
|
renderCollisionProxies(alpha);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void FaceModel::maybeUpdateNeckRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) {
|
|
// get the rotation axes in joint space and use them to adjust the rotation
|
|
glm::mat3 axes = glm::mat3_cast(_rotation);
|
|
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.transform * glm::translate(state.translation) *
|
|
joint.preTransform * glm::mat4_cast(joint.preRotation)));
|
|
state.rotation = glm::angleAxis(-_owningHead->getTweakedRoll(), glm::normalize(inverse * axes[2])) *
|
|
glm::angleAxis(_owningHead->getTweakedYaw(), glm::normalize(inverse * axes[1])) *
|
|
glm::angleAxis(-_owningHead->getTweakedPitch(), glm::normalize(inverse * axes[0])) * joint.rotation;
|
|
}
|
|
|
|
void FaceModel::maybeUpdateEyeRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) {
|
|
// likewise with the eye joints
|
|
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->getTweakedOrientation() * IDENTITY_FRONT, 0.0f));
|
|
glm::vec3 lookAt = glm::vec3(inverse * glm::vec4(_owningHead->getLookAtPosition() +
|
|
_owningHead->getSaccade() - _translation, 1.0f));
|
|
glm::quat between = rotationBetween(front, lookAt);
|
|
const float MAX_ANGLE = 30.0f;
|
|
state.rotation = glm::angleAxis(glm::clamp(glm::angle(between), -MAX_ANGLE, MAX_ANGLE), glm::axis(between)) *
|
|
joint.rotation;
|
|
}
|