mirror of
https://github.com/lubosz/overte.git
synced 2025-04-23 23:33:48 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi
This commit is contained in:
commit
55d8b763c5
16 changed files with 585 additions and 14 deletions
|
@ -60,6 +60,7 @@
|
|||
#include <ParticlesScriptingInterface.h>
|
||||
#include <PerfStat.h>
|
||||
#include <ResourceCache.h>
|
||||
#include <UserActivityLogger.h>
|
||||
#include <UUID.h>
|
||||
#include <OctreeSceneStats.h>
|
||||
#include <LocalVoxelsList.h>
|
||||
|
@ -269,6 +270,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
|
||||
// set the account manager's root URL and trigger a login request if we don't have the access token
|
||||
accountManager.setAuthURL(DEFAULT_NODE_AUTH_URL);
|
||||
UserActivityLogger::getInstance().launch(applicationVersion());
|
||||
|
||||
// once the event loop has started, check and signal for an access token
|
||||
QMetaObject::invokeMethod(&accountManager, "checkAndSignalForAccessToken", Qt::QueuedConnection);
|
||||
|
@ -401,7 +403,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
}
|
||||
|
||||
Application::~Application() {
|
||||
|
||||
int DELAY_TIME = 1000;
|
||||
UserActivityLogger::getInstance().close(DELAY_TIME);
|
||||
|
||||
qInstallMessageHandler(NULL);
|
||||
|
||||
// make sure we don't call the idle timer any more
|
||||
|
@ -3582,6 +3586,7 @@ ScriptEngine* Application::loadScript(const QString& scriptName, bool loadScript
|
|||
|
||||
_scriptEnginesHash.insertMulti(scriptURLString, scriptEngine);
|
||||
_runningScriptsWidget->setRunningScripts(getRunningScripts());
|
||||
UserActivityLogger::getInstance().loadedScript(scriptURLString);
|
||||
}
|
||||
|
||||
// setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <QOpenGLFramebufferObject>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <UserActivityLogger.h>
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
|
@ -61,6 +62,9 @@ void OculusManager::connect() {
|
|||
|
||||
_ovrHmd = ovrHmd_Create(0);
|
||||
if (_ovrHmd) {
|
||||
if (!_isConnected) {
|
||||
UserActivityLogger::getInstance().connectedDevice("hmd", "oculus");
|
||||
}
|
||||
_isConnected = true;
|
||||
|
||||
ovrHmd_GetDesc(_ovrHmd, &_ovrHmdDesc);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "Application.h"
|
||||
#include "SixenseManager.h"
|
||||
#include "UserActivityLogger.h"
|
||||
|
||||
#ifdef HAVE_SIXENSE
|
||||
const int CALIBRATION_STATE_IDLE = 0;
|
||||
|
@ -39,6 +40,7 @@ SixenseManager::SixenseManager() {
|
|||
|
||||
sixenseInit();
|
||||
#endif
|
||||
_hydrasConnected = false;
|
||||
_triggerPressed[0] = false;
|
||||
_bumperPressed[0] = false;
|
||||
_oldX[0] = -1;
|
||||
|
@ -70,7 +72,11 @@ void SixenseManager::setFilter(bool filter) {
|
|||
void SixenseManager::update(float deltaTime) {
|
||||
#ifdef HAVE_SIXENSE
|
||||
if (sixenseGetNumActiveControllers() == 0) {
|
||||
_hydrasConnected = false;
|
||||
return;
|
||||
} else if (!_hydrasConnected) {
|
||||
_hydrasConnected = true;
|
||||
UserActivityLogger::getInstance().connectedDevice("spatial_controller", "hydra");
|
||||
}
|
||||
MyAvatar* avatar = Application::getInstance()->getAvatar();
|
||||
Hand* hand = avatar->getHand();
|
||||
|
|
|
@ -71,6 +71,7 @@ private:
|
|||
float _lastDistance;
|
||||
|
||||
#endif
|
||||
bool _hydrasConnected;
|
||||
quint64 _lastMovement;
|
||||
glm::vec3 _amountMoved;
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ void ModelTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
|
|||
args->_elementsTouched++;
|
||||
// actually render it here...
|
||||
// we need to iterate the actual modelItems of the element
|
||||
ModelTreeElement* modelTreeElement = (ModelTreeElement*)element;
|
||||
ModelTreeElement* modelTreeElement = static_cast<ModelTreeElement*>(element);
|
||||
|
||||
QList<ModelItem>& modelItems = modelTreeElement->getModels();
|
||||
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
|
||||
#include "Application.h"
|
||||
#include "Menu.h"
|
||||
#include "PreferencesDialog.h"
|
||||
#include "ModelsBrowser.h"
|
||||
#include "PreferencesDialog.h"
|
||||
#include "UserActivityLogger.h"
|
||||
|
||||
const int SCROLL_PANEL_BOTTOM_MARGIN = 30;
|
||||
const int OK_BUTTON_RIGHT_MARGIN = 30;
|
||||
|
@ -176,6 +177,7 @@ void PreferencesDialog::savePreferences() {
|
|||
QString displayNameStr(ui.displayNameEdit->text());
|
||||
if (displayNameStr != _displayNameString) {
|
||||
myAvatar->setDisplayName(displayNameStr);
|
||||
UserActivityLogger::getInstance().changedDisplayName(displayNameStr);
|
||||
shouldDispatchIdentityPacket = true;
|
||||
}
|
||||
|
||||
|
@ -183,6 +185,7 @@ void PreferencesDialog::savePreferences() {
|
|||
if (faceModelURL.toString() != _faceURLString) {
|
||||
// change the faceModelURL in the profile, it will also update this user's BlendFace
|
||||
myAvatar->setFaceModelURL(faceModelURL);
|
||||
UserActivityLogger::getInstance().changedModel("head", faceModelURL.toString());
|
||||
shouldDispatchIdentityPacket = true;
|
||||
}
|
||||
|
||||
|
@ -190,6 +193,7 @@ void PreferencesDialog::savePreferences() {
|
|||
if (skeletonModelURL.toString() != _skeletonURLString) {
|
||||
// change the skeletonModelURL in the profile, it will also update this user's Body
|
||||
myAvatar->setSkeletonModelURL(skeletonModelURL);
|
||||
UserActivityLogger::getInstance().changedModel("skeleton", skeletonModelURL.toString());
|
||||
shouldDispatchIdentityPacket = true;
|
||||
}
|
||||
|
||||
|
|
136
interface/src/ui/overlays/BillboardOverlay.cpp
Normal file
136
interface/src/ui/overlays/BillboardOverlay.cpp
Normal file
|
@ -0,0 +1,136 @@
|
|||
//
|
||||
// BillboardOverlay.cpp
|
||||
//
|
||||
//
|
||||
// Created by Clement on 7/1/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 "../../Application.h"
|
||||
|
||||
#include "BillboardOverlay.h"
|
||||
|
||||
BillboardOverlay::BillboardOverlay()
|
||||
: _manager(NULL),
|
||||
_scale(1.0f),
|
||||
_isFacingAvatar(true) {
|
||||
}
|
||||
|
||||
void BillboardOverlay::render() {
|
||||
if (_billboard.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (!_billboardTexture) {
|
||||
QImage image = QImage::fromData(_billboard);
|
||||
if (image.format() != QImage::Format_ARGB32) {
|
||||
image = image.convertToFormat(QImage::Format_ARGB32);
|
||||
}
|
||||
_size = image.size();
|
||||
_billboardTexture.reset(new Texture());
|
||||
glBindTexture(GL_TEXTURE_2D, _billboardTexture->getID());
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _size.width(), _size.height(), 0,
|
||||
GL_BGRA, GL_UNSIGNED_BYTE, image.constBits());
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, _billboardTexture->getID());
|
||||
}
|
||||
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glAlphaFunc(GL_GREATER, 0.5f);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_LIGHTING);
|
||||
|
||||
glPushMatrix(); {
|
||||
glTranslatef(_position.x, _position.y, _position.z);
|
||||
if (_isFacingAvatar) {
|
||||
// rotate about vertical to face the camera
|
||||
glm::quat rotation = Application::getInstance()->getCamera()->getRotation();
|
||||
rotation *= glm::angleAxis(glm::pi<float>(), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
glm::vec3 axis = glm::axis(rotation);
|
||||
glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z);
|
||||
} else {
|
||||
glm::vec3 axis = glm::axis(_rotation);
|
||||
glRotatef(glm::degrees(glm::angle(_rotation)), axis.x, axis.y, axis.z);
|
||||
}
|
||||
glScalef(_scale, _scale, _scale);
|
||||
|
||||
float maxSize = glm::max(_size.width(), _size.height());
|
||||
float x = _size.width() / (2.0f * maxSize);
|
||||
float y = -_size.height() / (2.0f * maxSize);
|
||||
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
glBegin(GL_QUADS); {
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex2f(-x, -y);
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glVertex2f(x, -y);
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex2f(x, y);
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glVertex2f(-x, y);
|
||||
} glEnd();
|
||||
|
||||
} glPopMatrix();
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_LIGHTING);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
void BillboardOverlay::setProperties(const QScriptValue &properties) {
|
||||
Base3DOverlay::setProperties(properties);
|
||||
|
||||
QScriptValue urlValue = properties.property("url");
|
||||
if (urlValue.isValid()) {
|
||||
_url = urlValue.toVariant().toString();
|
||||
|
||||
setBillboardURL(_url);
|
||||
}
|
||||
|
||||
QScriptValue scaleValue = properties.property("scale");
|
||||
if (scaleValue.isValid()) {
|
||||
_scale = scaleValue.toVariant().toFloat();
|
||||
}
|
||||
|
||||
QScriptValue rotationValue = properties.property("rotation");
|
||||
if (rotationValue.isValid()) {
|
||||
QScriptValue x = rotationValue.property("x");
|
||||
QScriptValue y = rotationValue.property("y");
|
||||
QScriptValue z = rotationValue.property("z");
|
||||
QScriptValue w = rotationValue.property("w");
|
||||
if (x.isValid() && y.isValid() && z.isValid() && w.isValid()) {
|
||||
_rotation.x = x.toVariant().toFloat();
|
||||
_rotation.y = y.toVariant().toFloat();
|
||||
_rotation.z = z.toVariant().toFloat();
|
||||
_rotation.w = w.toVariant().toFloat();
|
||||
}
|
||||
}
|
||||
|
||||
QScriptValue isFacingAvatarValue = properties.property("isFacingAvatar");
|
||||
if (isFacingAvatarValue.isValid()) {
|
||||
_isFacingAvatar = isFacingAvatarValue.toVariant().toBool();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: handle setting image multiple times, how do we manage releasing the bound texture?
|
||||
void BillboardOverlay::setBillboardURL(const QUrl url) {
|
||||
// TODO: are we creating too many QNetworkAccessManager() when multiple calls to setImageURL are made?
|
||||
_manager->deleteLater();
|
||||
_manager = new QNetworkAccessManager();
|
||||
connect(_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
|
||||
_manager->get(QNetworkRequest(url));
|
||||
}
|
||||
|
||||
void BillboardOverlay::replyFinished(QNetworkReply* reply) {
|
||||
// replace our byte array with the downloaded data
|
||||
_billboard = reply->readAll();
|
||||
_manager->deleteLater();
|
||||
_manager = NULL;
|
||||
}
|
46
interface/src/ui/overlays/BillboardOverlay.h
Normal file
46
interface/src/ui/overlays/BillboardOverlay.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// BillboardOverlay.h
|
||||
//
|
||||
//
|
||||
// Created by Clement on 7/1/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_BillboardOverlay_h
|
||||
#define hifi_BillboardOverlay_h
|
||||
|
||||
#include <QScopedPointer>
|
||||
#include <QUrl>
|
||||
|
||||
#include "Base3DOverlay.h"
|
||||
#include "../../renderer/TextureCache.h"
|
||||
|
||||
class BillboardOverlay : public Base3DOverlay {
|
||||
Q_OBJECT
|
||||
public:
|
||||
BillboardOverlay();
|
||||
|
||||
virtual void render();
|
||||
virtual void setProperties(const QScriptValue& properties);
|
||||
|
||||
private slots:
|
||||
void replyFinished(QNetworkReply* reply);
|
||||
|
||||
private:
|
||||
void setBillboardURL(const QUrl url);
|
||||
|
||||
QNetworkAccessManager* _manager;
|
||||
QUrl _url;
|
||||
QByteArray _billboard;
|
||||
QSize _size;
|
||||
QScopedPointer<Texture> _billboardTexture;
|
||||
|
||||
glm::quat _rotation;
|
||||
float _scale;
|
||||
bool _isFacingAvatar;
|
||||
};
|
||||
|
||||
#endif // hifi_BillboardOverlay_h
|
|
@ -19,7 +19,7 @@
|
|||
#include "ImageOverlay.h"
|
||||
|
||||
ImageOverlay::ImageOverlay() :
|
||||
_manager(0),
|
||||
_manager(NULL),
|
||||
_textureID(0),
|
||||
_renderImage(false),
|
||||
_textureBound(false),
|
||||
|
@ -37,6 +37,7 @@ ImageOverlay::~ImageOverlay() {
|
|||
// TODO: handle setting image multiple times, how do we manage releasing the bound texture?
|
||||
void ImageOverlay::setImageURL(const QUrl& url) {
|
||||
// TODO: are we creating too many QNetworkAccessManager() when multiple calls to setImageURL are made?
|
||||
_manager->deleteLater();
|
||||
_manager = new QNetworkAccessManager();
|
||||
connect(_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
|
||||
_manager->get(QNetworkRequest(url));
|
||||
|
@ -49,6 +50,7 @@ void ImageOverlay::replyFinished(QNetworkReply* reply) {
|
|||
_textureImage.loadFromData(rawData);
|
||||
_renderImage = true;
|
||||
_manager->deleteLater();
|
||||
_manager = NULL;
|
||||
}
|
||||
|
||||
void ImageOverlay::render() {
|
||||
|
|
115
interface/src/ui/overlays/ModelOverlay.cpp
Normal file
115
interface/src/ui/overlays/ModelOverlay.cpp
Normal file
|
@ -0,0 +1,115 @@
|
|||
//
|
||||
// ModelOverlay.cpp
|
||||
//
|
||||
//
|
||||
// Created by Clement on 6/30/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 "../../Menu.h"
|
||||
|
||||
#include "ModelOverlay.h"
|
||||
|
||||
ModelOverlay::ModelOverlay()
|
||||
: _model(),
|
||||
_scale(1.0f),
|
||||
_updateModel(false) {
|
||||
_model.init();
|
||||
}
|
||||
|
||||
void ModelOverlay::update(float deltatime) {
|
||||
if (_updateModel) {
|
||||
_updateModel = false;
|
||||
|
||||
_model.setScaleToFit(true, _scale);
|
||||
_model.setSnapModelToCenter(true);
|
||||
_model.setRotation(_rotation);
|
||||
_model.setTranslation(_position);
|
||||
_model.setURL(_url);
|
||||
_model.simulate(deltatime, true);
|
||||
} else {
|
||||
_model.simulate(deltatime);
|
||||
}
|
||||
}
|
||||
|
||||
void ModelOverlay::render() {
|
||||
if (_model.isActive()) {
|
||||
|
||||
if (_model.isRenderable()) {
|
||||
_model.render(_alpha);
|
||||
}
|
||||
bool displayModelBounds = Menu::getInstance()->isOptionChecked(MenuOption::DisplayModelBounds);
|
||||
if (displayModelBounds) {
|
||||
glm::vec3 unRotatedMinimum = _model.getUnscaledMeshExtents().minimum;
|
||||
glm::vec3 unRotatedMaximum = _model.getUnscaledMeshExtents().maximum;
|
||||
glm::vec3 unRotatedExtents = unRotatedMaximum - unRotatedMinimum;
|
||||
|
||||
float width = unRotatedExtents.x;
|
||||
float height = unRotatedExtents.y;
|
||||
float depth = unRotatedExtents.z;
|
||||
|
||||
Extents rotatedExtents = _model.getUnscaledMeshExtents();
|
||||
calculateRotatedExtents(rotatedExtents, _rotation);
|
||||
|
||||
glm::vec3 rotatedSize = rotatedExtents.maximum - rotatedExtents.minimum;
|
||||
|
||||
const glm::vec3& modelScale = _model.getScale();
|
||||
|
||||
glPushMatrix(); {
|
||||
glTranslatef(_position.x, _position.y, _position.z);
|
||||
|
||||
// draw the rotated bounding cube
|
||||
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
glPushMatrix(); {
|
||||
glScalef(rotatedSize.x * modelScale.x, rotatedSize.y * modelScale.y, rotatedSize.z * modelScale.z);
|
||||
glutWireCube(1.0);
|
||||
} glPopMatrix();
|
||||
|
||||
// draw the model relative bounding box
|
||||
glm::vec3 axis = glm::axis(_rotation);
|
||||
glRotatef(glm::degrees(glm::angle(_rotation)), axis.x, axis.y, axis.z);
|
||||
glScalef(width * modelScale.x, height * modelScale.y, depth * modelScale.z);
|
||||
glColor3f(0.0f, 1.0f, 0.0f);
|
||||
glutWireCube(1.0);
|
||||
|
||||
} glPopMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModelOverlay::setProperties(const QScriptValue &properties) {
|
||||
Base3DOverlay::setProperties(properties);
|
||||
|
||||
QScriptValue urlValue = properties.property("url");
|
||||
if (urlValue.isValid()) {
|
||||
_url = urlValue.toVariant().toString();
|
||||
_updateModel = true;
|
||||
}
|
||||
|
||||
QScriptValue scaleValue = properties.property("scale");
|
||||
if (scaleValue.isValid()) {
|
||||
_scale = scaleValue.toVariant().toFloat();
|
||||
_updateModel = true;
|
||||
}
|
||||
|
||||
QScriptValue rotationValue = properties.property("rotation");
|
||||
if (rotationValue.isValid()) {
|
||||
QScriptValue x = rotationValue.property("x");
|
||||
QScriptValue y = rotationValue.property("y");
|
||||
QScriptValue z = rotationValue.property("z");
|
||||
QScriptValue w = rotationValue.property("w");
|
||||
if (x.isValid() && y.isValid() && z.isValid() && w.isValid()) {
|
||||
_rotation.x = x.toVariant().toFloat();
|
||||
_rotation.y = y.toVariant().toFloat();
|
||||
_rotation.z = z.toVariant().toFloat();
|
||||
_rotation.w = w.toVariant().toFloat();
|
||||
}
|
||||
_updateModel = true;
|
||||
}
|
||||
|
||||
if (properties.property("position").isValid()) {
|
||||
_updateModel = true;
|
||||
}
|
||||
}
|
38
interface/src/ui/overlays/ModelOverlay.h
Normal file
38
interface/src/ui/overlays/ModelOverlay.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// ModelOverlay.h
|
||||
//
|
||||
//
|
||||
// Created by Clement on 6/30/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_ModelOverlay_h
|
||||
#define hifi_ModelOverlay_h
|
||||
|
||||
#include "Base3DOverlay.h"
|
||||
|
||||
#include "../../renderer/Model.h"
|
||||
|
||||
class ModelOverlay : public Base3DOverlay {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ModelOverlay();
|
||||
|
||||
virtual void update(float deltatime);
|
||||
virtual void render();
|
||||
virtual void setProperties(const QScriptValue& properties);
|
||||
private:
|
||||
|
||||
Model _model;
|
||||
|
||||
QUrl _url;
|
||||
glm::quat _rotation;
|
||||
float _scale;
|
||||
|
||||
bool _updateModel;
|
||||
};
|
||||
|
||||
#endif // hifi_ModelOverlay_h
|
|
@ -10,13 +10,15 @@
|
|||
|
||||
#include <Application.h>
|
||||
|
||||
#include "BillboardOverlay.h"
|
||||
#include "Cube3DOverlay.h"
|
||||
#include "ImageOverlay.h"
|
||||
#include "Line3DOverlay.h"
|
||||
#include "LocalVoxelsOverlay.h"
|
||||
#include "ModelOverlay.h"
|
||||
#include "Overlays.h"
|
||||
#include "Sphere3DOverlay.h"
|
||||
#include "TextOverlay.h"
|
||||
#include "LocalVoxelsOverlay.h"
|
||||
|
||||
Overlays::Overlays() : _nextOverlayID(1) {
|
||||
}
|
||||
|
@ -156,6 +158,18 @@ unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& prope
|
|||
thisOverlay->setProperties(properties);
|
||||
created = true;
|
||||
is3D = true;
|
||||
} else if (type == "model") {
|
||||
thisOverlay = new ModelOverlay();
|
||||
thisOverlay->init(_parent);
|
||||
thisOverlay->setProperties(properties);
|
||||
created = true;
|
||||
is3D = true;
|
||||
} else if (type == "billboard") {
|
||||
thisOverlay = new BillboardOverlay();
|
||||
thisOverlay->init(_parent);
|
||||
thisOverlay->setProperties(properties);
|
||||
created = true;
|
||||
is3D = true;
|
||||
}
|
||||
|
||||
if (created) {
|
||||
|
|
|
@ -137,7 +137,7 @@ background: transparent;</string>
|
|||
<property name="font">
|
||||
<font>
|
||||
<family>Helvetica,Arial,sans-serif</family>
|
||||
<pointsize>16</pointsize>
|
||||
<pointsize>-1</pointsize>
|
||||
<weight>75</weight>
|
||||
<italic>false</italic>
|
||||
<bold>true</bold>
|
||||
|
@ -326,9 +326,6 @@ padding-top: 3px;</string>
|
|||
<property name="layoutDirection">
|
||||
<enum>Qt::LeftToRight</enum>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">margin: 0;</string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
|
@ -336,7 +333,7 @@ padding-top: 3px;</string>
|
|||
<number>0</number>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
|
@ -352,7 +349,7 @@ padding-top: 3px;</string>
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>269</width>
|
||||
<width>284</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -460,7 +457,6 @@ font: bold 16px;</string>
|
|||
<string notr="true">background: transparent;
|
||||
font-size: 14px;</string>
|
||||
</property>
|
||||
<zorder>runningScriptsList</zorder>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -627,10 +623,10 @@ QListView::item {
|
|||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "NodeList.h"
|
||||
#include "PacketHeaders.h"
|
||||
#include "UserActivityLogger.h"
|
||||
|
||||
#include "DomainHandler.h"
|
||||
|
||||
|
@ -83,6 +84,7 @@ void DomainHandler::setHostname(const QString& hostname) {
|
|||
qDebug("Looking up DS hostname %s.", _hostname.toLocal8Bit().constData());
|
||||
QHostInfo::lookupHost(_hostname, this, SLOT(completedHostnameLookup(const QHostInfo&)));
|
||||
|
||||
UserActivityLogger::getInstance().changedDomain(_hostname);
|
||||
emit hostnameChanged(_hostname);
|
||||
}
|
||||
}
|
||||
|
|
155
libraries/networking/src/UserActivityLogger.cpp
Normal file
155
libraries/networking/src/UserActivityLogger.cpp
Normal file
|
@ -0,0 +1,155 @@
|
|||
//
|
||||
// UserActivityLogger.cpp
|
||||
//
|
||||
//
|
||||
// Created by Clement on 5/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 "UserActivityLogger.h"
|
||||
|
||||
#include <QEventLoop>
|
||||
#include <QJsonDocument>
|
||||
#include <QHttpMultiPart>
|
||||
#include <QTimer>
|
||||
|
||||
static const QString USER_ACTIVITY_URL = "/api/v1/user_activities";
|
||||
|
||||
UserActivityLogger& UserActivityLogger::getInstance() {
|
||||
static UserActivityLogger sharedInstance;
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
UserActivityLogger::UserActivityLogger() {
|
||||
}
|
||||
|
||||
void UserActivityLogger::logAction(QString action, QJsonObject details, JSONCallbackParameters params) {
|
||||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
QHttpMultiPart* multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
|
||||
|
||||
// Adding the action name
|
||||
QHttpPart actionPart;
|
||||
actionPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"action_name\"");
|
||||
actionPart.setBody(QByteArray().append(action));
|
||||
multipart->append(actionPart);
|
||||
|
||||
// If there are action details, add them to the multipart
|
||||
if (!details.isEmpty()) {
|
||||
QHttpPart detailsPart;
|
||||
detailsPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data;"
|
||||
" name=\"action_details\"");
|
||||
detailsPart.setBody(QJsonDocument(details).toJson(QJsonDocument::Compact));
|
||||
multipart->append(detailsPart);
|
||||
}
|
||||
qDebug() << "Logging activity" << action;
|
||||
|
||||
// if no callbacks specified, call our owns
|
||||
if (params.isEmpty()) {
|
||||
params.jsonCallbackReceiver = this;
|
||||
params.jsonCallbackMethod = "requestFinished";
|
||||
params.errorCallbackReceiver = this;
|
||||
params.errorCallbackMethod = "requestError";
|
||||
}
|
||||
|
||||
accountManager.authenticatedRequest(USER_ACTIVITY_URL,
|
||||
QNetworkAccessManager::PostOperation,
|
||||
params,
|
||||
NULL,
|
||||
multipart);
|
||||
}
|
||||
|
||||
void UserActivityLogger::requestFinished(const QJsonObject& object) {
|
||||
qDebug() << object;
|
||||
}
|
||||
|
||||
void UserActivityLogger::requestError(QNetworkReply::NetworkError error,const QString& string) {
|
||||
qDebug() << error << ": " << string;
|
||||
}
|
||||
|
||||
void UserActivityLogger::launch(QString applicationVersion) {
|
||||
const QString ACTION_NAME = "launch";
|
||||
QJsonObject actionDetails;
|
||||
QString VERSION_KEY = "version";
|
||||
actionDetails.insert(VERSION_KEY, applicationVersion);
|
||||
|
||||
logAction(ACTION_NAME, actionDetails);
|
||||
}
|
||||
|
||||
void UserActivityLogger::close(int delayTime) {
|
||||
const QString ACTION_NAME = "close";
|
||||
|
||||
// In order to get the end of the session, we need to give the account manager enough time to send the packet.
|
||||
QEventLoop loop;
|
||||
// Here we connect the callbacks to stop the event loop
|
||||
JSONCallbackParameters params;
|
||||
params.jsonCallbackReceiver = &loop;
|
||||
params.errorCallbackReceiver = &loop;
|
||||
params.jsonCallbackMethod = "quit";
|
||||
params.errorCallbackMethod = "quit";
|
||||
// In case something goes wrong, we also setup a timer so that the delai is not greater than delayTime
|
||||
QTimer timer;
|
||||
connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
|
||||
// Now we can log it
|
||||
logAction(ACTION_NAME, QJsonObject(), params);
|
||||
timer.start(delayTime);
|
||||
loop.exec();
|
||||
}
|
||||
|
||||
void UserActivityLogger::changedDisplayName(QString displayName) {
|
||||
const QString ACTION_NAME = "changed_display_name";
|
||||
QJsonObject actionDetails;
|
||||
const QString DISPLAY_NAME = "display_name";
|
||||
|
||||
actionDetails.insert(DISPLAY_NAME, displayName);
|
||||
|
||||
logAction(ACTION_NAME, actionDetails);
|
||||
}
|
||||
|
||||
void UserActivityLogger::changedModel(QString typeOfModel, QString modelURL) {
|
||||
const QString ACTION_NAME = "changed_model";
|
||||
QJsonObject actionDetails;
|
||||
const QString TYPE_OF_MODEL = "type_of_model";
|
||||
const QString MODEL_URL = "model_url";
|
||||
|
||||
actionDetails.insert(TYPE_OF_MODEL, typeOfModel);
|
||||
actionDetails.insert(MODEL_URL, modelURL);
|
||||
|
||||
logAction(ACTION_NAME, actionDetails);
|
||||
}
|
||||
|
||||
void UserActivityLogger::changedDomain(QString domainURL) {
|
||||
const QString ACTION_NAME = "changed_domain";
|
||||
QJsonObject actionDetails;
|
||||
const QString DOMAIN_URL = "domain_url";
|
||||
|
||||
actionDetails.insert(DOMAIN_URL, domainURL);
|
||||
|
||||
logAction(ACTION_NAME, actionDetails);
|
||||
}
|
||||
|
||||
void UserActivityLogger::connectedDevice(QString typeOfDevice, QString deviceName) {
|
||||
const QString ACTION_NAME = "connected_device";
|
||||
QJsonObject actionDetails;
|
||||
const QString TYPE_OF_DEVICE = "type_of_device";
|
||||
const QString DEVICE_NAME = "device_name";
|
||||
|
||||
actionDetails.insert(TYPE_OF_DEVICE, typeOfDevice);
|
||||
actionDetails.insert(DEVICE_NAME, deviceName);
|
||||
|
||||
logAction(ACTION_NAME, actionDetails);
|
||||
|
||||
}
|
||||
|
||||
void UserActivityLogger::loadedScript(QString scriptName) {
|
||||
const QString ACTION_NAME = "loaded_script";
|
||||
QJsonObject actionDetails;
|
||||
const QString SCRIPT_NAME = "script_name";
|
||||
|
||||
actionDetails.insert(SCRIPT_NAME, scriptName);
|
||||
|
||||
logAction(ACTION_NAME, actionDetails);
|
||||
|
||||
}
|
47
libraries/networking/src/UserActivityLogger.h
Normal file
47
libraries/networking/src/UserActivityLogger.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// UserActivityLogger.h
|
||||
//
|
||||
//
|
||||
// Created by Clement on 5/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
|
||||
//
|
||||
|
||||
#ifndef hifi_UserActivityLogger_h
|
||||
#define hifi_UserActivityLogger_h
|
||||
|
||||
#include "AccountManager.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QJsonObject>
|
||||
#include <QNetworkReply>
|
||||
|
||||
class UserActivityLogger : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static UserActivityLogger& getInstance();
|
||||
|
||||
public slots:
|
||||
void logAction(QString action, QJsonObject details = QJsonObject(), JSONCallbackParameters params = JSONCallbackParameters());
|
||||
|
||||
void launch(QString applicationVersion);
|
||||
void close(int delayTime);
|
||||
void changedDisplayName(QString displayName);
|
||||
void changedModel(QString typeOfModel, QString modelURL);
|
||||
void changedDomain(QString domainURL);
|
||||
void connectedDevice(QString typeOfDevice, QString deviceName);
|
||||
void loadedScript(QString scriptName);
|
||||
|
||||
private slots:
|
||||
void requestFinished(const QJsonObject& object);
|
||||
void requestError(QNetworkReply::NetworkError error,const QString& string);
|
||||
|
||||
private:
|
||||
UserActivityLogger();
|
||||
};
|
||||
|
||||
#endif // hifi_UserActivityLogger_h
|
Loading…
Reference in a new issue