Working on allowing attachment models to be uploaded.

This commit is contained in:
Andrzej Kapolka 2014-05-04 15:23:31 -07:00
parent adb301bfe3
commit e0400dbd9c
11 changed files with 79 additions and 57 deletions

View file

@ -63,11 +63,11 @@
#include <UUID.h> #include <UUID.h>
#include <OctreeSceneStats.h> #include <OctreeSceneStats.h>
#include <LocalVoxelsList.h> #include <LocalVoxelsList.h>
#include <ModelUploader.h>
#include "Application.h" #include "Application.h"
#include "InterfaceVersion.h" #include "InterfaceVersion.h"
#include "Menu.h" #include "Menu.h"
#include "ModelUploader.h"
#include "Util.h" #include "Util.h"
#include "devices/OculusManager.h" #include "devices/OculusManager.h"
#include "devices/TV3DManager.h" #include "devices/TV3DManager.h"
@ -3090,6 +3090,16 @@ void Application::setMenuShortcutsEnabled(bool enabled) {
setShortcutsEnabled(_window->menuBar(), enabled); setShortcutsEnabled(_window->menuBar(), enabled);
} }
void Application::uploadModel(ModelType modelType) {
ModelUploader* uploader = new ModelUploader(modelType);
QThread* thread = new QThread();
thread->connect(uploader, SIGNAL(destroyed()), SLOT(quit()));
thread->connect(thread, SIGNAL(finished()), SLOT(deleteLater()));
uploader->connect(thread, SIGNAL(started()), SLOT(send()));
thread->start();
}
void Application::updateWindowTitle(){ void Application::updateWindowTitle(){
QString buildVersion = " (build " + applicationVersion() + ")"; QString buildVersion = " (build " + applicationVersion() + ")";
@ -3417,22 +3427,16 @@ void Application::toggleRunningScriptsWidget() {
} }
} }
void Application::uploadFST(bool isHead) {
ModelUploader* uploader = new ModelUploader(isHead);
QThread* thread = new QThread();
thread->connect(uploader, SIGNAL(destroyed()), SLOT(quit()));
thread->connect(thread, SIGNAL(finished()), SLOT(deleteLater()));
uploader->connect(thread, SIGNAL(started()), SLOT(send()));
thread->start();
}
void Application::uploadHead() { void Application::uploadHead() {
uploadFST(true); uploadModel(HEAD_MODEL);
} }
void Application::uploadSkeleton() { void Application::uploadSkeleton() {
uploadFST(false); uploadModel(SKELETON_MODEL);
}
void Application::uploadAttachment() {
uploadModel(ATTACHMENT_MODEL);
} }
ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScriptFromEditor) { ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScriptFromEditor) {

View file

@ -71,6 +71,7 @@
#include "scripting/ControllerScriptingInterface.h" #include "scripting/ControllerScriptingInterface.h"
#include "ui/BandwidthDialog.h" #include "ui/BandwidthDialog.h"
#include "ui/BandwidthMeter.h" #include "ui/BandwidthMeter.h"
#include "ui/ModelsBrowser.h"
#include "ui/OctreeStatsDialog.h" #include "ui/OctreeStatsDialog.h"
#include "ui/RearMirrorTools.h" #include "ui/RearMirrorTools.h"
#include "ui/LodToolsDialog.h" #include "ui/LodToolsDialog.h"
@ -295,9 +296,9 @@ public slots:
void reloadAllScripts(); void reloadAllScripts();
void toggleRunningScriptsWidget(); void toggleRunningScriptsWidget();
void uploadFST(bool isHead);
void uploadHead(); void uploadHead();
void uploadSkeleton(); void uploadSkeleton();
void uploadAttachment();
void bumpSettings() { ++_numChangedSettings; } void bumpSettings() { ++_numChangedSettings; }
@ -375,13 +376,11 @@ private:
void setMenuShortcutsEnabled(bool enabled); void setMenuShortcutsEnabled(bool enabled);
void uploadModel(ModelType modelType);
static void attachNewHeadToNode(Node *newNode); static void attachNewHeadToNode(Node *newNode);
static void* networkReceive(void* args); // network receive thread static void* networkReceive(void* args); // network receive thread
void findAxisAlignment();
void displayRearMirrorTools();
MainWindow* _window; MainWindow* _window;
GLCanvas* _glWidget; // our GLCanvas has a couple extra features GLCanvas* _glWidget; // our GLCanvas has a couple extra features

View file

@ -157,6 +157,8 @@ Menu::Menu() :
addDisabledActionAndSeparator(fileMenu, "Upload Avatar Model"); addDisabledActionAndSeparator(fileMenu, "Upload Avatar Model");
addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadHead, 0, Application::getInstance(), SLOT(uploadHead())); addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadHead, 0, Application::getInstance(), SLOT(uploadHead()));
addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadSkeleton, 0, Application::getInstance(), SLOT(uploadSkeleton())); addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadSkeleton, 0, Application::getInstance(), SLOT(uploadSkeleton()));
addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadAttachment, 0,
Application::getInstance(), SLOT(uploadAttachment()));
addDisabledActionAndSeparator(fileMenu, "Settings"); addDisabledActionAndSeparator(fileMenu, "Settings");
addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsImport, 0, this, SLOT(importSettings())); addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsImport, 0, this, SLOT(importSettings()));
addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsExport, 0, this, SLOT(exportSettings())); addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsExport, 0, this, SLOT(exportSettings()));

View file

@ -363,6 +363,7 @@ namespace MenuOption {
const QString TestPing = "Test Ping"; const QString TestPing = "Test Ping";
const QString TransmitterDrive = "Transmitter Drive"; const QString TransmitterDrive = "Transmitter Drive";
const QString TurnWithHead = "Turn using Head"; const QString TurnWithHead = "Turn using Head";
const QString UploadAttachment = "Upload Attachment Model";
const QString UploadHead = "Upload Head Model"; const QString UploadHead = "Upload Head Model";
const QString UploadSkeleton = "Upload Skeleton Model"; const QString UploadSkeleton = "Upload Skeleton Model";
const QString Visage = "Visage"; const QString Visage = "Visage";

View file

@ -59,11 +59,11 @@ static const int MAX_CHECK = 30;
static const int QCOMPRESS_HEADER_POSITION = 0; static const int QCOMPRESS_HEADER_POSITION = 0;
static const int QCOMPRESS_HEADER_SIZE = 4; static const int QCOMPRESS_HEADER_SIZE = 4;
ModelUploader::ModelUploader(bool isHead) : ModelUploader::ModelUploader(ModelType modelType) :
_lodCount(-1), _lodCount(-1),
_texturesCount(-1), _texturesCount(-1),
_totalSize(0), _totalSize(0),
_isHead(isHead), _modelType(modelType),
_readyToSend(false), _readyToSend(false),
_dataMultiPart(new QHttpMultiPart(QHttpMultiPart::FormDataType)), _dataMultiPart(new QHttpMultiPart(QHttpMultiPart::FormDataType)),
_numberOfChecks(MAX_CHECK) _numberOfChecks(MAX_CHECK)
@ -190,7 +190,7 @@ bool ModelUploader::zip() {
} }
// open the dialog to configure the rest // open the dialog to configure the rest
ModelPropertiesDialog properties(_isHead, mapping, basePath, geometry); ModelPropertiesDialog properties(_modelType, mapping, basePath, geometry);
if (properties.exec() == QDialog::Rejected) { if (properties.exec() == QDialog::Rejected) {
return false; return false;
} }
@ -202,7 +202,7 @@ bool ModelUploader::zip() {
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"model_name\""); textPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"model_name\"");
textPart.setBody(nameField); textPart.setBody(nameField);
_dataMultiPart->append(textPart); _dataMultiPart->append(textPart);
_url = S3_URL + ((_isHead)? "/models/heads/" : "/models/skeletons/") + nameField + ".fst"; _url = S3_URL + "/models/" + MODEL_TYPE_NAMES[_modelType] + "/" + nameField + ".fst";
} else { } else {
QMessageBox::warning(NULL, QMessageBox::warning(NULL,
QString("ModelUploader::zip()"), QString("ModelUploader::zip()"),
@ -260,11 +260,7 @@ bool ModelUploader::zip() {
QHttpPart textPart; QHttpPart textPart;
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data;" textPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data;"
" name=\"model_category\""); " name=\"model_category\"");
if (_isHead) { textPart.setBody(MODEL_TYPE_NAMES[_modelType]);
textPart.setBody("heads");
} else {
textPart.setBody("skeletons");
}
_dataMultiPart->append(textPart); _dataMultiPart->append(textPart);
_readyToSend = true; _readyToSend = true;
@ -510,9 +506,9 @@ bool ModelUploader::addPart(const QFile& file, const QByteArray& contents, const
return true; return true;
} }
ModelPropertiesDialog::ModelPropertiesDialog(bool isHead, const QVariantHash& originalMapping, ModelPropertiesDialog::ModelPropertiesDialog(ModelType modelType, const QVariantHash& originalMapping,
const QString& basePath, const FBXGeometry& geometry) : const QString& basePath, const FBXGeometry& geometry) :
_isHead(isHead), _modelType(modelType),
_originalMapping(originalMapping), _originalMapping(originalMapping),
_basePath(basePath), _basePath(basePath),
_geometry(geometry) { _geometry(geometry) {
@ -531,10 +527,12 @@ ModelPropertiesDialog::ModelPropertiesDialog(bool isHead, const QVariantHash& or
_scale->setMaximum(FLT_MAX); _scale->setMaximum(FLT_MAX);
_scale->setSingleStep(0.01); _scale->setSingleStep(0.01);
form->addRow("Left Eye Joint:", _leftEyeJoint = createJointBox()); if (_modelType != ATTACHMENT_MODEL) {
form->addRow("Right Eye Joint:", _rightEyeJoint = createJointBox()); form->addRow("Left Eye Joint:", _leftEyeJoint = createJointBox());
form->addRow("Neck Joint:", _neckJoint = createJointBox()); form->addRow("Right Eye Joint:", _rightEyeJoint = createJointBox());
if (!isHead) { form->addRow("Neck Joint:", _neckJoint = createJointBox());
}
if (_modelType == SKELETON_MODEL) {
form->addRow("Root Joint:", _rootJoint = createJointBox()); form->addRow("Root Joint:", _rootJoint = createJointBox());
form->addRow("Lean Joint:", _leanJoint = createJointBox()); form->addRow("Lean Joint:", _leanJoint = createJointBox());
form->addRow("Head Joint:", _headJoint = createJointBox()); form->addRow("Head Joint:", _headJoint = createJointBox());
@ -573,10 +571,12 @@ QVariantHash ModelPropertiesDialog::getMapping() const {
mapping.insert(JOINT_INDEX_FIELD, jointIndices); mapping.insert(JOINT_INDEX_FIELD, jointIndices);
QVariantHash joints = mapping.value(JOINT_FIELD).toHash(); QVariantHash joints = mapping.value(JOINT_FIELD).toHash();
insertJointMapping(joints, "jointEyeLeft", _leftEyeJoint->currentText()); if (_modelType != ATTACHMENT_MODEL) {
insertJointMapping(joints, "jointEyeRight", _rightEyeJoint->currentText()); insertJointMapping(joints, "jointEyeLeft", _leftEyeJoint->currentText());
insertJointMapping(joints, "jointNeck", _neckJoint->currentText()); insertJointMapping(joints, "jointEyeRight", _rightEyeJoint->currentText());
if (!_isHead) { insertJointMapping(joints, "jointNeck", _neckJoint->currentText());
}
if (_modelType == SKELETON_MODEL) {
insertJointMapping(joints, "jointRoot", _rootJoint->currentText()); insertJointMapping(joints, "jointRoot", _rootJoint->currentText());
insertJointMapping(joints, "jointLean", _leanJoint->currentText()); insertJointMapping(joints, "jointLean", _leanJoint->currentText());
insertJointMapping(joints, "jointHead", _headJoint->currentText()); insertJointMapping(joints, "jointHead", _headJoint->currentText());
@ -604,10 +604,12 @@ void ModelPropertiesDialog::reset() {
_scale->setValue(_originalMapping.value(SCALE_FIELD).toDouble()); _scale->setValue(_originalMapping.value(SCALE_FIELD).toDouble());
QVariantHash jointHash = _originalMapping.value(JOINT_FIELD).toHash(); QVariantHash jointHash = _originalMapping.value(JOINT_FIELD).toHash();
setJointText(_leftEyeJoint, jointHash.value("jointEyeLeft").toString()); if (_modelType != ATTACHMENT_MODEL) {
setJointText(_rightEyeJoint, jointHash.value("jointEyeRight").toString()); setJointText(_leftEyeJoint, jointHash.value("jointEyeLeft").toString());
setJointText(_neckJoint, jointHash.value("jointNeck").toString()); setJointText(_rightEyeJoint, jointHash.value("jointEyeRight").toString());
if (!_isHead) { setJointText(_neckJoint, jointHash.value("jointNeck").toString());
}
if (_modelType == SKELETON_MODEL) {
setJointText(_rootJoint, jointHash.value("jointRoot").toString()); setJointText(_rootJoint, jointHash.value("jointRoot").toString());
setJointText(_leanJoint, jointHash.value("jointLean").toString()); setJointText(_leanJoint, jointHash.value("jointLean").toString());
setJointText(_headJoint, jointHash.value("jointHead").toString()); setJointText(_headJoint, jointHash.value("jointHead").toString());

View file

@ -17,6 +17,8 @@
#include <FBXReader.h> #include <FBXReader.h>
#include "ui/ModelsBrowser.h"
class QComboBox; class QComboBox;
class QDoubleSpinBox; class QDoubleSpinBox;
class QFileInfo; class QFileInfo;
@ -30,7 +32,7 @@ class ModelUploader : public QObject {
Q_OBJECT Q_OBJECT
public: public:
ModelUploader(bool isHead); ModelUploader(ModelType type);
~ModelUploader(); ~ModelUploader();
public slots: public slots:
@ -49,7 +51,7 @@ private:
int _lodCount; int _lodCount;
int _texturesCount; int _texturesCount;
int _totalSize; int _totalSize;
bool _isHead; ModelType _modelType;
bool _readyToSend; bool _readyToSend;
QHttpMultiPart* _dataMultiPart; QHttpMultiPart* _dataMultiPart;
@ -73,7 +75,7 @@ class ModelPropertiesDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
ModelPropertiesDialog(bool isHead, const QVariantHash& originalMapping, ModelPropertiesDialog(ModelType modelType, const QVariantHash& originalMapping,
const QString& basePath, const FBXGeometry& geometry); const QString& basePath, const FBXGeometry& geometry);
QVariantHash getMapping() const; QVariantHash getMapping() const;
@ -87,7 +89,7 @@ private:
QComboBox* createJointBox(bool withNone = true) const; QComboBox* createJointBox(bool withNone = true) const;
void insertJointMapping(QVariantHash& joints, const QString& joint, const QString& name) const; void insertJointMapping(QVariantHash& joints, const QString& joint, const QString& name) const;
bool _isHead; ModelType _modelType;
QVariantHash _originalMapping; QVariantHash _originalMapping;
QString _basePath; QString _basePath;
FBXGeometry _geometry; FBXGeometry _geometry;

View file

@ -22,10 +22,11 @@
#include "ModelsBrowser.h" #include "ModelsBrowser.h"
const char* MODEL_TYPE_NAMES[] = { "heads", "skeletons", "attachments" };
static const QString S3_URL = "http://highfidelity-public.s3-us-west-1.amazonaws.com"; static const QString S3_URL = "http://highfidelity-public.s3-us-west-1.amazonaws.com";
static const QString PUBLIC_URL = "http://public.highfidelity.io"; static const QString PUBLIC_URL = "http://public.highfidelity.io";
static const QString HEAD_MODELS_LOCATION = "models/heads"; static const QString MODELS_LOCATION = "models/";
static const QString SKELETON_MODELS_LOCATION = "models/skeletons/";
static const QString PREFIX_PARAMETER_NAME = "prefix"; static const QString PREFIX_PARAMETER_NAME = "prefix";
static const QString MARKER_PARAMETER_NAME = "marker"; static const QString MARKER_PARAMETER_NAME = "marker";
@ -243,11 +244,7 @@ void ModelHandler::queryNewFiles(QString marker) {
// Build query // Build query
QUrl url(S3_URL); QUrl url(S3_URL);
QUrlQuery query; QUrlQuery query;
if (_type == Head) { query.addQueryItem(PREFIX_PARAMETER_NAME, MODELS_LOCATION + MODEL_TYPE_NAMES[_type]);
query.addQueryItem(PREFIX_PARAMETER_NAME, HEAD_MODELS_LOCATION);
} else if (_type == Skeleton) {
query.addQueryItem(PREFIX_PARAMETER_NAME, SKELETON_MODELS_LOCATION);
}
if (!marker.isEmpty()) { if (!marker.isEmpty()) {
query.addQueryItem(MARKER_PARAMETER_NAME, marker); query.addQueryItem(MARKER_PARAMETER_NAME, marker);

View file

@ -16,12 +16,14 @@
#include <QStandardItemModel> #include <QStandardItemModel>
#include <QTreeView> #include <QTreeView>
enum ModelType { enum ModelType {
Head, HEAD_MODEL,
Skeleton SKELETON_MODEL,
ATTACHMENT_MODEL
}; };
extern const char* MODEL_TYPE_NAMES[];
class ModelHandler : public QObject { class ModelHandler : public QObject {
Q_OBJECT Q_OBJECT
public: public:

View file

@ -48,7 +48,7 @@ void PreferencesDialog::openHeadModelBrowser() {
setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint); setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
show(); show();
ModelsBrowser modelBrowser(Head); ModelsBrowser modelBrowser(HEAD_MODEL);
connect(&modelBrowser, &ModelsBrowser::selected, this, &PreferencesDialog::setHeadUrl); connect(&modelBrowser, &ModelsBrowser::selected, this, &PreferencesDialog::setHeadUrl);
modelBrowser.browse(); modelBrowser.browse();
@ -60,7 +60,7 @@ void PreferencesDialog::openBodyModelBrowser() {
setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint); setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
show(); show();
ModelsBrowser modelBrowser(Skeleton); ModelsBrowser modelBrowser(SKELETON_MODEL);
connect(&modelBrowser, &ModelsBrowser::selected, this, &PreferencesDialog::setSkeletonUrl); connect(&modelBrowser, &ModelsBrowser::selected, this, &PreferencesDialog::setSkeletonUrl);
modelBrowser.browse(); modelBrowser.browse();

View file

@ -81,6 +81,7 @@ const glm::vec3 vec3Zero(0.0f);
class QNetworkAccessManager; class QNetworkAccessManager;
class AttachmentData;
class JointData; class JointData;
class AvatarData : public QObject { class AvatarData : public QObject {
@ -275,6 +276,7 @@ protected:
QUrl _faceModelURL; QUrl _faceModelURL;
QUrl _skeletonModelURL; QUrl _skeletonModelURL;
QVector<AttachmentData> _attachmentData;
QString _displayName; QString _displayName;
QRect _displayNameBoundingRect; QRect _displayNameBoundingRect;
@ -309,4 +311,13 @@ public:
glm::quat rotation; glm::quat rotation;
}; };
class AttachmentData {
public:
QUrl modelURL;
int jointIndex;
glm::vec3 translation;
glm::quat rotation;
float scale;
};
#endif // hifi_AvatarData_h #endif // hifi_AvatarData_h

View file

@ -49,6 +49,8 @@ PacketVersion versionForPacketType(PacketType type) {
switch (type) { switch (type) {
case PacketTypeAvatarData: case PacketTypeAvatarData:
return 3; return 3;
case PacketTypeAvatarIdentity:
return 1;
case PacketTypeEnvironmentData: case PacketTypeEnvironmentData:
return 1; return 1;
case PacketTypeParticleData: case PacketTypeParticleData: