From 53a276090547f5b49483e06c4fd564a89cd69712 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Sun, 4 May 2014 16:24:23 -0700 Subject: [PATCH] More attachment bits. --- interface/src/Menu.cpp | 12 ++++++++ interface/src/Menu.h | 4 +++ interface/src/avatar/MyAvatar.cpp | 40 ++++++++++++++++++++++++++ interface/src/ui/AttachmentsDialog.cpp | 39 +++++++++++++++++++++++++ interface/src/ui/AttachmentsDialog.h | 30 +++++++++++++++++++ libraries/avatars/src/AvatarData.cpp | 34 ++++++++++++++++++++-- libraries/avatars/src/AvatarData.h | 12 +++++++- libraries/shared/src/StreamUtils.cpp | 18 ++++++++++++ libraries/shared/src/StreamUtils.h | 7 +++++ 9 files changed, 192 insertions(+), 4 deletions(-) create mode 100644 interface/src/ui/AttachmentsDialog.cpp create mode 100644 interface/src/ui/AttachmentsDialog.h diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index b6df2f7269..ed03e77021 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -37,6 +37,7 @@ #include "Menu.h" #include "scripting/MenuScriptingInterface.h" #include "Util.h" +#include "ui/AttachmentsDialog.h" #include "ui/InfoView.h" #include "ui/MetavoxelEditor.h" #include "ui/ModelsBrowser.h" @@ -189,6 +190,8 @@ Menu::Menu() : SLOT(editPreferences()), QAction::PreferencesRole); + addActionToQMenuAndActionHash(editMenu, MenuOption::Attachments, 0, this, SLOT(editAttachments())); + addDisabledActionAndSeparator(editMenu, "Physics"); QObject* avatar = appInstance->getAvatar(); addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::ObeyEnvironmentalGravity, Qt::SHIFT | Qt::Key_G, true, @@ -834,6 +837,15 @@ void Menu::editPreferences() { } } +void Menu::editAttachments() { + if (!_attachmentsDialog) { + _attachmentsDialog = new AttachmentsDialog(); + _attachmentsDialog->show(); + } else { + _attachmentsDialog->close(); + } +} + void Menu::goToDomain(const QString newDomain) { if (NodeList::getInstance()->getDomainHandler().getHostname() != newDomain) { // send a node kill request, indicating to other clients that they should play the "disappeared" effect diff --git a/interface/src/Menu.h b/interface/src/Menu.h index e37d256f62..348d61bab8 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -64,6 +64,7 @@ struct ViewFrustumOffset { class QSettings; +class AttachmentsDialog; class BandwidthDialog; class LodToolsDialog; class MetavoxelEditor; @@ -171,6 +172,7 @@ public slots: private slots: void aboutApp(); void editPreferences(); + void editAttachments(); void goToDomainDialog(); void goToLocation(); void nameLocation(); @@ -252,6 +254,7 @@ private: SimpleMovingAverage _fastFPSAverage; QAction* _loginAction; QPointer _preferencesDialog; + QPointer _attachmentsDialog; QAction* _chatAction; QString _snapshotsLocation; }; @@ -261,6 +264,7 @@ namespace MenuOption { const QString AlignForearmsWithWrists = "Align Forearms with Wrists"; const QString AmbientOcclusion = "Ambient Occlusion"; const QString Atmosphere = "Atmosphere"; + const QString Attachments = "Attachments..."; const QString AudioNoiseReduction = "Audio Noise Reduction"; const QString AudioScope = "Audio Scope"; const QString AudioScopePause = "Pause Audio Scope"; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 652eb56258..6af7235117 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -491,6 +491,24 @@ void MyAvatar::saveData(QSettings* settings) { settings->setValue("faceModelURL", _faceModelURL); settings->setValue("skeletonModelURL", _skeletonModelURL); + + settings->beginWriteArray("attachmentData"); + for (int i = 0; i < _attachmentData.size(); i++) { + settings->setArrayIndex(i); + const AttachmentData& attachment = _attachmentData.at(i); + settings->setValue("modelURL", attachment.modelURL); + settings->setValue("jointName", attachment.jointName); + settings->setValue("translation_x", attachment.translation.x); + settings->setValue("translation_y", attachment.translation.y); + settings->setValue("translation_z", attachment.translation.z); + glm::vec3 eulers = safeEulerAngles(attachment.rotation); + settings->setValue("rotation_x", eulers.x); + settings->setValue("rotation_y", eulers.y); + settings->setValue("rotation_z", eulers.z); + settings->setValue("scale", attachment.scale); + } + settings->endArray(); + settings->setValue("displayName", _displayName); settings->endGroup(); @@ -519,6 +537,28 @@ void MyAvatar::loadData(QSettings* settings) { setFaceModelURL(settings->value("faceModelURL", DEFAULT_HEAD_MODEL_URL).toUrl()); setSkeletonModelURL(settings->value("skeletonModelURL").toUrl()); + + QVector attachmentData; + int attachmentCount = settings->beginReadArray("attachmentData"); + for (int i = 0; i < attachmentCount; i++) { + settings->setArrayIndex(i); + AttachmentData attachment; + attachment.modelURL = settings->value("modelURL").toUrl(); + attachment.jointName = settings->value("jointName").toString(); + attachment.translation.x = loadSetting(settings, "translation_x", 0.0f); + attachment.translation.y = loadSetting(settings, "translation_y", 0.0f); + attachment.translation.z = loadSetting(settings, "translation_z", 0.0f); + glm::vec3 eulers; + eulers.x = loadSetting(settings, "rotation_x", 0.0f); + eulers.y = loadSetting(settings, "rotation_y", 0.0f); + eulers.z = loadSetting(settings, "rotation_z", 0.0f); + attachment.rotation = glm::quat(eulers); + attachment.scale = loadSetting(settings, "scale", 1.0f); + attachmentData.append(attachment); + } + settings->endArray(); + setAttachmentData(attachmentData); + setDisplayName(settings->value("displayName").toString()); settings->endGroup(); diff --git a/interface/src/ui/AttachmentsDialog.cpp b/interface/src/ui/AttachmentsDialog.cpp new file mode 100644 index 0000000000..319927c492 --- /dev/null +++ b/interface/src/ui/AttachmentsDialog.cpp @@ -0,0 +1,39 @@ +// +// MetavoxelEditor.cpp +// interface/src/ui +// +// Created by Andrzej Kapolka on 1/21/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include +#include +#include + +#include "Application.h" +#include "AttachmentsDialog.h" + +AttachmentsDialog::AttachmentsDialog() : + QDialog(Application::getInstance()->getWindow()) { + + setWindowTitle("Edit Attachments"); + setAttribute(Qt::WA_DeleteOnClose); + + QVBoxLayout* layout = new QVBoxLayout(); + setLayout(layout); + + QPushButton* newAttachment = new QPushButton("New Attachment"); + connect(newAttachment, SIGNAL(clicked(bool)), SLOT(addAttachment())); + layout->addWidget(newAttachment); + + QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok); + layout->addWidget(buttons); + connect(buttons, SIGNAL(accepted()), SLOT(deleteLater())); +} + +void AttachmentsDialog::addAttachment() { + +} diff --git a/interface/src/ui/AttachmentsDialog.h b/interface/src/ui/AttachmentsDialog.h new file mode 100644 index 0000000000..f6dc3d25b4 --- /dev/null +++ b/interface/src/ui/AttachmentsDialog.h @@ -0,0 +1,30 @@ +// +// AttachmentsDialog.h +// interface/src/ui +// +// Created by Andrzej Kapolka on 5/4/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_AttachmentsDialog_h +#define hifi_AttachmentsDialog_h + +#include + +/// Allows users to edit the avatar attachments. +class AttachmentsDialog : public QDialog { + Q_OBJECT + +public: + + AttachmentsDialog(); + +private slots: + + void addAttachment(); +}; + +#endif // hifi_AttachmentsDialog_h diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index b57d5406d5..485b5517f0 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -599,8 +599,9 @@ bool AvatarData::hasIdentityChangedAfterParsing(const QByteArray &packet) { QUuid avatarUUID; QUrl faceModelURL, skeletonModelURL; + QVector attachmentData; QString displayName; - packetStream >> avatarUUID >> faceModelURL >> skeletonModelURL >> displayName; + packetStream >> avatarUUID >> faceModelURL >> skeletonModelURL >> attachmentData >> displayName; bool hasIdentityChanged = false; @@ -618,7 +619,12 @@ bool AvatarData::hasIdentityChangedAfterParsing(const QByteArray &packet) { setDisplayName(displayName); hasIdentityChanged = true; } - + + if (attachmentData != _attachmentData) { + setAttachmentData(attachmentData); + hasIdentityChanged = true; + } + return hasIdentityChanged; } @@ -626,7 +632,7 @@ QByteArray AvatarData::identityByteArray() { QByteArray identityData; QDataStream identityStream(&identityData, QIODevice::Append); - identityStream << QUuid() << _faceModelURL << _skeletonModelURL << _displayName; + identityStream << QUuid() << _faceModelURL << _skeletonModelURL << _attachmentData << _displayName; return identityData; } @@ -654,6 +660,12 @@ void AvatarData::setSkeletonModelURL(const QUrl& skeletonModelURL) { updateJointMappings(); } +void AvatarData::setAttachmentData(const QVector& attachmentData) { + _attachmentData = attachmentData; + + qDebug() << "Changing attachment data for avatar."; +} + void AvatarData::setDisplayName(const QString& displayName) { _displayName = displayName; @@ -762,3 +774,19 @@ void AvatarData::updateJointMappings() { connect(networkReply, SIGNAL(finished()), this, SLOT(setJointMappingsFromNetworkReply())); } } + +bool AttachmentData::operator==(const AttachmentData& other) const { + return modelURL == other.modelURL && jointName == other.jointName && translation == other.translation && + rotation == other.rotation && scale == other.scale; +} + +QDataStream& operator<<(QDataStream& out, const AttachmentData& attachment) { + return out << attachment.modelURL << attachment.jointName << + attachment.translation << attachment.rotation << attachment.scale; +} + +QDataStream& operator>>(QDataStream& in, AttachmentData& attachment) { + return in >> attachment.modelURL >> attachment.jointName >> + attachment.translation >> attachment.rotation >> attachment.scale; +} + diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 78b33571e8..a853706005 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -45,6 +45,8 @@ typedef unsigned long long quint64; #include #include +#include + #include #include "HeadData.h" @@ -79,6 +81,7 @@ enum KeyState { const glm::vec3 vec3Zero(0.0f); +class QDataStream; class QNetworkAccessManager; class AttachmentData; @@ -211,9 +214,11 @@ public: const QUrl& getFaceModelURL() const { return _faceModelURL; } QString getFaceModelURLString() const { return _faceModelURL.toString(); } const QUrl& getSkeletonModelURL() const { return _skeletonModelURL; } + const QVector& getAttachmentData() const { return _attachmentData; } const QString& getDisplayName() const { return _displayName; } virtual void setFaceModelURL(const QUrl& faceModelURL); virtual void setSkeletonModelURL(const QUrl& skeletonModelURL); + virtual void setAttachmentData(const QVector& attachmentData); virtual void setDisplayName(const QString& displayName); virtual void setBillboard(const QByteArray& billboard); @@ -314,10 +319,15 @@ public: class AttachmentData { public: QUrl modelURL; - int jointIndex; + QString jointName; glm::vec3 translation; glm::quat rotation; float scale; + + bool operator==(const AttachmentData& other) const; }; +QDataStream& operator<<(QDataStream& out, const AttachmentData& attachment); +QDataStream& operator>>(QDataStream& in, AttachmentData& attachment); + #endif // hifi_AvatarData_h diff --git a/libraries/shared/src/StreamUtils.cpp b/libraries/shared/src/StreamUtils.cpp index d7b0c83c1f..5356c45a51 100644 --- a/libraries/shared/src/StreamUtils.cpp +++ b/libraries/shared/src/StreamUtils.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include #include "StreamUtils.h" @@ -47,6 +49,22 @@ std::ostream& operator<<(std::ostream& s, const glm::mat4& m) { return s; } +QDataStream& operator<<(QDataStream& out, const glm::vec3& vector) { + return out << vector.x << vector.y << vector.z; +} + +QDataStream& operator>>(QDataStream& in, glm::vec3& vector) { + return in >> vector.x >> vector.y >> vector.z; +} + +QDataStream& operator<<(QDataStream& out, const glm::quat& quaternion) { + return out << quaternion.x << quaternion.y << quaternion.z << quaternion.w; +} + +QDataStream& operator>>(QDataStream& in, glm::quat& quaternion) { + return in >> quaternion.x >> quaternion.y >> quaternion.z >> quaternion.w; +} + // less common utils can be enabled with DEBUG #ifdef DEBUG diff --git a/libraries/shared/src/StreamUtils.h b/libraries/shared/src/StreamUtils.h index 2546d49ffc..2a42a3ea7b 100644 --- a/libraries/shared/src/StreamUtils.h +++ b/libraries/shared/src/StreamUtils.h @@ -19,6 +19,7 @@ #include #include +class QDataStream; namespace StreamUtil { // dump the buffer, 32 bytes per row, each byte in hex, separated by whitespace @@ -29,6 +30,12 @@ std::ostream& operator<<(std::ostream& s, const glm::vec3& v); std::ostream& operator<<(std::ostream& s, const glm::quat& q); std::ostream& operator<<(std::ostream& s, const glm::mat4& m); +QDataStream& operator<<(QDataStream& out, const glm::vec3& vector); +QDataStream& operator>>(QDataStream& in, glm::vec3& vector); + +QDataStream& operator<<(QDataStream& out, const glm::quat& quaternion); +QDataStream& operator>>(QDataStream& in, glm::quat& quaternion); + // less common utils can be enabled with DEBUG #ifdef DEBUG #include "CollisionInfo.h"