Merge branch 'master' into DOC-191
|
@ -265,7 +265,7 @@ static const int AVATAR_MIXER_BROADCAST_FRAMES_PER_SECOND = 45;
|
||||||
void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) {
|
void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) {
|
||||||
quint64 start = usecTimestampNow();
|
quint64 start = usecTimestampNow();
|
||||||
|
|
||||||
if (node->getType() == NodeType::Agent && node->getLinkedData() && node->getActiveSocket() && !node->isUpstream()) {
|
if ((node->getType() == NodeType::Agent || node->getType() == NodeType::EntityScriptServer) && node->getLinkedData() && node->getActiveSocket() && !node->isUpstream()) {
|
||||||
broadcastAvatarDataToAgent(node);
|
broadcastAvatarDataToAgent(node);
|
||||||
} else if (node->getType() == NodeType::DownstreamAvatarMixer) {
|
} else if (node->getType() == NodeType::DownstreamAvatarMixer) {
|
||||||
broadcastAvatarDataToDownstreamMixer(node);
|
broadcastAvatarDataToDownstreamMixer(node);
|
||||||
|
@ -448,13 +448,6 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node)
|
||||||
// or that somehow we haven't sent
|
// or that somehow we haven't sent
|
||||||
if (lastSeqToReceiver == lastSeqFromSender && lastSeqToReceiver != 0) {
|
if (lastSeqToReceiver == lastSeqFromSender && lastSeqToReceiver != 0) {
|
||||||
++numAvatarsHeldBack;
|
++numAvatarsHeldBack;
|
||||||
|
|
||||||
// BUGZ-781 verbose debugging:
|
|
||||||
auto usecLastTimeSent = destinationNodeData->getLastOtherAvatarEncodeTime(sourceAvatarNodeData->getNodeLocalID());
|
|
||||||
if (usecLastTimeSent != 0 && startIgnoreCalculation - usecLastTimeSent > 10 * USECS_PER_SECOND) {
|
|
||||||
qCDebug(avatars) << "Not sent avatar" << *sourceAvatarNode << "to Node" << *destinationNode << "in > 10 s";
|
|
||||||
}
|
|
||||||
|
|
||||||
sendAvatar = false;
|
sendAvatar = false;
|
||||||
} else if (lastSeqFromSender == 0) {
|
} else if (lastSeqFromSender == 0) {
|
||||||
// We have have not yet received any data about this avatar. Ignore it for now
|
// We have have not yet received any data about this avatar. Ignore it for now
|
||||||
|
|
|
@ -86,8 +86,6 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
|
||||||
this, "handleOctreePacket");
|
this, "handleOctreePacket");
|
||||||
packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat");
|
packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat");
|
||||||
|
|
||||||
auto avatarHashMap = DependencyManager::set<AvatarHashMap>();
|
|
||||||
|
|
||||||
packetReceiver.registerListener(PacketType::ReloadEntityServerScript, this, "handleReloadEntityServerScriptPacket");
|
packetReceiver.registerListener(PacketType::ReloadEntityServerScript, this, "handleReloadEntityServerScriptPacket");
|
||||||
packetReceiver.registerListener(PacketType::EntityScriptGetStatus, this, "handleEntityScriptGetStatusPacket");
|
packetReceiver.registerListener(PacketType::EntityScriptGetStatus, this, "handleEntityScriptGetStatusPacket");
|
||||||
packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket");
|
packetReceiver.registerListener(PacketType::EntityServerScriptLog, this, "handleEntityServerScriptLogPacket");
|
||||||
|
@ -255,6 +253,7 @@ void EntityScriptServer::handleEntityScriptCallMethodPacket(QSharedPointer<Recei
|
||||||
void EntityScriptServer::run() {
|
void EntityScriptServer::run() {
|
||||||
DependencyManager::set<ScriptEngines>(ScriptEngine::ENTITY_SERVER_SCRIPT);
|
DependencyManager::set<ScriptEngines>(ScriptEngine::ENTITY_SERVER_SCRIPT);
|
||||||
DependencyManager::set<EntityScriptServerServices>();
|
DependencyManager::set<EntityScriptServerServices>();
|
||||||
|
DependencyManager::set<AvatarHashMap>();
|
||||||
|
|
||||||
// make sure we request our script once the agent connects to the domain
|
// make sure we request our script once the agent connects to the domain
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
@ -448,6 +447,7 @@ void EntityScriptServer::resetEntitiesScriptEngine() {
|
||||||
newEngine->globalObject().setProperty("WebSocketServer", webSocketServerConstructorValue);
|
newEngine->globalObject().setProperty("WebSocketServer", webSocketServerConstructorValue);
|
||||||
|
|
||||||
newEngine->registerGlobalObject("SoundCache", DependencyManager::get<SoundCacheScriptingInterface>().data());
|
newEngine->registerGlobalObject("SoundCache", DependencyManager::get<SoundCacheScriptingInterface>().data());
|
||||||
|
newEngine->registerGlobalObject("AvatarList", DependencyManager::get<AvatarHashMap>().data());
|
||||||
|
|
||||||
// connect this script engines printedMessage signal to the global ScriptEngines these various messages
|
// connect this script engines printedMessage signal to the global ScriptEngines these various messages
|
||||||
auto scriptEngines = DependencyManager::get<ScriptEngines>().data();
|
auto scriptEngines = DependencyManager::get<ScriptEngines>().data();
|
||||||
|
|
4
cmake/externals/wasapi/CMakeLists.txt
vendored
|
@ -6,8 +6,8 @@ if (WIN32)
|
||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
ExternalProject_Add(
|
ExternalProject_Add(
|
||||||
${EXTERNAL_NAME}
|
${EXTERNAL_NAME}
|
||||||
URL https://public.highfidelity.com/dependencies/qtaudio_wasapi11.zip
|
URL https://public.highfidelity.com/dependencies/qtaudio_wasapi12.zip
|
||||||
URL_MD5 d0eb8489455e7f79d59155535a2c8861
|
URL_MD5 9e2eef41165f85344808f754b48bf08d
|
||||||
CONFIGURE_COMMAND ""
|
CONFIGURE_COMMAND ""
|
||||||
BUILD_COMMAND ""
|
BUILD_COMMAND ""
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
|
|
36
cmake/ports/bullet3/bullet-git-fix-build-clang-8.patch
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
From 7638b7c5a659dceb4e580ae87d4d60b00847ef94 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Emil=20Nord=C3=A9n?= <emilnorden@yahoo.se>
|
||||||
|
Date: Sat, 4 May 2019 08:38:53 +0200
|
||||||
|
Subject: [PATCH] fixed build on latest version of clang
|
||||||
|
|
||||||
|
---
|
||||||
|
src/Bullet3Common/b3Vector3.h | 2 +-
|
||||||
|
src/LinearMath/btVector3.h | 2 +-
|
||||||
|
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/Bullet3Common/b3Vector3.h b/src/Bullet3Common/b3Vector3.h
|
||||||
|
index 56e6c13311..a70d68d6e1 100644
|
||||||
|
--- a/src/Bullet3Common/b3Vector3.h
|
||||||
|
+++ b/src/Bullet3Common/b3Vector3.h
|
||||||
|
@@ -36,7 +36,7 @@ subject to the following restrictions:
|
||||||
|
#pragma warning(disable : 4556) // value of intrinsic immediate argument '4294967239' is out of range '0 - 255'
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-#define B3_SHUFFLE(x, y, z, w) ((w) << 6 | (z) << 4 | (y) << 2 | (x))
|
||||||
|
+#define B3_SHUFFLE(x, y, z, w) (((w) << 6 | (z) << 4 | (y) << 2 | (x)) & 0xff)
|
||||||
|
//#define b3_pshufd_ps( _a, _mask ) (__m128) _mm_shuffle_epi32((__m128i)(_a), (_mask) )
|
||||||
|
#define b3_pshufd_ps(_a, _mask) _mm_shuffle_ps((_a), (_a), (_mask))
|
||||||
|
#define b3_splat3_ps(_a, _i) b3_pshufd_ps((_a), B3_SHUFFLE(_i, _i, _i, 3))
|
||||||
|
diff --git a/src/LinearMath/btVector3.h b/src/LinearMath/btVector3.h
|
||||||
|
index 61fd8d1e46..d65ed9808d 100644
|
||||||
|
--- a/src/LinearMath/btVector3.h
|
||||||
|
+++ b/src/LinearMath/btVector3.h
|
||||||
|
@@ -36,7 +36,7 @@ subject to the following restrictions:
|
||||||
|
#pragma warning(disable : 4556) // value of intrinsic immediate argument '4294967239' is out of range '0 - 255'
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-#define BT_SHUFFLE(x, y, z, w) ((w) << 6 | (z) << 4 | (y) << 2 | (x))
|
||||||
|
+#define BT_SHUFFLE(x, y, z, w) (((w) << 6 | (z) << 4 | (y) << 2 | (x)) & 0xff)
|
||||||
|
//#define bt_pshufd_ps( _a, _mask ) (__m128) _mm_shuffle_epi32((__m128i)(_a), (_mask) )
|
||||||
|
#define bt_pshufd_ps(_a, _mask) _mm_shuffle_ps((_a), (_a), (_mask))
|
||||||
|
#define bt_splat3_ps(_a, _i) bt_pshufd_ps((_a), BT_SHUFFLE(_i, _i, _i, 3))
|
|
@ -27,6 +27,7 @@ vcpkg_from_github(
|
||||||
REF ab8f16961e19a86ee20c6a1d61f662392524cc77
|
REF ab8f16961e19a86ee20c6a1d61f662392524cc77
|
||||||
SHA512 927742db29867517283d45e475f0c534a9a57e165cae221f26e08e88057253a1682ac9919b2dc547b9cf388ba0b931b175623461d44f28c9184796ba90b1ed55
|
SHA512 927742db29867517283d45e475f0c534a9a57e165cae221f26e08e88057253a1682ac9919b2dc547b9cf388ba0b931b175623461d44f28c9184796ba90b1ed55
|
||||||
HEAD_REF master
|
HEAD_REF master
|
||||||
|
PATCHES "bullet-git-fix-build-clang-8.patch"
|
||||||
)
|
)
|
||||||
|
|
||||||
vcpkg_configure_cmake(
|
vcpkg_configure_cmake(
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Source: hifi-deps
|
Source: hifi-deps
|
||||||
Version: 0.1
|
Version: 0.3
|
||||||
Description: Collected dependencies for High Fidelity applications
|
Description: Collected dependencies for High Fidelity applications
|
||||||
Build-Depends: bullet3, draco, etc2comp, glm, nvtt, openexr (!android), openssl (windows), tbb (!android&!osx), zlib, webrtc (!android)
|
Build-Depends: bullet3, draco, etc2comp, glm, nvtt, openexr (!android), openssl (windows), tbb (!android&!osx), zlib, webrtc (!android)
|
||||||
|
|
|
@ -134,7 +134,7 @@ endif()
|
||||||
downloadVcpkg = True
|
downloadVcpkg = True
|
||||||
|
|
||||||
if not downloadVcpkg and not os.path.isfile(self.exe):
|
if not downloadVcpkg and not os.path.isfile(self.exe):
|
||||||
print("Missing executable, boostrapping")
|
print("Missing executable, boot-strapping")
|
||||||
downloadVcpkg = True
|
downloadVcpkg = True
|
||||||
|
|
||||||
# Make sure we have a vcpkg executable
|
# Make sure we have a vcpkg executable
|
||||||
|
@ -265,7 +265,7 @@ endif()
|
||||||
if platform.system() == 'Windows':
|
if platform.system() == 'Windows':
|
||||||
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-windows3.tar.gz'
|
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-windows3.tar.gz'
|
||||||
elif platform.system() == 'Darwin':
|
elif platform.system() == 'Darwin':
|
||||||
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-macos3.tar.gz'
|
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-macos.tar.gz?versionId=bLAgnoJ8IMKpqv8NFDcAu8hsyQy3Rwwz'
|
||||||
elif platform.system() == 'Linux':
|
elif platform.system() == 'Linux':
|
||||||
if platform.linux_distribution()[1][:3] == '16.':
|
if platform.linux_distribution()[1][:3] == '16.':
|
||||||
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-16.04-with-symbols.tar.gz'
|
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-16.04-with-symbols.tar.gz'
|
||||||
|
|
|
@ -2478,8 +2478,8 @@
|
||||||
{
|
{
|
||||||
"easingType": "easeInOutQuad",
|
"easingType": "easeInOutQuad",
|
||||||
"id": "talk",
|
"id": "talk",
|
||||||
"interpDuration": 1,
|
"interpDuration": 20,
|
||||||
"interpTarget": 1,
|
"interpTarget": 20,
|
||||||
"interpType": "evaluateBoth",
|
"interpType": "evaluateBoth",
|
||||||
"priority": 0.33,
|
"priority": 0.33,
|
||||||
"resume": true,
|
"resume": true,
|
||||||
|
@ -2489,8 +2489,8 @@
|
||||||
{
|
{
|
||||||
"easingType": "easeInOutQuad",
|
"easingType": "easeInOutQuad",
|
||||||
"id": "talk02",
|
"id": "talk02",
|
||||||
"interpDuration": 1,
|
"interpDuration": 20,
|
||||||
"interpTarget": 1,
|
"interpTarget": 20,
|
||||||
"interpType": "evaluateBoth",
|
"interpType": "evaluateBoth",
|
||||||
"priority": 0.33,
|
"priority": 0.33,
|
||||||
"resume": true,
|
"resume": true,
|
||||||
|
@ -2500,8 +2500,8 @@
|
||||||
{
|
{
|
||||||
"easingType": "easeInOutQuad",
|
"easingType": "easeInOutQuad",
|
||||||
"id": "talk03",
|
"id": "talk03",
|
||||||
"interpDuration": 1,
|
"interpDuration": 20,
|
||||||
"interpTarget": 1,
|
"interpTarget": 20,
|
||||||
"interpType": "evaluateBoth",
|
"interpType": "evaluateBoth",
|
||||||
"priority": 0.33,
|
"priority": 0.33,
|
||||||
"resume": true,
|
"resume": true,
|
||||||
|
@ -2511,8 +2511,8 @@
|
||||||
{
|
{
|
||||||
"easingType": "easeInOutQuad",
|
"easingType": "easeInOutQuad",
|
||||||
"id": "talk04",
|
"id": "talk04",
|
||||||
"interpDuration": 1,
|
"interpDuration": 20,
|
||||||
"interpTarget": 1,
|
"interpTarget": 20,
|
||||||
"interpType": "evaluateBoth",
|
"interpType": "evaluateBoth",
|
||||||
"priority": 0.33,
|
"priority": 0.33,
|
||||||
"resume": true,
|
"resume": true,
|
||||||
|
@ -2522,8 +2522,8 @@
|
||||||
{
|
{
|
||||||
"easingType": "easeInOutQuad",
|
"easingType": "easeInOutQuad",
|
||||||
"id": "talk_armsdown",
|
"id": "talk_armsdown",
|
||||||
"interpDuration": 1,
|
"interpDuration": 20,
|
||||||
"interpTarget": 1,
|
"interpTarget": 20,
|
||||||
"interpType": "evaluateBoth",
|
"interpType": "evaluateBoth",
|
||||||
"priority": 0.33,
|
"priority": 0.33,
|
||||||
"resume": true,
|
"resume": true,
|
||||||
|
@ -2533,8 +2533,8 @@
|
||||||
{
|
{
|
||||||
"easingType": "easeInOutQuad",
|
"easingType": "easeInOutQuad",
|
||||||
"id": "talk_lefthand",
|
"id": "talk_lefthand",
|
||||||
"interpDuration": 1,
|
"interpDuration": 20,
|
||||||
"interpTarget": 1,
|
"interpTarget": 20,
|
||||||
"interpType": "evaluateBoth",
|
"interpType": "evaluateBoth",
|
||||||
"priority": 0.33,
|
"priority": 0.33,
|
||||||
"resume": true,
|
"resume": true,
|
||||||
|
@ -2544,8 +2544,8 @@
|
||||||
{
|
{
|
||||||
"easingType": "easeInOutQuad",
|
"easingType": "easeInOutQuad",
|
||||||
"id": "talk_righthand",
|
"id": "talk_righthand",
|
||||||
"interpDuration": 1,
|
"interpDuration": 20,
|
||||||
"interpTarget": 1,
|
"interpTarget": 20,
|
||||||
"interpType": "evaluateBoth",
|
"interpType": "evaluateBoth",
|
||||||
"priority": 0.33,
|
"priority": 0.33,
|
||||||
"resume": true,
|
"resume": true,
|
||||||
|
@ -4736,32 +4736,6 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"children": [
|
"children": [
|
||||||
{
|
|
||||||
"children": [
|
|
||||||
],
|
|
||||||
"data": {
|
|
||||||
"endFrame": 30,
|
|
||||||
"loopFlag": true,
|
|
||||||
"startFrame": 1,
|
|
||||||
"timeScale": 1,
|
|
||||||
"url": "qrc:///avatar/animations/side_step_short_left.fbx"
|
|
||||||
},
|
|
||||||
"id": "strafeLeftShortStep_c",
|
|
||||||
"type": "clip"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"children": [
|
|
||||||
],
|
|
||||||
"data": {
|
|
||||||
"endFrame": 20,
|
|
||||||
"loopFlag": true,
|
|
||||||
"startFrame": 1,
|
|
||||||
"timeScale": 1,
|
|
||||||
"url": "qrc:///avatar/animations/side_step_left.fbx"
|
|
||||||
},
|
|
||||||
"id": "strafeLeftStep_c",
|
|
||||||
"type": "clip"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"children": [
|
"children": [
|
||||||
],
|
],
|
||||||
|
@ -4819,8 +4793,6 @@
|
||||||
"alpha": 0,
|
"alpha": 0,
|
||||||
"alphaVar": "moveLateralAlpha",
|
"alphaVar": "moveLateralAlpha",
|
||||||
"characteristicSpeeds": [
|
"characteristicSpeeds": [
|
||||||
0.1,
|
|
||||||
0.5,
|
|
||||||
1,
|
1,
|
||||||
2.55,
|
2.55,
|
||||||
3.35,
|
3.35,
|
||||||
|
@ -4834,34 +4806,6 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"children": [
|
"children": [
|
||||||
{
|
|
||||||
"children": [
|
|
||||||
],
|
|
||||||
"data": {
|
|
||||||
"endFrame": 30,
|
|
||||||
"loopFlag": true,
|
|
||||||
"mirrorFlag": true,
|
|
||||||
"startFrame": 1,
|
|
||||||
"timeScale": 1,
|
|
||||||
"url": "qrc:///avatar/animations/side_step_short_left.fbx"
|
|
||||||
},
|
|
||||||
"id": "strafeRightShortStep_c",
|
|
||||||
"type": "clip"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"children": [
|
|
||||||
],
|
|
||||||
"data": {
|
|
||||||
"endFrame": 20,
|
|
||||||
"loopFlag": true,
|
|
||||||
"mirrorFlag": true,
|
|
||||||
"startFrame": 1,
|
|
||||||
"timeScale": 1,
|
|
||||||
"url": "qrc:///avatar/animations/side_step_left.fbx"
|
|
||||||
},
|
|
||||||
"id": "strafeRightStep_c",
|
|
||||||
"type": "clip"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"children": [
|
"children": [
|
||||||
],
|
],
|
||||||
|
@ -4923,8 +4867,6 @@
|
||||||
"alpha": 0,
|
"alpha": 0,
|
||||||
"alphaVar": "moveLateralAlpha",
|
"alphaVar": "moveLateralAlpha",
|
||||||
"characteristicSpeeds": [
|
"characteristicSpeeds": [
|
||||||
0.1,
|
|
||||||
0.5,
|
|
||||||
1,
|
1,
|
||||||
2.55,
|
2.55,
|
||||||
3.4,
|
3.4,
|
||||||
|
@ -5242,62 +5184,6 @@
|
||||||
"interpTarget": 6,
|
"interpTarget": 6,
|
||||||
"interpType": "evaluateBoth",
|
"interpType": "evaluateBoth",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{
|
|
||||||
"state": "idle",
|
|
||||||
"var": "isNotInput"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"state": "WALKFWD",
|
|
||||||
"var": "isInputForward"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"state": "WALKBWD",
|
|
||||||
"var": "isInputBackward"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"state": "STRAFERIGHT",
|
|
||||||
"var": "isInputRight"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"state": "STRAFELEFT",
|
|
||||||
"var": "isInputLeft"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"state": "turnRight",
|
|
||||||
"var": "isTurningRight"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"state": "turnLeft",
|
|
||||||
"var": "isTurningLeft"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"state": "fly",
|
|
||||||
"var": "isFlying"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"state": "takeoffStand",
|
|
||||||
"var": "isTakeoffStand"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"state": "TAKEOFFRUN",
|
|
||||||
"var": "isTakeoffRun"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"state": "inAirStand",
|
|
||||||
"var": "isInAirStand"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"state": "INAIRRUN",
|
|
||||||
"var": "isInAirRun"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"state": "strafeRightHmd",
|
|
||||||
"var": "isMovingRightHmd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"state": "strafeLeftHmd",
|
|
||||||
"var": "isMovingLeftHmd"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"state": "idle",
|
"state": "idle",
|
||||||
"var": "isNotSeated"
|
"var": "isNotSeated"
|
||||||
|
@ -5307,7 +5193,7 @@
|
||||||
{
|
{
|
||||||
"easingType": "easeInOutQuad",
|
"easingType": "easeInOutQuad",
|
||||||
"id": "idle",
|
"id": "idle",
|
||||||
"interpDuration": 20,
|
"interpDuration": 15,
|
||||||
"interpTarget": 20,
|
"interpTarget": 20,
|
||||||
"interpType": "evaluateBoth",
|
"interpType": "evaluateBoth",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
|
@ -5439,8 +5325,8 @@
|
||||||
{
|
{
|
||||||
"easingType": "easeInOutQuad",
|
"easingType": "easeInOutQuad",
|
||||||
"id": "idleSettle",
|
"id": "idleSettle",
|
||||||
"interpDuration": 15,
|
"interpDuration": 13,
|
||||||
"interpTarget": 15,
|
"interpTarget": 14,
|
||||||
"interpType": "snapshotPrev",
|
"interpType": "snapshotPrev",
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{
|
{
|
||||||
|
@ -5533,7 +5419,7 @@
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{
|
{
|
||||||
"state": "idleSettle",
|
"state": "idleSettle",
|
||||||
"var": "isNotInput"
|
"var": "isNotInputSlow"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"state": "WALKBWD",
|
"state": "WALKBWD",
|
||||||
|
@ -5597,7 +5483,7 @@
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{
|
{
|
||||||
"state": "idleSettle",
|
"state": "idleSettle",
|
||||||
"var": "isNotInput"
|
"var": "isNotInputSlow"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"state": "WALKFWD",
|
"state": "WALKFWD",
|
||||||
|
@ -5661,7 +5547,7 @@
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{
|
{
|
||||||
"state": "idleSettle",
|
"state": "idleSettle",
|
||||||
"var": "isNotInput"
|
"var": "isNotInputSlow"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"state": "WALKFWD",
|
"state": "WALKFWD",
|
||||||
|
@ -5673,7 +5559,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"state": "STRAFELEFT",
|
"state": "STRAFELEFT",
|
||||||
"var": "isInputLeft"
|
"var": "isMovingLeft"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"state": "turnRight",
|
"state": "turnRight",
|
||||||
|
@ -5725,7 +5611,7 @@
|
||||||
"transitions": [
|
"transitions": [
|
||||||
{
|
{
|
||||||
"state": "idleSettle",
|
"state": "idleSettle",
|
||||||
"var": "isNotInput"
|
"var": "isNotInputSlow"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"state": "WALKFWD",
|
"state": "WALKFWD",
|
||||||
|
@ -5737,7 +5623,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"state": "STRAFERIGHT",
|
"state": "STRAFERIGHT",
|
||||||
"var": "isInputRight"
|
"var": "isMovingRight"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"state": "turnRight",
|
"state": "turnRight",
|
||||||
|
|
|
@ -78,6 +78,15 @@
|
||||||
"to": "Actions.Yaw"
|
"to": "Actions.Yaw"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ "from": { "makeAxis" : [
|
||||||
|
["Keyboard.Left"],
|
||||||
|
["Keyboard.Right"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"when": ["Application.CameraFirstPersonLookat", "!Keyboard.Shift"],
|
||||||
|
"to": "Actions.Yaw"
|
||||||
|
},
|
||||||
|
|
||||||
{ "from": { "makeAxis" : [
|
{ "from": { "makeAxis" : [
|
||||||
["Keyboard.Left"],
|
["Keyboard.Left"],
|
||||||
["Keyboard.Right"]
|
["Keyboard.Right"]
|
||||||
|
@ -114,6 +123,15 @@
|
||||||
"to": "Actions.Yaw"
|
"to": "Actions.Yaw"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ "from": { "makeAxis" : [
|
||||||
|
["Keyboard.A"],
|
||||||
|
["Keyboard.D"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"when": ["Application.CameraFirstPersonLookat", "!Keyboard.Control"],
|
||||||
|
"to": "Actions.Yaw"
|
||||||
|
},
|
||||||
|
|
||||||
{ "from": { "makeAxis" : [
|
{ "from": { "makeAxis" : [
|
||||||
["Keyboard.A"],
|
["Keyboard.A"],
|
||||||
["Keyboard.D"]
|
["Keyboard.D"]
|
||||||
|
@ -150,6 +168,15 @@
|
||||||
"to": "Actions.Yaw"
|
"to": "Actions.Yaw"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ "from": { "makeAxis" : [
|
||||||
|
["Keyboard.TouchpadLeft"],
|
||||||
|
["Keyboard.TouchpadRight"]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"when": "Application.CameraFirstPersonLookat",
|
||||||
|
"to": "Actions.Yaw"
|
||||||
|
},
|
||||||
|
|
||||||
{ "from": { "makeAxis" : [
|
{ "from": { "makeAxis" : [
|
||||||
["Keyboard.TouchpadLeft"],
|
["Keyboard.TouchpadLeft"],
|
||||||
["Keyboard.TouchpadRight"]
|
["Keyboard.TouchpadRight"]
|
||||||
|
@ -222,10 +249,12 @@
|
||||||
{ "from": "Keyboard.Left", "when": "Keyboard.Shift", "to": "Actions.LATERAL_LEFT" },
|
{ "from": "Keyboard.Left", "when": "Keyboard.Shift", "to": "Actions.LATERAL_LEFT" },
|
||||||
{ "from": "Keyboard.Right", "when": "Keyboard.Shift", "to": "Actions.LATERAL_RIGHT" },
|
{ "from": "Keyboard.Right", "when": "Keyboard.Shift", "to": "Actions.LATERAL_RIGHT" },
|
||||||
{ "from": "Keyboard.Up", "when": "Application.CameraFirstPerson", "to": "Actions.LONGITUDINAL_FORWARD" },
|
{ "from": "Keyboard.Up", "when": "Application.CameraFirstPerson", "to": "Actions.LONGITUDINAL_FORWARD" },
|
||||||
|
{ "from": "Keyboard.Up", "when": "Application.CameraFirstPersonLookat", "to": "Actions.LONGITUDINAL_FORWARD" },
|
||||||
{ "from": "Keyboard.Up", "when": "Application.CameraThirdPerson", "to": "Actions.LONGITUDINAL_FORWARD" },
|
{ "from": "Keyboard.Up", "when": "Application.CameraThirdPerson", "to": "Actions.LONGITUDINAL_FORWARD" },
|
||||||
{ "from": "Keyboard.Up", "when": "Application.CameraLookAt", "to": "Actions.LONGITUDINAL_FORWARD" },
|
{ "from": "Keyboard.Up", "when": "Application.CameraLookAt", "to": "Actions.LONGITUDINAL_FORWARD" },
|
||||||
{ "from": "Keyboard.Up", "when": "Application.CameraSelfie", "to": "Actions.LONGITUDINAL_BACKWARD" },
|
{ "from": "Keyboard.Up", "when": "Application.CameraSelfie", "to": "Actions.LONGITUDINAL_BACKWARD" },
|
||||||
{ "from": "Keyboard.Down", "when": "Application.CameraFirstPerson", "to": "Actions.LONGITUDINAL_BACKWARD" },
|
{ "from": "Keyboard.Down", "when": "Application.CameraFirstPerson", "to": "Actions.LONGITUDINAL_BACKWARD" },
|
||||||
|
{ "from": "Keyboard.Down", "when": "Application.CameraFirstPersonLookat", "to": "Actions.LONGITUDINAL_BACKWARD" },
|
||||||
{ "from": "Keyboard.Down", "when": "Application.CameraThirdPerson", "to": "Actions.LONGITUDINAL_BACKWARD" },
|
{ "from": "Keyboard.Down", "when": "Application.CameraThirdPerson", "to": "Actions.LONGITUDINAL_BACKWARD" },
|
||||||
{ "from": "Keyboard.Down", "when": "Application.CameraLookAt", "to": "Actions.LONGITUDINAL_BACKWARD" },
|
{ "from": "Keyboard.Down", "when": "Application.CameraLookAt", "to": "Actions.LONGITUDINAL_BACKWARD" },
|
||||||
{ "from": "Keyboard.Down", "when": "Application.CameraSelfie", "to": "Actions.LONGITUDINAL_FORWARD" },
|
{ "from": "Keyboard.Down", "when": "Application.CameraSelfie", "to": "Actions.LONGITUDINAL_FORWARD" },
|
||||||
|
|
|
@ -33,6 +33,12 @@ Item {
|
||||||
property var item: null
|
property var item: null
|
||||||
|
|
||||||
function load(url, scriptUrl) {
|
function load(url, scriptUrl) {
|
||||||
|
// Ensure we reset any existing item to "about:blank" to ensure web audio stops: DEV-2375
|
||||||
|
if (root.item != null) {
|
||||||
|
root.item.url = "about:blank"
|
||||||
|
root.item.destroy()
|
||||||
|
root.item = null
|
||||||
|
}
|
||||||
QmlSurface.load("./controls/WebView.qml", root, function(newItem) {
|
QmlSurface.load("./controls/WebView.qml", root, function(newItem) {
|
||||||
root.item = newItem
|
root.item = newItem
|
||||||
root.item.url = url
|
root.item.url = url
|
||||||
|
|
|
@ -580,8 +580,9 @@ Rectangle {
|
||||||
sendToScript(msg);
|
sendToScript(msg);
|
||||||
} else if (msg.method === "showInvalidatedLightbox") {
|
} else if (msg.method === "showInvalidatedLightbox") {
|
||||||
lightboxPopup.titleText = "Item Invalidated";
|
lightboxPopup.titleText = "Item Invalidated";
|
||||||
lightboxPopup.bodyText = 'Your item is marked "invalidated" because this item has been suspended ' +
|
lightboxPopup.bodyText = 'This item has been invalidated and is no longer available.<br>' +
|
||||||
"from the Marketplace due to a claim against its author.";
|
'If you have questions, please contact marketplace@highfidelity.com.<br>' +
|
||||||
|
'Thank you!';
|
||||||
lightboxPopup.button1text = "CLOSE";
|
lightboxPopup.button1text = "CLOSE";
|
||||||
lightboxPopup.button1method = function() {
|
lightboxPopup.button1method = function() {
|
||||||
lightboxPopup.visible = false;
|
lightboxPopup.visible = false;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import QtQuick 2.10
|
import QtQuick 2.10
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
import "../simplifiedConstants" as SimplifiedConstants
|
import "../simplifiedConstants" as SimplifiedConstants
|
||||||
import "../simplifiedControls" as SimplifiedControls
|
import "../simplifiedControls" as SimplifiedControls
|
||||||
import "./components" as AvatarAppComponents
|
import "./components" as AvatarAppComponents
|
||||||
|
@ -79,7 +80,11 @@ Rectangle {
|
||||||
errorText.text = "There was a problem while retrieving your inventory. " +
|
errorText.text = "There was a problem while retrieving your inventory. " +
|
||||||
"Please try closing and re-opening the Avatar app.\n\nInventory status: " + result.status + "\nMessage: " + result.message;
|
"Please try closing and re-opening the Avatar app.\n\nInventory status: " + result.status + "\nMessage: " + result.message;
|
||||||
} else if (result.data && result.data.assets && result.data.assets.length === 0 && avatarAppInventoryModel.count === 0) {
|
} else if (result.data && result.data.assets && result.data.assets.length === 0 && avatarAppInventoryModel.count === 0) {
|
||||||
errorText.text = "You have not created any avatars yet! Create an avatar with the Avatar Creator, then close and re-open the Avatar App."
|
emptyInventoryContainer.visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.getValue("simplifiedUI/debugFTUE", 0) === 4) {
|
||||||
|
emptyInventoryContainer.visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
avatarAppInventoryModel.handlePage(result.status !== "success" && result.message, result);
|
avatarAppInventoryModel.handlePage(result.status !== "success" && result.message, result);
|
||||||
|
@ -140,8 +145,95 @@ Rectangle {
|
||||||
anchors.rightMargin: 24
|
anchors.rightMargin: 24
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: emptyInventoryContainer
|
||||||
|
visible: false
|
||||||
|
anchors.top: displayNameHeader.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
|
Flickable {
|
||||||
|
id: emptyInventoryFlickable
|
||||||
|
anchors.fill: parent
|
||||||
|
contentWidth: parent.width
|
||||||
|
contentHeight: emptyInventoryLayout.height
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: emptyInventoryLayout
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 26
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 26
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
HifiStylesUit.GraphikSemiBold {
|
||||||
|
text: "Stand out from the crowd!"
|
||||||
|
Layout.preferredWidth: parent.width
|
||||||
|
Layout.preferredHeight: paintedHeight
|
||||||
|
Layout.topMargin: 16
|
||||||
|
size: 28
|
||||||
|
color: simplifiedUI.colors.text.white
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
|
||||||
|
HifiStylesUit.GraphikRegular {
|
||||||
|
text: "Create your custom avatar."
|
||||||
|
Layout.preferredWidth: parent.width
|
||||||
|
Layout.preferredHeight: paintedHeight
|
||||||
|
Layout.topMargin: 2
|
||||||
|
size: 18
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
color: simplifiedUI.colors.text.white
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: avatarImage;
|
||||||
|
source: "images/avatarProfilePic.png"
|
||||||
|
Layout.preferredWidth: parent.width
|
||||||
|
Layout.preferredHeight: 450
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
mipmap: true
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
source: "images/qrCode.jpg"
|
||||||
|
Layout.preferredWidth: 190
|
||||||
|
Layout.preferredHeight: 190
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.topMargin: -160
|
||||||
|
mipmap: true
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
}
|
||||||
|
|
||||||
|
HifiStylesUit.GraphikSemiBold {
|
||||||
|
text: "Scan for Mobile App"
|
||||||
|
Layout.preferredWidth: parent.width
|
||||||
|
Layout.preferredHeight: paintedHeight
|
||||||
|
Layout.topMargin: 12
|
||||||
|
size: 28
|
||||||
|
color: simplifiedUI.colors.text.white
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SimplifiedControls.VerticalScrollBar {
|
||||||
|
parent: emptyInventoryFlickable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: avatarInfoTextContainer
|
id: avatarInfoTextContainer
|
||||||
|
visible: !emptyInventoryContainer.visible
|
||||||
width: parent.implicitWidth
|
width: parent.implicitWidth
|
||||||
height: childrenRect.height
|
height: childrenRect.height
|
||||||
anchors.top: displayNameHeader.bottom
|
anchors.top: displayNameHeader.bottom
|
||||||
|
@ -164,7 +256,7 @@ Rectangle {
|
||||||
id: yourAvatarsSubtitle
|
id: yourAvatarsSubtitle
|
||||||
text: "These are the avatars that you've created and uploaded via the Avatar Creator."
|
text: "These are the avatars that you've created and uploaded via the Avatar Creator."
|
||||||
width: parent.width
|
width: parent.width
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.Wrap
|
||||||
anchors.top: yourAvatarsTitle.bottom
|
anchors.top: yourAvatarsTitle.bottom
|
||||||
anchors.topMargin: 6
|
anchors.topMargin: 6
|
||||||
verticalAlignment: TextInput.AlignVCenter
|
verticalAlignment: TextInput.AlignVCenter
|
||||||
|
@ -208,9 +300,10 @@ Rectangle {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
visible: !emptyInventoryContainer.visible
|
||||||
|
|
||||||
AnimatedImage {
|
AnimatedImage {
|
||||||
visible: !inventoryContentsList.visible && !errorText.visible
|
visible: !(inventoryContentsList.visible || errorText.visible)
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: 72
|
width: 72
|
||||||
height: width
|
height: width
|
||||||
|
@ -271,6 +364,8 @@ Rectangle {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
root.avatarPreviewUrl = "../../images/defaultAvatar.svg";
|
||||||
}
|
}
|
||||||
|
|
||||||
function fromScript(message) {
|
function fromScript(message) {
|
||||||
|
|
After Width: | Height: | Size: 319 KiB |
After Width: | Height: | Size: 159 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 145 KiB |
After Width: | Height: | Size: 151 KiB |
After Width: | Height: | Size: 150 KiB |
After Width: | Height: | Size: 148 KiB |
After Width: | Height: | Size: 138 KiB |
After Width: | Height: | Size: 148 KiB |
|
@ -225,9 +225,9 @@ Flickable {
|
||||||
SimplifiedControls.RadioButton {
|
SimplifiedControls.RadioButton {
|
||||||
id: firstPerson
|
id: firstPerson
|
||||||
text: "First Person View"
|
text: "First Person View"
|
||||||
checked: Camera.mode === "first person"
|
checked: Camera.mode === "first person look at"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
Camera.mode = "first person"
|
Camera.mode = "first person look at"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ Flickable {
|
||||||
target: Camera
|
target: Camera
|
||||||
|
|
||||||
onModeUpdated: {
|
onModeUpdated: {
|
||||||
if (Camera.mode === "first person") {
|
if (Camera.mode === "first person look at") {
|
||||||
firstPerson.checked = true
|
firstPerson.checked = true
|
||||||
} else if (Camera.mode === "look at") {
|
} else if (Camera.mode === "look at") {
|
||||||
thirdPerson.checked = true
|
thirdPerson.checked = true
|
||||||
|
|
|
@ -54,8 +54,8 @@ Rectangle {
|
||||||
|
|
||||||
if ((MyAvatar.skeletonModelURL.indexOf("defaultAvatar") > -1 || MyAvatar.skeletonModelURL.indexOf("fst") === -1) &&
|
if ((MyAvatar.skeletonModelURL.indexOf("defaultAvatar") > -1 || MyAvatar.skeletonModelURL.indexOf("fst") === -1) &&
|
||||||
topBarInventoryModel.count > 0) {
|
topBarInventoryModel.count > 0) {
|
||||||
Settings.setValue("simplifiedUI/alreadyAutoSelectedAvatar", true);
|
Settings.setValue("simplifiedUI/alreadyAutoSelectedAvatarFromInventory", true);
|
||||||
MyAvatar.useFullAvatarURL = topBarInventoryModel.get(0).download_url;
|
MyAvatar.useFullAvatarURL(topBarInventoryModel.get(0).download_url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ Rectangle {
|
||||||
if (isLoggedIn) {
|
if (isLoggedIn) {
|
||||||
Commerce.getWalletStatus();
|
Commerce.getWalletStatus();
|
||||||
} else {
|
} else {
|
||||||
// Show some error to the user
|
// Show some error to the user in the UI?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,12 +113,68 @@ Rectangle {
|
||||||
topBarInventoryModel.getNextPage();
|
topBarInventoryModel.getNextPage();
|
||||||
} else {
|
} else {
|
||||||
inventoryFullyReceived = true;
|
inventoryFullyReceived = true;
|
||||||
|
var scriptExecutionCount = Settings.getValue("simplifiedUI/SUIScriptExecutionCount");
|
||||||
|
var currentAvatarURL = MyAvatar.skeletonModelURL;
|
||||||
|
var currentAvatarURLContainsDefaultAvatar = currentAvatarURL.indexOf("defaultAvatar") > -1;
|
||||||
|
var currentAvatarURLContainsFST = currentAvatarURL.indexOf("fst") > -1;
|
||||||
|
var currentAvatarURLContainsSimplifiedAvatar = currentAvatarURL.indexOf("simplifiedAvatar") > -1;
|
||||||
|
var alreadyAutoSelectedAvatarFromInventory = Settings.getValue("simplifiedUI/alreadyAutoSelectedAvatarFromInventory", false);
|
||||||
|
var userHasValidAvatarInInventory = topBarInventoryModel.count > 0 &&
|
||||||
|
topBarInventoryModel.get(0).download_url.indexOf(".fst") > -1;
|
||||||
|
var simplifiedAvatarPrefix = "https://content.highfidelity.com/Experiences/Releases/simplifiedUI/simplifiedFTUE/avatars/simplifiedAvatar_";
|
||||||
|
var simplifiedAvatarColors = ["Blue", "Cyan", "Green", "Magenta", "Red"];
|
||||||
|
var simplifiedAvatarSuffix = "/avatar.fst";
|
||||||
|
|
||||||
// If we have an avatar in our inventory AND we haven't already auto-selected an avatar...
|
// Use `Settings.setValue("simplifiedUI/debugFTUE", 0);` to turn off FTUE Debug Mode.
|
||||||
if ((!Settings.getValue("simplifiedUI/alreadyAutoSelectedAvatar", false) ||
|
// Use `Settings.setValue("simplifiedUI/debugFTUE", 1);` to debug FTUE Screen 1.
|
||||||
MyAvatar.skeletonModelURL.indexOf("defaultAvatar") > -1 || MyAvatar.skeletonModelURL.indexOf("fst") === -1) && topBarInventoryModel.count > 0) {
|
// Use `Settings.setValue("simplifiedUI/debugFTUE", 2);` to debug FTUE Screen 2.
|
||||||
Settings.setValue("simplifiedUI/alreadyAutoSelectedAvatar", true);
|
// Use `Settings.setValue("simplifiedUI/debugFTUE", 3);` to debug FTUE Screen 3.
|
||||||
MyAvatar.skeletonModelURL = topBarInventoryModel.get(0).download_url;
|
// Use `Settings.setValue("simplifiedUI/debugFTUE", 4);` to force the UI to show what would happen if the user had an empty Inventory.
|
||||||
|
|
||||||
|
var debugFTUE = Settings.getValue("simplifiedUI/debugFTUE", 0);
|
||||||
|
if (debugFTUE === 1 || debugFTUE === 2) {
|
||||||
|
scriptExecutionCount = 1;
|
||||||
|
currentAvatarURLContainsDefaultAvatar = true;
|
||||||
|
if (debugFTUE === 1) {
|
||||||
|
userHasValidAvatarInInventory = false;
|
||||||
|
currentAvatarURLContainsSimplifiedAvatar = false;
|
||||||
|
}
|
||||||
|
} else if (debugFTUE === 3) {
|
||||||
|
scriptExecutionCount = 2;
|
||||||
|
currentAvatarURLContainsDefaultAvatar = false;
|
||||||
|
currentAvatarURLContainsSimplifiedAvatar = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have never auto-selected and the user is still using a default avatar or if the current avatar is not valid (fst), or if
|
||||||
|
// the current avatar is the old default (Woody), use top avatar from inventory or one of the new defaults.
|
||||||
|
|
||||||
|
// If the current avatar URL is invalid, OR the user is using the "default avatar" (Woody)...
|
||||||
|
if (!currentAvatarURLContainsFST || currentAvatarURLContainsDefaultAvatar) {
|
||||||
|
// If the user has a valid avatar in their inventory...
|
||||||
|
if (userHasValidAvatarInInventory) {
|
||||||
|
// ...use the first avatar in the user's inventory.
|
||||||
|
MyAvatar.useFullAvatarURL(topBarInventoryModel.get(0).download_url);
|
||||||
|
Settings.setValue("simplifiedUI/alreadyAutoSelectedAvatarFromInventory", true);
|
||||||
|
// Else if the user isn't wearing a "Simplified Avatar"
|
||||||
|
} else if (!currentAvatarURLContainsSimplifiedAvatar) {
|
||||||
|
// ...assign to the user a new "Simplified Avatar" (i.e. a simple avatar of random color)
|
||||||
|
var avatarColor = simplifiedAvatarColors[Math.floor(Math.random() * simplifiedAvatarColors.length)];
|
||||||
|
var simplifiedAvatarModelURL = simplifiedAvatarPrefix + avatarColor + simplifiedAvatarSuffix;
|
||||||
|
MyAvatar.useFullAvatarURL(simplifiedAvatarModelURL);
|
||||||
|
currentAvatarURLContainsSimplifiedAvatar = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scriptExecutionCount === 1) {
|
||||||
|
sendToScript({
|
||||||
|
"source": "SimplifiedTopBar.qml",
|
||||||
|
"method": "displayInitialLaunchWindow"
|
||||||
|
});
|
||||||
|
} else if (scriptExecutionCount === 2 && currentAvatarURLContainsSimplifiedAvatar) {
|
||||||
|
sendToScript({
|
||||||
|
"source": "SimplifiedTopBar.qml",
|
||||||
|
"method": "displaySecondLaunchWindow"
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -373,7 +429,7 @@ Rectangle {
|
||||||
SimplifiedControls.TextField {
|
SimplifiedControls.TextField {
|
||||||
id: goToTextField
|
id: goToTextField
|
||||||
readonly property string shortPlaceholderText: "Jump to..."
|
readonly property string shortPlaceholderText: "Jump to..."
|
||||||
readonly property string longPlaceholderText: "Type the name of a location to quickly jump there..."
|
readonly property string longPlaceholderText: "Quickly jump to a location by typing '/LocationName'"
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: Math.min(parent.width, 445)
|
width: Math.min(parent.width, 445)
|
||||||
height: 35
|
height: 35
|
||||||
|
@ -384,6 +440,7 @@ Rectangle {
|
||||||
placeholderTextColor: "#8E8E8E"
|
placeholderTextColor: "#8E8E8E"
|
||||||
font.pixelSize: 14
|
font.pixelSize: 14
|
||||||
placeholderText: width - leftPadding - rightPadding < goToTextFieldMetrics.width ? shortPlaceholderText : longPlaceholderText
|
placeholderText: width - leftPadding - rightPadding < goToTextFieldMetrics.width ? shortPlaceholderText : longPlaceholderText
|
||||||
|
blankPlaceholderTextOnFocus: false
|
||||||
clip: true
|
clip: true
|
||||||
selectByMouse: true
|
selectByMouse: true
|
||||||
autoScroll: true
|
autoScroll: true
|
||||||
|
@ -569,6 +626,8 @@ Rectangle {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
avatarButtonImage.source = "../images/defaultAvatar.svg";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -718,6 +718,7 @@ private:
|
||||||
static const QString STATE_IN_HMD = "InHMD";
|
static const QString STATE_IN_HMD = "InHMD";
|
||||||
static const QString STATE_CAMERA_FULL_SCREEN_MIRROR = "CameraFSM";
|
static const QString STATE_CAMERA_FULL_SCREEN_MIRROR = "CameraFSM";
|
||||||
static const QString STATE_CAMERA_FIRST_PERSON = "CameraFirstPerson";
|
static const QString STATE_CAMERA_FIRST_PERSON = "CameraFirstPerson";
|
||||||
|
static const QString STATE_CAMERA_FIRST_PERSON_LOOK_AT = "CameraFirstPersonLookat";
|
||||||
static const QString STATE_CAMERA_THIRD_PERSON = "CameraThirdPerson";
|
static const QString STATE_CAMERA_THIRD_PERSON = "CameraThirdPerson";
|
||||||
static const QString STATE_CAMERA_ENTITY = "CameraEntity";
|
static const QString STATE_CAMERA_ENTITY = "CameraEntity";
|
||||||
static const QString STATE_CAMERA_INDEPENDENT = "CameraIndependent";
|
static const QString STATE_CAMERA_INDEPENDENT = "CameraIndependent";
|
||||||
|
@ -939,7 +940,8 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
|
||||||
DependencyManager::set<AudioInjectorManager>();
|
DependencyManager::set<AudioInjectorManager>();
|
||||||
DependencyManager::set<MessagesClient>();
|
DependencyManager::set<MessagesClient>();
|
||||||
controller::StateController::setStateVariables({ { STATE_IN_HMD, STATE_CAMERA_FULL_SCREEN_MIRROR,
|
controller::StateController::setStateVariables({ { STATE_IN_HMD, STATE_CAMERA_FULL_SCREEN_MIRROR,
|
||||||
STATE_CAMERA_FIRST_PERSON, STATE_CAMERA_THIRD_PERSON, STATE_CAMERA_ENTITY, STATE_CAMERA_INDEPENDENT, STATE_CAMERA_LOOK_AT, STATE_CAMERA_SELFIE,
|
STATE_CAMERA_FIRST_PERSON, STATE_CAMERA_FIRST_PERSON_LOOK_AT, STATE_CAMERA_THIRD_PERSON,
|
||||||
|
STATE_CAMERA_ENTITY, STATE_CAMERA_INDEPENDENT, STATE_CAMERA_LOOK_AT, STATE_CAMERA_SELFIE,
|
||||||
STATE_SNAP_TURN, STATE_ADVANCED_MOVEMENT_CONTROLS, STATE_GROUNDED, STATE_NAV_FOCUSED,
|
STATE_SNAP_TURN, STATE_ADVANCED_MOVEMENT_CONTROLS, STATE_GROUNDED, STATE_NAV_FOCUSED,
|
||||||
STATE_PLATFORM_WINDOWS, STATE_PLATFORM_MAC, STATE_PLATFORM_ANDROID, STATE_LEFT_HAND_DOMINANT, STATE_RIGHT_HAND_DOMINANT, STATE_STRAFE_ENABLED } });
|
STATE_PLATFORM_WINDOWS, STATE_PLATFORM_MAC, STATE_PLATFORM_ANDROID, STATE_LEFT_HAND_DOMINANT, STATE_RIGHT_HAND_DOMINANT, STATE_STRAFE_ENABLED } });
|
||||||
DependencyManager::set<UserInputMapper>();
|
DependencyManager::set<UserInputMapper>();
|
||||||
|
@ -974,6 +976,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
|
||||||
|
|
||||||
QObject::connect(PlatformHelper::instance(), &PlatformHelper::systemWillWake, [] {
|
QObject::connect(PlatformHelper::instance(), &PlatformHelper::systemWillWake, [] {
|
||||||
QMetaObject::invokeMethod(DependencyManager::get<NodeList>().data(), "noteAwakening", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(DependencyManager::get<NodeList>().data(), "noteAwakening", Qt::QueuedConnection);
|
||||||
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "noteAwakening", Qt::QueuedConnection);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -1886,6 +1889,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
_applicationStateDevice->setInputVariant(STATE_CAMERA_FIRST_PERSON, []() -> float {
|
_applicationStateDevice->setInputVariant(STATE_CAMERA_FIRST_PERSON, []() -> float {
|
||||||
return qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON ? 1 : 0;
|
return qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON ? 1 : 0;
|
||||||
});
|
});
|
||||||
|
_applicationStateDevice->setInputVariant(STATE_CAMERA_FIRST_PERSON_LOOK_AT, []() -> float {
|
||||||
|
return qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON_LOOK_AT ? 1 : 0;
|
||||||
|
});
|
||||||
_applicationStateDevice->setInputVariant(STATE_CAMERA_THIRD_PERSON, []() -> float {
|
_applicationStateDevice->setInputVariant(STATE_CAMERA_THIRD_PERSON, []() -> float {
|
||||||
return qApp->getCamera().getMode() == CAMERA_MODE_THIRD_PERSON ? 1 : 0;
|
return qApp->getCamera().getMode() == CAMERA_MODE_THIRD_PERSON ? 1 : 0;
|
||||||
});
|
});
|
||||||
|
@ -1995,7 +2001,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
settingsTimer->start();
|
settingsTimer->start();
|
||||||
}, QThread::LowestPriority);
|
}, QThread::LowestPriority);
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPersonLookAt)) {
|
||||||
getMyAvatar()->setBoomLength(MyAvatar::ZOOM_MIN); // So that camera doesn't auto-switch to third person.
|
getMyAvatar()->setBoomLength(MyAvatar::ZOOM_MIN); // So that camera doesn't auto-switch to third person.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2958,13 +2964,29 @@ Application::~Application() {
|
||||||
qInstallMessageHandler(LogHandler::verboseMessageHandler);
|
qInstallMessageHandler(LogHandler::verboseMessageHandler);
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
|
// 10/16/2019 - Disabling this call. This causes known crashes (A), and it is not
|
||||||
|
// fully understood whether it might cause other unknown crashes (B).
|
||||||
|
//
|
||||||
|
// (A) Although we try to shutdown the ScriptEngine threads in onAboutToQuit, there is
|
||||||
|
// currently no guarantee that they have stopped. Waiting on them to stop has so far appeared to
|
||||||
|
// never return on Mac, causing the application to hang on shutdown. Because ScriptEngines
|
||||||
|
// may still be running, they may end up receiving events that are triggered from this processEvents call,
|
||||||
|
// and then try to access resources that are no longer available at this point in time.
|
||||||
|
// If the ScriptEngine threads were fully destroyed before getting here, this would
|
||||||
|
// not be an issue.
|
||||||
|
//
|
||||||
|
// (B) It seems likely that a bunch of potential event handlers are dependent on Application
|
||||||
|
// and other common dependencies to be available and not destroyed or in the middle of being
|
||||||
|
// destroyed.
|
||||||
|
|
||||||
|
|
||||||
// Clear the event queue before application is totally destructed.
|
// Clear the event queue before application is totally destructed.
|
||||||
// This will drain the messasge queue of pending "deleteLaters" queued up
|
// This will drain the messasge queue of pending "deleteLaters" queued up
|
||||||
// during shutdown of the script engines.
|
// during shutdown of the script engines.
|
||||||
// We do this here because there is a possiblty that [NSApplication terminate:]
|
// We do this here because there is a possiblty that [NSApplication terminate:]
|
||||||
// will be called during processEvents which will invoke all static destructors.
|
// will be called during processEvents which will invoke all static destructors.
|
||||||
// We want to postpone this utill the last possible moment.
|
// We want to postpone this utill the last possible moment.
|
||||||
QCoreApplication::processEvents();
|
//QCoreApplication::processEvents();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3610,14 +3632,17 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) {
|
||||||
// Using the latter will cause the camera to wobble with idle animations,
|
// Using the latter will cause the camera to wobble with idle animations,
|
||||||
// or with changes from the face tracker
|
// or with changes from the face tracker
|
||||||
CameraMode mode = _myCamera.getMode();
|
CameraMode mode = _myCamera.getMode();
|
||||||
if (mode == CAMERA_MODE_FIRST_PERSON) {
|
if (mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT) {
|
||||||
_thirdPersonHMDCameraBoomValid= false;
|
_thirdPersonHMDCameraBoomValid= false;
|
||||||
if (isHMDMode()) {
|
if (isHMDMode()) {
|
||||||
mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
|
mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
|
||||||
_myCamera.setPosition(extractTranslation(camMat));
|
_myCamera.setPosition(extractTranslation(camMat));
|
||||||
_myCamera.setOrientation(glmExtractRotation(camMat));
|
_myCamera.setOrientation(glmExtractRotation(camMat));
|
||||||
|
} else if (mode == CAMERA_MODE_FIRST_PERSON) {
|
||||||
|
_myCamera.setPosition(myAvatar->getDefaultEyePosition());
|
||||||
|
_myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation());
|
||||||
} else {
|
} else {
|
||||||
_myCamera.setPosition(myAvatar->getLookAtPivotPoint());
|
_myCamera.setPosition(myAvatar->getCameraEyesPosition(deltaTime));
|
||||||
_myCamera.setOrientation(myAvatar->getLookAtRotation());
|
_myCamera.setOrientation(myAvatar->getLookAtRotation());
|
||||||
}
|
}
|
||||||
} else if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) {
|
} else if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) {
|
||||||
|
@ -4406,7 +4431,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
|
|
||||||
case Qt::Key_1: {
|
case Qt::Key_1: {
|
||||||
Menu* menu = Menu::getInstance();
|
Menu* menu = Menu::getInstance();
|
||||||
menu->triggerOption(MenuOption::FirstPerson);
|
menu->triggerOption(MenuOption::FirstPersonLookAt);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Qt::Key_2: {
|
case Qt::Key_2: {
|
||||||
|
@ -5491,7 +5516,7 @@ void Application::loadSettings() {
|
||||||
isFirstPerson = menu->isOptionChecked(MenuOption::FirstPersonHMD);
|
isFirstPerson = menu->isOptionChecked(MenuOption::FirstPersonHMD);
|
||||||
} else {
|
} else {
|
||||||
// if HMD is not active, only use first person if the menu option is checked
|
// if HMD is not active, only use first person if the menu option is checked
|
||||||
isFirstPerson = menu->isOptionChecked(MenuOption::FirstPerson);
|
isFirstPerson = menu->isOptionChecked(MenuOption::FirstPersonLookAt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5506,9 +5531,9 @@ void Application::loadSettings() {
|
||||||
|
|
||||||
// finish initializing the camera, based on everything we checked above. Third person camera will be used if no settings
|
// finish initializing the camera, based on everything we checked above. Third person camera will be used if no settings
|
||||||
// dictated that we should be in first person
|
// dictated that we should be in first person
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, isFirstPerson);
|
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPersonLookAt, isFirstPerson);
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !isFirstPerson);
|
Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !isFirstPerson);
|
||||||
_myCamera.setMode((isFirstPerson) ? CAMERA_MODE_FIRST_PERSON : CAMERA_MODE_LOOK_AT);
|
_myCamera.setMode((isFirstPerson) ? CAMERA_MODE_FIRST_PERSON_LOOK_AT : CAMERA_MODE_LOOK_AT);
|
||||||
cameraMenuChanged();
|
cameraMenuChanged();
|
||||||
|
|
||||||
auto inputs = pluginManager->getInputPlugins();
|
auto inputs = pluginManager->getInputPlugins();
|
||||||
|
@ -5672,7 +5697,7 @@ void Application::pauseUntilLoginDetermined() {
|
||||||
menu->getMenu("Developer")->setVisible(false);
|
menu->getMenu("Developer")->setVisible(false);
|
||||||
}
|
}
|
||||||
_previousCameraMode = _myCamera.getMode();
|
_previousCameraMode = _myCamera.getMode();
|
||||||
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
|
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON_LOOK_AT);
|
||||||
cameraModeChanged();
|
cameraModeChanged();
|
||||||
|
|
||||||
// disconnect domain handler.
|
// disconnect domain handler.
|
||||||
|
@ -5861,11 +5886,11 @@ void Application::cycleCamera() {
|
||||||
if (menu->isOptionChecked(MenuOption::FullscreenMirror)) {
|
if (menu->isOptionChecked(MenuOption::FullscreenMirror)) {
|
||||||
|
|
||||||
menu->setIsOptionChecked(MenuOption::FullscreenMirror, false);
|
menu->setIsOptionChecked(MenuOption::FullscreenMirror, false);
|
||||||
menu->setIsOptionChecked(MenuOption::FirstPerson, true);
|
menu->setIsOptionChecked(MenuOption::FirstPersonLookAt, true);
|
||||||
|
|
||||||
} else if (menu->isOptionChecked(MenuOption::FirstPerson)) {
|
} else if (menu->isOptionChecked(MenuOption::FirstPersonLookAt)) {
|
||||||
|
|
||||||
menu->setIsOptionChecked(MenuOption::FirstPerson, false);
|
menu->setIsOptionChecked(MenuOption::FirstPersonLookAt, false);
|
||||||
menu->setIsOptionChecked(MenuOption::LookAtCamera, true);
|
menu->setIsOptionChecked(MenuOption::LookAtCamera, true);
|
||||||
|
|
||||||
} else if (menu->isOptionChecked(MenuOption::LookAtCamera)) {
|
} else if (menu->isOptionChecked(MenuOption::LookAtCamera)) {
|
||||||
|
@ -5884,8 +5909,8 @@ void Application::cycleCamera() {
|
||||||
|
|
||||||
void Application::cameraModeChanged() {
|
void Application::cameraModeChanged() {
|
||||||
switch (_myCamera.getMode()) {
|
switch (_myCamera.getMode()) {
|
||||||
case CAMERA_MODE_FIRST_PERSON:
|
case CAMERA_MODE_FIRST_PERSON_LOOK_AT:
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, true);
|
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPersonLookAt, true);
|
||||||
break;
|
break;
|
||||||
case CAMERA_MODE_LOOK_AT:
|
case CAMERA_MODE_LOOK_AT:
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::LookAtCamera, true);
|
Menu::getInstance()->setIsOptionChecked(MenuOption::LookAtCamera, true);
|
||||||
|
@ -5905,12 +5930,12 @@ void Application::changeViewAsNeeded(float boomLength) {
|
||||||
// This is called when the boom length has changed
|
// This is called when the boom length has changed
|
||||||
bool boomLengthGreaterThanMinimum = (boomLength > MyAvatar::ZOOM_MIN);
|
bool boomLengthGreaterThanMinimum = (boomLength > MyAvatar::ZOOM_MIN);
|
||||||
|
|
||||||
if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON && boomLengthGreaterThanMinimum) {
|
if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON_LOOK_AT && boomLengthGreaterThanMinimum) {
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, false);
|
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPersonLookAt, false);
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::LookAtCamera, true);
|
Menu::getInstance()->setIsOptionChecked(MenuOption::LookAtCamera, true);
|
||||||
cameraMenuChanged();
|
cameraMenuChanged();
|
||||||
} else if (_myCamera.getMode() == CAMERA_MODE_LOOK_AT && !boomLengthGreaterThanMinimum) {
|
} else if (_myCamera.getMode() == CAMERA_MODE_LOOK_AT && !boomLengthGreaterThanMinimum) {
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, true);
|
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPersonLookAt, true);
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::LookAtCamera, false);
|
Menu::getInstance()->setIsOptionChecked(MenuOption::LookAtCamera, false);
|
||||||
cameraMenuChanged();
|
cameraMenuChanged();
|
||||||
}
|
}
|
||||||
|
@ -5918,9 +5943,9 @@ void Application::changeViewAsNeeded(float boomLength) {
|
||||||
|
|
||||||
void Application::cameraMenuChanged() {
|
void Application::cameraMenuChanged() {
|
||||||
auto menu = Menu::getInstance();
|
auto menu = Menu::getInstance();
|
||||||
if (menu->isOptionChecked(MenuOption::FirstPerson)) {
|
if (menu->isOptionChecked(MenuOption::FirstPersonLookAt)) {
|
||||||
if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) {
|
if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON_LOOK_AT) {
|
||||||
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
|
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON_LOOK_AT);
|
||||||
getMyAvatar()->setBoomLength(MyAvatar::ZOOM_MIN);
|
getMyAvatar()->setBoomLength(MyAvatar::ZOOM_MIN);
|
||||||
}
|
}
|
||||||
} else if (menu->isOptionChecked(MenuOption::LookAtCamera)) {
|
} else if (menu->isOptionChecked(MenuOption::LookAtCamera)) {
|
||||||
|
@ -9021,7 +9046,7 @@ void Application::setDisplayPlugin(DisplayPluginPointer newDisplayPlugin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isHmd && menu->isOptionChecked(MenuOption::FirstPersonHMD)) {
|
if (isHmd && menu->isOptionChecked(MenuOption::FirstPersonHMD)) {
|
||||||
menu->setIsOptionChecked(MenuOption::FirstPerson, true);
|
menu->setIsOptionChecked(MenuOption::FirstPersonLookAt, true);
|
||||||
cameraMenuChanged();
|
cameraMenuChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -172,7 +172,7 @@ Menu::Menu() {
|
||||||
|
|
||||||
// View > First Person
|
// View > First Person
|
||||||
auto firstPersonAction = cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash(
|
auto firstPersonAction = cameraModeGroup->addAction(addCheckableActionToQMenuAndActionHash(
|
||||||
viewMenu, MenuOption::FirstPerson, 0,
|
viewMenu, MenuOption::FirstPersonLookAt, 0,
|
||||||
true, qApp, SLOT(cameraMenuChanged())));
|
true, qApp, SLOT(cameraMenuChanged())));
|
||||||
|
|
||||||
firstPersonAction->setProperty(EXCLUSION_GROUP_KEY, QVariant::fromValue(cameraModeGroup));
|
firstPersonAction->setProperty(EXCLUSION_GROUP_KEY, QVariant::fromValue(cameraModeGroup));
|
||||||
|
@ -640,11 +640,6 @@ Menu::Menu() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Developer >> Tests >>>
|
|
||||||
MenuWrapper* testMenu = developerMenu->addMenu("Tests");
|
|
||||||
addActionToQMenuAndActionHash(testMenu, MenuOption::RunClientScriptTests, 0, dialogsManager.data(), SLOT(showTestingResults()));
|
|
||||||
|
|
||||||
// Developer > Timing >>>
|
// Developer > Timing >>>
|
||||||
MenuWrapper* timingMenu = developerMenu->addMenu("Timing");
|
MenuWrapper* timingMenu = developerMenu->addMenu("Timing");
|
||||||
MenuWrapper* perfTimerMenu = timingMenu->addMenu("Performance Timer");
|
MenuWrapper* perfTimerMenu = timingMenu->addMenu("Performance Timer");
|
||||||
|
|
|
@ -111,7 +111,8 @@ namespace MenuOption {
|
||||||
const QString ExpandSimulationTiming = "Expand /simulation";
|
const QString ExpandSimulationTiming = "Expand /simulation";
|
||||||
const QString ExpandPhysicsTiming = "Expand /physics";
|
const QString ExpandPhysicsTiming = "Expand /physics";
|
||||||
const QString ExpandUpdateTiming = "Expand /update";
|
const QString ExpandUpdateTiming = "Expand /update";
|
||||||
const QString FirstPerson = "First Person";
|
const QString FirstPerson = "First Person Legacy";
|
||||||
|
const QString FirstPersonLookAt = "First Person";
|
||||||
const QString FirstPersonHMD = "Enter First Person Mode in HMD";
|
const QString FirstPersonHMD = "Enter First Person Mode in HMD";
|
||||||
const QString FivePointCalibration = "5 Point Calibration";
|
const QString FivePointCalibration = "5 Point Calibration";
|
||||||
const QString FixGaze = "Fix Gaze (no saccade)";
|
const QString FixGaze = "Fix Gaze (no saccade)";
|
||||||
|
@ -178,7 +179,6 @@ namespace MenuOption {
|
||||||
const QString ResetAvatarSize = "Reset Avatar Size";
|
const QString ResetAvatarSize = "Reset Avatar Size";
|
||||||
const QString ResetSensors = "Reset Sensors";
|
const QString ResetSensors = "Reset Sensors";
|
||||||
const QString RunningScripts = "Running Scripts...";
|
const QString RunningScripts = "Running Scripts...";
|
||||||
const QString RunClientScriptTests = "Run Client Script Tests";
|
|
||||||
const QString RunTimingTests = "Run Timing Tests";
|
const QString RunTimingTests = "Run Timing Tests";
|
||||||
const QString ScriptedMotorControl = "Enable Scripted Motor Control";
|
const QString ScriptedMotorControl = "Enable Scripted Motor Control";
|
||||||
const QString ShowTrackedObjects = "Show Tracked Objects";
|
const QString ShowTrackedObjects = "Show Tracked Objects";
|
||||||
|
|
|
@ -152,7 +152,7 @@ static int triggerReactionNameToIndex(const QString& reactionName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int beginEndReactionNameToIndex(const QString& reactionName) {
|
static int beginEndReactionNameToIndex(const QString& reactionName) {
|
||||||
assert(NUM_AVATAR_BEGIN_END_REACTIONS == TRIGGER_REACTION_NAMES.size());
|
assert(NUM_AVATAR_BEGIN_END_REACTIONS == BEGIN_END_REACTION_NAMES.size());
|
||||||
return BEGIN_END_REACTION_NAMES.indexOf(reactionName);
|
return BEGIN_END_REACTION_NAMES.indexOf(reactionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -958,7 +958,8 @@ void MyAvatar::simulate(float deltaTime, bool inView) {
|
||||||
head->setScale(getModelScale());
|
head->setScale(getModelScale());
|
||||||
head->simulate(deltaTime);
|
head->simulate(deltaTime);
|
||||||
CameraMode mode = qApp->getCamera().getMode();
|
CameraMode mode = qApp->getCamera().getMode();
|
||||||
if (_scriptControlsHeadLookAt || mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) {
|
if (_scriptControlsHeadLookAt || mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT || mode == CAMERA_MODE_FIRST_PERSON ||
|
||||||
|
mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) {
|
||||||
if (!_pointAtActive || !_isPointTargetValid) {
|
if (!_pointAtActive || !_isPointTargetValid) {
|
||||||
updateHeadLookAt(deltaTime);
|
updateHeadLookAt(deltaTime);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2178,7 +2179,7 @@ void MyAvatar::computeMyLookAtTarget(const AvatarHash& hash) {
|
||||||
glm::vec3 myForward = _lookAtYaw * IDENTITY_FORWARD;
|
glm::vec3 myForward = _lookAtYaw * IDENTITY_FORWARD;
|
||||||
glm::vec3 myPosition = getHead()->getEyePosition();
|
glm::vec3 myPosition = getHead()->getEyePosition();
|
||||||
CameraMode mode = qApp->getCamera().getMode();
|
CameraMode mode = qApp->getCamera().getMode();
|
||||||
if (mode == CAMERA_MODE_FIRST_PERSON) {
|
if (mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT || mode == CAMERA_MODE_FIRST_PERSON) {
|
||||||
myPosition = qApp->getCamera().getPosition();
|
myPosition = qApp->getCamera().getPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2719,7 +2720,7 @@ void MyAvatar::updateMotors() {
|
||||||
if (_characterController.getState() == CharacterController::State::Hover ||
|
if (_characterController.getState() == CharacterController::State::Hover ||
|
||||||
_characterController.computeCollisionMask() == BULLET_COLLISION_MASK_COLLISIONLESS) {
|
_characterController.computeCollisionMask() == BULLET_COLLISION_MASK_COLLISIONLESS) {
|
||||||
CameraMode mode = qApp->getCamera().getMode();
|
CameraMode mode = qApp->getCamera().getMode();
|
||||||
if (mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE) {
|
if (!qApp->isHMDMode() && (mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE)) {
|
||||||
motorRotation = getLookAtRotation();
|
motorRotation = getLookAtRotation();
|
||||||
} else {
|
} else {
|
||||||
motorRotation = getMyHead()->getHeadOrientation();
|
motorRotation = getMyHead()->getHeadOrientation();
|
||||||
|
@ -3399,7 +3400,8 @@ bool MyAvatar::cameraInsideHead(const glm::vec3& cameraPosition) const {
|
||||||
|
|
||||||
bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const {
|
bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const {
|
||||||
bool defaultMode = renderArgs->_renderMode == RenderArgs::DEFAULT_RENDER_MODE;
|
bool defaultMode = renderArgs->_renderMode == RenderArgs::DEFAULT_RENDER_MODE;
|
||||||
bool firstPerson = qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON;
|
bool firstPerson = qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON_LOOK_AT ||
|
||||||
|
qApp->getCamera().getMode() == CAMERA_MODE_FIRST_PERSON;
|
||||||
bool overrideAnim = _skeletonModel ? _skeletonModel->getRig().isPlayingOverrideAnimation() : false;
|
bool overrideAnim = _skeletonModel ? _skeletonModel->getRig().isPlayingOverrideAnimation() : false;
|
||||||
bool insideHead = cameraInsideHead(renderArgs->getViewFrustum().getPosition());
|
bool insideHead = cameraInsideHead(renderArgs->getViewFrustum().getPosition());
|
||||||
return !defaultMode || (!firstPerson && !insideHead) || (overrideAnim && !insideHead);
|
return !defaultMode || (!firstPerson && !insideHead) || (overrideAnim && !insideHead);
|
||||||
|
@ -3444,8 +3446,8 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
||||||
float targetSpeed = getDriveKey(YAW) * _yawSpeed;
|
float targetSpeed = getDriveKey(YAW) * _yawSpeed;
|
||||||
CameraMode mode = qApp->getCamera().getMode();
|
CameraMode mode = qApp->getCamera().getMode();
|
||||||
bool computeLookAt = isReadyForPhysics() && !qApp->isHMDMode() &&
|
bool computeLookAt = isReadyForPhysics() && !qApp->isHMDMode() &&
|
||||||
(mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE);
|
(mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE);
|
||||||
bool smoothCameraYaw = computeLookAt && mode != CAMERA_MODE_FIRST_PERSON;
|
bool smoothCameraYaw = computeLookAt && mode != CAMERA_MODE_FIRST_PERSON_LOOK_AT;
|
||||||
if (smoothCameraYaw) {
|
if (smoothCameraYaw) {
|
||||||
// For "Look At" and "Selfie" camera modes we also smooth the yaw rotation from right-click mouse movement.
|
// For "Look At" and "Selfie" camera modes we also smooth the yaw rotation from right-click mouse movement.
|
||||||
float speedFromDeltaYaw = deltaTime > FLT_EPSILON ? getDriveKey(DELTA_YAW) / deltaTime : 0.0f;
|
float speedFromDeltaYaw = deltaTime > FLT_EPSILON ? getDriveKey(DELTA_YAW) / deltaTime : 0.0f;
|
||||||
|
@ -3569,11 +3571,11 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
||||||
if (isMovingFwdBwd) {
|
if (isMovingFwdBwd) {
|
||||||
if (isMovingSideways) {
|
if (isMovingSideways) {
|
||||||
// Reorient avatar to face camera diagonal
|
// Reorient avatar to face camera diagonal
|
||||||
blend = mode == CAMERA_MODE_FIRST_PERSON ? 1.0f : DIAGONAL_TURN_BLEND;
|
blend = mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT ? 1.0f : DIAGONAL_TURN_BLEND;
|
||||||
float turnSign = getDriveKey(TRANSLATE_Z) < 0.0f ? -1.0f : 1.0f;
|
float turnSign = getDriveKey(TRANSLATE_Z) < 0.0f ? -1.0f : 1.0f;
|
||||||
turnSign = getDriveKey(TRANSLATE_X) > 0.0f ? -turnSign : turnSign;
|
turnSign = getDriveKey(TRANSLATE_X) > 0.0f ? -turnSign : turnSign;
|
||||||
faceRotation = _lookAtYaw * glm::angleAxis(turnSign * 0.25f * PI, Vectors::UP);
|
faceRotation = _lookAtYaw * glm::angleAxis(turnSign * 0.25f * PI, Vectors::UP);
|
||||||
} else if (mode == CAMERA_MODE_FIRST_PERSON) {
|
} else if (mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT) {
|
||||||
blend = 1.0f;
|
blend = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3644,11 +3646,11 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
||||||
glm::vec3 ajustedYawVector = cameraYawVector;
|
glm::vec3 ajustedYawVector = cameraYawVector;
|
||||||
float limitAngle = 0.0f;
|
float limitAngle = 0.0f;
|
||||||
float triggerAngle = -glm::sin(glm::radians(TRIGGER_REORIENT_ANGLE));
|
float triggerAngle = -glm::sin(glm::radians(TRIGGER_REORIENT_ANGLE));
|
||||||
if (mode == CAMERA_MODE_FIRST_PERSON) {
|
if (mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT) {
|
||||||
limitAngle = glm::sin(glm::radians(90.0f - FIRST_PERSON_TRIGGER_REORIENT_ANGLE));
|
limitAngle = glm::sin(glm::radians(90.0f - FIRST_PERSON_TRIGGER_REORIENT_ANGLE));
|
||||||
triggerAngle = limitAngle;
|
triggerAngle = limitAngle;
|
||||||
}
|
}
|
||||||
float reorientAngle = mode == CAMERA_MODE_FIRST_PERSON ? FIRST_PERSON_REORIENT_ANGLE : DEFAULT_REORIENT_ANGLE;
|
float reorientAngle = mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT ? FIRST_PERSON_REORIENT_ANGLE : DEFAULT_REORIENT_ANGLE;
|
||||||
if (frontBackDot < limitAngle) {
|
if (frontBackDot < limitAngle) {
|
||||||
if (frontBackDot < 0.0f) {
|
if (frontBackDot < 0.0f) {
|
||||||
ajustedYawVector = (leftRightDot < 0.0f ? -avatarVectorRight : avatarVectorRight);
|
ajustedYawVector = (leftRightDot < 0.0f ? -avatarVectorRight : avatarVectorRight);
|
||||||
|
@ -3684,7 +3686,7 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
||||||
}
|
}
|
||||||
_headLookAtActive = true;
|
_headLookAtActive = true;
|
||||||
const float FIRST_PERSON_RECENTER_SECONDS = 15.0f;
|
const float FIRST_PERSON_RECENTER_SECONDS = 15.0f;
|
||||||
if (mode == CAMERA_MODE_FIRST_PERSON) {
|
if (mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT) {
|
||||||
if (getDriveKey(YAW) + getDriveKey(STEP_YAW) + getDriveKey(DELTA_YAW) == 0.0f) {
|
if (getDriveKey(YAW) + getDriveKey(STEP_YAW) + getDriveKey(DELTA_YAW) == 0.0f) {
|
||||||
if (_firstPersonSteadyHeadTimer < FIRST_PERSON_RECENTER_SECONDS) {
|
if (_firstPersonSteadyHeadTimer < FIRST_PERSON_RECENTER_SECONDS) {
|
||||||
if (_firstPersonSteadyHeadTimer > 0.0f) {
|
if (_firstPersonSteadyHeadTimer > 0.0f) {
|
||||||
|
@ -3772,7 +3774,7 @@ glm::vec3 MyAvatar::scaleMotorSpeed(const glm::vec3 forward, const glm::vec3 rig
|
||||||
// Desktop mode.
|
// Desktop mode.
|
||||||
direction = (zSpeed * forward) + (xSpeed * right);
|
direction = (zSpeed * forward) + (xSpeed * right);
|
||||||
CameraMode mode = qApp->getCamera().getMode();
|
CameraMode mode = qApp->getCamera().getMode();
|
||||||
if ((mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_SELFIE) &&
|
if ((mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT || mode == CAMERA_MODE_SELFIE) &&
|
||||||
zSpeed != 0.0f && xSpeed != 0.0f && !isFlying()){
|
zSpeed != 0.0f && xSpeed != 0.0f && !isFlying()){
|
||||||
direction = (zSpeed * forward);
|
direction = (zSpeed * forward);
|
||||||
}
|
}
|
||||||
|
@ -5437,7 +5439,7 @@ glm::quat MyAvatar::getOrientationForAudio() {
|
||||||
case AudioListenerMode::FROM_HEAD: {
|
case AudioListenerMode::FROM_HEAD: {
|
||||||
// Using the camera's orientation instead, when the current mode is controlling the avatar's head.
|
// Using the camera's orientation instead, when the current mode is controlling the avatar's head.
|
||||||
CameraMode mode = qApp->getCamera().getMode();
|
CameraMode mode = qApp->getCamera().getMode();
|
||||||
bool headFollowsCamera = mode == CAMERA_MODE_FIRST_PERSON || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE;
|
bool headFollowsCamera = mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT || mode == CAMERA_MODE_LOOK_AT || mode == CAMERA_MODE_SELFIE;
|
||||||
result = headFollowsCamera ? qApp->getCamera().getOrientation() : getHead()->getFinalOrientationInWorldFrame();
|
result = headFollowsCamera ? qApp->getCamera().getOrientation() : getHead()->getFinalOrientationInWorldFrame();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -6812,6 +6814,66 @@ glm::vec3 MyAvatar::getLookAtPivotPoint() {
|
||||||
return yAxisEyePosition;
|
return yAxisEyePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 MyAvatar::getCameraEyesPosition(float deltaTime) {
|
||||||
|
glm::vec3 defaultEyesPosition = getLookAtPivotPoint();
|
||||||
|
if (isFlying()) {
|
||||||
|
return defaultEyesPosition;
|
||||||
|
}
|
||||||
|
glm::vec3 avatarFrontVector = getWorldOrientation() * Vectors::FRONT;
|
||||||
|
glm::vec3 avatarUpVector = getWorldOrientation() * Vectors::UP;
|
||||||
|
// Compute the offset between the default and real eye positions.
|
||||||
|
glm::vec3 defaultEyesToEyesVector = getHead()->getEyePosition() - defaultEyesPosition;
|
||||||
|
float FRONT_OFFSET_IDLE_MULTIPLIER = 2.5f;
|
||||||
|
float FRONT_OFFSET_JUMP_MULTIPLIER = 1.5f;
|
||||||
|
float frontOffset = FRONT_OFFSET_IDLE_MULTIPLIER * glm::length(defaultEyesPosition - getDefaultEyePosition());
|
||||||
|
|
||||||
|
// Looking down will aproximate move the camera forward to meet the real eye position
|
||||||
|
float mixAlpha = glm::dot(_lookAtPitch * Vectors::FRONT, -avatarUpVector);
|
||||||
|
bool isLanding = false;
|
||||||
|
// When jumping the camera should follow the real eye on the Y coordenate
|
||||||
|
float upOffset = 0.0f;
|
||||||
|
if (isJumping() || _characterController.getState() == CharacterController::State::Takeoff) {
|
||||||
|
upOffset = glm::dot(defaultEyesToEyesVector, avatarUpVector);
|
||||||
|
frontOffset = glm::dot(defaultEyesToEyesVector, avatarFrontVector) * FRONT_OFFSET_JUMP_MULTIPLIER;
|
||||||
|
mixAlpha = 1.0f;
|
||||||
|
_landingAfterJumpTime = 0.0f;
|
||||||
|
} else {
|
||||||
|
// Limit the range effect from 45 to 0 degrees
|
||||||
|
// between the front camera and the down vectors
|
||||||
|
const float HEAD_OFFSET_RANGE_IN_DEGREES = 45.0f;
|
||||||
|
const float HEAD_OFFSET_RANGE_OUT_DEGREES = 0.0f;
|
||||||
|
float rangeIn = glm::cos(glm::radians(HEAD_OFFSET_RANGE_IN_DEGREES));
|
||||||
|
float rangeOut = glm::cos(glm::radians(HEAD_OFFSET_RANGE_OUT_DEGREES));
|
||||||
|
mixAlpha = mixAlpha < rangeIn ? 0.0f : (mixAlpha - rangeIn) / (rangeOut - rangeIn);
|
||||||
|
const float WAIT_TO_LAND_TIME = 1.0f;
|
||||||
|
if (_landingAfterJumpTime < WAIT_TO_LAND_TIME) {
|
||||||
|
_landingAfterJumpTime += deltaTime;
|
||||||
|
isLanding = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const float FPS = 60.0f;
|
||||||
|
float timeScale = deltaTime * FPS;
|
||||||
|
frontOffset = frontOffset < 0.0f ? 0.0f : mixAlpha * frontOffset;
|
||||||
|
glm::vec3 cameraOffset = upOffset * Vectors::UP + frontOffset * Vectors::FRONT;
|
||||||
|
const float JUMPING_TAU = 0.1f;
|
||||||
|
const float NO_JUMP_TAU = 0.3f;
|
||||||
|
const float LANDING_TAU = 0.05f;
|
||||||
|
float tau = NO_JUMP_TAU;
|
||||||
|
if (isJumping()) {
|
||||||
|
tau = JUMPING_TAU;
|
||||||
|
} else if (isLanding) {
|
||||||
|
tau = LANDING_TAU;
|
||||||
|
}
|
||||||
|
_cameraEyesOffset = _cameraEyesOffset + (cameraOffset - _cameraEyesOffset) * min(1.0f, tau * timeScale);
|
||||||
|
glm::vec3 estimatedCameraPosition = defaultEyesPosition + getWorldOrientation() * _cameraEyesOffset;
|
||||||
|
return estimatedCameraPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MyAvatar::isJumping() {
|
||||||
|
return (_characterController.getState() == CharacterController::State::InAir ||
|
||||||
|
_characterController.getState() == CharacterController::State::Takeoff) && !isFlying();
|
||||||
|
}
|
||||||
|
|
||||||
bool MyAvatar::setPointAt(const glm::vec3& pointAtTarget) {
|
bool MyAvatar::setPointAt(const glm::vec3& pointAtTarget) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
|
@ -1919,6 +1919,8 @@ public:
|
||||||
|
|
||||||
bool getIsJointOverridden(int jointIndex) const;
|
bool getIsJointOverridden(int jointIndex) const;
|
||||||
glm::vec3 getLookAtPivotPoint();
|
glm::vec3 getLookAtPivotPoint();
|
||||||
|
glm::vec3 getCameraEyesPosition(float deltaTime);
|
||||||
|
bool isJumping();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
|
@ -2973,6 +2975,9 @@ private:
|
||||||
|
|
||||||
// used to prevent character from jumping after endSit is called.
|
// used to prevent character from jumping after endSit is called.
|
||||||
bool _endSitKeyPressComplete { false };
|
bool _endSitKeyPressComplete { false };
|
||||||
|
|
||||||
|
glm::vec3 _cameraEyesOffset;
|
||||||
|
float _landingAfterJumpTime { 0.0f };
|
||||||
};
|
};
|
||||||
|
|
||||||
QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode);
|
QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode);
|
||||||
|
|
|
@ -52,6 +52,23 @@ static const QVariantMap DOCK_AREA {
|
||||||
{ "RIGHT", DockArea::RIGHT }
|
{ "RIGHT", DockArea::RIGHT }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* The possible "relative position anchors" of an <code>InteractiveWindow</code>. Used when defining the `relativePosition` property of an `InteractiveWindow`.
|
||||||
|
* @typedef {object} InteractiveWindow.RelativePositionAnchors
|
||||||
|
* @property {InteractiveWindow.RelativePositionAnchor} NO_ANCHOR - Specifies that the position of the `InteractiveWindow` will not be relative to any part of the Interface window.
|
||||||
|
* @property {InteractiveWindow.RelativePositionAnchor} TOP_LEFT - Specifies that the `relativePosition` of the `InteractiveWindow` will be offset from the top left of the Interface window.
|
||||||
|
* @property {InteractiveWindow.RelativePositionAnchor} TOP_RIGHT - Specifies that the `relativePosition` of the `InteractiveWindow` will be offset from the top right of the Interface window.
|
||||||
|
* @property {InteractiveWindow.RelativePositionAnchor} BOTTOM_RIGHT - Specifies that the `relativePosition` of the `InteractiveWindow` will be offset from the bottom right of the Interface window.
|
||||||
|
* @property {InteractiveWindow.RelativePositionAnchor} BOTTOM_LEFT - Specifies that the `relativePosition` of the `InteractiveWindow` will be offset from the bottom left of the Interface window.
|
||||||
|
*/
|
||||||
|
static const QVariantMap RELATIVE_POSITION_ANCHOR {
|
||||||
|
{ "NO_ANCHOR", RelativePositionAnchor::NO_ANCHOR },
|
||||||
|
{ "TOP_LEFT", RelativePositionAnchor::TOP_LEFT },
|
||||||
|
{ "TOP_RIGHT", RelativePositionAnchor::TOP_RIGHT },
|
||||||
|
{ "BOTTOM_RIGHT", RelativePositionAnchor::BOTTOM_RIGHT },
|
||||||
|
{ "BOTTOM_LEFT", RelativePositionAnchor::BOTTOM_LEFT }
|
||||||
|
};
|
||||||
|
|
||||||
DesktopScriptingInterface::DesktopScriptingInterface(QObject* parent, bool restricted)
|
DesktopScriptingInterface::DesktopScriptingInterface(QObject* parent, bool restricted)
|
||||||
: QObject(parent), _restricted(restricted) { }
|
: QObject(parent), _restricted(restricted) { }
|
||||||
|
|
||||||
|
@ -99,6 +116,10 @@ QVariantMap DesktopScriptingInterface::getDockArea() {
|
||||||
return DOCK_AREA;
|
return DOCK_AREA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariantMap DesktopScriptingInterface::getRelativePositionAnchor() {
|
||||||
|
return RELATIVE_POSITION_ANCHOR;
|
||||||
|
}
|
||||||
|
|
||||||
void DesktopScriptingInterface::setHUDAlpha(float alpha) {
|
void DesktopScriptingInterface::setHUDAlpha(float alpha) {
|
||||||
qApp->getApplicationCompositor().setAlpha(alpha);
|
qApp->getApplicationCompositor().setAlpha(alpha);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,9 @@
|
||||||
* @property {InteractiveWindow.DockAreas} DockArea - The possible docking locations of an {@link InteractiveWindow}: top,
|
* @property {InteractiveWindow.DockAreas} DockArea - The possible docking locations of an {@link InteractiveWindow}: top,
|
||||||
* bottom, left, or right of the Interface window.
|
* bottom, left, or right of the Interface window.
|
||||||
* <em>Read-only.</em>
|
* <em>Read-only.</em>
|
||||||
|
* @property {InteractiveWindow.RelativePositionAnchors} RelativePositionAnchor - The possible "relative position anchors" for an {@link InteractiveWindow}: top left,
|
||||||
|
* top right, bottom right, or bottom left of the Interface window.
|
||||||
|
* <em>Read-only.</em>
|
||||||
*/
|
*/
|
||||||
class DesktopScriptingInterface : public QObject, public Dependency {
|
class DesktopScriptingInterface : public QObject, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -50,6 +53,7 @@ class DesktopScriptingInterface : public QObject, public Dependency {
|
||||||
|
|
||||||
Q_PROPERTY(QVariantMap PresentationMode READ getPresentationMode CONSTANT FINAL)
|
Q_PROPERTY(QVariantMap PresentationMode READ getPresentationMode CONSTANT FINAL)
|
||||||
Q_PROPERTY(QVariantMap DockArea READ getDockArea CONSTANT FINAL)
|
Q_PROPERTY(QVariantMap DockArea READ getDockArea CONSTANT FINAL)
|
||||||
|
Q_PROPERTY(QVariantMap RelativePositionAnchor READ getRelativePositionAnchor CONSTANT FINAL)
|
||||||
Q_PROPERTY(int ALWAYS_ON_TOP READ flagAlwaysOnTop CONSTANT FINAL)
|
Q_PROPERTY(int ALWAYS_ON_TOP READ flagAlwaysOnTop CONSTANT FINAL)
|
||||||
Q_PROPERTY(int CLOSE_BUTTON_HIDES READ flagCloseButtonHides CONSTANT FINAL)
|
Q_PROPERTY(int CLOSE_BUTTON_HIDES READ flagCloseButtonHides CONSTANT FINAL)
|
||||||
|
|
||||||
|
@ -106,7 +110,7 @@ private:
|
||||||
Q_INVOKABLE InteractiveWindowPointer createWindowOnThread(const QString& sourceUrl, const QVariantMap& properties, QThread* targetThread);
|
Q_INVOKABLE InteractiveWindowPointer createWindowOnThread(const QString& sourceUrl, const QVariantMap& properties, QThread* targetThread);
|
||||||
|
|
||||||
static QVariantMap getDockArea();
|
static QVariantMap getDockArea();
|
||||||
|
static QVariantMap getRelativePositionAnchor();
|
||||||
Q_INVOKABLE static QVariantMap getPresentationMode();
|
Q_INVOKABLE static QVariantMap getPresentationMode();
|
||||||
const bool _restricted;
|
const bool _restricted;
|
||||||
};
|
};
|
||||||
|
|
|
@ -82,11 +82,18 @@ void RenderScriptingInterface::forceShadowsEnabled(bool enabled) {
|
||||||
_shadowsEnabled = (enabled);
|
_shadowsEnabled = (enabled);
|
||||||
_shadowsEnabledSetting.set(enabled);
|
_shadowsEnabledSetting.set(enabled);
|
||||||
|
|
||||||
auto lightingModelConfig = qApp->getRenderEngine()->getConfiguration()->getConfig<MakeLightingModel>("RenderMainView.LightingModel");
|
auto renderConfig = qApp->getRenderEngine()->getConfiguration();
|
||||||
|
assert(renderConfig);
|
||||||
|
auto lightingModelConfig = renderConfig->getConfig<MakeLightingModel>("RenderMainView.LightingModel");
|
||||||
if (lightingModelConfig) {
|
if (lightingModelConfig) {
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::Shadows, enabled);
|
Menu::getInstance()->setIsOptionChecked(MenuOption::Shadows, enabled);
|
||||||
lightingModelConfig->setShadow(enabled);
|
lightingModelConfig->setShadow(enabled);
|
||||||
}
|
}
|
||||||
|
auto secondaryLightingModelConfig = renderConfig->getConfig<MakeLightingModel>("RenderSecondView.LightingModel");
|
||||||
|
if (secondaryLightingModelConfig) {
|
||||||
|
Menu::getInstance()->setIsOptionChecked(MenuOption::Shadows, enabled);
|
||||||
|
secondaryLightingModelConfig->setShadow(enabled);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -186,15 +186,6 @@ void DialogsManager::setAddressBarVisible(bool addressBarVisible) {
|
||||||
emit addressBarShown(_addressBarVisible);
|
emit addressBarShown(_addressBarVisible);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogsManager::showTestingResults() {
|
|
||||||
if (!_testingDialog) {
|
|
||||||
_testingDialog = new TestingDialog(qApp->getWindow());
|
|
||||||
connect(_testingDialog, SIGNAL(closed()), _testingDialog, SLOT(deleteLater()));
|
|
||||||
}
|
|
||||||
_testingDialog->show();
|
|
||||||
_testingDialog->raise();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DialogsManager::showDomainConnectionDialog() {
|
void DialogsManager::showDomainConnectionDialog() {
|
||||||
// if the dialog already exists we delete it so the connection data is refreshed
|
// if the dialog already exists we delete it so the connection data is refreshed
|
||||||
if (_domainConnectionDialog) {
|
if (_domainConnectionDialog) {
|
||||||
|
|
|
@ -53,7 +53,6 @@ public slots:
|
||||||
void lodTools();
|
void lodTools();
|
||||||
void hmdTools(bool showTools);
|
void hmdTools(bool showTools);
|
||||||
void showDomainConnectionDialog();
|
void showDomainConnectionDialog();
|
||||||
void showTestingResults();
|
|
||||||
void toggleAddressBar();
|
void toggleAddressBar();
|
||||||
|
|
||||||
// Application Update
|
// Application Update
|
||||||
|
|
|
@ -39,6 +39,9 @@ static const char* const ADDITIONAL_FLAGS_PROPERTY = "additionalFlags";
|
||||||
static const char* const OVERRIDE_FLAGS_PROPERTY = "overrideFlags";
|
static const char* const OVERRIDE_FLAGS_PROPERTY = "overrideFlags";
|
||||||
static const char* const SOURCE_PROPERTY = "source";
|
static const char* const SOURCE_PROPERTY = "source";
|
||||||
static const char* const TITLE_PROPERTY = "title";
|
static const char* const TITLE_PROPERTY = "title";
|
||||||
|
static const char* const RELATIVE_POSITION_ANCHOR_PROPERTY = "relativePositionAnchor";
|
||||||
|
static const char* const RELATIVE_POSITION_PROPERTY = "relativePosition";
|
||||||
|
static const char* const IS_FULL_SCREEN_WINDOW = "isFullScreenWindow";
|
||||||
static const char* const POSITION_PROPERTY = "position";
|
static const char* const POSITION_PROPERTY = "position";
|
||||||
static const char* const INTERACTIVE_WINDOW_POSITION_PROPERTY = "interactiveWindowPosition";
|
static const char* const INTERACTIVE_WINDOW_POSITION_PROPERTY = "interactiveWindowPosition";
|
||||||
static const char* const SIZE_PROPERTY = "size";
|
static const char* const SIZE_PROPERTY = "size";
|
||||||
|
@ -112,6 +115,15 @@ void InteractiveWindow::forwardKeyReleaseEvent(int key, int modifiers) {
|
||||||
QCoreApplication::postEvent(QCoreApplication::instance(), event);
|
QCoreApplication::postEvent(QCoreApplication::instance(), event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InteractiveWindow::onMainWindowGeometryChanged(QRect geometry) {
|
||||||
|
// This handler is only connected `if (_isFullScreenWindow || _relativePositionAnchor != RelativePositionAnchor::NONE)`.
|
||||||
|
if (_isFullScreenWindow) {
|
||||||
|
repositionAndResizeFullScreenWindow();
|
||||||
|
} else if (_relativePositionAnchor != RelativePositionAnchor::NO_ANCHOR) {
|
||||||
|
setPositionUsingRelativePositionAndAnchor(geometry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InteractiveWindow::emitMainWindowResizeEvent() {
|
void InteractiveWindow::emitMainWindowResizeEvent() {
|
||||||
emit qApp->getWindow()->windowGeometryChanged(qApp->getWindow()->geometry());
|
emit qApp->getWindow()->windowGeometryChanged(qApp->getWindow()->geometry());
|
||||||
}
|
}
|
||||||
|
@ -184,22 +196,32 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
|
||||||
*/
|
*/
|
||||||
if (nativeWindowInfo.contains(DOCK_AREA_PROPERTY)) {
|
if (nativeWindowInfo.contains(DOCK_AREA_PROPERTY)) {
|
||||||
DockArea dockedArea = (DockArea) nativeWindowInfo[DOCK_AREA_PROPERTY].toInt();
|
DockArea dockedArea = (DockArea) nativeWindowInfo[DOCK_AREA_PROPERTY].toInt();
|
||||||
|
int tempWidth = 0;
|
||||||
|
int tempHeight = 0;
|
||||||
switch (dockedArea) {
|
switch (dockedArea) {
|
||||||
case DockArea::TOP:
|
case DockArea::TOP:
|
||||||
dockArea = Qt::TopDockWidgetArea;
|
dockArea = Qt::TopDockWidgetArea;
|
||||||
_dockWidget->setFixedHeight(windowSize.height());
|
tempHeight = windowSize.height();
|
||||||
|
_dockWidget->setFixedHeight(tempHeight);
|
||||||
|
qApp->getWindow()->setDockedWidgetRelativePositionOffset(QSize(0, -tempHeight));
|
||||||
break;
|
break;
|
||||||
case DockArea::BOTTOM:
|
case DockArea::BOTTOM:
|
||||||
dockArea = Qt::BottomDockWidgetArea;
|
dockArea = Qt::BottomDockWidgetArea;
|
||||||
_dockWidget->setFixedHeight(windowSize.height());
|
tempHeight = windowSize.height();
|
||||||
|
_dockWidget->setFixedHeight(tempHeight);
|
||||||
|
qApp->getWindow()->setDockedWidgetRelativePositionOffset(QSize(0, tempHeight));
|
||||||
break;
|
break;
|
||||||
case DockArea::LEFT:
|
case DockArea::LEFT:
|
||||||
dockArea = Qt::LeftDockWidgetArea;
|
dockArea = Qt::LeftDockWidgetArea;
|
||||||
_dockWidget->setFixedWidth(windowSize.width());
|
tempWidth = windowSize.width();
|
||||||
|
_dockWidget->setFixedWidth(tempWidth);
|
||||||
|
qApp->getWindow()->setDockedWidgetRelativePositionOffset(QSize(-tempWidth, 0));
|
||||||
break;
|
break;
|
||||||
case DockArea::RIGHT:
|
case DockArea::RIGHT:
|
||||||
dockArea = Qt::RightDockWidgetArea;
|
dockArea = Qt::RightDockWidgetArea;
|
||||||
_dockWidget->setFixedWidth(windowSize.width());
|
tempWidth = windowSize.width();
|
||||||
|
_dockWidget->setFixedWidth(tempWidth);
|
||||||
|
qApp->getWindow()->setDockedWidgetRelativePositionOffset(QSize(tempWidth, 0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -255,6 +277,9 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
|
||||||
if (properties.contains(TITLE_PROPERTY)) {
|
if (properties.contains(TITLE_PROPERTY)) {
|
||||||
object->setProperty(TITLE_PROPERTY, properties[TITLE_PROPERTY].toString());
|
object->setProperty(TITLE_PROPERTY, properties[TITLE_PROPERTY].toString());
|
||||||
}
|
}
|
||||||
|
if (properties.contains(VISIBLE_PROPERTY)) {
|
||||||
|
object->setProperty(VISIBLE_PROPERTY, properties[INTERACTIVE_WINDOW_VISIBLE_PROPERTY].toBool());
|
||||||
|
}
|
||||||
if (properties.contains(SIZE_PROPERTY)) {
|
if (properties.contains(SIZE_PROPERTY)) {
|
||||||
const auto size = vec2FromVariant(properties[SIZE_PROPERTY]);
|
const auto size = vec2FromVariant(properties[SIZE_PROPERTY]);
|
||||||
object->setProperty(INTERACTIVE_WINDOW_SIZE_PROPERTY, QSize(size.x, size.y));
|
object->setProperty(INTERACTIVE_WINDOW_SIZE_PROPERTY, QSize(size.x, size.y));
|
||||||
|
@ -263,8 +288,21 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
|
||||||
const auto position = vec2FromVariant(properties[POSITION_PROPERTY]);
|
const auto position = vec2FromVariant(properties[POSITION_PROPERTY]);
|
||||||
object->setProperty(INTERACTIVE_WINDOW_POSITION_PROPERTY, QPointF(position.x, position.y));
|
object->setProperty(INTERACTIVE_WINDOW_POSITION_PROPERTY, QPointF(position.x, position.y));
|
||||||
}
|
}
|
||||||
if (properties.contains(VISIBLE_PROPERTY)) {
|
if (properties.contains(RELATIVE_POSITION_ANCHOR_PROPERTY)) {
|
||||||
object->setProperty(VISIBLE_PROPERTY, properties[INTERACTIVE_WINDOW_VISIBLE_PROPERTY].toBool());
|
_relativePositionAnchor = static_cast<RelativePositionAnchor>(properties[RELATIVE_POSITION_ANCHOR_PROPERTY].toInt());
|
||||||
|
}
|
||||||
|
if (properties.contains(RELATIVE_POSITION_PROPERTY)) {
|
||||||
|
_relativePosition = vec2FromVariant(properties[RELATIVE_POSITION_PROPERTY]);
|
||||||
|
setPositionUsingRelativePositionAndAnchor(qApp->getWindow()->geometry());
|
||||||
|
}
|
||||||
|
if (properties.contains(IS_FULL_SCREEN_WINDOW)) {
|
||||||
|
_isFullScreenWindow = properties[IS_FULL_SCREEN_WINDOW].toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_isFullScreenWindow) {
|
||||||
|
QRect geo = qApp->getWindow()->geometry();
|
||||||
|
object->setProperty(INTERACTIVE_WINDOW_POSITION_PROPERTY, QPointF(geo.x(), geo.y()));
|
||||||
|
object->setProperty(INTERACTIVE_WINDOW_SIZE_PROPERTY, QSize(geo.width(), geo.height()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The qmlToScript method handles the thread-safety of this call. Because the QVariant argument
|
// The qmlToScript method handles the thread-safety of this call. Because the QVariant argument
|
||||||
|
@ -289,6 +327,10 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
|
||||||
connect(object, SIGNAL(presentationModeChanged()), this, SLOT(parentNativeWindowToMainWindow()), Qt::QueuedConnection);
|
connect(object, SIGNAL(presentationModeChanged()), this, SLOT(parentNativeWindowToMainWindow()), Qt::QueuedConnection);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (_isFullScreenWindow || _relativePositionAnchor != RelativePositionAnchor::NO_ANCHOR) {
|
||||||
|
connect(qApp->getWindow(), &MainWindow::windowGeometryChanged, this, &InteractiveWindow::onMainWindowGeometryChanged, Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
QUrl sourceURL{ sourceUrl };
|
QUrl sourceURL{ sourceUrl };
|
||||||
// If the passed URL doesn't correspond to a known scheme, assume it's a local file path
|
// If the passed URL doesn't correspond to a known scheme, assume it's a local file path
|
||||||
if (!KNOWN_SCHEMES.contains(sourceURL.scheme(), Qt::CaseInsensitive)) {
|
if (!KNOWN_SCHEMES.contains(sourceURL.scheme(), Qt::CaseInsensitive)) {
|
||||||
|
@ -414,6 +456,71 @@ void InteractiveWindow::setPosition(const glm::vec2& position) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RelativePositionAnchor InteractiveWindow::getRelativePositionAnchor() const {
|
||||||
|
return _relativePositionAnchor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InteractiveWindow::setRelativePositionAnchor(const RelativePositionAnchor& relativePositionAnchor) {
|
||||||
|
_relativePositionAnchor = relativePositionAnchor;
|
||||||
|
setPositionUsingRelativePositionAndAnchor(qApp->getWindow()->geometry());
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec2 InteractiveWindow::getRelativePosition() const {
|
||||||
|
return _relativePosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InteractiveWindow::setRelativePosition(const glm::vec2& relativePosition) {
|
||||||
|
_relativePosition = relativePosition;
|
||||||
|
setPositionUsingRelativePositionAndAnchor(qApp->getWindow()->geometry());
|
||||||
|
}
|
||||||
|
|
||||||
|
void InteractiveWindow::setPositionUsingRelativePositionAndAnchor(const QRect& mainWindowGeometry) {
|
||||||
|
RelativePositionAnchor relativePositionAnchor = getRelativePositionAnchor();
|
||||||
|
glm::vec2 relativePosition = getRelativePosition();
|
||||||
|
|
||||||
|
glm::vec2 newPosition;
|
||||||
|
|
||||||
|
switch (relativePositionAnchor) {
|
||||||
|
case RelativePositionAnchor::TOP_LEFT:
|
||||||
|
newPosition.x = mainWindowGeometry.x() + relativePosition.x;
|
||||||
|
newPosition.y = mainWindowGeometry.y() + relativePosition.y;
|
||||||
|
break;
|
||||||
|
case RelativePositionAnchor::TOP_RIGHT:
|
||||||
|
newPosition.x = mainWindowGeometry.x() + mainWindowGeometry.width() - relativePosition.x;
|
||||||
|
newPosition.y = mainWindowGeometry.y() + relativePosition.y;
|
||||||
|
break;
|
||||||
|
case RelativePositionAnchor::BOTTOM_RIGHT:
|
||||||
|
newPosition.x = mainWindowGeometry.x() + mainWindowGeometry.width() - relativePosition.x;
|
||||||
|
newPosition.y = mainWindowGeometry.y() + mainWindowGeometry.height() - relativePosition.y;
|
||||||
|
break;
|
||||||
|
case RelativePositionAnchor::BOTTOM_LEFT:
|
||||||
|
newPosition.x = mainWindowGeometry.x() + relativePosition.x;
|
||||||
|
newPosition.y = mainWindowGeometry.y() + mainWindowGeometry.height() - relativePosition.y;
|
||||||
|
break;
|
||||||
|
case RelativePositionAnchor::NO_ANCHOR:
|
||||||
|
// No-op.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we include the dimensions of the docked widget!
|
||||||
|
QSize dockedWidgetRelativePositionOffset = qApp->getWindow()->getDockedWidgetRelativePositionOffset();
|
||||||
|
newPosition.x = newPosition.x + dockedWidgetRelativePositionOffset.width();
|
||||||
|
newPosition.y = newPosition.y + dockedWidgetRelativePositionOffset.height();
|
||||||
|
|
||||||
|
if (_qmlWindowProxy) {
|
||||||
|
QMetaObject::invokeMethod(_qmlWindowProxy.get(), "writeProperty", Q_ARG(QString, INTERACTIVE_WINDOW_POSITION_PROPERTY),
|
||||||
|
Q_ARG(QVariant, QPointF(newPosition.x, newPosition.y)));
|
||||||
|
}
|
||||||
|
setPosition(newPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InteractiveWindow::repositionAndResizeFullScreenWindow() {
|
||||||
|
QRect windowGeometry = qApp->getWindow()->geometry();
|
||||||
|
|
||||||
|
setPosition(glm::vec2(windowGeometry.x(), windowGeometry.y()));
|
||||||
|
setSize(glm::vec2(windowGeometry.width(), windowGeometry.height()));
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec2 InteractiveWindow::getSize() const {
|
glm::vec2 InteractiveWindow::getSize() const {
|
||||||
if (!_qmlWindowProxy) {
|
if (!_qmlWindowProxy) {
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -89,6 +89,15 @@ namespace InteractiveWindowEnums {
|
||||||
RIGHT
|
RIGHT
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(DockArea);
|
Q_ENUM_NS(DockArea);
|
||||||
|
|
||||||
|
enum RelativePositionAnchor {
|
||||||
|
NO_ANCHOR,
|
||||||
|
TOP_LEFT,
|
||||||
|
TOP_RIGHT,
|
||||||
|
BOTTOM_RIGHT,
|
||||||
|
BOTTOM_LEFT
|
||||||
|
};
|
||||||
|
Q_ENUM_NS(RelativePositionAnchor);
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace InteractiveWindowEnums;
|
using namespace InteractiveWindowEnums;
|
||||||
|
@ -121,6 +130,8 @@ class InteractiveWindow : public QObject {
|
||||||
|
|
||||||
Q_PROPERTY(QString title READ getTitle WRITE setTitle)
|
Q_PROPERTY(QString title READ getTitle WRITE setTitle)
|
||||||
Q_PROPERTY(glm::vec2 position READ getPosition WRITE setPosition)
|
Q_PROPERTY(glm::vec2 position READ getPosition WRITE setPosition)
|
||||||
|
Q_PROPERTY(RelativePositionAnchor relativePositionAnchor READ getRelativePositionAnchor WRITE setRelativePositionAnchor)
|
||||||
|
Q_PROPERTY(glm::vec2 relativePosition READ getRelativePosition WRITE setRelativePosition)
|
||||||
Q_PROPERTY(glm::vec2 size READ getSize WRITE setSize)
|
Q_PROPERTY(glm::vec2 size READ getSize WRITE setSize)
|
||||||
Q_PROPERTY(bool visible READ isVisible WRITE setVisible)
|
Q_PROPERTY(bool visible READ isVisible WRITE setVisible)
|
||||||
Q_PROPERTY(int presentationMode READ getPresentationMode WRITE setPresentationMode)
|
Q_PROPERTY(int presentationMode READ getPresentationMode WRITE setPresentationMode)
|
||||||
|
@ -137,6 +148,21 @@ private:
|
||||||
Q_INVOKABLE glm::vec2 getPosition() const;
|
Q_INVOKABLE glm::vec2 getPosition() const;
|
||||||
Q_INVOKABLE void setPosition(const glm::vec2& position);
|
Q_INVOKABLE void setPosition(const glm::vec2& position);
|
||||||
|
|
||||||
|
RelativePositionAnchor _relativePositionAnchor{ RelativePositionAnchor::NO_ANCHOR };
|
||||||
|
Q_INVOKABLE RelativePositionAnchor getRelativePositionAnchor() const;
|
||||||
|
Q_INVOKABLE void setRelativePositionAnchor(const RelativePositionAnchor& position);
|
||||||
|
|
||||||
|
// This "relative position" is relative to the "relative position anchor" and excludes the window frame.
|
||||||
|
// This position will ALWAYS include the geometry of a docked widget, if one is present.
|
||||||
|
glm::vec2 _relativePosition{ 0.0f, 0.0f };
|
||||||
|
Q_INVOKABLE glm::vec2 getRelativePosition() const;
|
||||||
|
Q_INVOKABLE void setRelativePosition(const glm::vec2& position);
|
||||||
|
|
||||||
|
Q_INVOKABLE void setPositionUsingRelativePositionAndAnchor(const QRect& mainWindowGeometry);
|
||||||
|
|
||||||
|
bool _isFullScreenWindow{ false };
|
||||||
|
Q_INVOKABLE void repositionAndResizeFullScreenWindow();
|
||||||
|
|
||||||
Q_INVOKABLE glm::vec2 getSize() const;
|
Q_INVOKABLE glm::vec2 getSize() const;
|
||||||
Q_INVOKABLE void setSize(const glm::vec2& size);
|
Q_INVOKABLE void setSize(const glm::vec2& size);
|
||||||
|
|
||||||
|
@ -320,6 +346,7 @@ protected slots:
|
||||||
void forwardKeyPressEvent(int key, int modifiers);
|
void forwardKeyPressEvent(int key, int modifiers);
|
||||||
void forwardKeyReleaseEvent(int key, int modifiers);
|
void forwardKeyReleaseEvent(int key, int modifiers);
|
||||||
void emitMainWindowResizeEvent();
|
void emitMainWindowResizeEvent();
|
||||||
|
void onMainWindowGeometryChanged(QRect geometry);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<QmlWindowProxy> _qmlWindowProxy;
|
std::shared_ptr<QmlWindowProxy> _qmlWindowProxy;
|
||||||
|
|
|
@ -55,6 +55,8 @@ public:
|
||||||
float getFrame() const { return _frame; }
|
float getFrame() const { return _frame; }
|
||||||
void loadURL(const QString& url);
|
void loadURL(const QString& url);
|
||||||
|
|
||||||
|
AnimBlendType getBlendType() const { return _blendType; };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void setCurrentFrameInternal(float frame) override;
|
virtual void setCurrentFrameInternal(float frame) override;
|
||||||
|
|
|
@ -545,7 +545,8 @@ QStringList Rig::getAnimationRoles() const {
|
||||||
auto clipNode = std::dynamic_pointer_cast<AnimClip>(node);
|
auto clipNode = std::dynamic_pointer_cast<AnimClip>(node);
|
||||||
if (clipNode) {
|
if (clipNode) {
|
||||||
// filter out the userAnims, they are for internal use only.
|
// filter out the userAnims, they are for internal use only.
|
||||||
if (!clipNode->getID().startsWith("userAnim")) {
|
// also don't return additive blend node clips as valid roles.
|
||||||
|
if (!clipNode->getID().startsWith("userAnim") && clipNode->getBlendType() == AnimBlendType_Normal) {
|
||||||
list.append(node->getID());
|
list.append(node->getID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1432,6 +1433,69 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos
|
||||||
}
|
}
|
||||||
_lastEnableInverseKinematics = _enableInverseKinematics;
|
_lastEnableInverseKinematics = _enableInverseKinematics;
|
||||||
|
|
||||||
|
|
||||||
|
//stategraph vars based on input
|
||||||
|
const float INPUT_DEADZONE_THRESHOLD = 0.05f;
|
||||||
|
const float SLOW_SPEED_THRESHOLD = 1.5f;
|
||||||
|
|
||||||
|
if (fabsf(_previousControllerParameters.inputX) <= INPUT_DEADZONE_THRESHOLD &&
|
||||||
|
fabsf(_previousControllerParameters.inputZ) <= INPUT_DEADZONE_THRESHOLD) {
|
||||||
|
// no WASD input
|
||||||
|
if (fabsf(forwardSpeed) <= SLOW_SPEED_THRESHOLD && fabsf(lateralSpeed) <= SLOW_SPEED_THRESHOLD) {
|
||||||
|
_animVars.set("isInputForward", false);
|
||||||
|
_animVars.set("isInputBackward", false);
|
||||||
|
_animVars.set("isInputRight", false);
|
||||||
|
_animVars.set("isInputLeft", false);
|
||||||
|
_animVars.set("isNotInput", true);
|
||||||
|
_animVars.set("isNotInputSlow", true);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_animVars.set("isInputForward", false);
|
||||||
|
_animVars.set("isInputBackward", false);
|
||||||
|
_animVars.set("isInputRight", false);
|
||||||
|
_animVars.set("isInputLeft", false);
|
||||||
|
_animVars.set("isNotInput", true);
|
||||||
|
_animVars.set("isNotInputSlow", false);
|
||||||
|
}
|
||||||
|
} else if (fabsf(_previousControllerParameters.inputZ) >= fabsf(_previousControllerParameters.inputX)) {
|
||||||
|
if (_previousControllerParameters.inputZ > 0.0f) {
|
||||||
|
// forward
|
||||||
|
_animVars.set("isInputForward", true);
|
||||||
|
_animVars.set("isInputBackward", false);
|
||||||
|
_animVars.set("isInputRight", false);
|
||||||
|
_animVars.set("isInputLeft", false);
|
||||||
|
_animVars.set("isNotInput", false);
|
||||||
|
_animVars.set("isNotInputSlow", false);
|
||||||
|
} else {
|
||||||
|
// backward
|
||||||
|
_animVars.set("isInputForward", false);
|
||||||
|
_animVars.set("isInputBackward", true);
|
||||||
|
_animVars.set("isInputRight", false);
|
||||||
|
_animVars.set("isInputLeft", false);
|
||||||
|
_animVars.set("isNotInput", false);
|
||||||
|
_animVars.set("isNotInputSlow", false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (_previousControllerParameters.inputX > 0.0f) {
|
||||||
|
// right
|
||||||
|
_animVars.set("isInputForward", false);
|
||||||
|
_animVars.set("isInputBackward", false);
|
||||||
|
_animVars.set("isInputRight", true);
|
||||||
|
_animVars.set("isInputLeft", false);
|
||||||
|
_animVars.set("isNotInput", false);
|
||||||
|
_animVars.set("isNotInputSlow", false);
|
||||||
|
} else {
|
||||||
|
// left
|
||||||
|
_animVars.set("isInputForward", false);
|
||||||
|
_animVars.set("isInputBackward", false);
|
||||||
|
_animVars.set("isInputRight", false);
|
||||||
|
_animVars.set("isInputLeft", true);
|
||||||
|
_animVars.set("isNotInput", false);
|
||||||
|
_animVars.set("isNotInputSlow", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
_lastForward = forward;
|
_lastForward = forward;
|
||||||
_lastPosition = worldPosition;
|
_lastPosition = worldPosition;
|
||||||
|
@ -2160,50 +2224,6 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//deadzone constant
|
|
||||||
const float INPUT_DEADZONE_THRESHOLD = 0.05f;
|
|
||||||
|
|
||||||
if (fabsf(params.inputX) <= INPUT_DEADZONE_THRESHOLD && fabsf(params.inputZ) <= INPUT_DEADZONE_THRESHOLD) {
|
|
||||||
// no WASD input
|
|
||||||
_animVars.set("isInputForward", false);
|
|
||||||
_animVars.set("isInputBackward", false);
|
|
||||||
_animVars.set("isInputRight", false);
|
|
||||||
_animVars.set("isInputLeft", false);
|
|
||||||
_animVars.set("isNotInput", true);
|
|
||||||
} else if (fabsf(params.inputZ) >= fabsf(params.inputX)) {
|
|
||||||
if (params.inputZ > 0.0f) {
|
|
||||||
// forward
|
|
||||||
_animVars.set("isInputForward", true);
|
|
||||||
_animVars.set("isInputBackward", false);
|
|
||||||
_animVars.set("isInputRight", false);
|
|
||||||
_animVars.set("isInputLeft", false);
|
|
||||||
_animVars.set("isNotInput", false);
|
|
||||||
} else {
|
|
||||||
// backward
|
|
||||||
_animVars.set("isInputForward", false);
|
|
||||||
_animVars.set("isInputBackward", true);
|
|
||||||
_animVars.set("isInputRight", false);
|
|
||||||
_animVars.set("isInputLeft", false);
|
|
||||||
_animVars.set("isNotInput", false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (params.inputX > 0.0f) {
|
|
||||||
// right
|
|
||||||
_animVars.set("isInputForward", false);
|
|
||||||
_animVars.set("isInputBackward", false);
|
|
||||||
_animVars.set("isInputRight", true);
|
|
||||||
_animVars.set("isInputLeft", false);
|
|
||||||
_animVars.set("isNotInput", false);
|
|
||||||
} else {
|
|
||||||
// left
|
|
||||||
_animVars.set("isInputForward", false);
|
|
||||||
_animVars.set("isInputBackward", false);
|
|
||||||
_animVars.set("isInputRight", false);
|
|
||||||
_animVars.set("isInputLeft", true);
|
|
||||||
_animVars.set("isNotInput", false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
_headEnabled = params.primaryControllerFlags[PrimaryControllerType_Head] & (uint8_t)ControllerFlags::Enabled;
|
_headEnabled = params.primaryControllerFlags[PrimaryControllerType_Head] & (uint8_t)ControllerFlags::Enabled;
|
||||||
bool leftHandEnabled = params.primaryControllerFlags[PrimaryControllerType_LeftHand] & (uint8_t)ControllerFlags::Enabled;
|
bool leftHandEnabled = params.primaryControllerFlags[PrimaryControllerType_LeftHand] & (uint8_t)ControllerFlags::Enabled;
|
||||||
|
|
|
@ -88,8 +88,8 @@ public:
|
||||||
AnimPose secondaryControllerPoses[NumSecondaryControllerTypes]; // rig space
|
AnimPose secondaryControllerPoses[NumSecondaryControllerTypes]; // rig space
|
||||||
uint8_t secondaryControllerFlags[NumSecondaryControllerTypes];
|
uint8_t secondaryControllerFlags[NumSecondaryControllerTypes];
|
||||||
bool isTalking;
|
bool isTalking;
|
||||||
float inputX;
|
float inputX = 0.0f;
|
||||||
float inputZ;
|
float inputZ = 0.0f;
|
||||||
bool reactionEnabledFlags[NUM_AVATAR_BEGIN_END_REACTIONS];
|
bool reactionEnabledFlags[NUM_AVATAR_BEGIN_END_REACTIONS];
|
||||||
bool reactionTriggers[NUM_AVATAR_TRIGGER_REACTIONS];
|
bool reactionTriggers[NUM_AVATAR_TRIGGER_REACTIONS];
|
||||||
HFMJointShapeInfo hipsShapeInfo;
|
HFMJointShapeInfo hipsShapeInfo;
|
||||||
|
|
|
@ -1998,6 +1998,12 @@ void AudioClient::outputNotify() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioClient::noteAwakening() {
|
||||||
|
qCDebug(audioclient) << "Restarting the audio devices.";
|
||||||
|
switchInputToAudioDevice(_inputDeviceInfo);
|
||||||
|
switchOutputToAudioDevice(_outputDeviceInfo);
|
||||||
|
}
|
||||||
|
|
||||||
bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDeviceInfo, bool isShutdownRequest) {
|
bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDeviceInfo, bool isShutdownRequest) {
|
||||||
Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread");
|
Q_ASSERT_X(QThread::currentThread() == thread(), Q_FUNC_INFO, "Function invoked on wrong thread");
|
||||||
|
|
||||||
|
|
|
@ -255,6 +255,7 @@ public slots:
|
||||||
void setOutputGain(float gain) { _outputGain = gain; };
|
void setOutputGain(float gain) { _outputGain = gain; };
|
||||||
|
|
||||||
void outputNotify();
|
void outputNotify();
|
||||||
|
void noteAwakening();
|
||||||
|
|
||||||
void loadSettings();
|
void loadSettings();
|
||||||
void saveSettings();
|
void saveSettings();
|
||||||
|
|
|
@ -854,7 +854,8 @@ void Avatar::render(RenderArgs* renderArgs) {
|
||||||
float distanceToTarget = glm::length(toTarget);
|
float distanceToTarget = glm::length(toTarget);
|
||||||
const float DISPLAYNAME_DISTANCE = 20.0f;
|
const float DISPLAYNAME_DISTANCE = 20.0f;
|
||||||
updateDisplayNameAlpha(distanceToTarget < DISPLAYNAME_DISTANCE);
|
updateDisplayNameAlpha(distanceToTarget < DISPLAYNAME_DISTANCE);
|
||||||
if (!isMyAvatar() || renderArgs->_cameraMode != (int8_t)CAMERA_MODE_FIRST_PERSON) {
|
if (!isMyAvatar() || !(renderArgs->_cameraMode == (int8_t)CAMERA_MODE_FIRST_PERSON_LOOK_AT
|
||||||
|
|| renderArgs->_cameraMode == (int8_t)CAMERA_MODE_FIRST_PERSON)) {
|
||||||
auto& frustum = renderArgs->getViewFrustum();
|
auto& frustum = renderArgs->getViewFrustum();
|
||||||
auto textPosition = getDisplayNamePosition();
|
auto textPosition = getDisplayNamePosition();
|
||||||
if (frustum.pointIntersectsFrustum(textPosition)) {
|
if (frustum.pointIntersectsFrustum(textPosition)) {
|
||||||
|
|
|
@ -335,8 +335,8 @@ namespace controller {
|
||||||
makeAxisPair(Action::STEP_PITCH, "StepPitch"),
|
makeAxisPair(Action::STEP_PITCH, "StepPitch"),
|
||||||
makeAxisPair(Action::STEP_ROLL, "StepRoll"),
|
makeAxisPair(Action::STEP_ROLL, "StepRoll"),
|
||||||
makeAxisPair(Action::STEP_TRANSLATE_X, "StepTranslateX"),
|
makeAxisPair(Action::STEP_TRANSLATE_X, "StepTranslateX"),
|
||||||
makeAxisPair(Action::STEP_TRANSLATE_X, "StepTranslateY"),
|
makeAxisPair(Action::STEP_TRANSLATE_Y, "StepTranslateY"),
|
||||||
makeAxisPair(Action::STEP_TRANSLATE_X, "StepTranslateZ"),
|
makeAxisPair(Action::STEP_TRANSLATE_Z, "StepTranslateZ"),
|
||||||
|
|
||||||
makePosePair(Action::LEFT_HAND, "LeftHand"),
|
makePosePair(Action::LEFT_HAND, "LeftHand"),
|
||||||
makePosePair(Action::RIGHT_HAND, "RightHand"),
|
makePosePair(Action::RIGHT_HAND, "RightHand"),
|
||||||
|
|
|
@ -808,6 +808,8 @@ void AccountManager::requestAccountSettings() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qCDebug(networking) << "Requesting the Account Settings from the Metaverse API";
|
||||||
|
|
||||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||||
|
|
||||||
QUrl lockerURL = _authURL;
|
QUrl lockerURL = _authURL;
|
||||||
|
@ -834,6 +836,9 @@ void AccountManager::requestAccountSettingsFinished() {
|
||||||
if (rootObject.contains("status") && rootObject["status"].toString() == "success") {
|
if (rootObject.contains("status") && rootObject["status"].toString() == "success") {
|
||||||
if (rootObject.contains("data") && rootObject["data"].isObject()) {
|
if (rootObject.contains("data") && rootObject["data"].isObject()) {
|
||||||
_settings.unpack(rootObject["data"].toObject());
|
_settings.unpack(rootObject["data"].toObject());
|
||||||
|
_lastSuccessfulSyncTimestamp = _settings.lastChangeTimestamp();
|
||||||
|
|
||||||
|
qCDebug(networking) << "Received the Account Settings from the Metaverse API";
|
||||||
|
|
||||||
emit accountSettingsLoaded();
|
emit accountSettingsLoaded();
|
||||||
} else {
|
} else {
|
||||||
|
@ -874,6 +879,8 @@ void AccountManager::postAccountSettings() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qCDebug(networking) << "Account Settings have changed, pushing them to the Metaverse API";
|
||||||
|
|
||||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||||
|
|
||||||
QUrl lockerURL = _authURL;
|
QUrl lockerURL = _authURL;
|
||||||
|
|
|
@ -64,6 +64,11 @@ void RecordingScriptingInterface::playClip(NetworkClipLoaderPointer clipLoader,
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecordingScriptingInterface::loadRecording(const QString& url, QScriptValue callback) {
|
void RecordingScriptingInterface::loadRecording(const QString& url, QScriptValue callback) {
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
BLOCKING_INVOKE_METHOD(this, "loadRecording", Q_ARG(const QString&, url), Q_ARG(QScriptValue, callback));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto clipLoader = DependencyManager::get<recording::ClipCache>()->getClipLoader(url);
|
auto clipLoader = DependencyManager::get<recording::ClipCache>()->getClipLoader(url);
|
||||||
|
|
||||||
if (clipLoader->isLoaded()) {
|
if (clipLoader->isLoaded()) {
|
||||||
|
@ -117,6 +122,11 @@ void RecordingScriptingInterface::startPlaying() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecordingScriptingInterface::setPlayerVolume(float volume) {
|
void RecordingScriptingInterface::setPlayerVolume(float volume) {
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
BLOCKING_INVOKE_METHOD(this, "setPlayerVolume", Q_ARG(float, volume));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_player->setVolume(std::min(std::max(volume, 0.0f), 1.0f));
|
_player->setVolume(std::min(std::max(volume, 0.0f), 1.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,6 +147,11 @@ void RecordingScriptingInterface::setPlayFromCurrentLocation(bool playFromCurren
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecordingScriptingInterface::setPlayerLoop(bool loop) {
|
void RecordingScriptingInterface::setPlayerLoop(bool loop) {
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
BLOCKING_INVOKE_METHOD(this, "setPlayerLoop", Q_ARG(bool, loop));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_player->loop(loop);
|
_player->loop(loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,6 +210,16 @@ void RecordingScriptingInterface::startRecording() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecordingScriptingInterface::stopRecording() {
|
void RecordingScriptingInterface::stopRecording() {
|
||||||
|
if (!_recorder->isRecording()) {
|
||||||
|
qCWarning(scriptengine) << "Recorder is not running";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
BLOCKING_INVOKE_METHOD(this, "stopRecording");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_recorder->stop();
|
_recorder->stop();
|
||||||
_lastClip = _recorder->getClip();
|
_lastClip = _recorder->getClip();
|
||||||
_lastClip->seek(0);
|
_lastClip->seek(0);
|
||||||
|
|
|
@ -25,8 +25,14 @@
|
||||||
* <tr>
|
* <tr>
|
||||||
* <td><strong>First Person</strong></td>
|
* <td><strong>First Person</strong></td>
|
||||||
* <td><code>"first person"</code></td>
|
* <td><code>"first person"</code></td>
|
||||||
* <td>The camera is positioned such that you have the same view as your avatar. The camera moves and rotates with your
|
* <td>Legacy first person camera mode. The camera is positioned such that you have the same view as your avatar.
|
||||||
* avatar.</td>
|
* The camera moves and rotates with your avatar.</td>
|
||||||
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <td><strong>First Person Look At</strong></td>
|
||||||
|
* <td><code>"first person look at"</code></td>
|
||||||
|
* <td>Default first person camera mode. The camera is positioned such that you have the same view as your avatar.
|
||||||
|
* The camera moves and rotates with your avatar's head.</td>
|
||||||
* </tr>
|
* </tr>
|
||||||
* <tr>
|
* <tr>
|
||||||
* <td><strong>Third Person</strong></td>
|
* <td><strong>Third Person</strong></td>
|
||||||
|
@ -73,6 +79,8 @@ CameraMode stringToMode(const QString& mode) {
|
||||||
return CAMERA_MODE_THIRD_PERSON;
|
return CAMERA_MODE_THIRD_PERSON;
|
||||||
} else if (mode == "first person") {
|
} else if (mode == "first person") {
|
||||||
return CAMERA_MODE_FIRST_PERSON;
|
return CAMERA_MODE_FIRST_PERSON;
|
||||||
|
} else if (mode == "first person look at") {
|
||||||
|
return CAMERA_MODE_FIRST_PERSON_LOOK_AT;
|
||||||
} else if (mode == "mirror") {
|
} else if (mode == "mirror") {
|
||||||
return CAMERA_MODE_MIRROR;
|
return CAMERA_MODE_MIRROR;
|
||||||
} else if (mode == "independent") {
|
} else if (mode == "independent") {
|
||||||
|
@ -92,6 +100,8 @@ QString modeToString(CameraMode mode) {
|
||||||
return "third person";
|
return "third person";
|
||||||
} else if (mode == CAMERA_MODE_FIRST_PERSON) {
|
} else if (mode == CAMERA_MODE_FIRST_PERSON) {
|
||||||
return "first person";
|
return "first person";
|
||||||
|
} else if (mode == CAMERA_MODE_FIRST_PERSON_LOOK_AT) {
|
||||||
|
return "first person look at";
|
||||||
} else if (mode == CAMERA_MODE_MIRROR) {
|
} else if (mode == CAMERA_MODE_MIRROR) {
|
||||||
return "mirror";
|
return "mirror";
|
||||||
} else if (mode == CAMERA_MODE_INDEPENDENT) {
|
} else if (mode == CAMERA_MODE_INDEPENDENT) {
|
||||||
|
|
|
@ -19,6 +19,7 @@ enum CameraMode
|
||||||
{
|
{
|
||||||
CAMERA_MODE_NULL = -1,
|
CAMERA_MODE_NULL = -1,
|
||||||
CAMERA_MODE_THIRD_PERSON,
|
CAMERA_MODE_THIRD_PERSON,
|
||||||
|
CAMERA_MODE_FIRST_PERSON_LOOK_AT,
|
||||||
CAMERA_MODE_FIRST_PERSON,
|
CAMERA_MODE_FIRST_PERSON,
|
||||||
CAMERA_MODE_MIRROR,
|
CAMERA_MODE_MIRROR,
|
||||||
CAMERA_MODE_INDEPENDENT,
|
CAMERA_MODE_INDEPENDENT,
|
||||||
|
|
|
@ -24,6 +24,10 @@ public:
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
|
|
||||||
static QWindow* findMainWindow();
|
static QWindow* findMainWindow();
|
||||||
|
|
||||||
|
// This offset is used for positioning children window relative to the main window.
|
||||||
|
void setDockedWidgetRelativePositionOffset(const QSize& newOffset) { _dockedWidgetRelativePositionOffset.setWidth(newOffset.width()); _dockedWidgetRelativePositionOffset.setHeight(newOffset.height()); }
|
||||||
|
QSize getDockedWidgetRelativePositionOffset() { return _dockedWidgetRelativePositionOffset; }
|
||||||
public slots:
|
public slots:
|
||||||
void restoreGeometry();
|
void restoreGeometry();
|
||||||
void saveGeometry();
|
void saveGeometry();
|
||||||
|
@ -46,6 +50,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
Setting::Handle<QRect> _windowGeometry;
|
Setting::Handle<QRect> _windowGeometry;
|
||||||
Setting::Handle<int> _windowState;
|
Setting::Handle<int> _windowState;
|
||||||
|
QSize _dockedWidgetRelativePositionOffset{ 0, 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__MainWindow__) */
|
#endif /* defined(__hifi__MainWindow__) */
|
||||||
|
|
|
@ -92,15 +92,19 @@ public:
|
||||||
ToolbarProxy(QObject* qmlObject, QObject* parent = nullptr);
|
ToolbarProxy(QObject* qmlObject, QObject* parent = nullptr);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
* <em>Currently doesn't work.</em>
|
||||||
* @function ToolbarProxy#addButton
|
* @function ToolbarProxy#addButton
|
||||||
* @param {object} properties
|
* @param {object} properties - Button properties
|
||||||
* @returns {ToolbarButtonProxy}
|
* @returns {object} The button added.
|
||||||
|
* @deprecated This method is deprecated and will be removed.
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE ToolbarButtonProxy* addButton(const QVariant& properties);
|
Q_INVOKABLE ToolbarButtonProxy* addButton(const QVariant& properties);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
* <em>Currently doesn't work.</em>
|
||||||
* @function ToolbarProxy#removeButton
|
* @function ToolbarProxy#removeButton
|
||||||
* @param {string} name
|
* @param {string} name - Button name.
|
||||||
|
* @deprecated This method is deprecated and will be removed.
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE void removeButton(const QVariant& name);
|
Q_INVOKABLE void removeButton(const QVariant& name);
|
||||||
|
|
||||||
|
|
|
@ -1,117 +1,38 @@
|
||||||
var isActive = false;
|
(function () {
|
||||||
|
|
||||||
var toolBar = (function() {
|
// Get the system toolbar.
|
||||||
var that = {},
|
var toolbar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system");
|
||||||
toolBar,
|
if (!toolbar) {
|
||||||
activeButton,
|
print("ERROR: Couldn't get system toolbar.");
|
||||||
newModelButton,
|
return;
|
||||||
newShapeButton,
|
|
||||||
newLightButton,
|
|
||||||
newTextButton,
|
|
||||||
newWebButton,
|
|
||||||
newZoneButton,
|
|
||||||
newParticleButton,
|
|
||||||
newMaterialButton
|
|
||||||
|
|
||||||
var toolIconUrl = Script.resolvePath("../../system/assets/images/tools/");
|
|
||||||
|
|
||||||
function initialize() {
|
|
||||||
print("Toolbars: " + Toolbars);
|
|
||||||
toolBar = Toolbars.getToolbar("highfidelity.edit.toolbar");
|
|
||||||
print("Toolbar: " + toolBar);
|
|
||||||
activeButton = toolBar.addButton({
|
|
||||||
objectName: "activeButton",
|
|
||||||
imageURL: toolIconUrl + "edit-01.svg",
|
|
||||||
visible: true,
|
|
||||||
alpha: 0.9,
|
|
||||||
});
|
|
||||||
|
|
||||||
print("Button " + activeButton);
|
|
||||||
print("Button signal " + activeButton.clicked);
|
|
||||||
activeButton.clicked.connect(function(){
|
|
||||||
print("Clicked on button " + isActive);
|
|
||||||
that.setActive(!isActive);
|
|
||||||
});
|
|
||||||
|
|
||||||
newModelButton = toolBar.addButton({
|
|
||||||
objectName: "newModelButton",
|
|
||||||
imageURL: toolIconUrl + "model-01.svg",
|
|
||||||
alpha: 0.9,
|
|
||||||
visible: false
|
|
||||||
});
|
|
||||||
|
|
||||||
newShapeButton = toolBar.addButton({
|
|
||||||
objectName: "newShapeButton",
|
|
||||||
imageURL: toolIconUrl + "cube-01.svg",
|
|
||||||
alpha: 0.9,
|
|
||||||
visible: false
|
|
||||||
});
|
|
||||||
|
|
||||||
newLightButton = toolBar.addButton({
|
|
||||||
objectName: "newLightButton",
|
|
||||||
imageURL: toolIconUrl + "light-01.svg",
|
|
||||||
alpha: 0.9,
|
|
||||||
visible: false
|
|
||||||
});
|
|
||||||
|
|
||||||
newTextButton = toolBar.addButton({
|
|
||||||
objectName: "newTextButton",
|
|
||||||
imageURL: toolIconUrl + "text-01.svg",
|
|
||||||
alpha: 0.9,
|
|
||||||
visible: false
|
|
||||||
});
|
|
||||||
|
|
||||||
newWebButton = toolBar.addButton({
|
|
||||||
objectName: "newWebButton",
|
|
||||||
imageURL: toolIconUrl + "web-01.svg",
|
|
||||||
alpha: 0.9,
|
|
||||||
visible: false
|
|
||||||
});
|
|
||||||
|
|
||||||
newZoneButton = toolBar.addButton({
|
|
||||||
objectName: "newZoneButton",
|
|
||||||
imageURL: toolIconUrl + "zone-01.svg",
|
|
||||||
alpha: 0.9,
|
|
||||||
visible: false
|
|
||||||
});
|
|
||||||
|
|
||||||
newParticleButton = toolBar.addButton({
|
|
||||||
objectName: "newParticleButton",
|
|
||||||
imageURL: toolIconUrl + "particle-01.svg",
|
|
||||||
alpha: 0.9,
|
|
||||||
visible: false
|
|
||||||
});
|
|
||||||
|
|
||||||
newMaterialButton = toolBar.addButton({
|
|
||||||
objectName: "newMaterialButton",
|
|
||||||
imageURL: toolIconUrl + "material-01.svg",
|
|
||||||
alpha: 0.9,
|
|
||||||
visible: false
|
|
||||||
});
|
|
||||||
|
|
||||||
that.setActive(false);
|
|
||||||
newModelButton.clicked();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
that.setActive = function(active) {
|
Script.setTimeout(function () {
|
||||||
if (active != isActive) {
|
// Report the system toolbar visibility.
|
||||||
isActive = active;
|
var isToolbarVisible = toolbar.readProperty("visible");
|
||||||
that.showTools(isActive);
|
print("Toolbar visible: " + isToolbarVisible);
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Sets visibility of tool buttons, excluding the power button
|
// Briefly toggle the system toolbar visibility.
|
||||||
that.showTools = function(doShow) {
|
print("Toggle toolbar");
|
||||||
newModelButton.writeProperty('visible', doShow);
|
toolbar.writeProperty("visible", !isToolbarVisible);
|
||||||
newShapeButton.writeProperty('visible', doShow);
|
Script.setTimeout(function () {
|
||||||
newLightButton.writeProperty('visible', doShow);
|
print("Toggle toolbar");
|
||||||
newTextButton.writeProperty('visible', doShow);
|
toolbar.writeProperty("visible", isToolbarVisible);
|
||||||
newWebButton.writeProperty('visible', doShow);
|
}, 2000);
|
||||||
newZoneButton.writeProperty('visible', doShow);
|
}, 2000);
|
||||||
newParticleButton.writeProperty('visible', doShow);
|
|
||||||
newMaterialButton.writeProperty('visible', doShow);
|
Script.setTimeout(function () {
|
||||||
};
|
// Report the system toolbar visibility alternative method.
|
||||||
|
isToolbarVisible = toolbar.readProperties(["visible"]).visible;
|
||||||
|
print("Toolbar visible: " + isToolbarVisible);
|
||||||
|
|
||||||
|
// Briefly toggle the system toolbar visibility.
|
||||||
|
print("Toggle toolbar");
|
||||||
|
toolbar.writeProperties({ visible: !isToolbarVisible });
|
||||||
|
Script.setTimeout(function () {
|
||||||
|
print("Toggle toolbar");
|
||||||
|
toolbar.writeProperties({ visible: isToolbarVisible });
|
||||||
|
}, 2000);
|
||||||
|
}, 6000);
|
||||||
|
|
||||||
initialize();
|
|
||||||
return that;
|
|
||||||
}());
|
}());
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
//
|
||||||
|
// PropItem.qml
|
||||||
|
//
|
||||||
|
// Created by Sam Gateau on 3/2/2019
|
||||||
|
// Copyright 2019 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
|
||||||
|
|
||||||
|
PropItem {
|
||||||
|
Global { id: global }
|
||||||
|
id: root
|
||||||
|
|
||||||
|
// Scalar Prop
|
||||||
|
// property bool integral: false
|
||||||
|
// property var numDigits: 2
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: valueLabel
|
||||||
|
|
||||||
|
anchors.left: root.splitter.right
|
||||||
|
anchors.right: root.right
|
||||||
|
anchors.verticalCenter: root.verticalCenter
|
||||||
|
// horizontalAlignment: global.valueTextAlign
|
||||||
|
height: global.slimHeight
|
||||||
|
|
||||||
|
function getColor() {
|
||||||
|
var c = root.valueVarGetter();
|
||||||
|
return Qt.rgba(c.red, c.green, c.blue, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// background: Rectangle {
|
||||||
|
color: { return getColor() }
|
||||||
|
border.color: global.colorBorderLight
|
||||||
|
border.width: global.valueBorderWidth
|
||||||
|
radius: global.valueBorderRadius
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,12 +13,19 @@ import QtQuick.Layouts 1.3
|
||||||
|
|
||||||
import stylesUit 1.0
|
import stylesUit 1.0
|
||||||
import controlsUit 1.0 as HifiControls
|
import controlsUit 1.0 as HifiControls
|
||||||
|
import "../lib/prop" as Prop
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
HifiConstants { id: hifi;}
|
HifiConstants { id: hifi;}
|
||||||
color: Qt.rgba(hifi.colors.baseGray.r, hifi.colors.baseGray.g, hifi.colors.baseGray.b, 0.8);
|
color: Qt.rgba(hifi.colors.baseGray.r, hifi.colors.baseGray.g, hifi.colors.baseGray.b, 0.8);
|
||||||
id: root;
|
id: root;
|
||||||
|
|
||||||
|
property var theMaterial: {}
|
||||||
|
property var theMaterialAttributes: {}
|
||||||
|
property var hasMaterial: false
|
||||||
|
|
||||||
|
property var isReadOnly: true
|
||||||
|
|
||||||
function fromScript(message) {
|
function fromScript(message) {
|
||||||
switch (message.method) {
|
switch (message.method) {
|
||||||
case "setObjectInfo":
|
case "setObjectInfo":
|
||||||
|
@ -26,10 +33,19 @@ Rectangle {
|
||||||
break;
|
break;
|
||||||
case "setMaterialJSON":
|
case "setMaterialJSON":
|
||||||
materialJSONText.text = message.params.materialJSONText;
|
materialJSONText.text = message.params.materialJSONText;
|
||||||
|
|
||||||
|
theMaterial = JSON.parse(message.params.materialJSONText)
|
||||||
|
theMaterialAttributes = theMaterial.materials
|
||||||
|
hasMaterial = (theMaterial !== undefined)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: entityIDContainer
|
id: entityIDContainer
|
||||||
height: 52
|
height: 52
|
||||||
|
@ -45,8 +61,171 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Prop.PropString {
|
||||||
|
visible: hasMaterial && ("name" in theMaterialAttributes)
|
||||||
|
label: "name"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "name"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
Prop.PropString {
|
||||||
|
visible: hasMaterial && ("model" in theMaterialAttributes)
|
||||||
|
label: "model"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "model"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
Prop.PropColor {
|
||||||
|
visible: hasMaterial && ("albedo" in theMaterialAttributes)
|
||||||
|
label: "albedo"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "albedo"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
Prop.PropString {
|
||||||
|
visible: hasMaterial && ("albedoMap" in theMaterialAttributes)
|
||||||
|
label: "albedoMap"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "albedoMap"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
Prop.PropScalar {
|
||||||
|
visible: hasMaterial && ("opacity" in theMaterialAttributes)
|
||||||
|
label: "opacity"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "opacity"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
Prop.PropString {
|
||||||
|
visible: hasMaterial && ("opacityMap" in theMaterialAttributes)
|
||||||
|
label: "opacityMap"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "opacityMap"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
Prop.PropString {
|
||||||
|
visible: hasMaterial && ("opacityMapMode" in theMaterialAttributes)
|
||||||
|
label: "opacityMapMode"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "opacityMapMode"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
/*Prop.PropEnum {
|
||||||
|
visible: hasMaterial && ("opacityMapMode" in theMaterialAttributes)
|
||||||
|
label: "opacityMapMode"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "opacityMapMode"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
enums: ["None", "Mask", "Blend"]
|
||||||
|
} */
|
||||||
|
Prop.PropScalar {
|
||||||
|
visible: hasMaterial && ("opacityCutoff" in theMaterialAttributes)
|
||||||
|
label: "opacity Cutoff"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "opacityCutoff"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
Prop.PropString {
|
||||||
|
visible: hasMaterial && ("occlusionMap" in theMaterialAttributes)
|
||||||
|
label: "occlusionMap"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "occlusionMap"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
Prop.PropString {
|
||||||
|
visible: hasMaterial && ("normalMap" in theMaterialAttributes)
|
||||||
|
label: "normalMap"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "normalMap"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
Prop.PropString {
|
||||||
|
visible: hasMaterial && ("bumpMap" in theMaterialAttributes)
|
||||||
|
label: "normalMap from bumpMap"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "bumpMap"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
Prop.PropScalar {
|
||||||
|
visible: hasMaterial && ("roughness" in theMaterialAttributes)
|
||||||
|
label: "roughness"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "roughness"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
Prop.PropScalar {
|
||||||
|
visible: hasMaterial && ("metallic" in theMaterialAttributes)
|
||||||
|
label: "metallic"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "metallic"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
Prop.PropString {
|
||||||
|
visible: hasMaterial && ("roughnessMap" in theMaterialAttributes)
|
||||||
|
label: "roughnessMap"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "roughnessMap"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
Prop.PropString {
|
||||||
|
visible: hasMaterial && ("glossMap" in theMaterialAttributes)
|
||||||
|
label: "roughnessMap from glossMap"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "glossMap"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
Prop.PropString {
|
||||||
|
visible: hasMaterial && ("metallicMap" in theMaterialAttributes)
|
||||||
|
label: "metallicMap"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "metallicMap"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
Prop.PropString {
|
||||||
|
visible: hasMaterial && ("specularMap" in theMaterialAttributes)
|
||||||
|
label: "metallicMap from specularMap"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "specularMap"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
Prop.PropScalar {
|
||||||
|
visible: hasMaterial && ("scattering" in theMaterialAttributes)
|
||||||
|
label: "scattering"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "scattering"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
Prop.PropString {
|
||||||
|
visible: hasMaterial && ("scatteringMap" in theMaterialAttributes)
|
||||||
|
label: "scatteringMap"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "scatteringMap"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Prop.PropColor {
|
||||||
|
visible: hasMaterial && ("emissive" in theMaterialAttributes)
|
||||||
|
label: "emissive"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "emissive"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
Prop.PropString {
|
||||||
|
visible: hasMaterial && ("emissiveMap" in theMaterialAttributes)
|
||||||
|
label: "emissiveMap"
|
||||||
|
object: theMaterialAttributes
|
||||||
|
property: "emissiveMap"
|
||||||
|
readOnly: isReadOnly
|
||||||
|
}
|
||||||
|
|
||||||
Original.ScrollView {
|
Original.ScrollView {
|
||||||
anchors.top: entityIDContainer.bottom
|
// anchors.top: entityIDContainer.bottom
|
||||||
height: root.height - entityIDContainer.height
|
height: root.height - entityIDContainer.height
|
||||||
width: root.width
|
width: root.width
|
||||||
clip: true
|
clip: true
|
||||||
|
@ -63,3 +242,4 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -444,17 +444,9 @@ function updateEmoteIndicatorIcon(iconURL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function onGeometryChanged(rect) {
|
|
||||||
updateEmoteAppBarPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function onWindowMinimizedChanged(isMinimized) {
|
function onWindowMinimizedChanged(isMinimized) {
|
||||||
if (isMinimized) {
|
isWindowMinimized = isMinimized;
|
||||||
handleEmoteIndicatorVisibleChanged(false);
|
maybeChangeEmoteIndicatorVisibility(!isMinimized);
|
||||||
} else if (!HMD.active) {
|
|
||||||
handleEmoteIndicatorVisibleChanged(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -539,10 +531,11 @@ function showEmoteAppBar() {
|
||||||
x: EMOTE_APP_BAR_WIDTH_PX,
|
x: EMOTE_APP_BAR_WIDTH_PX,
|
||||||
y: EMOTE_APP_BAR_HEIGHT_PX
|
y: EMOTE_APP_BAR_HEIGHT_PX
|
||||||
},
|
},
|
||||||
position: {
|
relativePosition: {
|
||||||
x: Window.x + EMOTE_APP_BAR_LEFT_MARGIN,
|
x: EMOTE_APP_BAR_LEFT_MARGIN,
|
||||||
y: Window.y + Window.innerHeight - EMOTE_APP_BAR_BOTTOM_MARGIN
|
y: EMOTE_APP_BAR_BOTTOM_MARGIN
|
||||||
},
|
},
|
||||||
|
relativePositionAnchor: Desktop.RelativePositionAnchor.BOTTOM_LEFT,
|
||||||
overrideFlags: EMOTE_APP_BAR_WINDOW_FLAGS
|
overrideFlags: EMOTE_APP_BAR_WINDOW_FLAGS
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -550,10 +543,18 @@ function showEmoteAppBar() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function handleEmoteIndicatorVisibleChanged(shouldBeVisible) {
|
// There is currently no property in the Window Scripting Interface to determine
|
||||||
if (shouldBeVisible && !emoteAppBarWindow) {
|
// whether the Interface window is currently minimized. This feels like an oversight.
|
||||||
|
// We should add that functionality to the Window Scripting Interface, and remove `isWindowMinimized` below.
|
||||||
|
var isWindowMinimized = false;
|
||||||
|
function maybeChangeEmoteIndicatorVisibility(desiredVisibility) {
|
||||||
|
if (isWindowMinimized || HMD.active) {
|
||||||
|
desiredVisibility = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desiredVisibility && !emoteAppBarWindow) {
|
||||||
showEmoteAppBar();
|
showEmoteAppBar();
|
||||||
} else if (emoteAppBarWindow) {
|
} else if (!desiredVisibility && emoteAppBarWindow) {
|
||||||
emoteAppBarWindow.fromQml.disconnect(onMessageFromEmoteAppBar);
|
emoteAppBarWindow.fromQml.disconnect(onMessageFromEmoteAppBar);
|
||||||
emoteAppBarWindow.close();
|
emoteAppBarWindow.close();
|
||||||
emoteAppBarWindow = false;
|
emoteAppBarWindow = false;
|
||||||
|
@ -561,23 +562,25 @@ function handleEmoteIndicatorVisibleChanged(shouldBeVisible) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function handleFTUEScreensVisibilityChanged(ftueScreenVisible) {
|
||||||
|
maybeChangeEmoteIndicatorVisibility(!ftueScreenVisible);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function onDisplayModeChanged(isHMDMode) {
|
function onDisplayModeChanged(isHMDMode) {
|
||||||
reactionsBegun.forEach(function(react) {
|
reactionsBegun.forEach(function(react) {
|
||||||
endReactionWrapper(react);
|
endReactionWrapper(react);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isHMDMode) {
|
maybeChangeEmoteIndicatorVisibility(!isHMDMode);
|
||||||
handleEmoteIndicatorVisibleChanged(false);
|
|
||||||
} else {
|
|
||||||
handleEmoteIndicatorVisibleChanged(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var emojiAPI = Script.require("./emojiApp/simplifiedEmoji.js?" + Date.now());
|
var emojiAPI = Script.require("./emojiApp/simplifiedEmoji.js");
|
||||||
var keyPressSignalsConnected = false;
|
var keyPressSignalsConnected = false;
|
||||||
var emojiCodeMap;
|
var emojiCodeMap;
|
||||||
var customEmojiCodeMap;
|
var customEmojiCodeMap;
|
||||||
|
var _this;
|
||||||
function setup() {
|
function setup() {
|
||||||
deleteOldReticles();
|
deleteOldReticles();
|
||||||
|
|
||||||
|
@ -605,16 +608,25 @@ function setup() {
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
Window.minimizedChanged.connect(onWindowMinimizedChanged);
|
Window.minimizedChanged.connect(onWindowMinimizedChanged);
|
||||||
Window.geometryChanged.connect(onGeometryChanged);
|
|
||||||
HMD.displayModeChanged.connect(onDisplayModeChanged);
|
HMD.displayModeChanged.connect(onDisplayModeChanged);
|
||||||
|
|
||||||
getSounds();
|
getSounds();
|
||||||
handleEmoteIndicatorVisibleChanged(true);
|
maybeChangeEmoteIndicatorVisibility(true);
|
||||||
|
|
||||||
Controller.keyPressEvent.connect(keyPressHandler);
|
Controller.keyPressEvent.connect(keyPressHandler);
|
||||||
Controller.keyReleaseEvent.connect(keyReleaseHandler);
|
Controller.keyReleaseEvent.connect(keyReleaseHandler);
|
||||||
keyPressSignalsConnected = true;
|
keyPressSignalsConnected = true;
|
||||||
Script.scriptEnding.connect(unload);
|
Script.scriptEnding.connect(unload);
|
||||||
|
|
||||||
|
function Emote() {
|
||||||
|
_this = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Emote.prototype = {
|
||||||
|
handleFTUEScreensVisibilityChanged: handleFTUEScreensVisibilityChanged
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Emote();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -638,7 +650,6 @@ function unload() {
|
||||||
maybeDeleteRemoteIndicatorTimeout();
|
maybeDeleteRemoteIndicatorTimeout();
|
||||||
|
|
||||||
Window.minimizedChanged.disconnect(onWindowMinimizedChanged);
|
Window.minimizedChanged.disconnect(onWindowMinimizedChanged);
|
||||||
Window.geometryChanged.disconnect(onGeometryChanged);
|
|
||||||
HMD.displayModeChanged.disconnect(onDisplayModeChanged);
|
HMD.displayModeChanged.disconnect(onDisplayModeChanged);
|
||||||
|
|
||||||
if (keyPressSignalsConnected) {
|
if (keyPressSignalsConnected) {
|
||||||
|
@ -671,7 +682,6 @@ function unload() {
|
||||||
// #region EMOJI_UTILITY
|
// #region EMOJI_UTILITY
|
||||||
|
|
||||||
|
|
||||||
var EMOJI_52_BASE_URL = "../../resources/images/emojis/52px/";
|
|
||||||
function selectedEmoji(code) {
|
function selectedEmoji(code) {
|
||||||
emojiAPI.addEmoji(code);
|
emojiAPI.addEmoji(code);
|
||||||
// this URL needs to be relative to SimplifiedEmoteIndicator.qml
|
// this URL needs to be relative to SimplifiedEmoteIndicator.qml
|
||||||
|
@ -786,4 +796,6 @@ function toggleEmojiApp() {
|
||||||
// END EMOJI
|
// END EMOJI
|
||||||
// *************************************
|
// *************************************
|
||||||
|
|
||||||
setup();
|
var emote = setup();
|
||||||
|
|
||||||
|
module.exports = emote;
|
|
@ -1,15 +1,40 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Generator: Adobe Illustrator 23.0.6, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
<!-- Generator: Adobe Illustrator 23.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
|
||||||
viewBox="0 0 93.7 127.8" style="enable-background:new 0 0 93.7 127.8;" xml:space="preserve">
|
<!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
|
||||||
<path d="M91.9,97c-7.6,9.6-17.8,16.7-29.3,20.3h-0.1c-0.4,0.1-0.8,0.3-1.3,0.4c-4.6,1.3-9.5,2-14.4,2c-4.9,0-9.8-0.7-14.4-2
|
<!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
|
||||||
c-0.4-0.1-0.8-0.3-1.3-0.4h-0.1C19.6,113.8,9.4,106.6,1.8,97c0,0-0.5-0.5-0.9,0.1C0.6,97.6,1,98.5,1,98.5
|
<!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
|
||||||
C9.9,116,27,127.8,46.8,127.8l0,0c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0l0,0c19.7-0.1,36.8-11.8,45.8-29.3c0,0,0.4-0.9,0.1-1.4
|
<!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
|
||||||
C92.4,96.6,91.9,97,91.9,97z M91.9,78.8C84.3,88.4,74.1,95.5,62.6,99h-0.1c-0.4,0.1-0.8,0.3-1.3,0.4c-4.6,1.3-9.5,2-14.4,2
|
<!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
|
||||||
c-4.9,0-9.8-0.7-14.4-2c-0.4-0.1-0.8-0.3-1.3-0.4h-0.1C19.6,95.5,9.4,88.4,1.8,78.8c0,0-0.5-0.5-0.9,0.1C0.6,79.3,1,80.2,1,80.2
|
<!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
|
||||||
c8.9,17.5,26.1,29.2,45.8,29.3l0,0c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0l0,0c19.7-0.1,36.8-11.8,45.8-29.3c0,0,0.4-0.9,0.1-1.4
|
<!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
|
||||||
C92.4,78.3,91.9,78.8,91.9,78.8z M46.9,92.7c25.8,0,46.9-20.7,46.9-46.4S72.7,0,46.9,0S0,20.7,0,46.4S20.9,92.7,46.9,92.7z
|
<!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
|
||||||
M65.5,30.8c2.8,0,5,2.2,5,5s-2.2,5-5,5c-2.8,0-5-2.2-5-5S62.8,30.8,65.5,30.8z M36,54.3c2.7,3.2,6.6,5,10.8,5s8.2-1.9,10.8-5
|
]>
|
||||||
c0.9-1.1,2.7-1.2,3.8-0.4c1.1,0.9,1.3,2.6,0.3,3.7c-3.7,4.4-9.1,6.9-14.9,6.9c-5.8,0-11.2-2.5-14.9-6.9c-0.9-1.1-0.8-2.7,0.3-3.7
|
<svg version="1.1" id="Layer_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
|
||||||
C33.4,53.1,35,53.2,36,54.3z M28.1,30.8c2.8,0,5,2.2,5,5s-2.2,5-5,5c-2.8,0-5-2.2-5-5S25.3,30.8,28.1,30.8z"/>
|
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 52.8 49"
|
||||||
|
style="enable-background:new 0 0 52.8 49;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{opacity:0.7;}
|
||||||
|
.st1{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<metadata>
|
||||||
|
<sfw xmlns="&ns_sfw;">
|
||||||
|
<slices></slices>
|
||||||
|
<sliceSourceBounds bottomLeftOrigin="true" height="49" width="52.8" x="8.3" y="11.1"></sliceSourceBounds>
|
||||||
|
</sfw>
|
||||||
|
</metadata>
|
||||||
|
<g class="st0">
|
||||||
|
<path class="st1" d="M10.3,47.8c5.1,0.8,10.3,1.2,15.3,1.2c0.3,0,0.6,0,0.8,0c5.4-0.1,10.8-0.6,16.2-1.5c4-0.8,7.8-4.5,8.7-8.5
|
||||||
|
c1-4.8,1.5-9.8,1.5-14.6s-0.5-9.8-1.5-14.6c-0.8-3.9-4.7-7.6-8.7-8.4C37.3,0.6,31.8,0,26.4,0c-5.3-0.1-10.8,0.3-16.2,1.2
|
||||||
|
c-4,0.7-7.9,4.5-8.7,8.5c-1,5-1.5,9.9-1.5,14.9s0.5,9.9,1.5,14.9C2.4,43.3,6.2,47.1,10.3,47.8z M6.2,10.6C6.7,8.6,9,6.3,11,5.9
|
||||||
|
c4.9-0.8,9.7-1.2,14.6-1.2c0.3,0,0.6,0,0.8,0c5.1,0.1,10.3,0.6,15.3,1.4c2,0.4,4.4,2.7,4.8,4.6c0.9,4.5,1.3,9.1,1.3,13.7
|
||||||
|
s-0.4,9.1-1.3,13.6c-0.4,1.9-2.8,4.3-4.8,4.7c-5.1,0.9-10.3,1.4-15.3,1.4c-5.1,0.1-10.3-0.3-15.3-1.2c-2-0.3-4.4-2.7-4.8-4.6
|
||||||
|
c-0.9-4.6-1.4-9.3-1.4-14C4.9,19.9,5.3,15.1,6.2,10.6z"/>
|
||||||
|
<path class="st1" d="M14.1,32.3c-0.3,0.9-0.1,1.9,0.6,2.6c0.2,0.2,5,4.5,11,4.5c0.6,0,1.2-0.1,1.8-0.1c6.8-1,10.7-7.6,11-7.9
|
||||||
|
c0.5-0.8,0.4-1.9-0.1-2.7c-0.6-0.8-1.6-1.1-2.6-0.9c-6.4,1.7-12.9,2.7-19.5,2.9C15.3,30.8,14.5,31.4,14.1,32.3z"/>
|
||||||
|
<path class="st1" d="M17.1,25.7c3.4,0,6.2-2.8,6.2-6.2c0-3.4-2.8-6.2-6.2-6.2c-3.4,0-6.2,2.8-6.2,6.2C10.8,23,13.6,25.7,17.1,25.7z
|
||||||
|
"/>
|
||||||
|
<path class="st1" d="M34.3,20.4h4.2c1.3,0,2.3-1,2.3-2.3c0-1.3-1-2.3-2.3-2.3h-4.2c-1.3,0-2.3,1-2.3,2.3
|
||||||
|
C32,19.5,33.1,20.4,34.3,20.4z"/>
|
||||||
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.5 KiB |
350
scripts/simplifiedUI/ui/simplifiedFTUE/InitialLaunchWindow.qml
Normal file
|
@ -0,0 +1,350 @@
|
||||||
|
//
|
||||||
|
// InitialLaunchWindow.qml
|
||||||
|
//
|
||||||
|
// Copyright 2019 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
|
||||||
|
//
|
||||||
|
|
||||||
|
import QtQuick 2.10
|
||||||
|
import QtQuick.Controls 2.3
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
import stylesUit 1.0 as HifiStylesUit
|
||||||
|
import TabletScriptingInterface 1.0
|
||||||
|
import hifi.simplifiedUI.simplifiedConstants 1.0 as SimplifiedConstants
|
||||||
|
import hifi.simplifiedUI.simplifiedControls 1.0 as SimplifiedControls
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
color: simplifiedUI.colors.white
|
||||||
|
anchors.fill: parent
|
||||||
|
property bool landscapeOrientation: root.width > root.height
|
||||||
|
|
||||||
|
SimplifiedConstants.SimplifiedConstants {
|
||||||
|
id: simplifiedUI
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
var debugFTUE = Settings.getValue("simplifiedUI/debugFTUE", 0);
|
||||||
|
|
||||||
|
if ((debugFTUE !== 1 &&
|
||||||
|
(Settings.getValue("simplifiedUI/alreadyAutoSelectedAvatarFromInventory", false) ||
|
||||||
|
Settings.getValue("simplifiedUI/closedAvatarPageOfInitialLaunchWindow", false))) ||
|
||||||
|
debugFTUE === 2) {
|
||||||
|
tempAvatarPageContainer.visible = false;
|
||||||
|
controlsContainer.visible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: tempAvatarPageContainer
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: contentContainer
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: firstPageBottomBarContainer.top
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: avatarImage
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
height: Math.max(parent.height - 48, 350)
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 12
|
||||||
|
source: resourceDirectoryUrl + "qml/hifi/simplifiedUI/avatarApp/images/" +
|
||||||
|
MyAvatar.skeletonModelURL.substring(MyAvatar.skeletonModelURL.indexOf("simplifiedAvatar"), MyAvatar.skeletonModelURL.lastIndexOf("/")) + ".png"
|
||||||
|
mipmap: true
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
}
|
||||||
|
|
||||||
|
Flickable {
|
||||||
|
id: textContainer
|
||||||
|
clip: true
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 128
|
||||||
|
anchors.bottom: qrAndInstructionsContainer.top
|
||||||
|
anchors.bottomMargin: 32
|
||||||
|
anchors.left: avatarImage.right
|
||||||
|
anchors.leftMargin: 48
|
||||||
|
anchors.right: parent.right
|
||||||
|
contentWidth: width
|
||||||
|
contentHeight: contentItem.childrenRect.height
|
||||||
|
interactive: contentHeight > height
|
||||||
|
|
||||||
|
HifiStylesUit.RalewayBold {
|
||||||
|
id: headerText
|
||||||
|
text: "We know this isn't you..."
|
||||||
|
color: simplifiedUI.colors.text.black
|
||||||
|
size: 48
|
||||||
|
height: paintedHeight
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 16
|
||||||
|
}
|
||||||
|
|
||||||
|
HifiStylesUit.RalewayRegular {
|
||||||
|
id: descriptionText
|
||||||
|
anchors.top: headerText.bottom
|
||||||
|
anchors.topMargin: 10
|
||||||
|
anchors.left: parent.left
|
||||||
|
width: Math.min(700, parent.width) - headerText.anchors.rightMargin
|
||||||
|
height: paintedHeight
|
||||||
|
text: "...but we've given you this <b>temporary avatar</b> to use " +
|
||||||
|
"for today. If you see this avatar in-world, walk up and " +
|
||||||
|
"say hello to other new users!<br><br>" +
|
||||||
|
"<b>We want you to be you</b> so we've built " +
|
||||||
|
'<a href="https://www.highfidelity.com/knowledge/virtual-you/">Virtual You</a>, an Avatar Creator ' +
|
||||||
|
"App. Creating an avatar is as easy as taking a selfie and picking your " +
|
||||||
|
"outfits! Available now on iOS and Android."
|
||||||
|
color: simplifiedUI.colors.text.black
|
||||||
|
size: 22
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
|
||||||
|
onLinkActivated: {
|
||||||
|
Qt.openUrlExternally(link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: qrAndInstructionsContainer
|
||||||
|
anchors.left: avatarImage.right
|
||||||
|
anchors.leftMargin: 48
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 16
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
height: 130
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: avatarAppQRCodeImage
|
||||||
|
source: resourceDirectoryUrl + "qml/hifi/simplifiedUI/avatarApp/images/qrCode.jpg"
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
width: 130
|
||||||
|
mipmap: true
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
}
|
||||||
|
|
||||||
|
HifiStylesUit.RalewayBold {
|
||||||
|
id: instructionText
|
||||||
|
anchors.top: avatarAppQRCodeImage.top
|
||||||
|
anchors.bottom: avatarAppQRCodeImage.bottom
|
||||||
|
anchors.left: avatarAppQRCodeImage.right
|
||||||
|
anchors.leftMargin: 30
|
||||||
|
anchors.right: parent.right
|
||||||
|
text: "Use your mobile phone to scan this QR code."
|
||||||
|
color: simplifiedUI.colors.text.black
|
||||||
|
size: 22
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SimplifiedControls.VerticalScrollBar {
|
||||||
|
parent: textContainer
|
||||||
|
visible: parent.contentHeight > parent.height
|
||||||
|
size: parent.height / parent.contentHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: firstPageBottomBarContainer
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 32
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 32
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
height: continueLink.height + 48
|
||||||
|
|
||||||
|
HifiStylesUit.RalewayBold {
|
||||||
|
id: continueLink
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: "Continue >"
|
||||||
|
width: parent.width
|
||||||
|
height: paintedHeight
|
||||||
|
color: simplifiedUI.colors.text.lightBlue
|
||||||
|
opacity: continueMouseArea.containsMouse ? 1.0 : 0.7
|
||||||
|
size: 36
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: continueMouseArea
|
||||||
|
hoverEnabled: true
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
Tablet.playSound(TabletEnums.ButtonClick);
|
||||||
|
tempAvatarPageContainer.visible = false;
|
||||||
|
Settings.setValue("simplifiedUI/closedAvatarPageOfInitialLaunchWindow", true);
|
||||||
|
controlsContainer.visible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: controlsContainer
|
||||||
|
visible: false
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
HifiStylesUit.RalewayRegular {
|
||||||
|
id: controlsDescriptionText
|
||||||
|
text: "Use these avatar controls to<br><b>interact with and move around in your new HQ.</b>"
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 48
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 32
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 32
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
height: paintedHeight
|
||||||
|
color: simplifiedUI.colors.text.black
|
||||||
|
size: 36
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
anchors.top: controlsDescriptionText.bottom
|
||||||
|
anchors.topMargin: 16
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: bottomBarContainer.top
|
||||||
|
|
||||||
|
GridView {
|
||||||
|
id: controlsGrid
|
||||||
|
property int maxColumns: 2
|
||||||
|
property int idealCellWidth: 361
|
||||||
|
anchors.fill: parent
|
||||||
|
clip: true
|
||||||
|
cellWidth: width / Math.min(Math.floor(width / idealCellWidth), maxColumns)
|
||||||
|
cellHeight: 225
|
||||||
|
model: ListModel {
|
||||||
|
ListElement {
|
||||||
|
imageHeight: 198
|
||||||
|
imageSource: "images/walkingControls.png"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
imageHeight: 193
|
||||||
|
imageSource: "images/mouseControls.png"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
imageHeight: 146
|
||||||
|
imageSource: "images/runJumpControls.png"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
imageHeight: 96
|
||||||
|
imageSource: "images/cameraControls.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delegate: Rectangle {
|
||||||
|
height: GridView.view.cellHeight
|
||||||
|
width: GridView.view.cellWidth
|
||||||
|
Image {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: parent.GridView.view.idealCellWidth
|
||||||
|
height: model.imageHeight
|
||||||
|
source: model.imageSource
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SimplifiedControls.VerticalScrollBar {
|
||||||
|
parent: controlsGrid
|
||||||
|
anchors.topMargin: 96
|
||||||
|
anchors.bottomMargin: anchors.topMargin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: bottomBarContainer
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 32
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 32
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
height: iHaveAGoodGrip.height + learnMoreLink.height + 48
|
||||||
|
|
||||||
|
HifiStylesUit.RalewayBold {
|
||||||
|
id: iHaveAGoodGrip
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: "I've got a good grip on the controls."
|
||||||
|
width: parent.width
|
||||||
|
height: paintedHeight
|
||||||
|
color: simplifiedUI.colors.text.lightBlue
|
||||||
|
opacity: goodGripMouseArea.containsMouse ? 1.0 : 0.7
|
||||||
|
size: 36
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: goodGripMouseArea
|
||||||
|
hoverEnabled: true
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
Tablet.playSound(TabletEnums.ButtonClick);
|
||||||
|
sendToScript({
|
||||||
|
"source": "InitialLaunchWindow.qml",
|
||||||
|
"method": "closeInitialLaunchWindow"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HifiStylesUit.RalewayBold {
|
||||||
|
id: learnMoreLink
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 16
|
||||||
|
anchors.top: iHaveAGoodGrip.bottom
|
||||||
|
anchors.topMargin: 8
|
||||||
|
text: "Learn more about our controls."
|
||||||
|
width: paintedWidth
|
||||||
|
height: paintedHeight
|
||||||
|
color: simplifiedUI.colors.text.lightBlue
|
||||||
|
opacity: learnMoreAboutControlsMouseArea.containsMouse ? 1.0 : 0.7
|
||||||
|
size: 14
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: learnMoreAboutControlsMouseArea
|
||||||
|
hoverEnabled: true
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
Tablet.playSound(TabletEnums.ButtonClick);
|
||||||
|
Qt.openUrlExternally("https://www.highfidelity.com/knowledge/get-around");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: topLeftAccentImage
|
||||||
|
width: 400
|
||||||
|
height: 180
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.top: parent.top
|
||||||
|
source: "images/defaultTopLeft.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: bottomRightAccentImage
|
||||||
|
width: 80
|
||||||
|
height: 250
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
source: "images/defaultBottomRight.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
signal sendToScript(var message);
|
||||||
|
}
|
186
scripts/simplifiedUI/ui/simplifiedFTUE/SecondLaunchWindow.qml
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
//
|
||||||
|
// SecondLaunchWindow.qml
|
||||||
|
//
|
||||||
|
// Copyright 2019 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
|
||||||
|
//
|
||||||
|
|
||||||
|
import QtQuick 2.10
|
||||||
|
import QtQuick.Controls 2.3
|
||||||
|
import QtGraphicalEffects 1.0
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
import stylesUit 1.0 as HifiStylesUit
|
||||||
|
import TabletScriptingInterface 1.0
|
||||||
|
import hifi.simplifiedUI.simplifiedConstants 1.0 as SimplifiedConstants
|
||||||
|
import hifi.simplifiedUI.simplifiedControls 1.0 as SimplifiedControls
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
color: simplifiedUI.colors.white
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
SimplifiedConstants.SimplifiedConstants {
|
||||||
|
id: simplifiedUI
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: contentContainer
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: continueLink.top
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: avatarImage
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
height: Math.max(parent.height - 48, 350)
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 12
|
||||||
|
source: resourceDirectoryUrl + "qml/hifi/simplifiedUI/avatarApp/images/hero.png"
|
||||||
|
mipmap: true
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 196
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: 32
|
||||||
|
anchors.left: avatarImage.right
|
||||||
|
anchors.leftMargin: 48
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
Flickable {
|
||||||
|
id: textContainer
|
||||||
|
clip: true
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
width: Math.min(700, parent.width)
|
||||||
|
contentWidth: width
|
||||||
|
contentHeight: contentItem.childrenRect.height
|
||||||
|
interactive: contentHeight > height
|
||||||
|
|
||||||
|
HifiStylesUit.RalewayBold {
|
||||||
|
id: headerText
|
||||||
|
text: "Stand out from the crowd!"
|
||||||
|
color: simplifiedUI.colors.text.black
|
||||||
|
size: 48
|
||||||
|
height: paintedHeight
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 16
|
||||||
|
}
|
||||||
|
|
||||||
|
HifiStylesUit.RalewayRegular {
|
||||||
|
id: descriptionText
|
||||||
|
anchors.top: headerText.bottom
|
||||||
|
anchors.topMargin: 10
|
||||||
|
anchors.left: parent.left
|
||||||
|
width: parent.width - headerText.anchors.rightMargin
|
||||||
|
height: paintedHeight
|
||||||
|
text: "You can create and upload custom avatars from our Avatar Creator App. " +
|
||||||
|
"It's as easy as taking a selfie.<br>Available now on iOS and Android Platforms."
|
||||||
|
color: simplifiedUI.colors.text.black
|
||||||
|
size: 22
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: qrAndInstructionsContainer
|
||||||
|
anchors.top: descriptionText.bottom
|
||||||
|
anchors.topMargin: 24
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 16
|
||||||
|
height: avatarAppQRCodeImage.height
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: avatarAppQRCodeImage
|
||||||
|
source: resourceDirectoryUrl + "qml/hifi/simplifiedUI/avatarApp/images/qrCode.jpg"
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
width: 130
|
||||||
|
height: width
|
||||||
|
mipmap: true
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
}
|
||||||
|
|
||||||
|
HifiStylesUit.RalewayBold {
|
||||||
|
id: instructionText
|
||||||
|
anchors.top: avatarAppQRCodeImage.top
|
||||||
|
anchors.bottom: avatarAppQRCodeImage.bottom
|
||||||
|
anchors.left: avatarAppQRCodeImage.right
|
||||||
|
anchors.leftMargin: 30
|
||||||
|
anchors.right: parent.right
|
||||||
|
text: "Use your mobile phone to scan this QR code."
|
||||||
|
color: simplifiedUI.colors.text.black
|
||||||
|
size: 22
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SimplifiedControls.VerticalScrollBar {
|
||||||
|
parent: textContainer
|
||||||
|
visible: parent.contentHeight > parent.height
|
||||||
|
size: parent.height / parent.contentHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HifiStylesUit.RalewayBold {
|
||||||
|
id: continueLink
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 16
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: 16
|
||||||
|
height: 96
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
text: "No thanks, I'll keep using my default avatar."
|
||||||
|
color: simplifiedUI.colors.text.lightBlue
|
||||||
|
opacity: continueMouseArea.containsMouse ? 1.0 : 0.7
|
||||||
|
size: 24
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: continueMouseArea
|
||||||
|
hoverEnabled: true
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
Tablet.playSound(TabletEnums.ButtonClick);
|
||||||
|
sendToScript({
|
||||||
|
"source": "SecondLaunchWindow.qml",
|
||||||
|
"method": "closeSecondLaunchWindow"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: topLeftAccentImage
|
||||||
|
width: 130
|
||||||
|
height: 320
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.top: parent.top
|
||||||
|
source: "images/standOutTopLeft.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: bottomRightAccentImage
|
||||||
|
width: 250
|
||||||
|
height: 80
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
source: "images/standOutBottomRight.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
signal sendToScript(var message);
|
||||||
|
}
|
BIN
scripts/simplifiedUI/ui/simplifiedFTUE/images/cameraControls.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 2.8 KiB |
BIN
scripts/simplifiedUI/ui/simplifiedFTUE/images/defaultTopLeft.png
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
scripts/simplifiedUI/ui/simplifiedFTUE/images/mouseControls.png
Normal file
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 9.7 KiB |
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
|
|
||||||
// START CONFIG OPTIONS
|
// START CONFIG OPTIONS
|
||||||
var DOCKED_QML_SUPPORTED = true;
|
|
||||||
var TOOLBAR_NAME = "com.highfidelity.interface.toolbar.system";
|
var TOOLBAR_NAME = "com.highfidelity.interface.toolbar.system";
|
||||||
var DEFAULT_SCRIPTS_PATH_PREFIX = ScriptDiscoveryService.defaultScriptsPath + "/";
|
var DEFAULT_SCRIPTS_PATH_PREFIX = ScriptDiscoveryService.defaultScriptsPath + "/";
|
||||||
// END CONFIG OPTIONS
|
// END CONFIG OPTIONS
|
||||||
|
@ -160,6 +159,7 @@ var SETTINGS_APP_WINDOW_FLAGS = 0x00000001 | // Qt::Window
|
||||||
0x08000000 | // Qt::WindowCloseButtonHint
|
0x08000000 | // Qt::WindowCloseButtonHint
|
||||||
0x00008000 | // Qt::WindowMaximizeButtonHint
|
0x00008000 | // Qt::WindowMaximizeButtonHint
|
||||||
0x00004000; // Qt::WindowMinimizeButtonHint
|
0x00004000; // Qt::WindowMinimizeButtonHint
|
||||||
|
var SETTINGS_APP_RIGHT_MARGIN = 48;
|
||||||
var settingsAppWindow = false;
|
var settingsAppWindow = false;
|
||||||
function toggleSettingsApp() {
|
function toggleSettingsApp() {
|
||||||
if (settingsAppWindow) {
|
if (settingsAppWindow) {
|
||||||
|
@ -179,7 +179,7 @@ function toggleSettingsApp() {
|
||||||
y: SETTINGS_APP_HEIGHT_PX
|
y: SETTINGS_APP_HEIGHT_PX
|
||||||
},
|
},
|
||||||
position: {
|
position: {
|
||||||
x: Math.max(Window.x + POPOUT_SAFE_MARGIN_X, Window.x + Window.innerWidth / 2 - SETTINGS_APP_WIDTH_PX / 2),
|
x: Window.x + Window.innerWidth - SETTINGS_APP_WIDTH_PX - SETTINGS_APP_RIGHT_MARGIN,
|
||||||
y: Math.max(Window.y + POPOUT_SAFE_MARGIN_Y, Window.y + Window.innerHeight / 2 - SETTINGS_APP_HEIGHT_PX / 2)
|
y: Math.max(Window.y + POPOUT_SAFE_MARGIN_Y, Window.y + Window.innerHeight / 2 - SETTINGS_APP_HEIGHT_PX / 2)
|
||||||
},
|
},
|
||||||
overrideFlags: SETTINGS_APP_WINDOW_FLAGS
|
overrideFlags: SETTINGS_APP_WINDOW_FLAGS
|
||||||
|
@ -283,28 +283,21 @@ function maybeDeleteOutputDeviceMutedOverlay() {
|
||||||
|
|
||||||
var outputDeviceMutedOverlay = false;
|
var outputDeviceMutedOverlay = false;
|
||||||
var OUTPUT_DEVICE_MUTED_OVERLAY_DEFAULT_DIMS_PX = 300;
|
var OUTPUT_DEVICE_MUTED_OVERLAY_DEFAULT_DIMS_PX = 300;
|
||||||
var OUTPUT_DEVICE_MUTED_MARGIN_BOTTOM_PX = 20;
|
var OUTPUT_DEVICE_MUTED_OVERLAY_DEFAULT_MARGINS_PX = 20;
|
||||||
var OUTPUT_DEVICE_MUTED_MARGIN_LEFT_RIGHT_PX = 20;
|
var OUTPUT_DEVICE_MUTED_DIMS_RATIO_TO_WINDOW_SIZE = 0.8;
|
||||||
function updateOutputDeviceMutedOverlay(isMuted) {
|
function updateOutputDeviceMutedOverlay(isMuted) {
|
||||||
if (isMuted) {
|
if (isMuted) {
|
||||||
var props = {
|
var props = {
|
||||||
imageURL: Script.resolvePath("images/outputDeviceMuted.svg"),
|
imageURL: Script.resolvePath("images/outputDeviceMuted.svg"),
|
||||||
alpha: 0.5
|
alpha: 0.5
|
||||||
};
|
};
|
||||||
|
|
||||||
var overlayDims = OUTPUT_DEVICE_MUTED_OVERLAY_DEFAULT_DIMS_PX;
|
var overlayDims = OUTPUT_DEVICE_MUTED_OVERLAY_DEFAULT_DIMS_PX;
|
||||||
props.x = Window.innerWidth / 2 - overlayDims / 2;
|
var overlayWithMarginsDims = overlayDims + 2 * OUTPUT_DEVICE_MUTED_OVERLAY_DEFAULT_MARGINS_PX;
|
||||||
props.y = Window.innerHeight / 2 - overlayDims / 2;
|
|
||||||
|
|
||||||
var outputDeviceMutedOverlayBottomY = props.y + overlayDims;
|
if (overlayWithMarginsDims > Window.innerHeight || overlayWithMarginsDims > Window.innerWidth) {
|
||||||
var inputDeviceMutedOverlayTopY = INPUT_DEVICE_MUTED_MARGIN_TOP_PX;
|
var minWindowDims = Math.min(Window.innerHeight, Window.innerWidth);
|
||||||
if (outputDeviceMutedOverlayBottomY + OUTPUT_DEVICE_MUTED_MARGIN_BOTTOM_PX > inputDeviceMutedOverlayTopY) {
|
overlayDims = Math.round(minWindowDims * OUTPUT_DEVICE_MUTED_DIMS_RATIO_TO_WINDOW_SIZE);
|
||||||
overlayDims = 2 * (inputDeviceMutedOverlayTopY - Window.innerHeight / 2 - OUTPUT_DEVICE_MUTED_MARGIN_BOTTOM_PX);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (overlayDims + OUTPUT_DEVICE_MUTED_MARGIN_LEFT_RIGHT_PX > Window.innerWidth) {
|
|
||||||
overlayDims = Math.min(Window.innerWidth - OUTPUT_DEVICE_MUTED_MARGIN_LEFT_RIGHT_PX, overlayDims);
|
|
||||||
} else {
|
|
||||||
overlayDims = Math.min(OUTPUT_DEVICE_MUTED_OVERLAY_DEFAULT_DIMS_PX, overlayDims);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
props.width = overlayDims;
|
props.width = overlayDims;
|
||||||
|
@ -358,6 +351,124 @@ function setOutputMuted(outputMuted) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var TOP_BAR_HEIGHT_PX = 48;
|
||||||
|
var INITIAL_LAUNCH_QML_PATH = Script.resolvePath("./simplifiedFTUE/InitialLaunchWindow.qml");
|
||||||
|
var INITIAL_LAUNCH_WINDOW_TITLE = "Initial Launch";
|
||||||
|
var INITIAL_LAUNCH_PRESENTATION_MODE = Desktop.PresentationMode.NATIVE;
|
||||||
|
var INITIAL_WINDOW_FLAGS = 0x00000001 | // Qt::Window
|
||||||
|
0x00000008 | // Qt::Popup
|
||||||
|
0x00000002 | // Qt::Tool
|
||||||
|
0x00000800 | // Qt::FramelessWindowHint
|
||||||
|
0x40000000; // Qt::NoDropShadowWindowHint
|
||||||
|
var initialLaunchWindow = false;
|
||||||
|
function displayInitialLaunchWindow() {
|
||||||
|
if (initialLaunchWindow) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
simplifiedEmote.handleFTUEScreensVisibilityChanged(true);
|
||||||
|
|
||||||
|
initialLaunchWindow = Desktop.createWindow(INITIAL_LAUNCH_QML_PATH, {
|
||||||
|
title: INITIAL_LAUNCH_WINDOW_TITLE,
|
||||||
|
presentationMode: INITIAL_LAUNCH_PRESENTATION_MODE,
|
||||||
|
isFullScreenWindow: true,
|
||||||
|
overrideFlags: INITIAL_WINDOW_FLAGS
|
||||||
|
});
|
||||||
|
|
||||||
|
initialLaunchWindow.fromQml.connect(onMessageFromInitialLaunchWindow);
|
||||||
|
|
||||||
|
Window.location = "file:///~/serverless/tutorial.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
var SECOND_LAUNCH_QML_PATH = Script.resolvePath("simplifiedFTUE/SecondLaunchWindow.qml");
|
||||||
|
var SECOND_LAUNCH_WINDOW_TITLE = "Second Launch";
|
||||||
|
var SECOND_LAUNCH_PRESENTATION_MODE = Desktop.PresentationMode.NATIVE;
|
||||||
|
var SECOND_WINDOW_FLAGS = 0x00000001 | // Qt::Window
|
||||||
|
0x00000008 | // Qt::Popup
|
||||||
|
0x00000002 | // Qt::Tool
|
||||||
|
0x00000800 | // Qt::FramelessWindowHint
|
||||||
|
0x40000000; // Qt::NoDropShadowWindowHint
|
||||||
|
var secondLaunchWindow = false;
|
||||||
|
function displaySecondLaunchWindow() {
|
||||||
|
if (secondLaunchWindow) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
simplifiedEmote.handleFTUEScreensVisibilityChanged(true);
|
||||||
|
|
||||||
|
secondLaunchWindow = Desktop.createWindow(SECOND_LAUNCH_QML_PATH, {
|
||||||
|
title: SECOND_LAUNCH_WINDOW_TITLE,
|
||||||
|
presentationMode: SECOND_LAUNCH_PRESENTATION_MODE,
|
||||||
|
isFullScreenWindow: true,
|
||||||
|
overrideFlags: SECOND_WINDOW_FLAGS
|
||||||
|
});
|
||||||
|
|
||||||
|
secondLaunchWindow.fromQml.connect(onMessageFromSecondLaunchWindow);
|
||||||
|
|
||||||
|
Window.location = "file:///~/serverless/tutorial.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeInitialLaunchWindow() {
|
||||||
|
if (initialLaunchWindow) {
|
||||||
|
initialLaunchWindow.fromQml.disconnect(onMessageFromInitialLaunchWindow);
|
||||||
|
initialLaunchWindow.close();
|
||||||
|
initialLaunchWindow = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
simplifiedEmote.handleFTUEScreensVisibilityChanged(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeSecondLaunchWindow() {
|
||||||
|
if (secondLaunchWindow) {
|
||||||
|
secondLaunchWindow.fromQml.disconnect(onMessageFromSecondLaunchWindow);
|
||||||
|
secondLaunchWindow.close();
|
||||||
|
secondLaunchWindow = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
simplifiedEmote.handleFTUEScreensVisibilityChanged(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
var INITIAL_LAUNCH_WINDOW_MESSAGE_SOURCE = "InitialLaunchWindow.qml";
|
||||||
|
function onMessageFromInitialLaunchWindow(message) {
|
||||||
|
if (message.source !== INITIAL_LAUNCH_WINDOW_MESSAGE_SOURCE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (message.method) {
|
||||||
|
case "closeInitialLaunchWindow":
|
||||||
|
closeInitialLaunchWindow();
|
||||||
|
var homeLocation = LocationBookmarks.getAddress("hqhome");
|
||||||
|
if (homeLocation) {
|
||||||
|
Window.location = homeLocation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.log("Unrecognized message from " + INITIAL_LAUNCH_WINDOW_MESSAGE_SOURCE + ": " + JSON.stringify(message));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var SECOND_LAUNCH_WINDOW_MESSAGE_SOURCE = "SecondLaunchWindow.qml";
|
||||||
|
function onMessageFromSecondLaunchWindow(message) {
|
||||||
|
if (message.source !== SECOND_LAUNCH_WINDOW_MESSAGE_SOURCE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (message.method) {
|
||||||
|
case "closeSecondLaunchWindow":
|
||||||
|
closeSecondLaunchWindow();
|
||||||
|
var homeLocation = LocationBookmarks.getAddress("hqhome");
|
||||||
|
if (homeLocation) {
|
||||||
|
Window.location = homeLocation;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.log("Unrecognized message from " + SECOND_LAUNCH_WINDOW_MESSAGE_SOURCE + ": " + JSON.stringify(message));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var WAIT_FOR_TOP_BAR_MS = 1000;
|
var WAIT_FOR_TOP_BAR_MS = 1000;
|
||||||
function sendLocalStatusToQml() {
|
function sendLocalStatusToQml() {
|
||||||
|
@ -403,6 +514,14 @@ function onMessageFromTopBar(message) {
|
||||||
si.toggleStatus();
|
si.toggleStatus();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "displayInitialLaunchWindow":
|
||||||
|
displayInitialLaunchWindow();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "displaySecondLaunchWindow":
|
||||||
|
displaySecondLaunchWindow();
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
console.log("Unrecognized message from " + TOP_BAR_MESSAGE_SOURCE + ": " + JSON.stringify(message));
|
console.log("Unrecognized message from " + TOP_BAR_MESSAGE_SOURCE + ": " + JSON.stringify(message));
|
||||||
break;
|
break;
|
||||||
|
@ -431,7 +550,6 @@ var TOP_BAR_QML_PATH = Script.resourcesPath() + "qml/hifi/simplifiedUI/topBar/Si
|
||||||
var TOP_BAR_WINDOW_TITLE = "Simplified Top Bar";
|
var TOP_BAR_WINDOW_TITLE = "Simplified Top Bar";
|
||||||
var TOP_BAR_PRESENTATION_MODE = Desktop.PresentationMode.NATIVE;
|
var TOP_BAR_PRESENTATION_MODE = Desktop.PresentationMode.NATIVE;
|
||||||
var TOP_BAR_WIDTH_PX = Window.innerWidth;
|
var TOP_BAR_WIDTH_PX = Window.innerWidth;
|
||||||
var TOP_BAR_HEIGHT_PX = 48;
|
|
||||||
var topBarWindow = false;
|
var topBarWindow = false;
|
||||||
function loadSimplifiedTopBar() {
|
function loadSimplifiedTopBar() {
|
||||||
var windowProps = {
|
var windowProps = {
|
||||||
|
@ -442,16 +560,9 @@ function loadSimplifiedTopBar() {
|
||||||
y: TOP_BAR_HEIGHT_PX
|
y: TOP_BAR_HEIGHT_PX
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (DOCKED_QML_SUPPORTED) {
|
|
||||||
windowProps.presentationWindowInfo = {
|
windowProps.presentationWindowInfo = {
|
||||||
dockArea: Desktop.DockArea.TOP
|
dockArea: Desktop.DockArea.TOP
|
||||||
};
|
};
|
||||||
} else {
|
|
||||||
windowProps.position = {
|
|
||||||
x: Window.x,
|
|
||||||
y: Window.y
|
|
||||||
};
|
|
||||||
}
|
|
||||||
topBarWindow = Desktop.createWindow(TOP_BAR_QML_PATH, windowProps);
|
topBarWindow = Desktop.createWindow(TOP_BAR_QML_PATH, windowProps);
|
||||||
|
|
||||||
topBarWindow.fromQml.connect(onMessageFromTopBar);
|
topBarWindow.fromQml.connect(onMessageFromTopBar);
|
||||||
|
@ -516,32 +627,53 @@ function onHMDInputDeviceMutedChanged(isMuted) {
|
||||||
function onGeometryChanged(rect) {
|
function onGeometryChanged(rect) {
|
||||||
updateInputDeviceMutedOverlay(Audio.muted);
|
updateInputDeviceMutedOverlay(Audio.muted);
|
||||||
updateOutputDeviceMutedOverlay(isOutputMuted());
|
updateOutputDeviceMutedOverlay(isOutputMuted());
|
||||||
if (topBarWindow && !DOCKED_QML_SUPPORTED) {
|
}
|
||||||
topBarWindow.size = {
|
|
||||||
"x": rect.width,
|
var initialLaunchWindowIsMinimized = false;
|
||||||
"y": TOP_BAR_HEIGHT_PX
|
var secondLaunchWindowIsMinimized = false;
|
||||||
};
|
function onWindowMinimizedChanged(isMinimized) {
|
||||||
topBarWindow.position = {
|
if (isMinimized) {
|
||||||
"x": rect.x,
|
handleInitialLaunchWindowVisibleChanged(false);
|
||||||
"y": rect.y
|
handleSecondLaunchWindowVisibleChanged(false);
|
||||||
};
|
} else if (!HMD.active) {
|
||||||
|
handleInitialLaunchWindowVisibleChanged(true);
|
||||||
|
handleSecondLaunchWindowVisibleChanged(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onWindowMinimizedChanged() {
|
function handleInitialLaunchWindowVisibleChanged(shouldBeVisible) {
|
||||||
// prerequisite placeholder for Reduce Friction of Customer Acquisition sub task: https://highfidelity.atlassian.net/browse/DEV-585
|
if (shouldBeVisible && !initialLaunchWindow && initialLaunchWindowIsMinimized) {
|
||||||
print("WINDOW MINIMIZED CHANGED SIGNAL");
|
displayInitialLaunchWindow();
|
||||||
|
initialLaunchWindowIsMinimized = false;
|
||||||
|
} else if (!shouldBeVisible && initialLaunchWindow) {
|
||||||
|
closeInitialLaunchWindow();
|
||||||
|
initialLaunchWindowIsMinimized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSecondLaunchWindowVisibleChanged(shouldBeVisible) {
|
||||||
|
if (shouldBeVisible && !secondLaunchWindow && secondLaunchWindowIsMinimized) {
|
||||||
|
displaySecondLaunchWindow();
|
||||||
|
secondLaunchWindowIsMinimized = false;
|
||||||
|
} else if (!shouldBeVisible && secondLaunchWindow) {
|
||||||
|
closeSecondLaunchWindow();
|
||||||
|
secondLaunchWindowIsMinimized = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onDisplayModeChanged(isHMDMode) {
|
function onDisplayModeChanged(isHMDMode) {
|
||||||
if (isHMDMode) {
|
if (isHMDMode) {
|
||||||
Camera.setModeString("first person");
|
Camera.setModeString("first person look at");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isHMDMode) {
|
if (isHMDMode) {
|
||||||
onHMDInputDeviceMutedChanged(Audio.mutedHMD);
|
onHMDInputDeviceMutedChanged(Audio.mutedHMD);
|
||||||
|
handleInitialLaunchWindowVisibleChanged(false);
|
||||||
|
handleSecondLaunchWindowVisibleChanged(false);
|
||||||
} else {
|
} else {
|
||||||
onDesktopInputDeviceMutedChanged(Audio.mutedDesktop);
|
onDesktopInputDeviceMutedChanged(Audio.mutedDesktop);
|
||||||
|
handleInitialLaunchWindowVisibleChanged(true);
|
||||||
|
handleSecondLaunchWindowVisibleChanged(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,9 +716,9 @@ function restoreLODSettings() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var nametag = Script.require("./simplifiedNametag/simplifiedNametag.js?" + Date.now());
|
var nametag = Script.require("./simplifiedNametag/simplifiedNametag.js");
|
||||||
var si = Script.require("./simplifiedStatusIndicator/simplifiedStatusIndicator.js?" + Date.now());
|
var si = Script.require("./simplifiedStatusIndicator/simplifiedStatusIndicator.js");
|
||||||
var emote = Script.require("../simplifiedEmote/simplifiedEmote.js?" + Date.now());
|
var simplifiedEmote = Script.require("../simplifiedEmote/simplifiedEmote.js");
|
||||||
var oldShowAudioTools;
|
var oldShowAudioTools;
|
||||||
var oldShowBubbleTools;
|
var oldShowBubbleTools;
|
||||||
var keepExistingUIAndScriptsSetting = Settings.getValue("simplifiedUI/keepExistingUIAndScripts", false);
|
var keepExistingUIAndScriptsSetting = Settings.getValue("simplifiedUI/keepExistingUIAndScripts", false);
|
||||||
|
@ -653,6 +785,14 @@ function shutdown() {
|
||||||
settingsAppWindow.close();
|
settingsAppWindow.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (initialLaunchWindow) {
|
||||||
|
closeInitialLaunchWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (secondLaunchWindow) {
|
||||||
|
closeSecondLaunchWindow();
|
||||||
|
}
|
||||||
|
|
||||||
maybeDeleteInputDeviceMutedOverlay();
|
maybeDeleteInputDeviceMutedOverlay();
|
||||||
maybeDeleteOutputDeviceMutedOverlay();
|
maybeDeleteOutputDeviceMutedOverlay();
|
||||||
|
|
||||||
|
|
|
@ -50,11 +50,11 @@ var OVERLAY_DATA_HMD = {
|
||||||
};
|
};
|
||||||
|
|
||||||
var AWAY_INTRO = {
|
var AWAY_INTRO = {
|
||||||
url: "http://hifi-content.s3.amazonaws.com/ozan/dev/anim/standard_anims_160127/kneel.fbx",
|
url: "https://hifi-content.s3.amazonaws.com/doug/animation/fbx/afk_texting.fbx",
|
||||||
playbackRate: 30.0,
|
playbackRate: 30.0,
|
||||||
loopFlag: false,
|
loopFlag: true,
|
||||||
startFrame: 0.0,
|
startFrame: 1.0,
|
||||||
endFrame: 83.0
|
endFrame: 489.0
|
||||||
};
|
};
|
||||||
|
|
||||||
// MAIN CONTROL
|
// MAIN CONTROL
|
||||||
|
|
|
@ -76,7 +76,7 @@
|
||||||
"tooltip": "The angle in deg at which light emits. Starts in the entity's -z direction, and rotates around its x axis."
|
"tooltip": "The angle in deg at which light emits. Starts in the entity's -z direction, and rotates around its x axis."
|
||||||
},
|
},
|
||||||
"keyLight.castShadows": {
|
"keyLight.castShadows": {
|
||||||
"tooltip": "If enabled, shadows are cast. The entity or avatar casting the shadow must also have Cast Shadows enabled."
|
"tooltip": "If enabled, shadows are cast. The entity or avatar casting the shadow must also have Cast Shadows enabled. Note: Shadows are rendered only on high-profiled computers. This setting will have no effect on computers profiled to medium or low graphics."
|
||||||
},
|
},
|
||||||
"keyLight.shadowBias": {
|
"keyLight.shadowBias": {
|
||||||
"tooltip": "The bias of the shadows cast by the light. Use this to fine-tune your shadows to your scene to prevent shadow acne and peter panning."
|
"tooltip": "The bias of the shadows cast by the light. Use this to fine-tune your shadows to your scene to prevent shadow acne and peter panning."
|
||||||
|
@ -500,7 +500,7 @@
|
||||||
"tooltip": "If enabled, grabbed entities will follow the movements of your hand controller instead of your avatar's hand."
|
"tooltip": "If enabled, grabbed entities will follow the movements of your hand controller instead of your avatar's hand."
|
||||||
},
|
},
|
||||||
"canCastShadow": {
|
"canCastShadow": {
|
||||||
"tooltip": "If enabled, this geometry of this entity casts shadows when a shadow-casting light source shines on it."
|
"tooltip": "If enabled, the geometry of this entity casts shadows when a shadow-casting light source shines on it. Note: Shadows are rendered only on high-profiled computers. This setting will have no effect on computers profiled to medium or low graphics.."
|
||||||
},
|
},
|
||||||
"ignorePickIntersection": {
|
"ignorePickIntersection": {
|
||||||
"tooltip": "If enabled, this entity will not be considered for ray picks, and will also not occlude other entities when picking."
|
"tooltip": "If enabled, this entity will not be considered for ray picks, and will also not occlude other entities when picking."
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
// Automatically enter first person mode when entering HMD mode
|
// Automatically enter first person mode when entering HMD mode
|
||||||
HMD.displayModeChanged.connect(function(isHMDMode) {
|
HMD.displayModeChanged.connect(function(isHMDMode) {
|
||||||
if (isHMDMode) {
|
if (isHMDMode) {
|
||||||
Camera.setModeString("first person");
|
Camera.setModeString("first person look at");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -272,7 +272,7 @@
|
||||||
currentProgress = 0.0;
|
currentProgress = 0.0;
|
||||||
connectionToDomainFailed = false;
|
connectionToDomainFailed = false;
|
||||||
previousCameraMode = Camera.mode;
|
previousCameraMode = Camera.mode;
|
||||||
Camera.mode = "first person";
|
Camera.mode = "first person look at";
|
||||||
updateProgressBar(0.0);
|
updateProgressBar(0.0);
|
||||||
scaleInterstitialPage(MyAvatar.sensorToWorldScale);
|
scaleInterstitialPage(MyAvatar.sensorToWorldScale);
|
||||||
timer = Script.setTimeout(update, 2000);
|
timer = Script.setTimeout(update, 2000);
|
||||||
|
|
|
@ -52,8 +52,8 @@ function calcSpawnInfo(hand, landscape) {
|
||||||
|
|
||||||
var LEFT_HAND = Controller.Standard.LeftHand;
|
var LEFT_HAND = Controller.Standard.LeftHand;
|
||||||
var sensorToWorldScale = MyAvatar.sensorToWorldScale;
|
var sensorToWorldScale = MyAvatar.sensorToWorldScale;
|
||||||
var headPos = (HMD.active && Camera.mode === "first person") ? HMD.position : Camera.position;
|
var headPos = (HMD.active && (Camera.mode === "first person" || Camera.mode === "first person look at")) ? HMD.position : Camera.position;
|
||||||
var headRot = Quat.cancelOutRollAndPitch((HMD.active && Camera.mode === "first person") ?
|
var headRot = Quat.cancelOutRollAndPitch((HMD.active && (Camera.mode === "first person" || Camera.mode === "first person look at")) ?
|
||||||
HMD.orientation : Camera.orientation);
|
HMD.orientation : Camera.orientation);
|
||||||
|
|
||||||
var right = Quat.getRight(headRot);
|
var right = Quat.getRight(headRot);
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
function handJointName(hand) {
|
function handJointName(hand) {
|
||||||
var jointName;
|
var jointName;
|
||||||
if (hand === LEFT_HAND) {
|
if (hand === LEFT_HAND) {
|
||||||
if (Camera.mode === "first person") {
|
if (Camera.mode === "first person" || Camera.mode === "first person look at") {
|
||||||
jointName = "_CONTROLLER_LEFTHAND";
|
jointName = "_CONTROLLER_LEFTHAND";
|
||||||
} else if (Camera.mode === "third person") {
|
} else if (Camera.mode === "third person") {
|
||||||
jointName = "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND";
|
jointName = "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND";
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
jointName = "LeftHand";
|
jointName = "LeftHand";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (Camera.mode === "first person") {
|
if (Camera.mode === "first person" || Camera.mode === "first person look at") {
|
||||||
jointName = "_CONTROLLER_RIGHTHAND";
|
jointName = "_CONTROLLER_RIGHTHAND";
|
||||||
} else if (Camera.mode === "third person") {
|
} else if (Camera.mode === "third person") {
|
||||||
jointName = "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND";
|
jointName = "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND";
|
||||||
|
|
|
@ -61,17 +61,21 @@ Item {
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: 5
|
width: 5
|
||||||
height: 5
|
height: 5
|
||||||
color: "red"
|
color: "blue"
|
||||||
ColorAnimation on color { loops: Animation.Infinite; from: "red"; to: "yellow"; duration: 1000 }
|
ColorAnimation on color { loops: Animation.Infinite; from: "blue"; to: "yellow"; duration: 1000 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WebEngineView {
|
WebEngineView {
|
||||||
id: root
|
id: root
|
||||||
url: "https://google.com/"
|
url: "https://www.webrtc-experiment.com/Pluginfree-Screen-Sharing/#19583796789766627"
|
||||||
x: 6; y: 6;
|
// url: "https://vimeo.com/108650530"
|
||||||
width: parent.width * 0.8
|
// url: "https://www.youtube.com/watch?v=7EWQOeQf32U&autoplay=1&loop=1"
|
||||||
height: parent.height * 0.8
|
// x: 6; y: 6;
|
||||||
|
anchors.fill: parent
|
||||||
|
// width: parent.width * 0.8
|
||||||
|
// height: parent.height * 0.8
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ void MacQml::init() {
|
||||||
_surface->load(url, callback);
|
_surface->load(url, callback);
|
||||||
_surface->resize(_window->size());
|
_surface->resize(_window->size());
|
||||||
_surface->resume();
|
_surface->resume();
|
||||||
|
_window->installEventFilter(_surface.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacQml::draw() {
|
void MacQml::draw() {
|
||||||
|
|
|
@ -9,7 +9,7 @@ public:
|
||||||
QmlPtr _surface;
|
QmlPtr _surface;
|
||||||
GLuint _fbo{ 0 };
|
GLuint _fbo{ 0 };
|
||||||
|
|
||||||
MacQml(const QWindow* window) : Parent(window) {}
|
MacQml(QWindow* window) : Parent(window) {}
|
||||||
void update() override;
|
void update() override;
|
||||||
void init() override;
|
void init() override;
|
||||||
void draw() override;
|
void draw() override;
|
||||||
|
|
|
@ -24,7 +24,7 @@ public:
|
||||||
std::array<std::array<QmlInfo, DIVISIONS_Y>, DIVISIONS_X> _surfaces;
|
std::array<std::array<QmlInfo, DIVISIONS_Y>, DIVISIONS_X> _surfaces;
|
||||||
GLuint _fbo{ 0 };
|
GLuint _fbo{ 0 };
|
||||||
|
|
||||||
StressWeb(const QWindow* window) : Parent(window) {}
|
StressWeb(QWindow* window) : Parent(window) {}
|
||||||
static QString getSourceUrl(bool video);
|
static QString getSourceUrl(bool video);
|
||||||
void buildSurface(QmlInfo& qmlInfo, bool video);
|
void buildSurface(QmlInfo& qmlInfo, bool video);
|
||||||
void destroySurface(QmlInfo& qmlInfo);
|
void destroySurface(QmlInfo& qmlInfo);
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
class TestCase {
|
class TestCase {
|
||||||
public:
|
public:
|
||||||
using QmlPtr = QSharedPointer<hifi::qml::OffscreenSurface>;
|
using QmlPtr = QSharedPointer<hifi::qml::OffscreenSurface>;
|
||||||
using Builder = std::function<TestCase*(const QWindow*)>;
|
using Builder = std::function<TestCase*(QWindow*)>;
|
||||||
TestCase(const QWindow* window) : _window(window) {}
|
TestCase(QWindow* window) : _window(window) {}
|
||||||
virtual void init();
|
virtual void init();
|
||||||
virtual void destroy();
|
virtual void destroy();
|
||||||
virtual void update();
|
virtual void update();
|
||||||
|
@ -18,6 +18,6 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QOpenGLFunctions_4_1_Core _glf;
|
QOpenGLFunctions_4_1_Core _glf;
|
||||||
const QWindow* _window;
|
QWindow* _window;
|
||||||
std::function<void(uint32_t, void*)> _discardLamdba;
|
std::function<void(uint32_t, void*)> _discardLamdba;
|
||||||
};
|
};
|
||||||
|
|
|
@ -205,12 +205,22 @@ void TestWindow::resizeEvent(QResizeEvent* ev) {
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
auto format = getDefaultOpenGLSurfaceFormat();
|
auto format = getDefaultOpenGLSurfaceFormat();
|
||||||
format.setVersion(4, 1);
|
// Deal with some weirdness in the chromium context sharing on Mac.
|
||||||
|
// The primary share context needs to be 3.2, so that the Chromium will
|
||||||
|
// succeed in it's creation of it's command stub contexts.
|
||||||
|
format.setVersion(3, 2);
|
||||||
|
// This appears to resolve the issues with corrupted fonts on OSX. No
|
||||||
|
// idea why.
|
||||||
|
qputenv("QT_ENABLE_GLYPH_CACHE_WORKAROUND", "true");
|
||||||
|
// https://i.kym-cdn.com/entries/icons/original/000/008/342/ihave.jpg
|
||||||
QSurfaceFormat::setDefaultFormat(format);
|
QSurfaceFormat::setDefaultFormat(format);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
QGuiApplication app(argc, argv);
|
QGuiApplication app(argc, argv);
|
||||||
TestCase::Builder builder = [](const QWindow* window)->TestCase*{ return new MacQml(window); };
|
TestCase::Builder builder = [](QWindow* window)->TestCase*{ return new MacQml(window); };
|
||||||
TestWindow window(builder);
|
TestWindow window(builder);
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
# General
|
# General
|
||||||
This document describes the process to build Qt 5.12.3.
|
This document describes the process to build Qt 5.12.3.
|
||||||
Note that there are three patches. The first (to qfloat16.h) is needed to compile QT 5.12.3 on Visual Studio 2017 due to a bug in Visual Studio (*bitset* will not compile. Note that there is a change in CMakeLists.txt to support this.
|
Note that there are several patches.
|
||||||
The second patch is to OpenSL ES audio.
|
* The first (to qfloat16.h) is needed to compile QT 5.12.3 on Visual Studio 2017 due to a bug in Visual Studio (*bitset* will not compile. Note that there is a change in CMakeLists.txt to support this.
|
||||||
The third is a patch to QScriptEngine to prevent crashes in QScriptEnginePrivate::reportAdditionalMemoryCost, during garbage collection. See https://bugreports.qt.io/browse/QTBUG-76176
|
* The second patch is to OpenSL ES audio and allow audio echo cancelllation on Android.
|
||||||
|
* The third is a patch to QScriptEngine to prevent crashes in QScriptEnginePrivate::reportAdditionalMemoryCost, during garbage collection. See https://bugreports.qt.io/browse/QTBUG-76176
|
||||||
|
* The fourth is a patch which fixes video playback on WebEngineViews on mac. See https://bugreports.qt.io/browse/QTBUG-70967
|
||||||
## Requirements
|
## Requirements
|
||||||
### Windows
|
### Windows
|
||||||
1. Visual Studio 2017
|
1. Visual Studio 2017
|
||||||
|
@ -222,6 +224,7 @@ git clone --recursive git://code.qt.io/qt/qt5.git -b 5.12.3 --single-branch
|
||||||
`cd qt5`
|
`cd qt5`
|
||||||
`git apply --ignore-space-change --ignore-whitespace patches/aec.patch`
|
`git apply --ignore-space-change --ignore-whitespace patches/aec.patch`
|
||||||
`git apply --ignore-space-change --ignore-whitespace patches/qtscript-crash-fix.patch`
|
`git apply --ignore-space-change --ignore-whitespace patches/qtscript-crash-fix.patch`
|
||||||
|
`git apply --ignore-space-change --ignore-whitespace patches/mac-web-video.patch`
|
||||||
`cd ..`
|
`cd ..`
|
||||||
#### Configuring
|
#### Configuring
|
||||||
`mkdir qt5-install`
|
`mkdir qt5-install`
|
||||||
|
|
247
tools/qt-builder/patches/mac-web-video.patch
Normal file
|
@ -0,0 +1,247 @@
|
||||||
|
Submodule qtwebengine contains modified content
|
||||||
|
diff --git a/qtwebengine/src/core/stream_video_node.cpp b/qtwebengine/src/core/stream_video_node.cpp
|
||||||
|
index 29922f86..baa39d3b 100644
|
||||||
|
--- a/qtwebengine/src/core/stream_video_node.cpp
|
||||||
|
+++ b/qtwebengine/src/core/stream_video_node.cpp
|
||||||
|
@@ -62,38 +62,45 @@ protected:
|
||||||
|
const char *vertexShader() const override {
|
||||||
|
// Keep in sync with cc::VertexShaderVideoTransform
|
||||||
|
static const char *shader =
|
||||||
|
- "attribute highp vec4 a_position;\n"
|
||||||
|
- "attribute mediump vec2 a_texCoord;\n"
|
||||||
|
- "uniform highp mat4 matrix;\n"
|
||||||
|
- "uniform highp mat4 texMatrix;\n"
|
||||||
|
- "varying mediump vec2 v_texCoord;\n"
|
||||||
|
- "void main() {\n"
|
||||||
|
- " gl_Position = matrix * a_position;\n"
|
||||||
|
- " v_texCoord = vec4(texMatrix * vec4(a_texCoord.x, 1.0 - a_texCoord.y, 0.0, 1.0)).xy;\n"
|
||||||
|
- "}";
|
||||||
|
+ R"SHADER(#version 150 core
|
||||||
|
+in vec4 a_position;
|
||||||
|
+in vec2 a_texCoord;
|
||||||
|
+uniform mat4 matrix;
|
||||||
|
+uniform mat4 texMatrix;
|
||||||
|
+out vec2 v_texCoord;
|
||||||
|
+void main() {
|
||||||
|
+ gl_Position = matrix * a_position;
|
||||||
|
+ v_texCoord = vec4(texMatrix * vec4(a_texCoord.x, 1.0 - a_texCoord.y, 0.0, 1.0)).xy;
|
||||||
|
+}
|
||||||
|
+ )SHADER";
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *fragmentShader() const override {
|
||||||
|
// Keep in sync with cc::FragmentShaderRGBATexAlpha
|
||||||
|
static const char *shaderExternal =
|
||||||
|
- "#extension GL_OES_EGL_image_external : require\n"
|
||||||
|
- "varying mediump vec2 v_texCoord;\n"
|
||||||
|
- "uniform samplerExternalOES s_texture;\n"
|
||||||
|
- "uniform lowp float alpha;\n"
|
||||||
|
- "void main() {\n"
|
||||||
|
- " lowp vec4 texColor = texture2D(s_texture, v_texCoord);\n"
|
||||||
|
- " gl_FragColor = texColor * alpha;\n"
|
||||||
|
- "}";
|
||||||
|
+ R"SHADER(#version 150 core
|
||||||
|
+#extension GL_OES_EGL_image_external : require
|
||||||
|
+in vec2 v_texCoord;
|
||||||
|
+uniform samplerExternalOES s_texture;
|
||||||
|
+uniform float alpha;
|
||||||
|
+out vec4 fragColor;
|
||||||
|
+void main() {
|
||||||
|
+ vec4 texColor = texture(s_texture, v_texCoord);
|
||||||
|
+ fragColor = texColor * alpha;
|
||||||
|
+}
|
||||||
|
+ )SHADER";
|
||||||
|
static const char *shader2DRect =
|
||||||
|
- "#extension GL_ARB_texture_rectangle : require\n"
|
||||||
|
- "varying mediump vec2 v_texCoord;\n"
|
||||||
|
- "uniform sampler2DRect s_texture;\n"
|
||||||
|
- "uniform lowp float alpha;\n"
|
||||||
|
- "void main() {\n"
|
||||||
|
- " lowp vec4 texColor = texture2DRect(s_texture, v_texCoord);\n"
|
||||||
|
- " gl_FragColor = texColor * alpha;\n"
|
||||||
|
- "}";
|
||||||
|
+ R"SHADER(#version 150 core
|
||||||
|
+in vec2 v_texCoord;
|
||||||
|
+uniform sampler2D s_texture;
|
||||||
|
+uniform float alpha;
|
||||||
|
+out vec4 fragColor;
|
||||||
|
+void main() {
|
||||||
|
+ vec4 texColor = texture(s_texture, v_texCoord);
|
||||||
|
+ fragColor = texColor * alpha;
|
||||||
|
+}
|
||||||
|
+ )SHADER";
|
||||||
|
if (m_target == ExternalTarget)
|
||||||
|
return shaderExternal;
|
||||||
|
else
|
||||||
|
diff --git a/qtwebengine/src/core/yuv_video_node.cpp b/qtwebengine/src/core/yuv_video_node.cpp
|
||||||
|
index 4a436d95..dc4b6ff9 100644
|
||||||
|
--- a/qtwebengine/src/core/yuv_video_node.cpp
|
||||||
|
+++ b/qtwebengine/src/core/yuv_video_node.cpp
|
||||||
|
@@ -59,39 +59,41 @@ public:
|
||||||
|
YUVVideoMaterialShader(const gfx::ColorSpace &colorSpace)
|
||||||
|
{
|
||||||
|
static const char *shaderHead =
|
||||||
|
- "varying mediump vec2 v_yaTexCoord;\n"
|
||||||
|
- "varying mediump vec2 v_uvTexCoord;\n"
|
||||||
|
- "uniform sampler2D y_texture;\n"
|
||||||
|
- "uniform sampler2D u_texture;\n"
|
||||||
|
- "uniform sampler2D v_texture;\n"
|
||||||
|
- "uniform mediump float alpha;\n"
|
||||||
|
- "uniform mediump vec4 ya_clamp_rect;\n"
|
||||||
|
- "uniform mediump vec4 uv_clamp_rect;\n";
|
||||||
|
- static const char *shader =
|
||||||
|
- "void main() {\n"
|
||||||
|
- " mediump vec2 ya_clamped =\n"
|
||||||
|
- " max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));\n"
|
||||||
|
- " mediump float y_raw = texture2D(y_texture, ya_clamped).x;\n"
|
||||||
|
- " mediump vec2 uv_clamped =\n"
|
||||||
|
- " max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));\n"
|
||||||
|
- " mediump float u_unsigned = texture2D(u_texture, uv_clamped).x;\n"
|
||||||
|
- " mediump float v_unsigned = texture2D(v_texture, uv_clamped).x;\n"
|
||||||
|
- " mediump vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned);\n"
|
||||||
|
- " mediump vec3 rgb = DoColorConversion(yuv);\n"
|
||||||
|
- " gl_FragColor = vec4(rgb, 1.0) * alpha;\n"
|
||||||
|
- "}";
|
||||||
|
+ R"SHADER(#version 150 core
|
||||||
|
+in vec2 v_yaTexCoord;
|
||||||
|
+in vec2 v_uvTexCoord;
|
||||||
|
+uniform sampler2D y_texture;
|
||||||
|
+uniform sampler2D u_texture;
|
||||||
|
+uniform sampler2D v_texture;
|
||||||
|
+uniform float alpha;
|
||||||
|
+uniform vec4 ya_clamp_rect;
|
||||||
|
+uniform vec4 uv_clamp_rect;
|
||||||
|
+out vec4 fragColor;
|
||||||
|
+ )SHADER";
|
||||||
|
+
|
||||||
|
+ static const char *shader = R"SHADER(
|
||||||
|
+void main() {
|
||||||
|
+ vec2 ya_clamped =
|
||||||
|
+ max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));
|
||||||
|
+ float y_raw = texture(y_texture, ya_clamped).x;
|
||||||
|
+ vec2 uv_clamped =
|
||||||
|
+ max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));
|
||||||
|
+ float u_unsigned = texture(u_texture, uv_clamped).x;
|
||||||
|
+ float v_unsigned = texture(v_texture, uv_clamped).x;
|
||||||
|
+ vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned);
|
||||||
|
+ vec3 rgb = DoColorConversion(yuv);
|
||||||
|
+ fragColor = vec4(rgb, 1.0) * alpha;
|
||||||
|
+}
|
||||||
|
+ )SHADER";
|
||||||
|
+
|
||||||
|
// Invalid or unspecified color spaces should be treated as REC709.
|
||||||
|
gfx::ColorSpace src = colorSpace.IsValid() ? colorSpace : gfx::ColorSpace::CreateREC709();
|
||||||
|
gfx::ColorSpace dst = gfx::ColorSpace::CreateSRGB();
|
||||||
|
std::unique_ptr<gfx::ColorTransform> transform =
|
||||||
|
gfx::ColorTransform::NewColorTransform(src, dst, gfx::ColorTransform::Intent::INTENT_PERCEPTUAL);
|
||||||
|
|
||||||
|
- QByteArray header(shaderHead);
|
||||||
|
- if (QOpenGLContext::currentContext()->isOpenGLES())
|
||||||
|
- header = QByteArray("precision mediump float;\n") + header;
|
||||||
|
-
|
||||||
|
m_csShader = QByteArray::fromStdString(transform->GetShaderSource());
|
||||||
|
- m_fragmentShader = header + m_csShader + QByteArray(shader);
|
||||||
|
+ m_fragmentShader = QByteArray(shaderHead) + m_csShader + QByteArray(shader);
|
||||||
|
}
|
||||||
|
void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
|
||||||
|
|
||||||
|
@@ -108,20 +110,22 @@ protected:
|
||||||
|
const char *vertexShader() const override {
|
||||||
|
// Keep in sync with logic in VertexShader in components/viz/service/display/shader.cc
|
||||||
|
const char *shader =
|
||||||
|
- "attribute highp vec4 a_position;\n"
|
||||||
|
- "attribute mediump vec2 a_texCoord;\n"
|
||||||
|
- "uniform highp mat4 matrix;\n"
|
||||||
|
- "varying mediump vec2 v_yaTexCoord;\n"
|
||||||
|
- "varying mediump vec2 v_uvTexCoord;\n"
|
||||||
|
- "uniform mediump vec2 yaTexScale;\n"
|
||||||
|
- "uniform mediump vec2 yaTexOffset;\n"
|
||||||
|
- "uniform mediump vec2 uvTexScale;\n"
|
||||||
|
- "uniform mediump vec2 uvTexOffset;\n"
|
||||||
|
- "void main() {\n"
|
||||||
|
- " gl_Position = matrix * a_position;\n"
|
||||||
|
- " v_yaTexCoord = a_texCoord * yaTexScale + yaTexOffset;\n"
|
||||||
|
- " v_uvTexCoord = a_texCoord * uvTexScale + uvTexOffset;\n"
|
||||||
|
- "}";
|
||||||
|
+ R"SHADER(#version 150 core
|
||||||
|
+in vec4 a_position;
|
||||||
|
+in vec2 a_texCoord;
|
||||||
|
+uniform mat4 matrix;
|
||||||
|
+out vec2 v_yaTexCoord;
|
||||||
|
+out vec2 v_uvTexCoord;
|
||||||
|
+uniform vec2 yaTexScale;
|
||||||
|
+uniform vec2 yaTexOffset;
|
||||||
|
+uniform vec2 uvTexScale;
|
||||||
|
+uniform vec2 uvTexOffset;
|
||||||
|
+void main() {
|
||||||
|
+ gl_Position = matrix * a_position;
|
||||||
|
+ v_yaTexCoord = a_texCoord * yaTexScale + yaTexOffset;
|
||||||
|
+ v_uvTexCoord = a_texCoord * uvTexScale + uvTexOffset;
|
||||||
|
+}
|
||||||
|
+ )SHADER";
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -168,33 +172,35 @@ public:
|
||||||
|
YUVAVideoMaterialShader(const gfx::ColorSpace &colorSpace) : YUVVideoMaterialShader(colorSpace)
|
||||||
|
{
|
||||||
|
static const char *shaderHead =
|
||||||
|
- "varying mediump vec2 v_yaTexCoord;\n"
|
||||||
|
- "varying mediump vec2 v_uvTexCoord;\n"
|
||||||
|
- "uniform sampler2D y_texture;\n"
|
||||||
|
- "uniform sampler2D u_texture;\n"
|
||||||
|
- "uniform sampler2D v_texture;\n"
|
||||||
|
- "uniform sampler2D a_texture;\n"
|
||||||
|
- "uniform mediump float alpha;\n"
|
||||||
|
- "uniform mediump vec4 ya_clamp_rect;\n"
|
||||||
|
- "uniform mediump vec4 uv_clamp_rect;\n";
|
||||||
|
+ R"SHADER(#version 150 core
|
||||||
|
+in vec2 v_yaTexCoord;
|
||||||
|
+in vec2 v_uvTexCoord;
|
||||||
|
+uniform sampler2D y_texture;
|
||||||
|
+uniform sampler2D u_texture;
|
||||||
|
+uniform sampler2D v_texture;
|
||||||
|
+uniform sampler2D a_texture;
|
||||||
|
+uniform float alpha;
|
||||||
|
+uniform vec4 ya_clamp_rect;
|
||||||
|
+uniform vec4 uv_clamp_rect;
|
||||||
|
+out vec4 fragColor;
|
||||||
|
+ )SHADER";
|
||||||
|
static const char *shader =
|
||||||
|
- "void main() {\n"
|
||||||
|
- " mediump vec2 ya_clamped =\n"
|
||||||
|
- " max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));\n"
|
||||||
|
- " mediump float y_raw = texture2D(y_texture, ya_clamped).x;\n"
|
||||||
|
- " mediump vec2 uv_clamped =\n"
|
||||||
|
- " max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));\n"
|
||||||
|
- " mediump float u_unsigned = texture2D(u_texture, uv_clamped).x;\n"
|
||||||
|
- " mediump float v_unsigned = texture2D(v_texture, uv_clamped).x;\n"
|
||||||
|
- " mediump float a_raw = texture2D(a_texture, ya_clamped).x;\n"
|
||||||
|
- " mediump vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned);\n"
|
||||||
|
- " mediump vec3 rgb = DoColorConversion(yuv);\n"
|
||||||
|
- " gl_FragColor = vec4(rgb, 1.0) * (alpha * a_raw);\n"
|
||||||
|
- "}";
|
||||||
|
- QByteArray header(shaderHead);
|
||||||
|
- if (QOpenGLContext::currentContext()->isOpenGLES())
|
||||||
|
- header = QByteArray("precision mediump float;\n") + header;
|
||||||
|
- m_fragmentShader = header + m_csShader + QByteArray(shader);
|
||||||
|
+ R"SHADER(
|
||||||
|
+void main() {
|
||||||
|
+ vec2 ya_clamped =
|
||||||
|
+ max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));
|
||||||
|
+ float y_raw = texture(y_texture, ya_clamped).x;
|
||||||
|
+ vec2 uv_clamped =
|
||||||
|
+ max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));
|
||||||
|
+ float u_unsigned = texture(u_texture, uv_clamped).x;
|
||||||
|
+ float v_unsigned = texture(v_texture, uv_clamped).x;
|
||||||
|
+ float a_raw = texture(a_texture, ya_clamped).x;
|
||||||
|
+ vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned);
|
||||||
|
+ vec3 rgb = DoColorConversion(yuv);
|
||||||
|
+ fragColor = vec4(rgb, 1.0) * (alpha * a_raw);
|
||||||
|
+}
|
||||||
|
+ )SHADER";
|
||||||
|
+ m_fragmentShader = QByteArray(shaderHead) + m_csShader + QByteArray(shader);
|
||||||
|
}
|
||||||
|
void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
|
||||||
|
|