Merge branch 'master' of https://github.com/highfidelity/hifi into metavoxels

This commit is contained in:
Andrzej Kapolka 2014-07-10 14:39:42 -07:00
commit e55a0fbc9c
12 changed files with 94 additions and 54 deletions

View file

@ -23,6 +23,11 @@ GLCanvas::GLCanvas() : QGLWidget(QGLFormat(QGL::NoDepthBuffer)),
_throttleRendering(false),
_idleRenderInterval(MSECS_PER_FRAME_WHEN_THROTTLED)
{
#ifdef Q_OS_LINUX
// Cause GLCanvas::eventFilter to be called.
// It wouldn't hurt to do this on Mac and PC too; but apparently it's only needed on linux.
qApp->installEventFilter(this);
#endif
}
bool GLCanvas::isThrottleRendering() const {
@ -162,3 +167,35 @@ void GLCanvas::dragEnterEvent(QDragEnterEvent* event) {
void GLCanvas::dropEvent(QDropEvent* event) {
Application::getInstance()->dropEvent(event);
}
// Pressing Alt (and Meta) key alone activates the menubar because its style inherits the
// SHMenuBarAltKeyNavigation from QWindowsStyle. This makes it impossible for a scripts to
// receive keyPress events for the Alt (and Meta) key in a reliable manner.
//
// This filter catches events before QMenuBar can steal the keyboard focus.
// The idea was borrowed from
// http://www.archivum.info/qt-interest@trolltech.com/2006-09/00053/Re-(Qt4)-Alt-key-focus-QMenuBar-(solved).html
bool GLCanvas::eventFilter(QObject*, QEvent* event) {
switch (event->type()) {
case QEvent::KeyPress:
case QEvent::KeyRelease:
case QEvent::ShortcutOverride:
{
QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Alt || keyEvent->key() == Qt::Key_Meta) {
if (event->type() == QEvent::KeyPress) {
keyPressEvent(keyEvent);
} else if (event->type() == QEvent::KeyRelease) {
keyReleaseEvent(keyEvent);
} else {
QGLWidget::event(event);
}
return true;
}
}
default:
break;
}
return false;
}

View file

@ -50,6 +50,7 @@ protected:
private slots:
void activeChanged(Qt::ApplicationState state);
void throttleRender();
bool eventFilter(QObject*, QEvent* event);
};
#endif // hifi_GLCanvas_h

View file

@ -407,6 +407,7 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::GlowWhenSpeaking, 0, true);
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::ChatCircling, 0, false);
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::FocusIndicators, 0, false);
QMenu* sixenseOptionsMenu = developerMenu->addMenu("Sixense Options");
addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu, MenuOption::SixenseMouseInput, 0, true);

View file

@ -369,6 +369,7 @@ namespace MenuOption {
const QString FilterSixense = "Smooth Sixense Movement";
const QString LowVelocityFilter = "Low Velocity Filter";
const QString FirstPerson = "First Person";
const QString FocusIndicators = "Focus Indicators";
const QString FrameTimer = "Show Timer";
const QString FrustumRenderMode = "Render Mode";
const QString Fullscreen = "Fullscreen";

View file

@ -145,20 +145,20 @@ void Avatar::simulate(float deltaTime) {
_skeletonModel.setLODDistance(getLODDistance());
if (!_shouldRenderBillboard && inViewFrustum) {
if (_hasNewJointRotations) {
PerformanceTimer perfTimer("skeleton");
for (int i = 0; i < _jointData.size(); i++) {
const JointData& data = _jointData.at(i);
_skeletonModel.setJointState(i, data.valid, data.rotation);
}
_skeletonModel.simulate(deltaTime);
}
{
PerformanceTimer perfTimer("head");
PerformanceTimer perfTimer("skeleton");
if (_hasNewJointRotations) {
for (int i = 0; i < _jointData.size(); i++) {
const JointData& data = _jointData.at(i);
_skeletonModel.setJointState(i, data.valid, data.rotation);
}
}
_skeletonModel.simulate(deltaTime, _hasNewJointRotations);
simulateAttachments(deltaTime);
_hasNewJointRotations = false;
}
{
PerformanceTimer perfTimer("head");
glm::vec3 headPosition = _position;
_skeletonModel.getHeadPosition(headPosition);
Head* head = getHead();
@ -300,7 +300,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) {
}
// If this is the avatar being looked at, render a little ball above their head
if (_isLookAtTarget) {
if (_isLookAtTarget && Menu::getInstance()->isOptionChecked(MenuOption::FocusIndicators)) {
const float LOOK_AT_INDICATOR_RADIUS = 0.03f;
const float LOOK_AT_INDICATOR_OFFSET = 0.22f;
const float LOOK_AT_INDICATOR_COLOR[] = { 0.8f, 0.0f, 0.0f, 0.75f };

View file

@ -41,7 +41,7 @@ void AvatarManager::init() {
}
void AvatarManager::updateOtherAvatars(float deltaTime) {
if (_avatarHash.size() > 1) {
if (_avatarHash.size() < 2) {
return;
}
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);

View file

@ -49,9 +49,9 @@ void FaceModel::simulate(float deltaTime, bool fullUpdate) {
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(glm::quat());
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.getTransform() * glm::translate(state.getDefaultTranslationInParentFrame()) *
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.getTransform() * glm::translate(state.getDefaultTranslationInConstrainedFrame()) *
joint.preTransform * glm::mat4_cast(joint.preRotation)));
state.setRotationInParentFrame(glm::angleAxis(- RADIANS_PER_DEGREE * _owningHead->getFinalRoll(), glm::normalize(inverse * axes[2]))
state.setRotationInConstrainedFrame(glm::angleAxis(- RADIANS_PER_DEGREE * _owningHead->getFinalRoll(), glm::normalize(inverse * axes[2]))
* glm::angleAxis(RADIANS_PER_DEGREE * _owningHead->getFinalYaw(), glm::normalize(inverse * axes[1]))
* glm::angleAxis(- RADIANS_PER_DEGREE * _owningHead->getFinalPitch(), glm::normalize(inverse * axes[0]))
* joint.rotation);
@ -61,14 +61,14 @@ void FaceModel::maybeUpdateEyeRotation(const JointState& parentState, const FBXJ
// likewise with the eye joints
// NOTE: at the moment we do the math in the world-frame, hence the inverse transform is more complex than usual.
glm::mat4 inverse = glm::inverse(glm::mat4_cast(_rotation) * parentState.getTransform() *
glm::translate(state.getDefaultTranslationInParentFrame()) *
glm::translate(state.getDefaultTranslationInConstrainedFrame()) *
joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation));
glm::vec3 front = glm::vec3(inverse * glm::vec4(_owningHead->getFinalOrientationInWorldFrame() * 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 * RADIANS_PER_DEGREE;
state.setRotationInParentFrame(glm::angleAxis(glm::clamp(glm::angle(between), -MAX_ANGLE, MAX_ANGLE), glm::axis(between)) *
state.setRotationInConstrainedFrame(glm::angleAxis(glm::clamp(glm::angle(between), -MAX_ANGLE, MAX_ANGLE), glm::axis(between)) *
joint.rotation);
}

View file

@ -219,7 +219,7 @@ void SkeletonModel::applyPalmData(int jointIndex, PalmData& palm) {
JointState& parentState = _jointStates[parentJointIndex];
parentState.setRotationFromBindFrame(palmRotation, PALM_PRIORITY);
// lock hand to forearm by slamming its rotation (in parent-frame) to identity
_jointStates[jointIndex].setRotationInParentFrame(glm::quat());
_jointStates[jointIndex].setRotationInConstrainedFrame(glm::quat());
} else {
inverseKinematics(jointIndex, palmPosition, palmRotation, PALM_PRIORITY);
}
@ -255,9 +255,9 @@ void SkeletonModel::maybeUpdateLeanRotation(const JointState& parentState, const
}
// get the rotation axes in joint space and use them to adjust the rotation
glm::mat3 axes = glm::mat3_cast(glm::quat());
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.getTransform() * glm::translate(state.getDefaultTranslationInParentFrame()) *
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.getTransform() * glm::translate(state.getDefaultTranslationInConstrainedFrame()) *
joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation)));
state.setRotationInParentFrame(glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanSideways(),
state.setRotationInConstrainedFrame(glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanSideways(),
glm::normalize(inverse * axes[2])) * glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanForward(),
glm::normalize(inverse * axes[0])) * joint.rotation);
}

View file

@ -26,7 +26,7 @@ JointState::JointState() :
JointState::JointState(const JointState& other) : _constraint(NULL) {
_transform = other._transform;
_rotation = other._rotation;
_rotationInParentFrame = other._rotationInParentFrame;
_rotationInConstrainedFrame = other._rotationInConstrainedFrame;
_animationPriority = other._animationPriority;
_fbxJoint = other._fbxJoint;
// DO NOT copy _constraint
@ -43,7 +43,7 @@ JointState::~JointState() {
void JointState::setFBXJoint(const FBXJoint* joint) {
assert(joint != NULL);
_rotationInParentFrame = joint->rotation;
_rotationInConstrainedFrame = joint->rotation;
// NOTE: JointState does not own the FBXJoint to which it points.
_fbxJoint = joint;
if (_constraint) {
@ -68,24 +68,24 @@ void JointState::copyState(const JointState& state) {
_animationPriority = state._animationPriority;
_transform = state._transform;
_rotation = extractRotation(_transform);
_rotationInParentFrame = state._rotationInParentFrame;
_rotationInConstrainedFrame = state._rotationInConstrainedFrame;
_visibleTransform = state._visibleTransform;
_visibleRotation = extractRotation(_visibleTransform);
_visibleRotationInParentFrame = state._visibleRotationInParentFrame;
_visibleRotationInConstrainedFrame = state._visibleRotationInConstrainedFrame;
// DO NOT copy _fbxJoint or _constraint
}
void JointState::computeTransform(const glm::mat4& parentTransform) {
glm::quat modifiedRotation = _fbxJoint->preRotation * _rotationInParentFrame * _fbxJoint->postRotation;
glm::mat4 modifiedTransform = _fbxJoint->preTransform * glm::mat4_cast(modifiedRotation) * _fbxJoint->postTransform;
glm::quat rotationInConstrainedFrame = _fbxJoint->preRotation * _rotationInConstrainedFrame * _fbxJoint->postRotation;
glm::mat4 modifiedTransform = _fbxJoint->preTransform * glm::mat4_cast(rotationInConstrainedFrame) * _fbxJoint->postTransform;
_transform = parentTransform * glm::translate(_fbxJoint->translation) * modifiedTransform;
_rotation = extractRotation(_transform);
}
void JointState::computeVisibleTransform(const glm::mat4& parentTransform) {
glm::quat modifiedRotation = _fbxJoint->preRotation * _visibleRotationInParentFrame * _fbxJoint->postRotation;
glm::mat4 modifiedTransform = _fbxJoint->preTransform * glm::mat4_cast(modifiedRotation) * _fbxJoint->postTransform;
glm::quat rotationInConstrainedFrame = _fbxJoint->preRotation * _visibleRotationInConstrainedFrame * _fbxJoint->postRotation;
glm::mat4 modifiedTransform = _fbxJoint->preTransform * glm::mat4_cast(rotationInConstrainedFrame) * _fbxJoint->postTransform;
_visibleTransform = parentTransform * glm::translate(_fbxJoint->translation) * modifiedTransform;
_visibleRotation = extractRotation(_visibleTransform);
}
@ -97,7 +97,7 @@ glm::quat JointState::getRotationFromBindToModelFrame() const {
void JointState::restoreRotation(float fraction, float priority) {
assert(_fbxJoint != NULL);
if (priority == _animationPriority || _animationPriority == 0.0f) {
setRotationInParentFrame(safeMix(_rotationInParentFrame, _fbxJoint->rotation, fraction));
setRotationInConstrainedFrame(safeMix(_rotationInConstrainedFrame, _fbxJoint->rotation, fraction));
_animationPriority = 0.0f;
}
}
@ -106,11 +106,11 @@ void JointState::setRotationFromBindFrame(const glm::quat& rotation, float prior
// rotation is from bind- to model-frame
assert(_fbxJoint != NULL);
if (priority >= _animationPriority) {
glm::quat targetRotation = _rotationInParentFrame * glm::inverse(_rotation) * rotation * glm::inverse(_fbxJoint->inverseBindRotation);
glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(_rotation) * rotation * glm::inverse(_fbxJoint->inverseBindRotation);
if (constrain && _constraint) {
_constraint->softClamp(targetRotation, _rotationInParentFrame, 0.5f);
_constraint->softClamp(targetRotation, _rotationInConstrainedFrame, 0.5f);
}
setRotationInParentFrame(targetRotation);
setRotationInConstrainedFrame(targetRotation);
_animationPriority = priority;
}
}
@ -137,12 +137,12 @@ void JointState::applyRotationDelta(const glm::quat& delta, bool constrain, floa
_animationPriority = priority;
if (!constrain || _constraint == NULL) {
// no constraints
_rotationInParentFrame = _rotationInParentFrame * glm::inverse(_rotation) * delta * _rotation;
_rotationInConstrainedFrame = _rotationInConstrainedFrame * glm::inverse(_rotation) * delta * _rotation;
_rotation = delta * _rotation;
return;
}
glm::quat targetRotation = _rotationInParentFrame * glm::inverse(_rotation) * delta * _rotation;
setRotationInParentFrame(targetRotation);
glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(_rotation) * delta * _rotation;
setRotationInConstrainedFrame(targetRotation);
}
/// Applies delta rotation to joint but mixes a little bit of the default pose as well.
@ -154,30 +154,30 @@ void JointState::mixRotationDelta(const glm::quat& delta, float mixFactor, float
return;
}
_animationPriority = priority;
glm::quat targetRotation = _rotationInParentFrame * glm::inverse(_rotation) * delta * _rotation;
glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(_rotation) * delta * _rotation;
if (mixFactor > 0.0f && mixFactor <= 1.0f) {
targetRotation = safeMix(targetRotation, _fbxJoint->rotation, mixFactor);
}
if (_constraint) {
_constraint->softClamp(targetRotation, _rotationInParentFrame, 0.5f);
_constraint->softClamp(targetRotation, _rotationInConstrainedFrame, 0.5f);
}
setRotationInParentFrame(targetRotation);
setRotationInConstrainedFrame(targetRotation);
}
glm::quat JointState::computeParentRotation() const {
// R = Rp * Rpre * r * Rpost
// Rp = R * (Rpre * r * Rpost)^
return _rotation * glm::inverse(_fbxJoint->preRotation * _rotationInParentFrame * _fbxJoint->postRotation);
return _rotation * glm::inverse(_fbxJoint->preRotation * _rotationInConstrainedFrame * _fbxJoint->postRotation);
}
void JointState::setRotationInParentFrame(const glm::quat& targetRotation) {
void JointState::setRotationInConstrainedFrame(const glm::quat& targetRotation) {
glm::quat parentRotation = computeParentRotation();
_rotationInParentFrame = targetRotation;
_rotationInConstrainedFrame = targetRotation;
// R' = Rp * Rpre * r' * Rpost
_rotation = parentRotation * _fbxJoint->preRotation * _rotationInParentFrame * _fbxJoint->postRotation;
_rotation = parentRotation * _fbxJoint->preRotation * _rotationInConstrainedFrame * _fbxJoint->postRotation;
}
const glm::vec3& JointState::getDefaultTranslationInParentFrame() const {
const glm::vec3& JointState::getDefaultTranslationInConstrainedFrame() const {
assert(_fbxJoint != NULL);
return _fbxJoint->translation;
}
@ -185,5 +185,5 @@ const glm::vec3& JointState::getDefaultTranslationInParentFrame() const {
void JointState::slaveVisibleTransform() {
_visibleTransform = _transform;
_visibleRotation = _rotation;
_visibleRotationInParentFrame = _rotationInParentFrame;
_visibleRotationInConstrainedFrame = _rotationInConstrainedFrame;
}

View file

@ -66,14 +66,14 @@ public:
void restoreRotation(float fraction, float priority);
/// \param rotation is from bind- to model-frame
/// computes and sets new _rotationInParentFrame
/// computes and sets new _rotationInConstrainedFrame
/// NOTE: the JointState's model-frame transform/rotation are NOT updated!
void setRotationFromBindFrame(const glm::quat& rotation, float priority, bool constrain = false);
void setRotationInParentFrame(const glm::quat& targetRotation);
const glm::quat& getRotationInParentFrame() const { return _rotationInParentFrame; }
void setRotationInConstrainedFrame(const glm::quat& targetRotation);
const glm::quat& getRotationInConstrainedFrame() const { return _rotationInConstrainedFrame; }
const glm::vec3& getDefaultTranslationInParentFrame() const;
const glm::vec3& getDefaultTranslationInConstrainedFrame() const;
void clearTransformTranslation();
@ -92,11 +92,11 @@ private:
glm::mat4 _transform; // joint- to model-frame
glm::quat _rotation; // joint- to model-frame
glm::quat _rotationInParentFrame; // joint- to parentJoint-frame
glm::quat _rotationInConstrainedFrame; // rotation in frame where angular constraints would be applied
glm::mat4 _visibleTransform;
glm::quat _visibleRotation;
glm::quat _visibleRotationInParentFrame;
glm::quat _visibleRotationInConstrainedFrame;
const FBXJoint* _fbxJoint; // JointState does NOT own its FBXJoint
AngularConstraint* _constraint; // JointState owns its AngularConstraint

View file

@ -460,7 +460,7 @@ void Model::reset() {
}
const FBXGeometry& geometry = _geometry->getFBXGeometry();
for (int i = 0; i < _jointStates.size(); i++) {
_jointStates[i].setRotationInParentFrame(geometry.joints.at(i).rotation);
_jointStates[i].setRotationInConstrainedFrame(geometry.joints.at(i).rotation);
}
}
@ -688,7 +688,7 @@ bool Model::getJointState(int index, glm::quat& rotation) const {
if (index == -1 || index >= _jointStates.size()) {
return false;
}
rotation = _jointStates.at(index).getRotationInParentFrame();
rotation = _jointStates.at(index).getRotationInConstrainedFrame();
const glm::quat& defaultRotation = _geometry->getFBXGeometry().joints.at(index).rotation;
return glm::abs(rotation.x - defaultRotation.x) >= EPSILON ||
glm::abs(rotation.y - defaultRotation.y) >= EPSILON ||
@ -701,7 +701,7 @@ void Model::setJointState(int index, bool valid, const glm::quat& rotation, floa
JointState& state = _jointStates[index];
if (priority >= state._animationPriority) {
if (valid) {
state.setRotationInParentFrame(rotation);
state.setRotationInConstrainedFrame(rotation);
state._animationPriority = priority;
} else {
state.restoreRotation(1.0f, priority);
@ -1787,7 +1787,7 @@ void AnimationHandle::applyFrame(float frameIndex) {
if (mapping != -1) {
JointState& state = _model->_jointStates[mapping];
if (_priority >= state._animationPriority) {
state.setRotationInParentFrame(safeMix(floorFrame.rotations.at(i), ceilFrame.rotations.at(i), frameFraction));
state.setRotationInConstrainedFrame(safeMix(floorFrame.rotations.at(i), ceilFrame.rotations.at(i), frameFraction));
state._animationPriority = _priority;
}
}

View file

@ -490,11 +490,11 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
for (int i = 0; i < numJoints; i++) {
JointData& data = _jointData[i];
if (data.valid) {
_hasNewJointRotations = true;
sourceBuffer += unpackOrientationQuatFromBytes(sourceBuffer, data.rotation);
}
}
} // numJoints * 8 bytes
_hasNewJointRotations = true;
return sourceBuffer - startPosition;
}