mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Merge branch 'master' of https://github.com/highfidelity/hifi into avatarBandwidthBudgetImprovements
Conflicts: libraries/avatars/src/AvatarData.cpp
This commit is contained in:
commit
1b7ec7d61e
20 changed files with 281 additions and 87 deletions
|
@ -148,13 +148,22 @@ MyAvatar::MyAvatar(RigPointer rig) :
|
||||||
auto player = DependencyManager::get<Deck>();
|
auto player = DependencyManager::get<Deck>();
|
||||||
auto recorder = DependencyManager::get<Recorder>();
|
auto recorder = DependencyManager::get<Recorder>();
|
||||||
connect(player.data(), &Deck::playbackStateChanged, [=] {
|
connect(player.data(), &Deck::playbackStateChanged, [=] {
|
||||||
if (player->isPlaying()) {
|
bool isPlaying = player->isPlaying();
|
||||||
|
if (isPlaying) {
|
||||||
auto recordingInterface = DependencyManager::get<RecordingScriptingInterface>();
|
auto recordingInterface = DependencyManager::get<RecordingScriptingInterface>();
|
||||||
if (recordingInterface->getPlayFromCurrentLocation()) {
|
if (recordingInterface->getPlayFromCurrentLocation()) {
|
||||||
setRecordingBasis();
|
setRecordingBasis();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
clearRecordingBasis();
|
clearRecordingBasis();
|
||||||
|
useFullAvatarURL(_fullAvatarURLFromPreferences, _fullAvatarModelName);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto audioIO = DependencyManager::get<AudioClient>();
|
||||||
|
audioIO->setIsPlayingBackRecording(isPlaying);
|
||||||
|
|
||||||
|
if (_rig) {
|
||||||
|
_rig->setEnableAnimations(!isPlaying);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -180,8 +189,8 @@ MyAvatar::MyAvatar(RigPointer rig) :
|
||||||
|
|
||||||
if (recordingInterface->getPlayerUseSkeletonModel() && dummyAvatar.getSkeletonModelURL().isValid() &&
|
if (recordingInterface->getPlayerUseSkeletonModel() && dummyAvatar.getSkeletonModelURL().isValid() &&
|
||||||
(dummyAvatar.getSkeletonModelURL() != getSkeletonModelURL())) {
|
(dummyAvatar.getSkeletonModelURL() != getSkeletonModelURL())) {
|
||||||
// FIXME
|
|
||||||
//myAvatar->useFullAvatarURL()
|
setSkeletonModelURL(dummyAvatar.getSkeletonModelURL());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recordingInterface->getPlayerUseDisplayName() && dummyAvatar.getDisplayName() != getDisplayName()) {
|
if (recordingInterface->getPlayerUseDisplayName() && dummyAvatar.getDisplayName() != getDisplayName()) {
|
||||||
|
@ -204,6 +213,11 @@ MyAvatar::MyAvatar(RigPointer rig) :
|
||||||
// head orientation
|
// head orientation
|
||||||
_headData->setLookAtPosition(headData->getLookAtPosition());
|
_headData->setLookAtPosition(headData->getLookAtPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto jointData = dummyAvatar.getRawJointData();
|
||||||
|
if (jointData.length() > 0 && _rig) {
|
||||||
|
_rig->copyJointsFromJointData(jointData);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(rig.get(), SIGNAL(onLoadComplete()), this, SIGNAL(onLoadComplete()));
|
connect(rig.get(), SIGNAL(onLoadComplete()), this, SIGNAL(onLoadComplete()));
|
||||||
|
@ -471,7 +485,9 @@ void MyAvatar::simulate(float deltaTime) {
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("joints");
|
PerformanceTimer perfTimer("joints");
|
||||||
// copy out the skeleton joints from the model
|
// copy out the skeleton joints from the model
|
||||||
_rig->copyJointsIntoJointData(_jointData);
|
if (_rigEnabled) {
|
||||||
|
_rig->copyJointsIntoJointData(_jointData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -485,6 +485,7 @@ private:
|
||||||
std::unordered_set<int> _headBoneSet;
|
std::unordered_set<int> _headBoneSet;
|
||||||
RigPointer _rig;
|
RigPointer _rig;
|
||||||
bool _prevShouldDrawHead;
|
bool _prevShouldDrawHead;
|
||||||
|
bool _rigEnabled { true };
|
||||||
|
|
||||||
bool _enableDebugDrawDefaultPose { false };
|
bool _enableDebugDrawDefaultPose { false };
|
||||||
bool _enableDebugDrawAnimPose { false };
|
bool _enableDebugDrawAnimPose { false };
|
||||||
|
|
|
@ -483,6 +483,10 @@ void Rig::setEnableInverseKinematics(bool enable) {
|
||||||
_enableInverseKinematics = enable;
|
_enableInverseKinematics = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Rig::setEnableAnimations(bool enable) {
|
||||||
|
_enabledAnimations = enable;
|
||||||
|
}
|
||||||
|
|
||||||
AnimPose Rig::getAbsoluteDefaultPose(int index) const {
|
AnimPose Rig::getAbsoluteDefaultPose(int index) const {
|
||||||
if (_animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints()) {
|
if (_animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints()) {
|
||||||
return _absoluteDefaultPoses[index];
|
return _absoluteDefaultPoses[index];
|
||||||
|
@ -907,7 +911,7 @@ void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) {
|
||||||
|
|
||||||
setModelOffset(rootTransform);
|
setModelOffset(rootTransform);
|
||||||
|
|
||||||
if (_animNode) {
|
if (_animNode && _enabledAnimations) {
|
||||||
PerformanceTimer perfTimer("handleTriggers");
|
PerformanceTimer perfTimer("handleTriggers");
|
||||||
|
|
||||||
updateAnimationStateHandlers();
|
updateAnimationStateHandlers();
|
||||||
|
|
|
@ -210,6 +210,7 @@ public:
|
||||||
void computeAvatarBoundingCapsule(const FBXGeometry& geometry, float& radiusOut, float& heightOut, glm::vec3& offsetOut) const;
|
void computeAvatarBoundingCapsule(const FBXGeometry& geometry, float& radiusOut, float& heightOut, glm::vec3& offsetOut) const;
|
||||||
|
|
||||||
void setEnableInverseKinematics(bool enable);
|
void setEnableInverseKinematics(bool enable);
|
||||||
|
void setEnableAnimations(bool enable);
|
||||||
|
|
||||||
const glm::mat4& getGeometryToRigTransform() const { return _geometryToRigTransform; }
|
const glm::mat4& getGeometryToRigTransform() const { return _geometryToRigTransform; }
|
||||||
|
|
||||||
|
@ -314,6 +315,7 @@ protected:
|
||||||
int32_t _numOverrides { 0 };
|
int32_t _numOverrides { 0 };
|
||||||
bool _lastEnableInverseKinematics { true };
|
bool _lastEnableInverseKinematics { true };
|
||||||
bool _enableInverseKinematics { true };
|
bool _enableInverseKinematics { true };
|
||||||
|
bool _enabledAnimations { true };
|
||||||
|
|
||||||
mutable uint32_t _jointNameWarningCount { 0 };
|
mutable uint32_t _jointNameWarningCount { 0 };
|
||||||
|
|
||||||
|
|
|
@ -39,13 +39,10 @@
|
||||||
#include <plugins/CodecPlugin.h>
|
#include <plugins/CodecPlugin.h>
|
||||||
#include <plugins/PluginManager.h>
|
#include <plugins/PluginManager.h>
|
||||||
#include <udt/PacketHeaders.h>
|
#include <udt/PacketHeaders.h>
|
||||||
#include <PositionalAudioStream.h>
|
|
||||||
#include <SettingHandle.h>
|
#include <SettingHandle.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
#include <UUID.h>
|
|
||||||
#include <Transform.h>
|
#include <Transform.h>
|
||||||
|
|
||||||
#include "PositionalAudioStream.h"
|
|
||||||
#include "AudioClientLogging.h"
|
#include "AudioClientLogging.h"
|
||||||
#include "AudioLogging.h"
|
#include "AudioLogging.h"
|
||||||
|
|
||||||
|
@ -294,12 +291,12 @@ QString friendlyNameForAudioDevice(IMMDevice* pEndpoint) {
|
||||||
IPropertyStore* pPropertyStore;
|
IPropertyStore* pPropertyStore;
|
||||||
pEndpoint->OpenPropertyStore(STGM_READ, &pPropertyStore);
|
pEndpoint->OpenPropertyStore(STGM_READ, &pPropertyStore);
|
||||||
pEndpoint->Release();
|
pEndpoint->Release();
|
||||||
pEndpoint = NULL;
|
pEndpoint = nullptr;
|
||||||
PROPVARIANT pv;
|
PROPVARIANT pv;
|
||||||
PropVariantInit(&pv);
|
PropVariantInit(&pv);
|
||||||
HRESULT hr = pPropertyStore->GetValue(PKEY_Device_FriendlyName, &pv);
|
HRESULT hr = pPropertyStore->GetValue(PKEY_Device_FriendlyName, &pv);
|
||||||
pPropertyStore->Release();
|
pPropertyStore->Release();
|
||||||
pPropertyStore = NULL;
|
pPropertyStore = nullptr;
|
||||||
deviceName = QString::fromWCharArray((wchar_t*)pv.pwszVal);
|
deviceName = QString::fromWCharArray((wchar_t*)pv.pwszVal);
|
||||||
if (!IsWindows8OrGreater()) {
|
if (!IsWindows8OrGreater()) {
|
||||||
// Windows 7 provides only the 31 first characters of the device name.
|
// Windows 7 provides only the 31 first characters of the device name.
|
||||||
|
@ -313,9 +310,9 @@ QString friendlyNameForAudioDevice(IMMDevice* pEndpoint) {
|
||||||
QString AudioClient::friendlyNameForAudioDevice(wchar_t* guid) {
|
QString AudioClient::friendlyNameForAudioDevice(wchar_t* guid) {
|
||||||
QString deviceName;
|
QString deviceName;
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
CoInitialize(NULL);
|
CoInitialize(nullptr);
|
||||||
IMMDeviceEnumerator* pMMDeviceEnumerator = NULL;
|
IMMDeviceEnumerator* pMMDeviceEnumerator = nullptr;
|
||||||
CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pMMDeviceEnumerator);
|
CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pMMDeviceEnumerator);
|
||||||
IMMDevice* pEndpoint;
|
IMMDevice* pEndpoint;
|
||||||
hr = pMMDeviceEnumerator->GetDevice(guid, &pEndpoint);
|
hr = pMMDeviceEnumerator->GetDevice(guid, &pEndpoint);
|
||||||
if (hr == E_NOTFOUND) {
|
if (hr == E_NOTFOUND) {
|
||||||
|
@ -325,7 +322,7 @@ QString AudioClient::friendlyNameForAudioDevice(wchar_t* guid) {
|
||||||
deviceName = ::friendlyNameForAudioDevice(pEndpoint);
|
deviceName = ::friendlyNameForAudioDevice(pEndpoint);
|
||||||
}
|
}
|
||||||
pMMDeviceEnumerator->Release();
|
pMMDeviceEnumerator->Release();
|
||||||
pMMDeviceEnumerator = NULL;
|
pMMDeviceEnumerator = nullptr;
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
return deviceName;
|
return deviceName;
|
||||||
}
|
}
|
||||||
|
@ -968,8 +965,7 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioClient::handleAudioInput() {
|
void AudioClient::handleAudioInput() {
|
||||||
|
if (!_inputDevice || _isPlayingBackRecording) {
|
||||||
if (!_inputDevice) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,8 @@ public:
|
||||||
void setPositionGetter(AudioPositionGetter positionGetter) { _positionGetter = positionGetter; }
|
void setPositionGetter(AudioPositionGetter positionGetter) { _positionGetter = positionGetter; }
|
||||||
void setOrientationGetter(AudioOrientationGetter orientationGetter) { _orientationGetter = orientationGetter; }
|
void setOrientationGetter(AudioOrientationGetter orientationGetter) { _orientationGetter = orientationGetter; }
|
||||||
|
|
||||||
|
void setIsPlayingBackRecording(bool isPlayingBackRecording) { _isPlayingBackRecording = isPlayingBackRecording; }
|
||||||
|
|
||||||
Q_INVOKABLE void setAvatarBoundingBoxParameters(glm::vec3 corner, glm::vec3 scale);
|
Q_INVOKABLE void setAvatarBoundingBoxParameters(glm::vec3 corner, glm::vec3 scale);
|
||||||
|
|
||||||
void checkDevices();
|
void checkDevices();
|
||||||
|
@ -369,10 +371,12 @@ private:
|
||||||
QVector<QString> _inputDevices;
|
QVector<QString> _inputDevices;
|
||||||
QVector<QString> _outputDevices;
|
QVector<QString> _outputDevices;
|
||||||
|
|
||||||
bool _hasReceivedFirstPacket = false;
|
bool _hasReceivedFirstPacket { false };
|
||||||
|
|
||||||
QVector<AudioInjector*> _activeLocalAudioInjectors;
|
QVector<AudioInjector*> _activeLocalAudioInjectors;
|
||||||
|
|
||||||
|
bool _isPlayingBackRecording { false };
|
||||||
|
|
||||||
CodecPluginPointer _codec;
|
CodecPluginPointer _codec;
|
||||||
QString _selectedCodecName;
|
QString _selectedCodecName;
|
||||||
Encoder* _encoder { nullptr }; // for outbound mic stream
|
Encoder* _encoder { nullptr }; // for outbound mic stream
|
||||||
|
|
|
@ -91,4 +91,4 @@ void injectorOptionsFromScriptValue(const QScriptValue& object, AudioInjectorOpt
|
||||||
qCWarning(audio) << "Unknown audio injector option:" << it.name();
|
qCWarning(audio) << "Unknown audio injector option:" << it.name();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <ShapeInfo.h>
|
#include <ShapeInfo.h>
|
||||||
#include <AudioHelpers.h>
|
#include <AudioHelpers.h>
|
||||||
#include <Profile.h>
|
#include <Profile.h>
|
||||||
|
#include <VariantMapToScriptValue.h>
|
||||||
|
|
||||||
#include "AvatarLogging.h"
|
#include "AvatarLogging.h"
|
||||||
|
|
||||||
|
@ -2379,3 +2380,37 @@ std::priority_queue<AvatarPriority> AvatarData::sortAvatars(
|
||||||
}
|
}
|
||||||
return sortedAvatars;
|
return sortedAvatars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QScriptValue AvatarEntityMapToScriptValue(QScriptEngine* engine, const AvatarEntityMap& value) {
|
||||||
|
QScriptValue obj = engine->newObject();
|
||||||
|
for (auto entityID : value.keys()) {
|
||||||
|
QByteArray entityProperties = value.value(entityID);
|
||||||
|
QJsonDocument jsonEntityProperties = QJsonDocument::fromBinaryData(entityProperties);
|
||||||
|
if (!jsonEntityProperties.isObject()) {
|
||||||
|
qCDebug(avatars) << "bad AvatarEntityData in AvatarEntityMap" << QString(entityProperties.toHex());
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant variantEntityProperties = jsonEntityProperties.toVariant();
|
||||||
|
QVariantMap entityPropertiesMap = variantEntityProperties.toMap();
|
||||||
|
QScriptValue scriptEntityProperties = variantMapToScriptValue(entityPropertiesMap, *engine);
|
||||||
|
|
||||||
|
QString key = entityID.toString();
|
||||||
|
obj.setProperty(key, scriptEntityProperties);
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AvatarEntityMapFromScriptValue(const QScriptValue& object, AvatarEntityMap& value) {
|
||||||
|
QScriptValueIterator itr(object);
|
||||||
|
while (itr.hasNext()) {
|
||||||
|
itr.next();
|
||||||
|
QUuid EntityID = QUuid(itr.name());
|
||||||
|
|
||||||
|
QScriptValue scriptEntityProperties = itr.value();
|
||||||
|
QVariant variantEntityProperties = scriptEntityProperties.toVariant();
|
||||||
|
QJsonDocument jsonEntityProperties = QJsonDocument::fromVariant(variantEntityProperties);
|
||||||
|
QByteArray binaryEntityProperties = jsonEntityProperties.toBinaryData();
|
||||||
|
|
||||||
|
value[EntityID] = binaryEntityProperties;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ typedef unsigned long long quint64;
|
||||||
#include <QVariantMap>
|
#include <QVariantMap>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QtScript/QScriptable>
|
#include <QtScript/QScriptable>
|
||||||
|
#include <QtScript/QScriptValueIterator>
|
||||||
#include <QReadWriteLock>
|
#include <QReadWriteLock>
|
||||||
|
|
||||||
#include <JointData.h>
|
#include <JointData.h>
|
||||||
|
@ -847,6 +848,11 @@ Q_DECLARE_METATYPE(RayToAvatarIntersectionResult)
|
||||||
QScriptValue RayToAvatarIntersectionResultToScriptValue(QScriptEngine* engine, const RayToAvatarIntersectionResult& results);
|
QScriptValue RayToAvatarIntersectionResultToScriptValue(QScriptEngine* engine, const RayToAvatarIntersectionResult& results);
|
||||||
void RayToAvatarIntersectionResultFromScriptValue(const QScriptValue& object, RayToAvatarIntersectionResult& results);
|
void RayToAvatarIntersectionResultFromScriptValue(const QScriptValue& object, RayToAvatarIntersectionResult& results);
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(AvatarEntityMap)
|
||||||
|
|
||||||
|
QScriptValue AvatarEntityMapToScriptValue(QScriptEngine* engine, const AvatarEntityMap& value);
|
||||||
|
void AvatarEntityMapFromScriptValue(const QScriptValue& object, AvatarEntityMap& value);
|
||||||
|
|
||||||
// faux joint indexes (-1 means invalid)
|
// faux joint indexes (-1 means invalid)
|
||||||
const int SENSOR_TO_WORLD_MATRIX_INDEX = 65534; // -2
|
const int SENSOR_TO_WORLD_MATRIX_INDEX = 65534; // -2
|
||||||
const int CONTROLLER_RIGHTHAND_INDEX = 65533; // -3
|
const int CONTROLLER_RIGHTHAND_INDEX = 65533; // -3
|
||||||
|
|
|
@ -576,6 +576,7 @@ void ScriptEngine::init() {
|
||||||
qScriptRegisterMetaType(this, EntityItemIDtoScriptValue, EntityItemIDfromScriptValue);
|
qScriptRegisterMetaType(this, EntityItemIDtoScriptValue, EntityItemIDfromScriptValue);
|
||||||
qScriptRegisterMetaType(this, RayToEntityIntersectionResultToScriptValue, RayToEntityIntersectionResultFromScriptValue);
|
qScriptRegisterMetaType(this, RayToEntityIntersectionResultToScriptValue, RayToEntityIntersectionResultFromScriptValue);
|
||||||
qScriptRegisterMetaType(this, RayToAvatarIntersectionResultToScriptValue, RayToAvatarIntersectionResultFromScriptValue);
|
qScriptRegisterMetaType(this, RayToAvatarIntersectionResultToScriptValue, RayToAvatarIntersectionResultFromScriptValue);
|
||||||
|
qScriptRegisterMetaType(this, AvatarEntityMapToScriptValue, AvatarEntityMapFromScriptValue);
|
||||||
qScriptRegisterSequenceMetaType<QVector<QUuid>>(this);
|
qScriptRegisterSequenceMetaType<QVector<QUuid>>(this);
|
||||||
qScriptRegisterSequenceMetaType<QVector<EntityItemID>>(this);
|
qScriptRegisterSequenceMetaType<QVector<EntityItemID>>(this);
|
||||||
|
|
||||||
|
|
|
@ -366,6 +366,7 @@ void TabletProxy::gotoWebScreen(const QString& url, const QString& injectedJavaS
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root) {
|
if (root) {
|
||||||
|
removeButtonsFromHomeScreen();
|
||||||
QMetaObject::invokeMethod(root, "loadSource", Q_ARG(const QVariant&, QVariant(WEB_VIEW_SOURCE_URL)));
|
QMetaObject::invokeMethod(root, "loadSource", Q_ARG(const QVariant&, QVariant(WEB_VIEW_SOURCE_URL)));
|
||||||
QMetaObject::invokeMethod(root, "setShown", Q_ARG(const QVariant&, QVariant(true)));
|
QMetaObject::invokeMethod(root, "setShown", Q_ARG(const QVariant&, QVariant(true)));
|
||||||
QMetaObject::invokeMethod(root, "loadWebUrl", Q_ARG(const QVariant&, QVariant(url)), Q_ARG(const QVariant&, QVariant(injectedJavaScriptUrl)));
|
QMetaObject::invokeMethod(root, "loadWebUrl", Q_ARG(const QVariant&, QVariant(url)), Q_ARG(const QVariant&, QVariant(injectedJavaScriptUrl)));
|
||||||
|
|
|
@ -12,14 +12,14 @@
|
||||||
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
|
||||||
Script.include("/~/system/libraries/toolBars.js");
|
Script.include("/~/system/libraries/toolBars.js");
|
||||||
|
|
||||||
var recordingFile = "recording.rec";
|
var recordingFile = "recording.hfr";
|
||||||
|
|
||||||
function setPlayerOptions() {
|
function setPlayerOptions() {
|
||||||
Recording.setPlayFromCurrentLocation(true);
|
Recording.setPlayFromCurrentLocation(true);
|
||||||
Recording.setPlayerUseDisplayName(false);
|
Recording.setPlayerUseDisplayName(false);
|
||||||
Recording.setPlayerUseAttachments(false);
|
Recording.setPlayerUseAttachments(false);
|
||||||
Recording.setPlayerUseHeadModel(false);
|
Recording.setPlayerUseHeadModel(false);
|
||||||
Recording.setPlayerUseSkeletonModel(false);
|
Recording.setPlayerUseSkeletonModel(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
var windowDimensions = Controller.getViewportDimensions();
|
var windowDimensions = Controller.getViewportDimensions();
|
||||||
|
@ -142,7 +142,6 @@ function setupTimer() {
|
||||||
backgroundAlpha: 1.0,
|
backgroundAlpha: 1.0,
|
||||||
visible: true
|
visible: true
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateTimer() {
|
function updateTimer() {
|
||||||
|
@ -272,7 +271,7 @@ function mousePressEvent(event) {
|
||||||
}
|
}
|
||||||
} else if (loadIcon === toolBar.clicked(clickedOverlay)) {
|
} else if (loadIcon === toolBar.clicked(clickedOverlay)) {
|
||||||
if (!Recording.isRecording() && !Recording.isPlaying()) {
|
if (!Recording.isRecording() && !Recording.isPlaying()) {
|
||||||
recordingFile = Window.browse("Load recorcding from file", ".", "Recordings (*.hfr *.rec *.HFR *.REC)");
|
recordingFile = Window.browse("Load recording from file", ".", "Recordings (*.hfr *.rec *.HFR *.REC)");
|
||||||
if (!(recordingFile === "null" || recordingFile === null || recordingFile === "")) {
|
if (!(recordingFile === "null" || recordingFile === null || recordingFile === "")) {
|
||||||
Recording.loadRecording(recordingFile);
|
Recording.loadRecording(recordingFile);
|
||||||
}
|
}
|
||||||
|
@ -345,5 +344,3 @@ Script.scriptEnding.connect(scriptEnding);
|
||||||
|
|
||||||
// Should be called last to put everything into position
|
// Should be called last to put everything into position
|
||||||
moveUI();
|
moveUI();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,19 +16,51 @@
|
||||||
var TABLET_BUTTON_NAME = "AUDIO";
|
var TABLET_BUTTON_NAME = "AUDIO";
|
||||||
var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png";
|
var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png";
|
||||||
|
|
||||||
|
var MUTE_ICONS = {
|
||||||
|
icon: "icons/tablet-icons/mic-mute-i.svg",
|
||||||
|
activeIcon: "icons/tablet-icons/mic-mute-a.svg"
|
||||||
|
};
|
||||||
|
|
||||||
|
var UNMUTE_ICONS = {
|
||||||
|
icon: "icons/tablet-icons/mic-unmute-i.svg",
|
||||||
|
activeIcon: "icons/tablet-icons/mic-unmute-a.svg"
|
||||||
|
};
|
||||||
|
|
||||||
function onMuteToggled() {
|
function onMuteToggled() {
|
||||||
button.editProperties({ isActive: AudioDevice.getMuted() });
|
if (AudioDevice.getMuted()) {
|
||||||
|
button.editProperties(MUTE_ICONS);
|
||||||
|
} else {
|
||||||
|
button.editProperties(UNMUTE_ICONS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
function onClicked(){
|
|
||||||
var entity = HMD.tabletID;
|
var shouldActivateButton = false;
|
||||||
Entities.editEntity(entity, { textures: JSON.stringify({ "tex.close": HOME_BUTTON_TEXTURE }) });
|
var onAudioScreen = false;
|
||||||
tablet.gotoMenuScreen("Audio");
|
|
||||||
|
function onClicked() {
|
||||||
|
if (onAudioScreen) {
|
||||||
|
// for toolbar-mode: go back to home screen, this will close the window.
|
||||||
|
tablet.gotoHomeScreen();
|
||||||
|
} else {
|
||||||
|
var entity = HMD.tabletID;
|
||||||
|
Entities.editEntity(entity, { textures: JSON.stringify({ "tex.close": HOME_BUTTON_TEXTURE }) });
|
||||||
|
shouldActivateButton = true;
|
||||||
|
tablet.gotoMenuScreen("Audio");
|
||||||
|
onAudioScreen = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onScreenChanged(type, url) {
|
||||||
|
// for toolbar mode: change button to active when window is first openend, false otherwise.
|
||||||
|
button.editProperties({isActive: shouldActivateButton});
|
||||||
|
shouldActivateButton = false;
|
||||||
|
onAudioScreen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||||
var button = tablet.addButton({
|
var button = tablet.addButton({
|
||||||
icon: "icons/tablet-icons/mic-unmute-i.svg",
|
icon: AudioDevice.getMuted() ? MUTE_ICONS.icon : UNMUTE_ICONS.icon,
|
||||||
activeIcon: "icons/tablet-icons/mic-mute-a.svg",
|
activeIcon: AudioDevice.getMuted() ? MUTE_ICONS.activeIcon : UNMUTE_ICONS.activeIcon,
|
||||||
text: TABLET_BUTTON_NAME,
|
text: TABLET_BUTTON_NAME,
|
||||||
sortOrder: 1
|
sortOrder: 1
|
||||||
});
|
});
|
||||||
|
@ -36,10 +68,12 @@ var button = tablet.addButton({
|
||||||
onMuteToggled();
|
onMuteToggled();
|
||||||
|
|
||||||
button.clicked.connect(onClicked);
|
button.clicked.connect(onClicked);
|
||||||
|
tablet.screenChanged.connect(onScreenChanged);
|
||||||
AudioDevice.muteToggled.connect(onMuteToggled);
|
AudioDevice.muteToggled.connect(onMuteToggled);
|
||||||
|
|
||||||
Script.scriptEnding.connect(function () {
|
Script.scriptEnding.connect(function () {
|
||||||
button.clicked.disconnect(onClicked);
|
button.clicked.disconnect(onClicked);
|
||||||
|
tablet.screenChanged.disconnect(onScreenChanged);
|
||||||
AudioDevice.muteToggled.disconnect(onMuteToggled);
|
AudioDevice.muteToggled.disconnect(onMuteToggled);
|
||||||
tablet.removeButton(button);
|
tablet.removeButton(button);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1233,7 +1233,13 @@ function MyController(hand) {
|
||||||
});
|
});
|
||||||
if (grabbableEntities.length > 0) {
|
if (grabbableEntities.length > 0) {
|
||||||
if (!this.grabPointIntersectsEntity) {
|
if (!this.grabPointIntersectsEntity) {
|
||||||
Controller.triggerHapticPulse(1, 20, this.hand);
|
// don't do haptic pulse for tablet
|
||||||
|
var nonTabletEntities = grabbableEntities.filter(function(entityID) {
|
||||||
|
return entityID != HMD.tabletID && entityID != HMD.homeButtonID;
|
||||||
|
});
|
||||||
|
if (nonTabletEntities.length > 0) {
|
||||||
|
Controller.triggerHapticPulse(1, 20, this.hand);
|
||||||
|
}
|
||||||
this.grabPointIntersectsEntity = true;
|
this.grabPointIntersectsEntity = true;
|
||||||
this.grabPointSphereOn();
|
this.grabPointSphereOn();
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,24 +49,30 @@ function calcSpawnInfo(hand, height) {
|
||||||
var handController = getControllerWorldLocation(hand, true);
|
var handController = getControllerWorldLocation(hand, true);
|
||||||
var controllerPosition = handController.position;
|
var controllerPosition = handController.position;
|
||||||
|
|
||||||
// compute the angle of the chord with length (height / 2)
|
// base of the tablet is slightly above controller position
|
||||||
var theta = Math.asin(height / (2 * Vec3.distance(headPos, controllerPosition)));
|
var TABLET_BASE_DISPLACEMENT = {x: 0, y: 0.1, z: 0};
|
||||||
|
var tabletBase = Vec3.sum(controllerPosition, TABLET_BASE_DISPLACEMENT);
|
||||||
|
|
||||||
// then we can use this angle to rotate the vector between the HMD position and the center of the tablet.
|
var d = Vec3.subtract(headPos, tabletBase);
|
||||||
// this vector, u, will become our new look at direction.
|
var theta = Math.acos(d.y / Vec3.length(d));
|
||||||
var d = Vec3.normalize(Vec3.subtract(headPos, controllerPosition));
|
d.y = 0;
|
||||||
|
if (Vec3.length(d) < 0.0001) {
|
||||||
|
d = {x: 1, y: 0, z: 0};
|
||||||
|
} else {
|
||||||
|
d = Vec3.normalize(d);
|
||||||
|
}
|
||||||
var w = Vec3.normalize(Vec3.cross(Y_AXIS, d));
|
var w = Vec3.normalize(Vec3.cross(Y_AXIS, d));
|
||||||
var q = Quat.angleAxis(theta * (180 / Math.PI), w);
|
var ANGLE_OFFSET = 25;
|
||||||
|
var q = Quat.angleAxis(theta * (180 / Math.PI) - (90 - ANGLE_OFFSET), w);
|
||||||
var u = Vec3.multiplyQbyV(q, d);
|
var u = Vec3.multiplyQbyV(q, d);
|
||||||
|
|
||||||
// use u to compute a full lookAt quaternion.
|
// use u to compute a full lookAt quaternion.
|
||||||
var lookAtRot = Quat.lookAt(controllerPosition, Vec3.sum(controllerPosition, u), Y_AXIS);
|
var lookAtRot = Quat.lookAt(tabletBase, Vec3.sum(tabletBase, u), Y_AXIS);
|
||||||
|
var yDisplacement = (height / 2);
|
||||||
// adjust the tablet position by a small amount.
|
|
||||||
var yDisplacement = (height / 2) + 0.1;
|
|
||||||
var zDisplacement = 0.05;
|
var zDisplacement = 0.05;
|
||||||
var tabletOffset = Vec3.multiplyQbyV(lookAtRot, {x: 0, y: yDisplacement, z: zDisplacement});
|
var tabletOffset = Vec3.multiplyQbyV(lookAtRot, {x: 0, y: yDisplacement, z: zDisplacement});
|
||||||
finalPosition = Vec3.sum(controllerPosition, tabletOffset);
|
finalPosition = Vec3.sum(tabletBase, tabletOffset);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
position: finalPosition,
|
position: finalPosition,
|
||||||
rotation: lookAtRot
|
rotation: lookAtRot
|
||||||
|
|
|
@ -52,10 +52,16 @@ function onMessageBoxClosed(id, button) {
|
||||||
|
|
||||||
Window.messageBoxClosed.connect(onMessageBoxClosed);
|
Window.messageBoxClosed.connect(onMessageBoxClosed);
|
||||||
|
|
||||||
|
var shouldActivateButton = false;
|
||||||
|
var onMarketplaceScreen = false;
|
||||||
|
|
||||||
function showMarketplace() {
|
function showMarketplace() {
|
||||||
UserActivityLogger.openedMarketplace();
|
UserActivityLogger.openedMarketplace();
|
||||||
|
|
||||||
|
shouldActivateButton = true;
|
||||||
tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL);
|
tablet.gotoWebScreen(MARKETPLACE_URL_INITIAL, MARKETPLACES_INJECT_SCRIPT_URL);
|
||||||
|
onMarketplaceScreen = true;
|
||||||
|
|
||||||
tablet.webEventReceived.connect(function (message) {
|
tablet.webEventReceived.connect(function (message) {
|
||||||
|
|
||||||
if (message === GOTO_DIRECTORY) {
|
if (message === GOTO_DIRECTORY) {
|
||||||
|
@ -98,15 +104,10 @@ function showMarketplace() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleMarketplace() {
|
|
||||||
var entity = HMD.tabletID;
|
|
||||||
Entities.editEntity(entity, {textures: JSON.stringify({"tex.close": HOME_BUTTON_TEXTURE})});
|
|
||||||
showMarketplace();
|
|
||||||
}
|
|
||||||
|
|
||||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||||
var marketplaceButton = tablet.addButton({
|
var marketplaceButton = tablet.addButton({
|
||||||
icon: "icons/tablet-icons/market-i.svg",
|
icon: "icons/tablet-icons/market-i.svg",
|
||||||
|
activeIcon: "icons/tablet-icons/market-a.svg",
|
||||||
text: "MARKET",
|
text: "MARKET",
|
||||||
sortOrder: 9
|
sortOrder: 9
|
||||||
});
|
});
|
||||||
|
@ -117,16 +118,30 @@ function onCanWriteAssetsChanged() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function onClick() {
|
function onClick() {
|
||||||
toggleMarketplace();
|
if (onMarketplaceScreen) {
|
||||||
|
// for toolbar-mode: go back to home screen, this will close the window.
|
||||||
|
tablet.gotoHomeScreen();
|
||||||
|
} else {
|
||||||
|
var entity = HMD.tabletID;
|
||||||
|
Entities.editEntity(entity, {textures: JSON.stringify({"tex.close": HOME_BUTTON_TEXTURE})});
|
||||||
|
showMarketplace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onScreenChanged(type, url) {
|
||||||
|
// for toolbar mode: change button to active when window is first openend, false otherwise.
|
||||||
|
marketplaceButton.editProperties({isActive: shouldActivateButton});
|
||||||
|
shouldActivateButton = false;
|
||||||
|
onMarketplaceScreen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
marketplaceButton.clicked.connect(onClick);
|
marketplaceButton.clicked.connect(onClick);
|
||||||
|
tablet.screenChanged.connect(onScreenChanged);
|
||||||
Entities.canWriteAssetsChanged.connect(onCanWriteAssetsChanged);
|
Entities.canWriteAssetsChanged.connect(onCanWriteAssetsChanged);
|
||||||
|
|
||||||
Script.scriptEnding.connect(function () {
|
Script.scriptEnding.connect(function () {
|
||||||
if (tablet) {
|
tablet.removeButton(marketplaceButton);
|
||||||
tablet.removeButton(marketplaceButton);
|
tablet.screenChanged.disconnect(onScreenChanged);
|
||||||
}
|
|
||||||
Entities.canWriteAssetsChanged.disconnect(onCanWriteAssetsChanged);
|
Entities.canWriteAssetsChanged.disconnect(onCanWriteAssetsChanged);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -10,26 +10,46 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png";
|
var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png";
|
||||||
//var HOME_BUTTON_TEXTURE = Script.resourcesPath() + "meshes/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png";
|
// var HOME_BUTTON_TEXTURE = Script.resourcesPath() + "meshes/tablet-with-home-button.fbx/tablet-with-home-button.fbm/button-root.png";
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||||
var button = tablet.addButton({
|
var button = tablet.addButton({
|
||||||
icon: "icons/tablet-icons/menu-i.svg",
|
icon: "icons/tablet-icons/menu-i.svg",
|
||||||
|
activeIcon: "icons/tablet-icons/menu-a.svg",
|
||||||
text: "MENU",
|
text: "MENU",
|
||||||
sortOrder: 3
|
sortOrder: 3
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var shouldActivateButton = false;
|
||||||
|
var onMenuScreen = false;
|
||||||
|
|
||||||
function onClicked() {
|
function onClicked() {
|
||||||
var entity = HMD.tabletID;
|
if (onMenuScreen) {
|
||||||
Entities.editEntity(entity, {textures: JSON.stringify({"tex.close": HOME_BUTTON_TEXTURE})});
|
// for toolbar-mode: go back to home screen, this will close the window.
|
||||||
tablet.gotoMenuScreen();
|
tablet.gotoHomeScreen();
|
||||||
|
} else {
|
||||||
|
var entity = HMD.tabletID;
|
||||||
|
Entities.editEntity(entity, {textures: JSON.stringify({"tex.close": HOME_BUTTON_TEXTURE})});
|
||||||
|
shouldActivateButton = true;
|
||||||
|
tablet.gotoMenuScreen();
|
||||||
|
onMenuScreen = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onScreenChanged(type, url) {
|
||||||
|
// for toolbar mode: change button to active when window is first openend, false otherwise.
|
||||||
|
button.editProperties({isActive: shouldActivateButton});
|
||||||
|
shouldActivateButton = false;
|
||||||
|
onMenuScreen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.clicked.connect(onClicked);
|
button.clicked.connect(onClicked);
|
||||||
|
tablet.screenChanged.connect(onScreenChanged);
|
||||||
|
|
||||||
Script.scriptEnding.connect(function () {
|
Script.scriptEnding.connect(function () {
|
||||||
button.clicked.disconnect(onClicked);
|
button.clicked.disconnect(onClicked);
|
||||||
tablet.removeButton(button);
|
tablet.removeButton(button);
|
||||||
|
tablet.screenChanged.disconnect(onScreenChanged);
|
||||||
});
|
});
|
||||||
}());
|
}());
|
||||||
|
|
|
@ -477,23 +477,17 @@ var button;
|
||||||
var buttonName = "PEOPLE";
|
var buttonName = "PEOPLE";
|
||||||
var tablet = null;
|
var tablet = null;
|
||||||
|
|
||||||
function onTabletScreenChanged(type, url) {
|
|
||||||
if (type !== "QML" || url !== "../Pal.qml") {
|
|
||||||
off();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function startup() {
|
function startup() {
|
||||||
tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||||
button = tablet.addButton({
|
button = tablet.addButton({
|
||||||
text: buttonName,
|
text: buttonName,
|
||||||
icon: "icons/tablet-icons/people-i.svg",
|
icon: "icons/tablet-icons/people-i.svg",
|
||||||
|
activeIcon: "icons/tablet-icons/people-a.svg",
|
||||||
sortOrder: 7
|
sortOrder: 7
|
||||||
});
|
});
|
||||||
tablet.fromQml.connect(fromQml);
|
tablet.fromQml.connect(fromQml);
|
||||||
button.clicked.connect(onTabletButtonClicked);
|
button.clicked.connect(onTabletButtonClicked);
|
||||||
tablet.screenChanged.connect(onTabletScreenChanged);
|
tablet.screenChanged.connect(onTabletScreenChanged);
|
||||||
|
|
||||||
Users.usernameFromIDReply.connect(usernameFromIDReply);
|
Users.usernameFromIDReply.connect(usernameFromIDReply);
|
||||||
Window.domainChanged.connect(clearLocalQMLDataAndClosePAL);
|
Window.domainChanged.connect(clearLocalQMLDataAndClosePAL);
|
||||||
Window.domainConnectionRefused.connect(clearLocalQMLDataAndClosePAL);
|
Window.domainConnectionRefused.connect(clearLocalQMLDataAndClosePAL);
|
||||||
|
@ -524,17 +518,39 @@ function off() {
|
||||||
Users.requestsDomainListData = false;
|
Users.requestsDomainListData = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var onPalScreen = false;
|
||||||
|
var shouldActivateButton = false;
|
||||||
|
|
||||||
function onTabletButtonClicked() {
|
function onTabletButtonClicked() {
|
||||||
tablet.loadQMLSource("../Pal.qml");
|
if (onPalScreen) {
|
||||||
Users.requestsDomainListData = true;
|
// for toolbar-mode: go back to home screen, this will close the window.
|
||||||
populateUserList();
|
tablet.gotoHomeScreen();
|
||||||
isWired = true;
|
} else {
|
||||||
Script.update.connect(updateOverlays);
|
shouldActivateButton = true;
|
||||||
Controller.mousePressEvent.connect(handleMouseEvent);
|
tablet.loadQMLSource("../Pal.qml");
|
||||||
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
|
onPalScreen = true;
|
||||||
triggerMapping.enable();
|
Users.requestsDomainListData = true;
|
||||||
triggerPressMapping.enable();
|
populateUserList();
|
||||||
audioTimer = createAudioInterval(conserveResources ? AUDIO_LEVEL_CONSERVED_UPDATE_INTERVAL_MS : AUDIO_LEVEL_UPDATE_INTERVAL_MS);
|
isWired = true;
|
||||||
|
Script.update.connect(updateOverlays);
|
||||||
|
Controller.mousePressEvent.connect(handleMouseEvent);
|
||||||
|
Controller.mouseMoveEvent.connect(handleMouseMoveEvent);
|
||||||
|
triggerMapping.enable();
|
||||||
|
triggerPressMapping.enable();
|
||||||
|
audioTimer = createAudioInterval(conserveResources ? AUDIO_LEVEL_CONSERVED_UPDATE_INTERVAL_MS : AUDIO_LEVEL_UPDATE_INTERVAL_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTabletScreenChanged(type, url) {
|
||||||
|
// for toolbar mode: change button to active when window is first openend, false otherwise.
|
||||||
|
button.editProperties({isActive: shouldActivateButton});
|
||||||
|
shouldActivateButton = false;
|
||||||
|
onPalScreen = false;
|
||||||
|
|
||||||
|
// disable sphere overlays when not on pal screen.
|
||||||
|
if (type !== "QML" || url !== "../Pal.qml") {
|
||||||
|
off();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -621,14 +637,12 @@ function shutdown() {
|
||||||
button.clicked.disconnect(onTabletButtonClicked);
|
button.clicked.disconnect(onTabletButtonClicked);
|
||||||
tablet.removeButton(button);
|
tablet.removeButton(button);
|
||||||
tablet.screenChanged.disconnect(onTabletScreenChanged);
|
tablet.screenChanged.disconnect(onTabletScreenChanged);
|
||||||
|
|
||||||
Users.usernameFromIDReply.disconnect(usernameFromIDReply);
|
Users.usernameFromIDReply.disconnect(usernameFromIDReply);
|
||||||
Window.domainChanged.disconnect(clearLocalQMLDataAndClosePAL);
|
Window.domainChanged.disconnect(clearLocalQMLDataAndClosePAL);
|
||||||
Window.domainConnectionRefused.disconnect(clearLocalQMLDataAndClosePAL);
|
Window.domainConnectionRefused.disconnect(clearLocalQMLDataAndClosePAL);
|
||||||
Messages.subscribe(CHANNEL);
|
Messages.subscribe(CHANNEL);
|
||||||
Messages.messageReceived.disconnect(receiveMessage);
|
Messages.messageReceived.disconnect(receiveMessage);
|
||||||
Users.avatarDisconnected.disconnect(avatarDisconnected);
|
Users.avatarDisconnected.disconnect(avatarDisconnected);
|
||||||
|
|
||||||
off();
|
off();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,27 @@
|
||||||
(function() { // BEGIN LOCAL_SCOPE
|
(function() { // BEGIN LOCAL_SCOPE
|
||||||
var gotoQmlSource = "TabletAddressDialog.qml";
|
var gotoQmlSource = "TabletAddressDialog.qml";
|
||||||
var buttonName = "GOTO";
|
var buttonName = "GOTO";
|
||||||
|
var onGotoScreen = false;
|
||||||
|
var shouldActivateButton = false;
|
||||||
|
|
||||||
function onClicked(){
|
function onClicked() {
|
||||||
tablet.loadQMLSource(gotoQmlSource);
|
if (onGotoScreen) {
|
||||||
|
// for toolbar-mode: go back to home screen, this will close the window.
|
||||||
|
tablet.gotoHomeScreen();
|
||||||
|
} else {
|
||||||
|
shouldActivateButton = true;
|
||||||
|
tablet.loadQMLSource(gotoQmlSource);
|
||||||
|
onGotoScreen = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onScreenChanged(type, url) {
|
||||||
|
// for toolbar mode: change button to active when window is first openend, false otherwise.
|
||||||
|
button.editProperties({isActive: shouldActivateButton});
|
||||||
|
shouldActivateButton = false;
|
||||||
|
onGotoScreen = false;
|
||||||
|
}
|
||||||
|
|
||||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||||
var button = tablet.addButton({
|
var button = tablet.addButton({
|
||||||
icon: "icons/tablet-icons/goto-i.svg",
|
icon: "icons/tablet-icons/goto-i.svg",
|
||||||
|
@ -27,12 +44,12 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
button.clicked.connect(onClicked);
|
button.clicked.connect(onClicked);
|
||||||
|
tablet.screenChanged.connect(onScreenChanged);
|
||||||
|
|
||||||
Script.scriptEnding.connect(function () {
|
Script.scriptEnding.connect(function () {
|
||||||
button.clicked.disconnect(onClicked);
|
button.clicked.disconnect(onClicked);
|
||||||
if (tablet) {
|
tablet.removeButton(button);
|
||||||
tablet.removeButton(button);
|
tablet.screenChanged.disconnect(onScreenChanged);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}()); // END LOCAL_SCOPE
|
}()); // END LOCAL_SCOPE
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
//
|
//
|
||||||
// users.js
|
// tablet-users.js
|
||||||
//
|
//
|
||||||
// Created by Faye Li on 18 Jan 2017.
|
// Created by Faye Li on 18 Jan 2017.
|
||||||
// Copyright 2017 High Fidelity, Inc.
|
// Copyright 2017 High Fidelity, Inc.
|
||||||
|
@ -36,16 +36,34 @@
|
||||||
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||||
var button = tablet.addButton({
|
var button = tablet.addButton({
|
||||||
icon: "icons/tablet-icons/users-i.svg",
|
icon: "icons/tablet-icons/users-i.svg",
|
||||||
|
activeIcon: "icons/tablet-icons/users-a.svg",
|
||||||
text: "USERS",
|
text: "USERS",
|
||||||
sortOrder: 11
|
sortOrder: 11
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var onUsersScreen = false;
|
||||||
|
var shouldActivateButton = false;
|
||||||
|
|
||||||
function onClicked() {
|
function onClicked() {
|
||||||
var tabletEntity = HMD.tabletID;
|
if (onUsersScreen) {
|
||||||
if (tabletEntity) {
|
// for toolbar-mode: go back to home screen, this will close the window.
|
||||||
Entities.editEntity(tabletEntity, {textures: JSON.stringify({"tex.close" : HOME_BUTTON_TEXTURE})});
|
tablet.gotoHomeScreen();
|
||||||
|
} else {
|
||||||
|
var tabletEntity = HMD.tabletID;
|
||||||
|
if (tabletEntity) {
|
||||||
|
Entities.editEntity(tabletEntity, {textures: JSON.stringify({"tex.close" : HOME_BUTTON_TEXTURE})});
|
||||||
|
}
|
||||||
|
shouldActivateButton = true;
|
||||||
|
tablet.gotoWebScreen(USERS_URL);
|
||||||
|
onUsersScreen = true;
|
||||||
}
|
}
|
||||||
tablet.gotoWebScreen(USERS_URL);
|
}
|
||||||
|
|
||||||
|
function onScreenChanged() {
|
||||||
|
// for toolbar mode: change button to active when window is first openend, false otherwise.
|
||||||
|
button.editProperties({isActive: shouldActivateButton});
|
||||||
|
shouldActivateButton = false;
|
||||||
|
onUsersScreen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onWebEventReceived(event) {
|
function onWebEventReceived(event) {
|
||||||
|
@ -88,12 +106,13 @@
|
||||||
// update your visibility (all, friends, or none)
|
// update your visibility (all, friends, or none)
|
||||||
myVisibility = event.data.visibility;
|
myVisibility = event.data.visibility;
|
||||||
GlobalServices.findableBy = myVisibility;
|
GlobalServices.findableBy = myVisibility;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
button.clicked.connect(onClicked);
|
button.clicked.connect(onClicked);
|
||||||
tablet.webEventReceived.connect(onWebEventReceived);
|
tablet.webEventReceived.connect(onWebEventReceived);
|
||||||
|
tablet.screenChanged.connect(onScreenChanged);
|
||||||
|
|
||||||
function cleanup() {
|
function cleanup() {
|
||||||
button.clicked.disconnect(onClicked);
|
button.clicked.disconnect(onClicked);
|
||||||
|
|
Loading…
Reference in a new issue