Merge pull request #4071 from Atlante45/head_rotation_fix

Head rotation fix
This commit is contained in:
Philip Rosedale 2015-01-08 17:24:23 -08:00
commit 22a609f014
5 changed files with 26 additions and 95 deletions

View file

@ -454,47 +454,6 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool
return;
}
renderDisplayName();
if (!_chatMessage.empty()) {
int width = 0;
int lastWidth = 0;
for (string::iterator it = _chatMessage.begin(); it != _chatMessage.end(); it++) {
width += (lastWidth = textRenderer(CHAT)->computeWidth(*it));
}
glPushMatrix();
glm::vec3 chatPosition = getHead()->getEyePosition() + getBodyUpDirection() * CHAT_MESSAGE_HEIGHT * _scale;
glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z);
glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation();
glm::vec3 chatAxis = glm::axis(chatRotation);
glRotatef(glm::degrees(glm::angle(chatRotation)), chatAxis.x, chatAxis.y, chatAxis.z);
glColor3f(0.0f, 0.8f, 0.0f);
glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
glRotatef(180.0f, 0.0f, 0.0f, 1.0f);
glScalef(_scale * CHAT_MESSAGE_SCALE, _scale * CHAT_MESSAGE_SCALE, 1.0f);
glDisable(GL_LIGHTING);
glDepthMask(false);
if (_keyState == NO_KEY_DOWN) {
textRenderer(CHAT)->draw(-width / 2.0f, 0, _chatMessage.c_str());
} else {
// rather than using substr and allocating a new string, just replace the last
// character with a null, then restore it
int lastIndex = _chatMessage.size() - 1;
char lastChar = _chatMessage[lastIndex];
_chatMessage[lastIndex] = '\0';
textRenderer(CHAT)->draw(-width / 2.0f, 0, _chatMessage.c_str());
_chatMessage[lastIndex] = lastChar;
glColor3f(0.0f, 1.0f, 0.0f);
textRenderer(CHAT)->draw(width / 2.0f - lastWidth, 0, _chatMessage.c_str() + lastIndex);
}
glEnable(GL_LIGHTING);
glDepthMask(true);
glPopMatrix();
}
}
glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const {

View file

@ -49,16 +49,22 @@ void FaceModel::maybeUpdateNeckRotation(const JointState& parentState, const FBX
Avatar* owningAvatar = static_cast<Avatar*>(_owningHead->_owningAvatar);
// 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.getDefaultTranslationInConstrainedFrame()) *
joint.preTransform * glm::mat4_cast(joint.preRotation)));
state.setRotationInConstrainedFrame(
glm::angleAxis(- RADIANS_PER_DEGREE * (_owningHead->getFinalRoll() - owningAvatar->getHead()->getFinalLeanSideways()),
glm::normalize(inverse * axes[2]))
* glm::angleAxis(RADIANS_PER_DEGREE * (_owningHead->getFinalYaw() - _owningHead->getTorsoTwist()),
glm::normalize(inverse * axes[1]))
* glm::angleAxis(- RADIANS_PER_DEGREE * (_owningHead->getFinalPitch() - owningAvatar->getHead()->getFinalLeanForward()),
glm::normalize(inverse * axes[0]))
* joint.rotation, DEFAULT_PRIORITY);
glm::mat3 inverse = glm::mat3(glm::inverse(parentState.getTransform() *
glm::translate(state.getDefaultTranslationInConstrainedFrame()) *
joint.preTransform * glm::mat4_cast(joint.preRotation)));
glm::vec3 pitchYawRoll = safeEulerAngles(_owningHead->getFinalOrientationInLocalFrame());
if (owningAvatar->isMyAvatar()) {
glm::vec3 lean = glm::radians(glm::vec3(_owningHead->getFinalLeanForward(),
_owningHead->getTorsoTwist(),
_owningHead->getFinalLeanSideways()));
pitchYawRoll -= lean;
}
state.setRotationInConstrainedFrame(glm::angleAxis(-pitchYawRoll.z, glm::normalize(inverse * axes[2]))
* glm::angleAxis(pitchYawRoll.y, glm::normalize(inverse * axes[1]))
* glm::angleAxis(-pitchYawRoll.x, glm::normalize(inverse * axes[0]))
* joint.rotation, DEFAULT_PRIORITY);
}
void FaceModel::maybeUpdateEyeRotation(Model* model, const JointState& parentState, const FBXJoint& joint, JointState& state) {

View file

@ -175,11 +175,6 @@ QByteArray AvatarData::toByteArray() {
// Instantaneous audio loudness (used to drive facial animation)
memcpy(destinationBuffer, &_headData->_audioLoudness, sizeof(float));
destinationBuffer += sizeof(float);
// chat message
*destinationBuffer++ = _chatMessage.size();
memcpy(destinationBuffer, _chatMessage.data(), _chatMessage.size() * sizeof(char));
destinationBuffer += _chatMessage.size() * sizeof(char);
// bitMask of less than byte wide items
unsigned char bitItems = 0;
@ -300,11 +295,10 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
// lookAt = 12
// audioLoudness = 4
// }
// + 1 byte for messageSize (0)
// + 1 byte for pupilSize
// + 1 byte for numJoints (0)
// = 53 bytes
int minPossibleSize = 53;
int minPossibleSize = 52;
int maxAvailableSize = packet.size() - offset;
if (minPossibleSize > maxAvailableSize) {
@ -420,23 +414,6 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
_headData->_audioLoudness = audioLoudness;
} // 4 bytes
// chat
int chatMessageSize = *sourceBuffer++;
minPossibleSize += chatMessageSize;
if (minPossibleSize > maxAvailableSize) {
if (shouldLogError(now)) {
qDebug() << "Malformed AvatarData packet before ChatMessage;"
<< " displayName = '" << _displayName << "'"
<< " minPossibleSize = " << minPossibleSize
<< " maxAvailableSize = " << maxAvailableSize;
}
return maxAvailableSize;
}
{ // chat payload
_chatMessage = string((char*)sourceBuffer, chatMessageSize);
sourceBuffer += chatMessageSize * sizeof(char);
} // 1 + chatMessageSize bytes
{ // bitFlags and face data
unsigned char bitItems = *sourceBuffer++;

View file

@ -32,17 +32,17 @@ typedef unsigned long long quint64;
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <QtCore/QElapsedTimer>
#include <QtCore/QByteArray>
#include <QtCore/QHash>
#include <QtCore/QObject>
#include <QtCore/QStringList>
#include <QtCore/QUrl>
#include <QtCore/QVector>
#include <QtCore/QVariantMap>
#include <QByteArray>
#include <QElapsedTimer>
#include <QHash>
#include <QObject>
#include <QRect>
#include <QScriptable>
#include <QStringList>
#include <QUrl>
#include <QUuid>
#include <QVariantMap>
#include <QVector>
#include <CollisionInfo.h>
#include <RegisteredMetaTypes.h>
@ -130,7 +130,6 @@ class AvatarData : public QObject {
Q_PROPERTY(float bodyYaw READ getBodyYaw WRITE setBodyYaw)
Q_PROPERTY(float bodyPitch READ getBodyPitch WRITE setBodyPitch)
Q_PROPERTY(float bodyRoll READ getBodyRoll WRITE setBodyRoll)
Q_PROPERTY(QString chatMessage READ getQStringChatMessage WRITE setChatMessage)
Q_PROPERTY(glm::quat orientation READ getOrientation WRITE setOrientation)
Q_PROPERTY(glm::quat headOrientation READ getHeadOrientation WRITE setHeadOrientation)
@ -242,12 +241,6 @@ public:
void setKeyState(KeyState s) { _keyState = s; }
KeyState keyState() const { return _keyState; }
// chat message
void setChatMessage(const std::string& msg) { _chatMessage = msg; }
void setChatMessage(const QString& string) { _chatMessage = string.toLocal8Bit().constData(); }
const std::string& setChatMessage() const { return _chatMessage; }
QString getQStringChatMessage() { return QString(_chatMessage.data()); }
bool isChatCirclingEnabled() const { return _isChatCirclingEnabled; }
const HeadData* getHeadData() const { return _headData; }
const HandData* getHandData() const { return _handData; }
@ -355,9 +348,6 @@ protected:
// key state
KeyState _keyState;
// chat message
std::string _chatMessage;
bool _isChatCirclingEnabled;
bool _forceFaceshiftConnected;
bool _hasNewJointRotations; // set in AvatarData, cleared in Avatar
@ -396,7 +386,6 @@ private:
AvatarData(const AvatarData&);
AvatarData& operator= (const AvatarData&);
};
Q_DECLARE_METATYPE(AvatarData*)
class JointData {

View file

@ -57,7 +57,7 @@ PacketVersion versionForPacketType(PacketType type) {
case PacketTypeInjectAudio:
return 1;
case PacketTypeAvatarData:
return 3;
return 4;
case PacketTypeAvatarIdentity:
return 1;
case PacketTypeEnvironmentData: