mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 22:51:20 +02:00
Merge pull request #13938 from wayne-chen/interstitalMerged
Interstitial Page with 404 Redirect
This commit is contained in:
commit
f67deb9f65
37 changed files with 1835 additions and 172 deletions
|
@ -332,6 +332,10 @@ if (APPLE)
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||||
"${PROJECT_SOURCE_DIR}/resources/fonts"
|
"${PROJECT_SOURCE_DIR}/resources/fonts"
|
||||||
"${RESOURCES_DEV_DIR}/fonts"
|
"${RESOURCES_DEV_DIR}/fonts"
|
||||||
|
# add redirect json to macOS builds.
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
||||||
|
"${PROJECT_SOURCE_DIR}/resources/serverless/redirect.json"
|
||||||
|
"${RESOURCES_DEV_DIR}/serverless/redirect.json"
|
||||||
)
|
)
|
||||||
|
|
||||||
# call the fixup_interface macro to add required bundling commands for installation
|
# call the fixup_interface macro to add required bundling commands for installation
|
||||||
|
@ -360,6 +364,9 @@ else()
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
||||||
"${PROJECT_SOURCE_DIR}/resources/serverless/tutorial.json"
|
"${PROJECT_SOURCE_DIR}/resources/serverless/tutorial.json"
|
||||||
"${RESOURCES_DEV_DIR}/serverless/tutorial.json"
|
"${RESOURCES_DEV_DIR}/serverless/tutorial.json"
|
||||||
|
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
||||||
|
"${PROJECT_SOURCE_DIR}/resources/serverless/redirect.json"
|
||||||
|
"${RESOURCES_DEV_DIR}/serverless/redirect.json"
|
||||||
# copy JSDoc files beside the executable
|
# copy JSDoc files beside the executable
|
||||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
COMMAND "${CMAKE_COMMAND}" -E copy_directory
|
||||||
"${CMAKE_SOURCE_DIR}/tools/jsdoc/out"
|
"${CMAKE_SOURCE_DIR}/tools/jsdoc/out"
|
||||||
|
|
BIN
interface/resources/images/loadingBar_placard.png
Normal file
BIN
interface/resources/images/loadingBar_placard.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
BIN
interface/resources/images/loadingBar_progress.png
Normal file
BIN
interface/resources/images/loadingBar_progress.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
BIN
interface/resources/meshes/redirect/oopsDialog_auth.fbx
Normal file
BIN
interface/resources/meshes/redirect/oopsDialog_auth.fbx
Normal file
Binary file not shown.
BIN
interface/resources/meshes/redirect/oopsDialog_auth.png
Normal file
BIN
interface/resources/meshes/redirect/oopsDialog_auth.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
BIN
interface/resources/meshes/redirect/oopsDialog_protocol.fbx
Normal file
BIN
interface/resources/meshes/redirect/oopsDialog_protocol.fbx
Normal file
Binary file not shown.
BIN
interface/resources/meshes/redirect/oopsDialog_protocol.png
Normal file
BIN
interface/resources/meshes/redirect/oopsDialog_protocol.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
BIN
interface/resources/meshes/redirect/oopsDialog_vague.fbx
Normal file
BIN
interface/resources/meshes/redirect/oopsDialog_vague.fbx
Normal file
Binary file not shown.
BIN
interface/resources/meshes/redirect/oopsDialog_vague.png
Normal file
BIN
interface/resources/meshes/redirect/oopsDialog_vague.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5 KiB |
|
@ -79,7 +79,7 @@ StackView {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
location.text = targetString;
|
location.text = targetString;
|
||||||
toggleOrGo(true, targetString);
|
toggleOrGo(targetString, true);
|
||||||
clearAddressLineTimer.start();
|
clearAddressLineTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,7 +399,7 @@ StackView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleOrGo(fromSuggestions, address) {
|
function toggleOrGo(address, fromSuggestions) {
|
||||||
if (address !== undefined && address !== "") {
|
if (address !== undefined && address !== "") {
|
||||||
addressBarDialog.loadAddress(address, fromSuggestions);
|
addressBarDialog.loadAddress(address, fromSuggestions);
|
||||||
clearAddressLineTimer.start();
|
clearAddressLineTimer.start();
|
||||||
|
|
934
interface/resources/serverless/redirect.json
Normal file
934
interface/resources/serverless/redirect.json
Normal file
|
@ -0,0 +1,934 @@
|
||||||
|
{
|
||||||
|
"DataVersion": 0,
|
||||||
|
"Paths":
|
||||||
|
{
|
||||||
|
"/": "/4,1.4,4/0,0.49544,0,0.868645"
|
||||||
|
},
|
||||||
|
"Entities": [
|
||||||
|
{
|
||||||
|
"clientOnly": false,
|
||||||
|
"collidesWith": "static,dynamic,kinematic,otherAvatar,",
|
||||||
|
"collisionMask": 23,
|
||||||
|
"created": "2018-09-05T18:13:00Z",
|
||||||
|
"dimensions": {
|
||||||
|
"blue": 1.159199833869934,
|
||||||
|
"green": 2.8062009811401367,
|
||||||
|
"red": 1.6216505765914917,
|
||||||
|
"x": 1.6216505765914917,
|
||||||
|
"y": 2.8062009811401367,
|
||||||
|
"z": 1.159199833869934
|
||||||
|
},
|
||||||
|
"id": "{d0ed60b8-9174-4c56-8e78-2c5399329ae0}",
|
||||||
|
"lastEdited": 1536171372916208,
|
||||||
|
"lastEditedBy": "{151cb20e-715a-4c80-aa0d-5b58b1c8a0c9}",
|
||||||
|
"locked": true,
|
||||||
|
"name": "Try Again Zone",
|
||||||
|
"owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
"position": {
|
||||||
|
"blue":4.015342712402344,
|
||||||
|
"green":1.649999976158142,
|
||||||
|
"red":2.00921893119812,
|
||||||
|
"x":2.00921893119812,
|
||||||
|
"y":1.649999976158142,
|
||||||
|
"z":4.015342712402344
|
||||||
|
},
|
||||||
|
"queryAACube": {
|
||||||
|
"scale": 3.4421300888061523,
|
||||||
|
"x": 1.6001315116882324,
|
||||||
|
"y": -0.07100248336791992,
|
||||||
|
"z": 0.14220571517944336
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"w": 0.9914448857307434,
|
||||||
|
"x": 0,
|
||||||
|
"y": -0.13052619993686676,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/zoneTryAgainEntityScript.js",
|
||||||
|
"shapeType": "box",
|
||||||
|
"type": "Zone",
|
||||||
|
"userData": "{\"grabbableKey\":{\"grabbable\":false}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"clientOnly": false,
|
||||||
|
"color": {
|
||||||
|
"blue": 0,
|
||||||
|
"green": 0,
|
||||||
|
"red": 255
|
||||||
|
},
|
||||||
|
"created": "2018-09-05T00:40:03Z",
|
||||||
|
"dimensions": {
|
||||||
|
"blue": 8.645400047302246,
|
||||||
|
"green": 0.20000000298023224,
|
||||||
|
"red": 20.025121688842773,
|
||||||
|
"x": 20.025121688842773,
|
||||||
|
"y": 0.20000000298023224,
|
||||||
|
"z": 8.645400047302246
|
||||||
|
},
|
||||||
|
"id": "{e44fb546-b34a-4966-9b11-73556f800d21}",
|
||||||
|
"lastEdited": 1536107948776951,
|
||||||
|
"lastEditedBy": "{ce82d352-3002-44ae-9b76-66492989a1db}",
|
||||||
|
"locked": true,
|
||||||
|
"name": "ceiling",
|
||||||
|
"owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
"position": {
|
||||||
|
"blue": 4.846520900726318,
|
||||||
|
"green": 2.912982940673828,
|
||||||
|
"red": 5.739595890045166,
|
||||||
|
"x": 5.739595890045166,
|
||||||
|
"y": 2.912982940673828,
|
||||||
|
"z": 4.846520900726318
|
||||||
|
},
|
||||||
|
"queryAACube": {
|
||||||
|
"scale": 21.812576293945312,
|
||||||
|
"x": -5.16669225692749,
|
||||||
|
"y": -7.993305206298828,
|
||||||
|
"z": -6.059767246246338
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"w": 0.970295786857605,
|
||||||
|
"x": 0,
|
||||||
|
"y": -0.24192190170288086,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"shape": "Cube",
|
||||||
|
"type": "Box",
|
||||||
|
"userData": "{\"grabbableKey\":{\"grabbable\":false}}",
|
||||||
|
"visible": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"clientOnly": false,
|
||||||
|
"color": {
|
||||||
|
"blue": 0,
|
||||||
|
"green": 0,
|
||||||
|
"red": 0
|
||||||
|
},
|
||||||
|
"created": "2018-09-05T00:40:03Z",
|
||||||
|
"dimensions": {
|
||||||
|
"blue": 6.9401350021362305,
|
||||||
|
"green": 0.04553089290857315,
|
||||||
|
"red": 7.004304885864258,
|
||||||
|
"x": 7.004304885864258,
|
||||||
|
"y": 0.04553089290857315,
|
||||||
|
"z": 6.9401350021362305
|
||||||
|
},
|
||||||
|
"id": "{8cd93fe5-16c0-44b7-b1e9-e7e06c4e9228}",
|
||||||
|
"lastEdited": 1536107948774796,
|
||||||
|
"lastEditedBy": "{4eecd88f-ef9b-4a83-bb9a-7f7496209c6b}",
|
||||||
|
"locked": true,
|
||||||
|
"name": "floor",
|
||||||
|
"owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
"position": {
|
||||||
|
"blue": 3.6175529956817627,
|
||||||
|
"green": 0,
|
||||||
|
"red": 4.102385997772217,
|
||||||
|
"x": 4.102385997772217,
|
||||||
|
"y": 0,
|
||||||
|
"z": 3.6175529956817627
|
||||||
|
},
|
||||||
|
"queryAACube": {
|
||||||
|
"scale": 9.860417366027832,
|
||||||
|
"x": -0.8278226852416992,
|
||||||
|
"y": -4.930208683013916,
|
||||||
|
"z": -1.3126556873321533
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"w": 0.8660253882408142,
|
||||||
|
"x": -1.5922749298624694e-05,
|
||||||
|
"y": 0.5,
|
||||||
|
"z": -4.572480611386709e-05
|
||||||
|
},
|
||||||
|
"shape": "Cube",
|
||||||
|
"type": "Box",
|
||||||
|
"userData": "{\"grabbableKey\":{\"grabbable\":false}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"clientOnly": false,
|
||||||
|
"color": {
|
||||||
|
"blue": 0,
|
||||||
|
"green": 0,
|
||||||
|
"red": 0
|
||||||
|
},
|
||||||
|
"created": "2018-09-05T00:40:03Z",
|
||||||
|
"dimensions": {
|
||||||
|
"blue": 11.117486953735352,
|
||||||
|
"green": 3.580313205718994,
|
||||||
|
"red": 0.20000000298023224,
|
||||||
|
"x": 0.20000000298023224,
|
||||||
|
"y": 3.580313205718994,
|
||||||
|
"z": 11.117486953735352
|
||||||
|
},
|
||||||
|
"id": "{147272dc-a344-4171-9621-efc1c2095997}",
|
||||||
|
"lastEdited": 1536107948776823,
|
||||||
|
"lastEditedBy": "{ce82d352-3002-44ae-9b76-66492989a1db}",
|
||||||
|
"locked": true,
|
||||||
|
"name": "leftWall",
|
||||||
|
"owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
"position": {
|
||||||
|
"blue": 6.1806135177612305,
|
||||||
|
"green": 1.0066027641296387,
|
||||||
|
"red": 1.4690406322479248,
|
||||||
|
"x": 1.4690406322479248,
|
||||||
|
"y": 1.0066027641296387,
|
||||||
|
"z": 6.1806135177612305
|
||||||
|
},
|
||||||
|
"queryAACube": {
|
||||||
|
"scale": 11.681488037109375,
|
||||||
|
"x": -4.371703147888184,
|
||||||
|
"y": -4.834141254425049,
|
||||||
|
"z": 0.33986949920654297
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"w": 0.8637980222702026,
|
||||||
|
"x": -4.57763671875e-05,
|
||||||
|
"y": 0.5038070678710938,
|
||||||
|
"z": -1.52587890625e-05
|
||||||
|
},
|
||||||
|
"shape": "Cube",
|
||||||
|
"type": "Box",
|
||||||
|
"userData": "{\"grabbableKey\":{\"grabbable\":false}}",
|
||||||
|
"visible": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"clientOnly": false,
|
||||||
|
"color": {
|
||||||
|
"blue": 0,
|
||||||
|
"green": 0,
|
||||||
|
"red": 0
|
||||||
|
},
|
||||||
|
"created": "2018-09-05T00:40:03Z",
|
||||||
|
"dimensions": {
|
||||||
|
"blue": 11.117486953735352,
|
||||||
|
"green": 3.580313205718994,
|
||||||
|
"red": 0.20000000298023224,
|
||||||
|
"x": 0.20000000298023224,
|
||||||
|
"y": 3.580313205718994,
|
||||||
|
"z": 11.117486953735352
|
||||||
|
},
|
||||||
|
"id": "{5f2b89b8-47e3-4915-a966-d46307a40f06}",
|
||||||
|
"lastEdited": 1536107948774605,
|
||||||
|
"lastEditedBy": "{ce82d352-3002-44ae-9b76-66492989a1db}",
|
||||||
|
"locked": true,
|
||||||
|
"name": "backWall",
|
||||||
|
"owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
"position": {
|
||||||
|
"blue": 5.268576622009277,
|
||||||
|
"green": 1.0066027641296387,
|
||||||
|
"red": 6.093774318695068,
|
||||||
|
"x": 6.093774318695068,
|
||||||
|
"y": 1.0066027641296387,
|
||||||
|
"z": 5.268576622009277
|
||||||
|
},
|
||||||
|
"queryAACube": {
|
||||||
|
"scale": 11.681488037109375,
|
||||||
|
"x": 0.25303030014038086,
|
||||||
|
"y": -4.834141254425049,
|
||||||
|
"z": -0.5721673965454102
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"w": 0.9662165641784668,
|
||||||
|
"x": -4.57763671875e-05,
|
||||||
|
"y": -0.2576791048049927,
|
||||||
|
"z": 1.52587890625e-05
|
||||||
|
},
|
||||||
|
"shape": "Cube",
|
||||||
|
"type": "Box",
|
||||||
|
"userData": "{\"grabbableKey\":{\"grabbable\":false}}",
|
||||||
|
"visible": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"clientOnly": false,
|
||||||
|
"created": "2018-09-05T00:40:03Z",
|
||||||
|
"dimensions": {
|
||||||
|
"blue": 14.40000057220459,
|
||||||
|
"green": 14.40000057220459,
|
||||||
|
"red": 14.40000057220459,
|
||||||
|
"x": 14.40000057220459,
|
||||||
|
"y": 14.40000057220459,
|
||||||
|
"z": 14.40000057220459
|
||||||
|
},
|
||||||
|
"id": "{baf96345-8f68-4068-af4c-3c690035852a}",
|
||||||
|
"lastEdited": 1536107948775591,
|
||||||
|
"lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}",
|
||||||
|
"locked": true,
|
||||||
|
"owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
"position": {
|
||||||
|
"blue": 2.3440732955932617,
|
||||||
|
"green": 1.6162219047546387,
|
||||||
|
"red": 1.8748211860656738,
|
||||||
|
"x": 1.8748211860656738,
|
||||||
|
"y": 1.6162219047546387,
|
||||||
|
"z": 2.3440732955932617
|
||||||
|
},
|
||||||
|
"queryAACube": {
|
||||||
|
"scale": 24.9415340423584,
|
||||||
|
"x": -10.595945358276367,
|
||||||
|
"y": -10.854545593261719,
|
||||||
|
"z": -10.126693725585938
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"w": 0.8697794675827026,
|
||||||
|
"x": -1.52587890625e-05,
|
||||||
|
"y": 0.4933699369430542,
|
||||||
|
"z": -4.57763671875e-05
|
||||||
|
},
|
||||||
|
"shapeType": "box",
|
||||||
|
"skyboxMode": "enabled",
|
||||||
|
"type": "Zone",
|
||||||
|
"userData": "{\"grabbableKey\":{\"grabbable\":false}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alpha": 0,
|
||||||
|
"alphaFinish": 0,
|
||||||
|
"alphaStart": 1,
|
||||||
|
"clientOnly": false,
|
||||||
|
"color": {
|
||||||
|
"blue": 211,
|
||||||
|
"green": 227,
|
||||||
|
"red": 104
|
||||||
|
},
|
||||||
|
"colorFinish": {
|
||||||
|
"blue": 0,
|
||||||
|
"green": 0,
|
||||||
|
"red": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"colorStart": {
|
||||||
|
"blue": 211,
|
||||||
|
"green": 227,
|
||||||
|
"red": 104,
|
||||||
|
"x": 104,
|
||||||
|
"y": 227,
|
||||||
|
"z": 211
|
||||||
|
},
|
||||||
|
"created": "2018-09-05T00:40:03Z",
|
||||||
|
"dimensions": {
|
||||||
|
"blue": 2.5,
|
||||||
|
"green": 2.5,
|
||||||
|
"red": 2.5,
|
||||||
|
"x": 2.5,
|
||||||
|
"y": 2.5,
|
||||||
|
"z": 2.5
|
||||||
|
},
|
||||||
|
"emitAcceleration": {
|
||||||
|
"blue": 0,
|
||||||
|
"green": 0,
|
||||||
|
"red": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"emitDimensions": {
|
||||||
|
"blue": 1,
|
||||||
|
"green": 1,
|
||||||
|
"red": 1,
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"z": 1
|
||||||
|
},
|
||||||
|
"emitOrientation": {
|
||||||
|
"w": 0.9993909597396851,
|
||||||
|
"x": 0.034897372126579285,
|
||||||
|
"y": -1.525880907138344e-05,
|
||||||
|
"z": -1.525880907138344e-05
|
||||||
|
},
|
||||||
|
"emitRate": 2,
|
||||||
|
"emitSpeed": 0,
|
||||||
|
"id": "{639a51f0-8613-4e46-bc7e-fef24597df73}",
|
||||||
|
"lastEdited": 1536107948776693,
|
||||||
|
"lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}",
|
||||||
|
"lifespan": 10,
|
||||||
|
"locked": true,
|
||||||
|
"maxParticles": 40,
|
||||||
|
"name": "Rays",
|
||||||
|
"owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
"particleRadius": 0.75,
|
||||||
|
"polarFinish": 3.1415927410125732,
|
||||||
|
"position": {
|
||||||
|
"blue": 1.3553659915924072,
|
||||||
|
"green": 1.2890124320983887,
|
||||||
|
"red": 2.5663273334503174,
|
||||||
|
"x": 2.5663273334503174,
|
||||||
|
"y": 1.2890124320983887,
|
||||||
|
"z": 1.3553659915924072
|
||||||
|
},
|
||||||
|
"queryAACube": {
|
||||||
|
"scale": 4.330127239227295,
|
||||||
|
"x": 0.4012637138366699,
|
||||||
|
"y": -0.8760511875152588,
|
||||||
|
"z": -0.8096976280212402
|
||||||
|
},
|
||||||
|
"radiusFinish": 0.10000000149011612,
|
||||||
|
"radiusStart": 0,
|
||||||
|
"rotation": {
|
||||||
|
"w": 0.9803768396377563,
|
||||||
|
"x": -1.52587890625e-05,
|
||||||
|
"y": 0.19707024097442627,
|
||||||
|
"z": -7.62939453125e-05
|
||||||
|
},
|
||||||
|
"speedSpread": 0,
|
||||||
|
"spinFinish": null,
|
||||||
|
"spinStart": null,
|
||||||
|
"textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/stripe.png",
|
||||||
|
"type": "ParticleEffect",
|
||||||
|
"userData": "{\"grabbableKey\":{\"grabbable\":false}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alpha": 0,
|
||||||
|
"alphaFinish": 0,
|
||||||
|
"alphaStart": 1,
|
||||||
|
"clientOnly": false,
|
||||||
|
"color": {
|
||||||
|
"blue": 255,
|
||||||
|
"green": 205,
|
||||||
|
"red": 3
|
||||||
|
},
|
||||||
|
"colorFinish": {
|
||||||
|
"blue": 0,
|
||||||
|
"green": 0,
|
||||||
|
"red": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"colorStart": {
|
||||||
|
"blue": 255,
|
||||||
|
"green": 204,
|
||||||
|
"red": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 204,
|
||||||
|
"z": 255
|
||||||
|
},
|
||||||
|
"created": "2018-09-05T00:40:03Z",
|
||||||
|
"dimensions": {
|
||||||
|
"blue": 2.5,
|
||||||
|
"green": 2.5,
|
||||||
|
"red": 2.5,
|
||||||
|
"x": 2.5,
|
||||||
|
"y": 2.5,
|
||||||
|
"z": 2.5
|
||||||
|
},
|
||||||
|
"emitAcceleration": {
|
||||||
|
"blue": 0,
|
||||||
|
"green": 0,
|
||||||
|
"red": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"emitDimensions": {
|
||||||
|
"blue": 1,
|
||||||
|
"green": 1,
|
||||||
|
"red": 1,
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"z": 1
|
||||||
|
},
|
||||||
|
"emitOrientation": {
|
||||||
|
"w": 0.9993909597396851,
|
||||||
|
"x": 0.034897372126579285,
|
||||||
|
"y": -1.525880907138344e-05,
|
||||||
|
"z": -1.525880907138344e-05
|
||||||
|
},
|
||||||
|
"emitRate": 2,
|
||||||
|
"emitSpeed": 0,
|
||||||
|
"emitterShouldTrail": true,
|
||||||
|
"id": "{e62ced49-fa18-4ae1-977f-abef5bc0f3ba}",
|
||||||
|
"lastEdited": 1536107948775366,
|
||||||
|
"lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}",
|
||||||
|
"lifespan": 10,
|
||||||
|
"locked": true,
|
||||||
|
"maxParticles": 40,
|
||||||
|
"name": "Rays",
|
||||||
|
"owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
"particleRadius": 0.75,
|
||||||
|
"polarFinish": 3.1415927410125732,
|
||||||
|
"position": {
|
||||||
|
"blue": 3.814434051513672,
|
||||||
|
"green": 1.2890124320983887,
|
||||||
|
"red": 1.2254328727722168,
|
||||||
|
"x": 1.2254328727722168,
|
||||||
|
"y": 1.2890124320983887,
|
||||||
|
"z": 3.814434051513672
|
||||||
|
},
|
||||||
|
"queryAACube": {
|
||||||
|
"scale": 4.330127239227295,
|
||||||
|
"x": -0.9396307468414307,
|
||||||
|
"y": -0.8760511875152588,
|
||||||
|
"z": 1.6493704319000244
|
||||||
|
},
|
||||||
|
"radiusFinish": 0.10000000149011612,
|
||||||
|
"radiusStart": 0,
|
||||||
|
"rotation": {
|
||||||
|
"w": 0.9594720602035522,
|
||||||
|
"x": -1.52587890625e-05,
|
||||||
|
"y": 0.28178834915161133,
|
||||||
|
"z": -4.57763671875e-05
|
||||||
|
},
|
||||||
|
"speedSpread": 0,
|
||||||
|
"spinFinish": null,
|
||||||
|
"spinStart": null,
|
||||||
|
"textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/stripe.png",
|
||||||
|
"type": "ParticleEffect",
|
||||||
|
"userData": "{\"grabbableKey\":{\"grabbable\":false}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alpha": 0,
|
||||||
|
"alphaFinish": 0,
|
||||||
|
"alphaStart": 0.25,
|
||||||
|
"clientOnly": false,
|
||||||
|
"colorFinish": {
|
||||||
|
"blue": 0,
|
||||||
|
"green": 0,
|
||||||
|
"red": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"colorStart": {
|
||||||
|
"blue": 255,
|
||||||
|
"green": 255,
|
||||||
|
"red": 255,
|
||||||
|
"x": 255,
|
||||||
|
"y": 255,
|
||||||
|
"z": 255
|
||||||
|
},
|
||||||
|
"created": "2018-09-05T00:40:03Z",
|
||||||
|
"dimensions": {
|
||||||
|
"blue": 13.24000072479248,
|
||||||
|
"green": 13.24000072479248,
|
||||||
|
"red": 13.24000072479248,
|
||||||
|
"x": 13.24000072479248,
|
||||||
|
"y": 13.24000072479248,
|
||||||
|
"z": 13.24000072479248
|
||||||
|
},
|
||||||
|
"emitAcceleration": {
|
||||||
|
"blue": 0,
|
||||||
|
"green": 0.10000000149011612,
|
||||||
|
"red": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0.10000000149011612,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"emitDimensions": {
|
||||||
|
"blue": 1,
|
||||||
|
"green": 1,
|
||||||
|
"red": 1,
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"z": 1
|
||||||
|
},
|
||||||
|
"emitOrientation": {
|
||||||
|
"w": 1,
|
||||||
|
"x": -1.52587890625e-05,
|
||||||
|
"y": -1.52587890625e-05,
|
||||||
|
"z": -1.52587890625e-05
|
||||||
|
},
|
||||||
|
"emitRate": 6,
|
||||||
|
"emitSpeed": 0,
|
||||||
|
"id": "{298c0571-cbd8-487b-8640-64037d6a8414}",
|
||||||
|
"lastEdited": 1536107948776382,
|
||||||
|
"lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}",
|
||||||
|
"lifespan": 10,
|
||||||
|
"locked": true,
|
||||||
|
"maxParticles": 10,
|
||||||
|
"name": "Stars",
|
||||||
|
"owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
"particleRadius": 0.07000000029802322,
|
||||||
|
"polarFinish": 3.1415927410125732,
|
||||||
|
"position": {
|
||||||
|
"blue": 1.3712034225463867,
|
||||||
|
"green": 0.3698839843273163,
|
||||||
|
"red": 2.6216418743133545,
|
||||||
|
"x": 2.6216418743133545,
|
||||||
|
"y": 0.3698839843273163,
|
||||||
|
"z": 1.3712034225463867
|
||||||
|
},
|
||||||
|
"queryAACube": {
|
||||||
|
"scale": 22.932353973388672,
|
||||||
|
"x": -8.844534873962402,
|
||||||
|
"y": -11.096293449401855,
|
||||||
|
"z": -10.09497356414795
|
||||||
|
},
|
||||||
|
"radiusFinish": 0,
|
||||||
|
"radiusStart": 0,
|
||||||
|
"rotation": {
|
||||||
|
"w": 0.9852597713470459,
|
||||||
|
"x": -1.52587890625e-05,
|
||||||
|
"y": -0.17106890678405762,
|
||||||
|
"z": -7.62939453125e-05
|
||||||
|
},
|
||||||
|
"speedSpread": 0,
|
||||||
|
"spinFinish": null,
|
||||||
|
"spinStart": null,
|
||||||
|
"textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/star.png",
|
||||||
|
"type": "ParticleEffect",
|
||||||
|
"userData": "{\"grabbableKey\":{\"grabbable\":false}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"clientOnly": false,
|
||||||
|
"created": "2018-09-05T00:40:03Z",
|
||||||
|
"dimensions": {
|
||||||
|
"blue": 2.1097896099090576,
|
||||||
|
"green": 0.04847164824604988,
|
||||||
|
"red": 1.458284616470337,
|
||||||
|
"x": 1.458284616470337,
|
||||||
|
"y": 0.04847164824604988,
|
||||||
|
"z": 2.1097896099090576
|
||||||
|
},
|
||||||
|
"id": "{6625dbb8-ff25-458d-a92e-644b58460604}",
|
||||||
|
"lastEdited": 1536107948776195,
|
||||||
|
"lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}",
|
||||||
|
"locked": true,
|
||||||
|
"modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal1.fbx",
|
||||||
|
"name": "Try Again",
|
||||||
|
"owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
"position": {
|
||||||
|
"blue": 3.946338653564453,
|
||||||
|
"green": 0.09449335932731628,
|
||||||
|
"red": 1.594836711883545,
|
||||||
|
"x": 1.594836711883545,
|
||||||
|
"y": 0.09449335932731628,
|
||||||
|
"z": 3.946338653564453
|
||||||
|
},
|
||||||
|
"queryAACube": {
|
||||||
|
"scale": 2.5651814937591553,
|
||||||
|
"x": 0.3122459650039673,
|
||||||
|
"y": -1.188097357749939,
|
||||||
|
"z": 2.663747787475586
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"w": 0.8220492601394653,
|
||||||
|
"x": -1.52587890625e-05,
|
||||||
|
"y": 0.5693598985671997,
|
||||||
|
"z": -0.0001068115234375
|
||||||
|
},
|
||||||
|
"script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/tryAgainEntityScript.js",
|
||||||
|
"shapeType": "static-mesh",
|
||||||
|
"type": "Model",
|
||||||
|
"userData": "{\"grabbableKey\":{\"grabbable\":false}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"clientOnly": false,
|
||||||
|
"created": "2018-09-05T00:40:03Z",
|
||||||
|
"dimensions": {
|
||||||
|
"blue": 0.06014331430196762,
|
||||||
|
"green": 2.582186460494995,
|
||||||
|
"red": 2.582186698913574,
|
||||||
|
"x": 2.582186698913574,
|
||||||
|
"y": 2.582186460494995,
|
||||||
|
"z": 0.06014331430196762
|
||||||
|
},
|
||||||
|
"id": "{dfe92dce-f09d-4e9e-b3ed-c68ecd4d476f}",
|
||||||
|
"lastEdited": 1536108160862286,
|
||||||
|
"lastEditedBy": "{4656d4a8-5e61-4230-ab34-2888d7945bd6}",
|
||||||
|
"modelURL": "",
|
||||||
|
"name": "Oops Dialog",
|
||||||
|
"owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
"position": {
|
||||||
|
"blue": 1.45927095413208,
|
||||||
|
"green": 1.6763916015625,
|
||||||
|
"red": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 1.6763916015625,
|
||||||
|
"z": 1.45927095413208
|
||||||
|
},
|
||||||
|
"queryAACube": {
|
||||||
|
"scale": 3.6522583961486816,
|
||||||
|
"x": -1.8261291980743408,
|
||||||
|
"y": -0.14973759651184082,
|
||||||
|
"z": -0.36685824394226074
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"w": 0.8684672117233276,
|
||||||
|
"x": -4.57763671875e-05,
|
||||||
|
"y": 0.4957197904586792,
|
||||||
|
"z": -7.62939453125e-05
|
||||||
|
},
|
||||||
|
"script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/oopsEntityScript.js",
|
||||||
|
"scriptTimestamp": 1536102551825,
|
||||||
|
"type": "Model",
|
||||||
|
"userData": "{\"grabbableKey\":{\"grabbable\":false}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"clientOnly": false,
|
||||||
|
"color": {
|
||||||
|
"blue": 0,
|
||||||
|
"green": 0,
|
||||||
|
"red": 0
|
||||||
|
},
|
||||||
|
"created": "2018-09-05T00:40:03Z",
|
||||||
|
"dimensions": {
|
||||||
|
"blue": 11.117486953735352,
|
||||||
|
"green": 3.580313205718994,
|
||||||
|
"red": 0.20000000298023224,
|
||||||
|
"x": 0.20000000298023224,
|
||||||
|
"y": 3.580313205718994,
|
||||||
|
"z": 11.117486953735352
|
||||||
|
},
|
||||||
|
"id": "{144a8cf4-b0e8-489a-9403-d74d4dc4cb3e}",
|
||||||
|
"lastEdited": 1536107948775774,
|
||||||
|
"lastEditedBy": "{ce82d352-3002-44ae-9b76-66492989a1db}",
|
||||||
|
"locked": true,
|
||||||
|
"name": "rightWall",
|
||||||
|
"owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
"position": {
|
||||||
|
"blue": 0,
|
||||||
|
"green": 1.0061144828796387,
|
||||||
|
"red": 4.965089321136475,
|
||||||
|
"x": 4.965089321136475,
|
||||||
|
"y": 1.0061144828796387,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"queryAACube": {
|
||||||
|
"scale": 11.681488037109375,
|
||||||
|
"x": -0.8756546974182129,
|
||||||
|
"y": -4.834629535675049,
|
||||||
|
"z": -5.8407440185546875
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"w": 0.8637980222702026,
|
||||||
|
"x": -4.57763671875e-05,
|
||||||
|
"y": 0.5038070678710938,
|
||||||
|
"z": -1.52587890625e-05
|
||||||
|
},
|
||||||
|
"shape": "Cube",
|
||||||
|
"type": "Box",
|
||||||
|
"userData": "{\"grabbableKey\":{\"grabbable\":false}}",
|
||||||
|
"visible": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"clientOnly": false,
|
||||||
|
"collidesWith": "static,dynamic,kinematic,otherAvatar,",
|
||||||
|
"collisionMask": 23,
|
||||||
|
"created": "2018-09-05T00:40:03Z",
|
||||||
|
"dimensions": {
|
||||||
|
"blue": 1.159199833869934,
|
||||||
|
"green": 2.8062009811401367,
|
||||||
|
"red": 1.6216505765914917,
|
||||||
|
"x": 1.6216505765914917,
|
||||||
|
"y": 2.8062009811401367,
|
||||||
|
"z": 1.159199833869934
|
||||||
|
},
|
||||||
|
"id": "{37f53408-3d0c-42a5-9891-e6c40a227349}",
|
||||||
|
"lastEdited": 1536107948775010,
|
||||||
|
"lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}",
|
||||||
|
"locked": true,
|
||||||
|
"name": "Back Zone",
|
||||||
|
"owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
"position": {
|
||||||
|
"blue": 1.8632707595825195,
|
||||||
|
"green": 1.6500625610351562,
|
||||||
|
"red": 3.3211965560913086,
|
||||||
|
"x": 3.3211965560913086,
|
||||||
|
"y": 1.6500625610351562,
|
||||||
|
"z": 1.8632707595825195
|
||||||
|
},
|
||||||
|
"queryAACube": {
|
||||||
|
"scale": 3.4421300888061523,
|
||||||
|
"x": 1.6001315116882324,
|
||||||
|
"y": -0.07100248336791992,
|
||||||
|
"z": 0.14220571517944336
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"w": 0.9304176568984985,
|
||||||
|
"x": 0,
|
||||||
|
"y": -0.36650121212005615,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/zoneBackEntityScript.js",
|
||||||
|
"shapeType": "box",
|
||||||
|
"type": "Zone",
|
||||||
|
"userData": "{\"grabbableKey\":{\"grabbable\":false}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"clientOnly": false,
|
||||||
|
"color": {
|
||||||
|
"blue": 0,
|
||||||
|
"green": 0,
|
||||||
|
"red": 0
|
||||||
|
},
|
||||||
|
"created": "2018-09-05T00:40:03Z",
|
||||||
|
"dimensions": {
|
||||||
|
"blue": 11.117486953735352,
|
||||||
|
"green": 3.580313205718994,
|
||||||
|
"red": 0.20000000298023224,
|
||||||
|
"x": 0.20000000298023224,
|
||||||
|
"y": 3.580313205718994,
|
||||||
|
"z": 11.117486953735352
|
||||||
|
},
|
||||||
|
"id": "{aa6e680c-6750-4776-95bc-ef3118cace5c}",
|
||||||
|
"lastEdited": 1536107948775945,
|
||||||
|
"lastEditedBy": "{ce82d352-3002-44ae-9b76-66492989a1db}",
|
||||||
|
"locked": true,
|
||||||
|
"name": "frontWall",
|
||||||
|
"owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
"position": {
|
||||||
|
"blue": 2.662257671356201,
|
||||||
|
"green": 1.0063786506652832,
|
||||||
|
"red": 1.4868733882904053,
|
||||||
|
"x": 1.4868733882904053,
|
||||||
|
"y": 1.0063786506652832,
|
||||||
|
"z": 2.662257671356201
|
||||||
|
},
|
||||||
|
"queryAACube": {
|
||||||
|
"scale": 11.681488037109375,
|
||||||
|
"x": -4.353870391845703,
|
||||||
|
"y": -4.834365367889404,
|
||||||
|
"z": -3.1784863471984863
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"w": 0.9666743278503418,
|
||||||
|
"x": -4.57763671875e-05,
|
||||||
|
"y": -0.2560006380081177,
|
||||||
|
"z": 1.52587890625e-05
|
||||||
|
},
|
||||||
|
"shape": "Cube",
|
||||||
|
"type": "Box",
|
||||||
|
"userData": "{\"grabbableKey\":{\"grabbable\":false}}",
|
||||||
|
"visible": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"clientOnly": false,
|
||||||
|
"created": "2018-09-05T00:40:03Z",
|
||||||
|
"dimensions": {
|
||||||
|
"blue": 2.1097896099090576,
|
||||||
|
"green": 0.04847164824604988,
|
||||||
|
"red": 1.458284616470337,
|
||||||
|
"x": 1.458284616470337,
|
||||||
|
"y": 0.04847164824604988,
|
||||||
|
"z": 2.1097896099090576
|
||||||
|
},
|
||||||
|
"id": "{303631f1-04f3-42a6-b8a8-8dd4b65d1231}",
|
||||||
|
"lastEdited": 1536107948776513,
|
||||||
|
"lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}",
|
||||||
|
"locked": true,
|
||||||
|
"modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal2.fbx",
|
||||||
|
"name": "Back",
|
||||||
|
"owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
"position": {
|
||||||
|
"blue": 1.5835940837860107,
|
||||||
|
"green": 0.09449335932731628,
|
||||||
|
"red": 3.028078079223633,
|
||||||
|
"x": 3.028078079223633,
|
||||||
|
"y": 0.09449335932731628,
|
||||||
|
"z": 1.5835940837860107
|
||||||
|
},
|
||||||
|
"queryAACube": {
|
||||||
|
"scale": 2.5651814937591553,
|
||||||
|
"x": 1.7454873323440552,
|
||||||
|
"y": -1.188097357749939,
|
||||||
|
"z": 0.3010033369064331
|
||||||
|
},
|
||||||
|
"rotation": {
|
||||||
|
"w": 0.9084458351135254,
|
||||||
|
"x": -1.52587890625e-05,
|
||||||
|
"y": 0.4179598093032837,
|
||||||
|
"z": -0.0001068115234375
|
||||||
|
},
|
||||||
|
"script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/backEntityScript.js",
|
||||||
|
"scriptTimestamp": 1535751754379,
|
||||||
|
"shapeType": "static-mesh",
|
||||||
|
"type": "Model",
|
||||||
|
"userData": "{\"grabbableKey\":{\"grabbable\":false}}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"alpha": 0,
|
||||||
|
"alphaFinish": 0,
|
||||||
|
"alphaStart": 0.25,
|
||||||
|
"clientOnly": false,
|
||||||
|
"colorFinish": {
|
||||||
|
"blue": 0,
|
||||||
|
"green": 0,
|
||||||
|
"red": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"colorStart": {
|
||||||
|
"blue": 255,
|
||||||
|
"green": 255,
|
||||||
|
"red": 255,
|
||||||
|
"x": 255,
|
||||||
|
"y": 255,
|
||||||
|
"z": 255
|
||||||
|
},
|
||||||
|
"created": "2018-09-05T00:40:03Z",
|
||||||
|
"dimensions": {
|
||||||
|
"blue": 13.24000072479248,
|
||||||
|
"green": 13.24000072479248,
|
||||||
|
"red": 13.24000072479248,
|
||||||
|
"x": 13.24000072479248,
|
||||||
|
"y": 13.24000072479248,
|
||||||
|
"z": 13.24000072479248
|
||||||
|
},
|
||||||
|
"emitAcceleration": {
|
||||||
|
"blue": 0,
|
||||||
|
"green": 0.10000000149011612,
|
||||||
|
"red": 0,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0.10000000149011612,
|
||||||
|
"z": 0
|
||||||
|
},
|
||||||
|
"emitDimensions": {
|
||||||
|
"blue": 1,
|
||||||
|
"green": 1,
|
||||||
|
"red": 1,
|
||||||
|
"x": 1,
|
||||||
|
"y": 1,
|
||||||
|
"z": 1
|
||||||
|
},
|
||||||
|
"emitOrientation": {
|
||||||
|
"w": 1,
|
||||||
|
"x": -1.52587890625e-05,
|
||||||
|
"y": -1.52587890625e-05,
|
||||||
|
"z": -1.52587890625e-05
|
||||||
|
},
|
||||||
|
"emitRate": 6,
|
||||||
|
"emitSpeed": 0,
|
||||||
|
"emitterShouldTrail": true,
|
||||||
|
"id": "{8ded39e6-303c-48f2-be79-81b715cca9f7}",
|
||||||
|
"lastEdited": 1536107948777127,
|
||||||
|
"lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}",
|
||||||
|
"lifespan": 10,
|
||||||
|
"locked": true,
|
||||||
|
"maxParticles": 10,
|
||||||
|
"name": "Stars",
|
||||||
|
"owningAvatarID": "{00000000-0000-0000-0000-000000000000}",
|
||||||
|
"particleRadius": 0.07000000029802322,
|
||||||
|
"polarFinish": 3.1415927410125732,
|
||||||
|
"position": {
|
||||||
|
"blue": 3.78922963142395,
|
||||||
|
"green": 0.3698839843273163,
|
||||||
|
"red": 1.1863799095153809,
|
||||||
|
"x": 1.1863799095153809,
|
||||||
|
"y": 0.3698839843273163,
|
||||||
|
"z": 3.78922963142395
|
||||||
|
},
|
||||||
|
"queryAACube": {
|
||||||
|
"scale": 22.932353973388672,
|
||||||
|
"x": -10.279796600341797,
|
||||||
|
"y": -11.096293449401855,
|
||||||
|
"z": -7.676947593688965
|
||||||
|
},
|
||||||
|
"radiusFinish": 0,
|
||||||
|
"radiusStart": 0,
|
||||||
|
"rotation": {
|
||||||
|
"w": 0.996429443359375,
|
||||||
|
"x": -1.52587890625e-05,
|
||||||
|
"y": -0.08442819118499756,
|
||||||
|
"z": -4.57763671875e-05
|
||||||
|
},
|
||||||
|
"speedSpread": 0,
|
||||||
|
"spinFinish": null,
|
||||||
|
"spinStart": null,
|
||||||
|
"textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/star.png",
|
||||||
|
"type": "ParticleEffect",
|
||||||
|
"userData": "{\"grabbableKey\":{\"grabbable\":false}}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Id": "{18abccad-2d57-4176-9d89-24dc424916f5}",
|
||||||
|
"Version": 93
|
||||||
|
}
|
|
@ -1186,6 +1186,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
const DomainHandler& domainHandler = nodeList->getDomainHandler();
|
const DomainHandler& domainHandler = nodeList->getDomainHandler();
|
||||||
|
|
||||||
connect(&domainHandler, SIGNAL(domainURLChanged(QUrl)), SLOT(domainURLChanged(QUrl)));
|
connect(&domainHandler, SIGNAL(domainURLChanged(QUrl)), SLOT(domainURLChanged(QUrl)));
|
||||||
|
connect(&domainHandler, SIGNAL(redirectToErrorDomainURL(QUrl)), SLOT(goToErrorDomainURL(QUrl)));
|
||||||
connect(&domainHandler, &DomainHandler::domainURLChanged, [](QUrl domainURL){
|
connect(&domainHandler, &DomainHandler::domainURLChanged, [](QUrl domainURL){
|
||||||
setCrashAnnotation("domain", domainURL.toString().toStdString());
|
setCrashAnnotation("domain", domainURL.toString().toStdString());
|
||||||
});
|
});
|
||||||
|
@ -1199,6 +1200,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
});
|
});
|
||||||
connect(&domainHandler, &DomainHandler::domainConnectionRefused, this, &Application::domainConnectionRefused);
|
connect(&domainHandler, &DomainHandler::domainConnectionRefused, this, &Application::domainConnectionRefused);
|
||||||
|
|
||||||
|
nodeList->getDomainHandler().setErrorDomainURL(QUrl(REDIRECT_HIFI_ADDRESS));
|
||||||
|
|
||||||
// We could clear ATP assets only when changing domains, but it's possible that the domain you are connected
|
// We could clear ATP assets only when changing domains, but it's possible that the domain you are connected
|
||||||
// to has gone down and switched to a new content set, so when you reconnect the cached ATP assets will no longer be valid.
|
// to has gone down and switched to a new content set, so when you reconnect the cached ATP assets will no longer be valid.
|
||||||
connect(&domainHandler, &DomainHandler::disconnectedFromDomain, DependencyManager::get<ScriptCache>().data(), &ScriptCache::clearATPScriptsFromCache);
|
connect(&domainHandler, &DomainHandler::disconnectedFromDomain, DependencyManager::get<ScriptCache>().data(), &ScriptCache::clearATPScriptsFromCache);
|
||||||
|
@ -1640,7 +1643,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
audioClient->setMuted(!audioClient->isMuted());
|
audioClient->setMuted(!audioClient->isMuted());
|
||||||
} else if (action == controller::toInt(controller::Action::CYCLE_CAMERA)) {
|
} else if (action == controller::toInt(controller::Action::CYCLE_CAMERA)) {
|
||||||
cycleCamera();
|
cycleCamera();
|
||||||
} else if (action == controller::toInt(controller::Action::CONTEXT_MENU)) {
|
} else if (action == controller::toInt(controller::Action::CONTEXT_MENU) && !isInterstitialMode()) {
|
||||||
toggleTabletUI();
|
toggleTabletUI();
|
||||||
} else if (action == controller::toInt(controller::Action::RETICLE_X)) {
|
} else if (action == controller::toInt(controller::Action::RETICLE_X)) {
|
||||||
auto oldPos = getApplicationCompositor().getReticlePosition();
|
auto oldPos = getApplicationCompositor().getReticlePosition();
|
||||||
|
@ -2249,6 +2252,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
|
|
||||||
connect(this, &QCoreApplication::aboutToQuit, this, &Application::addAssetToWorldMessageClose);
|
connect(this, &QCoreApplication::aboutToQuit, this, &Application::addAssetToWorldMessageClose);
|
||||||
connect(&domainHandler, &DomainHandler::domainURLChanged, this, &Application::addAssetToWorldMessageClose);
|
connect(&domainHandler, &DomainHandler::domainURLChanged, this, &Application::addAssetToWorldMessageClose);
|
||||||
|
connect(&domainHandler, &DomainHandler::redirectToErrorDomainURL, this, &Application::addAssetToWorldMessageClose);
|
||||||
|
|
||||||
updateSystemTabletMode();
|
updateSystemTabletMode();
|
||||||
|
|
||||||
|
@ -3012,6 +3016,9 @@ void Application::initializeUi() {
|
||||||
if (_window && _window->isFullScreen()) {
|
if (_window && _window->isFullScreen()) {
|
||||||
setFullscreen(nullptr, true);
|
setFullscreen(nullptr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
setIsInterstitialMode(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3490,6 +3497,15 @@ bool Application::isServerlessMode() const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::setIsInterstitialMode(bool interstitialMode) {
|
||||||
|
if (_interstitialMode != interstitialMode) {
|
||||||
|
_interstitialMode = interstitialMode;
|
||||||
|
|
||||||
|
DependencyManager::get<AudioClient>()->setAudioPaused(_interstitialMode);
|
||||||
|
DependencyManager::get<AvatarManager>()->setMyAvatarDataPacketsPaused(_interstitialMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Application::setIsServerlessMode(bool serverlessDomain) {
|
void Application::setIsServerlessMode(bool serverlessDomain) {
|
||||||
auto tree = getEntities()->getTree();
|
auto tree = getEntities()->getTree();
|
||||||
if (tree) {
|
if (tree) {
|
||||||
|
@ -3497,9 +3513,9 @@ void Application::setIsServerlessMode(bool serverlessDomain) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::loadServerlessDomain(QUrl domainURL) {
|
void Application::loadServerlessDomain(QUrl domainURL, bool errorDomain) {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
QMetaObject::invokeMethod(this, "loadServerlessDomain", Q_ARG(QUrl, domainURL));
|
QMetaObject::invokeMethod(this, "loadServerlessDomain", Q_ARG(QUrl, domainURL), Q_ARG(bool, errorDomain));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3531,8 +3547,11 @@ void Application::loadServerlessDomain(QUrl domainURL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<QString, QString> namedPaths = tmpTree->getNamedPaths();
|
std::map<QString, QString> namedPaths = tmpTree->getNamedPaths();
|
||||||
|
if (errorDomain) {
|
||||||
|
nodeList->getDomainHandler().loadedErrorDomain(namedPaths);
|
||||||
|
} else {
|
||||||
nodeList->getDomainHandler().connectedToServerless(namedPaths);
|
nodeList->getDomainHandler().connectedToServerless(namedPaths);
|
||||||
|
}
|
||||||
|
|
||||||
_fullSceneReceivedCounter++;
|
_fullSceneReceivedCounter++;
|
||||||
}
|
}
|
||||||
|
@ -3767,7 +3786,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
|
|
||||||
_controllerScriptingInterface->emitKeyPressEvent(event); // send events to any registered scripts
|
_controllerScriptingInterface->emitKeyPressEvent(event); // send events to any registered scripts
|
||||||
// if one of our scripts have asked to capture this event, then stop processing it
|
// if one of our scripts have asked to capture this event, then stop processing it
|
||||||
if (_controllerScriptingInterface->isKeyCaptured(event)) {
|
if (_controllerScriptingInterface->isKeyCaptured(event) || isInterstitialMode()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5554,6 +5573,7 @@ void Application::update(float deltaTime) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!_physicsEnabled) {
|
if (!_physicsEnabled) {
|
||||||
if (!domainLoadingInProgress) {
|
if (!domainLoadingInProgress) {
|
||||||
PROFILE_ASYNC_BEGIN(app, "Scene Loading", "");
|
PROFILE_ASYNC_BEGIN(app, "Scene Loading", "");
|
||||||
|
@ -5574,6 +5594,7 @@ void Application::update(float deltaTime) {
|
||||||
// scene is ready to compute its collision shape.
|
// scene is ready to compute its collision shape.
|
||||||
if (getMyAvatar()->isReadyForPhysics()) {
|
if (getMyAvatar()->isReadyForPhysics()) {
|
||||||
_physicsEnabled = true;
|
_physicsEnabled = true;
|
||||||
|
setIsInterstitialMode(false);
|
||||||
getMyAvatar()->updateMotionBehaviorFromMenu();
|
getMyAvatar()->updateMotionBehaviorFromMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5653,7 +5674,7 @@ void Application::update(float deltaTime) {
|
||||||
// Transfer the user inputs to the driveKeys
|
// Transfer the user inputs to the driveKeys
|
||||||
// FIXME can we drop drive keys and just have the avatar read the action states directly?
|
// FIXME can we drop drive keys and just have the avatar read the action states directly?
|
||||||
myAvatar->clearDriveKeys();
|
myAvatar->clearDriveKeys();
|
||||||
if (_myCamera.getMode() != CAMERA_MODE_INDEPENDENT) {
|
if (_myCamera.getMode() != CAMERA_MODE_INDEPENDENT && !isInterstitialMode()) {
|
||||||
if (!_controllerScriptingInterface->areActionsCaptured() && _myCamera.getMode() != CAMERA_MODE_MIRROR) {
|
if (!_controllerScriptingInterface->areActionsCaptured() && _myCamera.getMode() != CAMERA_MODE_MIRROR) {
|
||||||
myAvatar->setDriveKey(MyAvatar::TRANSLATE_Z, -1.0f * userInputMapper->getActionState(controller::Action::TRANSLATE_Z));
|
myAvatar->setDriveKey(MyAvatar::TRANSLATE_Z, -1.0f * userInputMapper->getActionState(controller::Action::TRANSLATE_Z));
|
||||||
myAvatar->setDriveKey(MyAvatar::TRANSLATE_Y, userInputMapper->getActionState(controller::Action::TRANSLATE_Y));
|
myAvatar->setDriveKey(MyAvatar::TRANSLATE_Y, userInputMapper->getActionState(controller::Action::TRANSLATE_Y));
|
||||||
|
@ -5969,7 +5990,7 @@ void Application::update(float deltaTime) {
|
||||||
// send packet containing downstream audio stats to the AudioMixer
|
// send packet containing downstream audio stats to the AudioMixer
|
||||||
{
|
{
|
||||||
quint64 sinceLastNack = now - _lastSendDownstreamAudioStats;
|
quint64 sinceLastNack = now - _lastSendDownstreamAudioStats;
|
||||||
if (sinceLastNack > TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS) {
|
if (sinceLastNack > TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS && !isInterstitialMode()) {
|
||||||
_lastSendDownstreamAudioStats = now;
|
_lastSendDownstreamAudioStats = now;
|
||||||
|
|
||||||
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "sendDownstreamAudioStatsPacket", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "sendDownstreamAudioStatsPacket", Qt::QueuedConnection);
|
||||||
|
@ -6132,6 +6153,7 @@ void Application::updateRenderArgs(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::queryAvatars() {
|
void Application::queryAvatars() {
|
||||||
|
if (!isInterstitialMode()) {
|
||||||
auto avatarPacket = NLPacket::create(PacketType::AvatarQuery);
|
auto avatarPacket = NLPacket::create(PacketType::AvatarQuery);
|
||||||
auto destinationBuffer = reinterpret_cast<unsigned char*>(avatarPacket->getPayload());
|
auto destinationBuffer = reinterpret_cast<unsigned char*>(avatarPacket->getPayload());
|
||||||
unsigned char* bufferStart = destinationBuffer;
|
unsigned char* bufferStart = destinationBuffer;
|
||||||
|
@ -6148,6 +6170,7 @@ void Application::queryAvatars() {
|
||||||
|
|
||||||
DependencyManager::get<NodeList>()->broadcastToNodes(std::move(avatarPacket), NodeSet() << NodeType::AvatarMixer);
|
DependencyManager::get<NodeList>()->broadcastToNodes(std::move(avatarPacket), NodeSet() << NodeType::AvatarMixer);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int Application::sendNackPackets() {
|
int Application::sendNackPackets() {
|
||||||
|
@ -6369,6 +6392,7 @@ void Application::clearDomainOctreeDetails() {
|
||||||
qCDebug(interfaceapp) << "Clearing domain octree details...";
|
qCDebug(interfaceapp) << "Clearing domain octree details...";
|
||||||
|
|
||||||
resetPhysicsReadyInformation();
|
resetPhysicsReadyInformation();
|
||||||
|
setIsInterstitialMode(true);
|
||||||
|
|
||||||
_octreeServerSceneStats.withWriteLock([&] {
|
_octreeServerSceneStats.withWriteLock([&] {
|
||||||
_octreeServerSceneStats.clear();
|
_octreeServerSceneStats.clear();
|
||||||
|
@ -6399,6 +6423,16 @@ void Application::domainURLChanged(QUrl domainURL) {
|
||||||
updateWindowTitle();
|
updateWindowTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::goToErrorDomainURL(QUrl errorDomainURL) {
|
||||||
|
// disable physics until we have enough information about our new location to not cause craziness.
|
||||||
|
resetPhysicsReadyInformation();
|
||||||
|
setIsServerlessMode(errorDomainURL.scheme() != URL_SCHEME_HIFI);
|
||||||
|
if (isServerlessMode()) {
|
||||||
|
loadServerlessDomain(errorDomainURL, true);
|
||||||
|
}
|
||||||
|
updateWindowTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Application::resettingDomain() {
|
void Application::resettingDomain() {
|
||||||
_notifiedPacketVersionMismatchThisDomain = false;
|
_notifiedPacketVersionMismatchThisDomain = false;
|
||||||
|
@ -6437,7 +6471,7 @@ void Application::nodeActivated(SharedNodePointer node) {
|
||||||
_octreeQuery.incrementConnectionID();
|
_octreeQuery.incrementConnectionID();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->getType() == NodeType::AudioMixer) {
|
if (node->getType() == NodeType::AudioMixer && !isInterstitialMode()) {
|
||||||
DependencyManager::get<AudioClient>()->negotiateAudioFormat();
|
DependencyManager::get<AudioClient>()->negotiateAudioFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6457,10 +6491,12 @@ void Application::nodeActivated(SharedNodePointer node) {
|
||||||
getMyAvatar()->markIdentityDataChanged();
|
getMyAvatar()->markIdentityDataChanged();
|
||||||
getMyAvatar()->resetLastSent();
|
getMyAvatar()->resetLastSent();
|
||||||
|
|
||||||
|
if (!isInterstitialMode()) {
|
||||||
// transmit a "sendAll" packet to the AvatarMixer we just connected to.
|
// transmit a "sendAll" packet to the AvatarMixer we just connected to.
|
||||||
getMyAvatar()->sendAvatarDataPacket(true);
|
getMyAvatar()->sendAvatarDataPacket(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Application::nodeKilled(SharedNodePointer node) {
|
void Application::nodeKilled(SharedNodePointer node) {
|
||||||
// These are here because connecting NodeList::nodeKilled to OctreePacketProcessor::nodeKilled doesn't work:
|
// These are here because connecting NodeList::nodeKilled to OctreePacketProcessor::nodeKilled doesn't work:
|
||||||
|
@ -7809,7 +7845,7 @@ float Application::getRenderResolutionScale() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::notifyPacketVersionMismatch() {
|
void Application::notifyPacketVersionMismatch() {
|
||||||
if (!_notifiedPacketVersionMismatchThisDomain) {
|
if (!_notifiedPacketVersionMismatchThisDomain && !isInterstitialMode()) {
|
||||||
_notifiedPacketVersionMismatchThisDomain = true;
|
_notifiedPacketVersionMismatchThisDomain = true;
|
||||||
|
|
||||||
QString message = "The location you are visiting is running an incompatible server version.\n";
|
QString message = "The location you are visiting is running an incompatible server version.\n";
|
||||||
|
|
|
@ -224,6 +224,7 @@ public:
|
||||||
void setHmdTabletBecomesToolbarSetting(bool value);
|
void setHmdTabletBecomesToolbarSetting(bool value);
|
||||||
bool getPreferStylusOverLaser() { return _preferStylusOverLaserSetting.get(); }
|
bool getPreferStylusOverLaser() { return _preferStylusOverLaserSetting.get(); }
|
||||||
void setPreferStylusOverLaser(bool value);
|
void setPreferStylusOverLaser(bool value);
|
||||||
|
|
||||||
// FIXME: Remove setting completely or make available through JavaScript API?
|
// FIXME: Remove setting completely or make available through JavaScript API?
|
||||||
//bool getPreferAvatarFingerOverStylus() { return _preferAvatarFingerOverStylusSetting.get(); }
|
//bool getPreferAvatarFingerOverStylus() { return _preferAvatarFingerOverStylusSetting.get(); }
|
||||||
bool getPreferAvatarFingerOverStylus() { return false; }
|
bool getPreferAvatarFingerOverStylus() { return false; }
|
||||||
|
@ -304,6 +305,7 @@ public:
|
||||||
void saveNextPhysicsStats(QString filename);
|
void saveNextPhysicsStats(QString filename);
|
||||||
|
|
||||||
bool isServerlessMode() const;
|
bool isServerlessMode() const;
|
||||||
|
bool isInterstitialMode() const { return _interstitialMode; }
|
||||||
|
|
||||||
void replaceDomainContent(const QString& url);
|
void replaceDomainContent(const QString& url);
|
||||||
|
|
||||||
|
@ -340,6 +342,7 @@ public slots:
|
||||||
bool importEntities(const QString& url);
|
bool importEntities(const QString& url);
|
||||||
void updateThreadPoolCount() const;
|
void updateThreadPoolCount() const;
|
||||||
void updateSystemTabletMode();
|
void updateSystemTabletMode();
|
||||||
|
void goToErrorDomainURL(QUrl errorDomainURL);
|
||||||
|
|
||||||
Q_INVOKABLE void loadDialog();
|
Q_INVOKABLE void loadDialog();
|
||||||
Q_INVOKABLE void loadScriptURLDialog() const;
|
Q_INVOKABLE void loadScriptURLDialog() const;
|
||||||
|
@ -428,7 +431,8 @@ public slots:
|
||||||
void setPreferredCursor(const QString& cursor);
|
void setPreferredCursor(const QString& cursor);
|
||||||
|
|
||||||
void setIsServerlessMode(bool serverlessDomain);
|
void setIsServerlessMode(bool serverlessDomain);
|
||||||
void loadServerlessDomain(QUrl domainURL);
|
void loadServerlessDomain(QUrl domainURL, bool errorDomain = false);
|
||||||
|
void setIsInterstitialMode(bool interstialMode);
|
||||||
|
|
||||||
void updateVerboseLogging();
|
void updateVerboseLogging();
|
||||||
|
|
||||||
|
@ -627,6 +631,7 @@ private:
|
||||||
QHash<int, QKeyEvent> _keysPressed;
|
QHash<int, QKeyEvent> _keysPressed;
|
||||||
|
|
||||||
bool _enableProcessOctreeThread;
|
bool _enableProcessOctreeThread;
|
||||||
|
bool _interstitialMode { false };
|
||||||
|
|
||||||
OctreePacketProcessor _octreeProcessor;
|
OctreePacketProcessor _octreeProcessor;
|
||||||
EntityEditPacketSender _entityEditSender;
|
EntityEditPacketSender _entityEditSender;
|
||||||
|
|
|
@ -11,16 +11,18 @@
|
||||||
|
|
||||||
#include "ConnectionMonitor.h"
|
#include "ConnectionMonitor.h"
|
||||||
|
|
||||||
|
#include "Application.h"
|
||||||
#include "ui/DialogsManager.h"
|
#include "ui/DialogsManager.h"
|
||||||
|
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
#include <DomainHandler.h>
|
#include <DomainHandler.h>
|
||||||
|
#include <AddressManager.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
|
|
||||||
// Because the connection monitor is created at startup, the time we wait on initial load
|
// Because the connection monitor is created at startup, the time we wait on initial load
|
||||||
// should be longer to allow the application to initialize.
|
// should be longer to allow the application to initialize.
|
||||||
static const int ON_INITIAL_LOAD_DISPLAY_AFTER_DISCONNECTED_FOR_X_MS = 10000;
|
static const int ON_INITIAL_LOAD_REDIRECT_AFTER_DISCONNECTED_FOR_X_MS = 10000;
|
||||||
static const int DISPLAY_AFTER_DISCONNECTED_FOR_X_MS = 5000;
|
static const int REDIRECT_AFTER_DISCONNECTED_FOR_X_MS = 5000;
|
||||||
|
|
||||||
void ConnectionMonitor::init() {
|
void ConnectionMonitor::init() {
|
||||||
// Connect to domain disconnected message
|
// Connect to domain disconnected message
|
||||||
|
@ -30,23 +32,25 @@ void ConnectionMonitor::init() {
|
||||||
connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, &ConnectionMonitor::startTimer);
|
connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, &ConnectionMonitor::startTimer);
|
||||||
connect(&domainHandler, &DomainHandler::connectedToDomain, this, &ConnectionMonitor::stopTimer);
|
connect(&domainHandler, &DomainHandler::connectedToDomain, this, &ConnectionMonitor::stopTimer);
|
||||||
connect(&domainHandler, &DomainHandler::domainConnectionRefused, this, &ConnectionMonitor::stopTimer);
|
connect(&domainHandler, &DomainHandler::domainConnectionRefused, this, &ConnectionMonitor::stopTimer);
|
||||||
|
connect(&domainHandler, &DomainHandler::redirectToErrorDomainURL, this, &ConnectionMonitor::stopTimer);
|
||||||
|
connect(this, &ConnectionMonitor::setRedirectErrorState, &domainHandler, &DomainHandler::setRedirectErrorState);
|
||||||
|
|
||||||
_timer.setSingleShot(true);
|
_timer.setSingleShot(true);
|
||||||
if (!domainHandler.isConnected()) {
|
if (!domainHandler.isConnected()) {
|
||||||
_timer.start(ON_INITIAL_LOAD_DISPLAY_AFTER_DISCONNECTED_FOR_X_MS);
|
_timer.start(ON_INITIAL_LOAD_REDIRECT_AFTER_DISCONNECTED_FOR_X_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(&_timer, &QTimer::timeout, this, []() {
|
connect(&_timer, &QTimer::timeout, this, [this]() {
|
||||||
qDebug() << "ConnectionMonitor: Showing connection failure window";
|
qDebug() << "ConnectionMonitor: Redirecting to 404 error domain";
|
||||||
DependencyManager::get<DialogsManager>()->setDomainConnectionFailureVisibility(true);
|
// set in a timeout error
|
||||||
|
emit setRedirectErrorState(REDIRECT_HIFI_ADDRESS, 5);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionMonitor::startTimer() {
|
void ConnectionMonitor::startTimer() {
|
||||||
_timer.start(DISPLAY_AFTER_DISCONNECTED_FOR_X_MS);
|
_timer.start(REDIRECT_AFTER_DISCONNECTED_FOR_X_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionMonitor::stopTimer() {
|
void ConnectionMonitor::stopTimer() {
|
||||||
_timer.stop();
|
_timer.stop();
|
||||||
DependencyManager::get<DialogsManager>()->setDomainConnectionFailureVisibility(false);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
class QUrl;
|
||||||
class QString;
|
class QString;
|
||||||
|
|
||||||
class ConnectionMonitor : public QObject {
|
class ConnectionMonitor : public QObject {
|
||||||
|
@ -22,6 +23,9 @@ class ConnectionMonitor : public QObject {
|
||||||
public:
|
public:
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void setRedirectErrorState(QUrl errorURL, int reasonCode);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void startTimer();
|
void startTimer();
|
||||||
void stopTimer();
|
void stopTimer();
|
||||||
|
|
|
@ -137,7 +137,7 @@ void AvatarManager::updateMyAvatar(float deltaTime) {
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
quint64 dt = now - _lastSendAvatarDataTime;
|
quint64 dt = now - _lastSendAvatarDataTime;
|
||||||
|
|
||||||
if (dt > MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS) {
|
if (dt > MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS && !_myAvatarDataPacketsPaused) {
|
||||||
// send head/hand data to the avatar mixer and voxel server
|
// send head/hand data to the avatar mixer and voxel server
|
||||||
PerformanceTimer perfTimer("send");
|
PerformanceTimer perfTimer("send");
|
||||||
_myAvatar->sendAvatarDataPacket();
|
_myAvatar->sendAvatarDataPacket();
|
||||||
|
@ -155,6 +155,16 @@ float AvatarManager::getAvatarDataRate(const QUuid& sessionID, const QString& ra
|
||||||
return avatar ? avatar->getDataRate(rateName) : 0.0f;
|
return avatar ? avatar->getDataRate(rateName) : 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AvatarManager::setMyAvatarDataPacketsPaused(bool pause) {
|
||||||
|
if (_myAvatarDataPacketsPaused != pause) {
|
||||||
|
_myAvatarDataPacketsPaused = pause;
|
||||||
|
|
||||||
|
if (!_myAvatarDataPacketsPaused) {
|
||||||
|
_myAvatar->sendAvatarDataPacket(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float AvatarManager::getAvatarUpdateRate(const QUuid& sessionID, const QString& rateName) const {
|
float AvatarManager::getAvatarUpdateRate(const QUuid& sessionID, const QString& rateName) const {
|
||||||
auto avatar = getAvatarBySessionID(sessionID);
|
auto avatar = getAvatarBySessionID(sessionID);
|
||||||
return avatar ? avatar->getUpdateRate(rateName) : 0.0f;
|
return avatar ? avatar->getUpdateRate(rateName) : 0.0f;
|
||||||
|
|
|
@ -91,6 +91,8 @@ public:
|
||||||
void updateOtherAvatars(float deltaTime);
|
void updateOtherAvatars(float deltaTime);
|
||||||
void sendIdentityRequest(const QUuid& avatarID) const;
|
void sendIdentityRequest(const QUuid& avatarID) const;
|
||||||
|
|
||||||
|
void setMyAvatarDataPacketsPaused(bool puase);
|
||||||
|
|
||||||
void postUpdate(float deltaTime, const render::ScenePointer& scene);
|
void postUpdate(float deltaTime, const render::ScenePointer& scene);
|
||||||
|
|
||||||
void clearOtherAvatars() override;
|
void clearOtherAvatars() override;
|
||||||
|
@ -219,6 +221,7 @@ private:
|
||||||
int _numAvatarsNotUpdated { 0 };
|
int _numAvatarsNotUpdated { 0 };
|
||||||
float _avatarSimulationTime { 0.0f };
|
float _avatarSimulationTime { 0.0f };
|
||||||
bool _shouldRender { true };
|
bool _shouldRender { true };
|
||||||
|
bool _myAvatarDataPacketsPaused { false };
|
||||||
mutable int _identityRequestsSent { 0 };
|
mutable int _identityRequestsSent { 0 };
|
||||||
|
|
||||||
mutable std::mutex _spaceLock;
|
mutable std::mutex _spaceLock;
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
#include "SceneScriptingInterface.h"
|
#include "SceneScriptingInterface.h"
|
||||||
#include "SafeLanding.h"
|
|
||||||
|
|
||||||
OctreePacketProcessor::OctreePacketProcessor():
|
OctreePacketProcessor::OctreePacketProcessor():
|
||||||
_safeLanding(new SafeLanding())
|
_safeLanding(new SafeLanding())
|
||||||
|
@ -133,7 +132,3 @@ void OctreePacketProcessor::processPacket(QSharedPointer<ReceivedMessage> messag
|
||||||
void OctreePacketProcessor::startEntitySequence() {
|
void OctreePacketProcessor::startEntitySequence() {
|
||||||
_safeLanding->startEntitySequence(qApp->getEntities());
|
_safeLanding->startEntitySequence(qApp->getEntities());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OctreePacketProcessor::isLoadSequenceComplete() const {
|
|
||||||
return _safeLanding->isLoadSequenceComplete();
|
|
||||||
}
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include <ReceivedPacketProcessor.h>
|
#include <ReceivedPacketProcessor.h>
|
||||||
#include <ReceivedMessage.h>
|
#include <ReceivedMessage.h>
|
||||||
|
|
||||||
class SafeLanding;
|
#include "SafeLanding.h"
|
||||||
|
|
||||||
/// Handles processing of incoming voxel packets for the interface application. As with other ReceivedPacketProcessor classes
|
/// Handles processing of incoming voxel packets for the interface application. As with other ReceivedPacketProcessor classes
|
||||||
/// the user is responsible for reading inbound packets and adding them to the processing queue by calling queueReceivedPacket()
|
/// the user is responsible for reading inbound packets and adding them to the processing queue by calling queueReceivedPacket()
|
||||||
|
@ -26,7 +26,8 @@ public:
|
||||||
~OctreePacketProcessor();
|
~OctreePacketProcessor();
|
||||||
|
|
||||||
void startEntitySequence();
|
void startEntitySequence();
|
||||||
bool isLoadSequenceComplete() const;
|
bool isLoadSequenceComplete() const { return _safeLanding->isLoadSequenceComplete(); }
|
||||||
|
float domainLoadingProgress() const { return _safeLanding->loadingProgressPercentage(); }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void packetVersionMismatch();
|
void packetVersionMismatch();
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "EntityTreeRenderer.h"
|
#include "EntityTreeRenderer.h"
|
||||||
#include "ModelEntityItem.h"
|
#include "ModelEntityItem.h"
|
||||||
#include "InterfaceLogging.h"
|
#include "InterfaceLogging.h"
|
||||||
|
#include "Application.h"
|
||||||
|
|
||||||
const int SafeLanding::SEQUENCE_MODULO = std::numeric_limits<OCTREE_PACKET_SEQUENCE>::max() + 1;
|
const int SafeLanding::SEQUENCE_MODULO = std::numeric_limits<OCTREE_PACKET_SEQUENCE>::max() + 1;
|
||||||
|
|
||||||
|
@ -53,6 +54,7 @@ void SafeLanding::startEntitySequence(QSharedPointer<EntityTreeRenderer> entityT
|
||||||
void SafeLanding::stopEntitySequence() {
|
void SafeLanding::stopEntitySequence() {
|
||||||
Locker lock(_lock);
|
Locker lock(_lock);
|
||||||
_trackingEntities = false;
|
_trackingEntities = false;
|
||||||
|
_maxTrackedEntityCount = 0;
|
||||||
_initialStart = INVALID_SEQUENCE;
|
_initialStart = INVALID_SEQUENCE;
|
||||||
_initialEnd = INVALID_SEQUENCE;
|
_initialEnd = INVALID_SEQUENCE;
|
||||||
_trackedEntities.clear();
|
_trackedEntities.clear();
|
||||||
|
@ -64,20 +66,13 @@ void SafeLanding::addTrackedEntity(const EntityItemID& entityID) {
|
||||||
Locker lock(_lock);
|
Locker lock(_lock);
|
||||||
EntityItemPointer entity = _entityTree->findEntityByID(entityID);
|
EntityItemPointer entity = _entityTree->findEntityByID(entityID);
|
||||||
|
|
||||||
if (entity && !entity->getCollisionless()) {
|
|
||||||
const auto& entityType = entity->getType();
|
|
||||||
if (entityType == EntityTypes::Model) {
|
|
||||||
ModelEntityItem * modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity).get();
|
|
||||||
static const std::set<ShapeType> downloadedCollisionTypes
|
|
||||||
{ SHAPE_TYPE_COMPOUND, SHAPE_TYPE_SIMPLE_COMPOUND, SHAPE_TYPE_STATIC_MESH, SHAPE_TYPE_SIMPLE_HULL };
|
|
||||||
bool hasAABox;
|
|
||||||
entity->getAABox(hasAABox);
|
|
||||||
if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) {
|
|
||||||
// Only track entities with downloaded collision bodies.
|
|
||||||
_trackedEntities.emplace(entityID, entity);
|
_trackedEntities.emplace(entityID, entity);
|
||||||
|
int trackedEntityCount = (int)_trackedEntities.size();
|
||||||
|
|
||||||
|
if (trackedEntityCount > _maxTrackedEntityCount) {
|
||||||
|
_maxTrackedEntityCount = trackedEntityCount;
|
||||||
}
|
}
|
||||||
}
|
qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +97,7 @@ void SafeLanding::noteReceivedsequenceNumber(int sequenceNumber) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SafeLanding::isLoadSequenceComplete() {
|
bool SafeLanding::isLoadSequenceComplete() {
|
||||||
if (isEntityPhysicsComplete() && isSequenceNumbersComplete()) {
|
if (isEntityLoadingComplete() && isSequenceNumbersComplete()) {
|
||||||
Locker lock(_lock);
|
Locker lock(_lock);
|
||||||
_trackedEntities.clear();
|
_trackedEntities.clear();
|
||||||
_initialStart = INVALID_SEQUENCE;
|
_initialStart = INVALID_SEQUENCE;
|
||||||
|
@ -114,6 +109,15 @@ bool SafeLanding::isLoadSequenceComplete() {
|
||||||
return !_trackingEntities;
|
return !_trackingEntities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float SafeLanding::loadingProgressPercentage() {
|
||||||
|
Locker lock(_lock);
|
||||||
|
if (_maxTrackedEntityCount > 0) {
|
||||||
|
return ((_maxTrackedEntityCount - _trackedEntities.size()) / (float)_maxTrackedEntityCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
bool SafeLanding::isSequenceNumbersComplete() {
|
bool SafeLanding::isSequenceNumbersComplete() {
|
||||||
if (_initialStart != INVALID_SEQUENCE) {
|
if (_initialStart != INVALID_SEQUENCE) {
|
||||||
Locker lock(_lock);
|
Locker lock(_lock);
|
||||||
|
@ -132,17 +136,42 @@ bool SafeLanding::isSequenceNumbersComplete() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SafeLanding::isEntityPhysicsComplete() {
|
bool isEntityPhysicsReady(const EntityItemPointer& entity) {
|
||||||
Locker lock(_lock);
|
if (entity && !entity->getCollisionless()) {
|
||||||
for (auto entityMapIter = _trackedEntities.begin(); entityMapIter != _trackedEntities.end(); ++entityMapIter) {
|
const auto& entityType = entity->getType();
|
||||||
auto entity = entityMapIter->second;
|
if (entityType == EntityTypes::Model) {
|
||||||
if (!entity->shouldBePhysical() || entity->isReadyToComputeShape()) {
|
ModelEntityItem * modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity).get();
|
||||||
entityMapIter = _trackedEntities.erase(entityMapIter);
|
static const std::set<ShapeType> downloadedCollisionTypes
|
||||||
if (entityMapIter == _trackedEntities.end()) {
|
{ SHAPE_TYPE_COMPOUND, SHAPE_TYPE_SIMPLE_COMPOUND, SHAPE_TYPE_STATIC_MESH, SHAPE_TYPE_SIMPLE_HULL };
|
||||||
break;
|
bool hasAABox;
|
||||||
|
entity->getAABox(hasAABox);
|
||||||
|
if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) {
|
||||||
|
return entity->isReadyToComputeShape();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SafeLanding::isEntityLoadingComplete() {
|
||||||
|
Locker lock(_lock);
|
||||||
|
auto entityTree = qApp->getEntities();
|
||||||
|
auto entityMapIter = _trackedEntities.begin();
|
||||||
|
|
||||||
|
while (entityMapIter != _trackedEntities.end()) {
|
||||||
|
auto entity = entityMapIter->second;
|
||||||
|
bool isVisuallyReady = (entity->isVisuallyReady() || !entityTree->renderableForEntityId(entityMapIter->first));
|
||||||
|
if (isEntityPhysicsReady(entity) && isVisuallyReady) {
|
||||||
|
entityMapIter = _trackedEntities.erase(entityMapIter);
|
||||||
|
} else {
|
||||||
|
if (!isVisuallyReady) {
|
||||||
|
entity->requestRenderUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
entityMapIter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
return _trackedEntities.empty();
|
return _trackedEntities.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <QtCore/QSharedPointer>
|
#include <QtCore/QSharedPointer>
|
||||||
|
|
||||||
#include "EntityItem.h"
|
#include "EntityItem.h"
|
||||||
|
#include "EntityDynamicInterface.h"
|
||||||
|
|
||||||
class EntityTreeRenderer;
|
class EntityTreeRenderer;
|
||||||
class EntityItemID;
|
class EntityItemID;
|
||||||
|
@ -29,6 +30,7 @@ public:
|
||||||
void setCompletionSequenceNumbers(int first, int last); // 'last' exclusive.
|
void setCompletionSequenceNumbers(int first, int last); // 'last' exclusive.
|
||||||
void noteReceivedsequenceNumber(int sequenceNumber);
|
void noteReceivedsequenceNumber(int sequenceNumber);
|
||||||
bool isLoadSequenceComplete();
|
bool isLoadSequenceComplete();
|
||||||
|
float loadingProgressPercentage();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void addTrackedEntity(const EntityItemID& entityID);
|
void addTrackedEntity(const EntityItemID& entityID);
|
||||||
|
@ -37,7 +39,7 @@ private slots:
|
||||||
private:
|
private:
|
||||||
bool isSequenceNumbersComplete();
|
bool isSequenceNumbersComplete();
|
||||||
void debugDumpSequenceIDs() const;
|
void debugDumpSequenceIDs() const;
|
||||||
bool isEntityPhysicsComplete();
|
bool isEntityLoadingComplete();
|
||||||
|
|
||||||
std::mutex _lock;
|
std::mutex _lock;
|
||||||
using Locker = std::lock_guard<std::mutex>;
|
using Locker = std::lock_guard<std::mutex>;
|
||||||
|
@ -49,6 +51,7 @@ private:
|
||||||
static constexpr int INVALID_SEQUENCE = -1;
|
static constexpr int INVALID_SEQUENCE = -1;
|
||||||
int _initialStart { INVALID_SEQUENCE };
|
int _initialStart { INVALID_SEQUENCE };
|
||||||
int _initialEnd { INVALID_SEQUENCE };
|
int _initialEnd { INVALID_SEQUENCE };
|
||||||
|
int _maxTrackedEntityCount { 0 };
|
||||||
|
|
||||||
struct SequenceLessThan {
|
struct SequenceLessThan {
|
||||||
bool operator()(const int& a, const int& b) const;
|
bool operator()(const int& a, const int& b) const;
|
||||||
|
|
|
@ -409,6 +409,10 @@ glm::vec2 WindowScriptingInterface::getDeviceSize() const {
|
||||||
return qApp->getDeviceSize();
|
return qApp->getDeviceSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int WindowScriptingInterface::getLastDomainConnectionError() const {
|
||||||
|
return DependencyManager::get<NodeList>()->getDomainHandler().getLastDomainConnectionError();
|
||||||
|
}
|
||||||
|
|
||||||
int WindowScriptingInterface::getX() {
|
int WindowScriptingInterface::getX() {
|
||||||
return qApp->getWindow()->geometry().x();
|
return qApp->getWindow()->geometry().x();
|
||||||
}
|
}
|
||||||
|
@ -584,3 +588,8 @@ void WindowScriptingInterface::onMessageBoxSelected(int button) {
|
||||||
_messageBoxes.remove(id);
|
_messageBoxes.remove(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float WindowScriptingInterface::domainLoadingProgress() {
|
||||||
|
return qApp->getOctreePacketProcessor().domainLoadingProgress();
|
||||||
|
}
|
||||||
|
|
|
@ -491,6 +491,13 @@ public slots:
|
||||||
*/
|
*/
|
||||||
glm::vec2 getDeviceSize() const;
|
glm::vec2 getDeviceSize() const;
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Gets the last domain connection error when a connection is refused.
|
||||||
|
* @function Window.getLastDomainConnectionError
|
||||||
|
* @returns {Window.ConnectionRefusedReason} Integer number that enumerates the last domain connection refused.
|
||||||
|
*/
|
||||||
|
int getLastDomainConnectionError() const;
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Open a non-modal message box that can have a variety of button combinations. See also,
|
* Open a non-modal message box that can have a variety of button combinations. See also,
|
||||||
* {@link Window.updateMessageBox|updateMessageBox} and {@link Window.closeMessageBox|closeMessageBox}.
|
* {@link Window.updateMessageBox|updateMessageBox} and {@link Window.closeMessageBox|closeMessageBox}.
|
||||||
|
@ -561,6 +568,8 @@ public slots:
|
||||||
*/
|
*/
|
||||||
void closeMessageBox(int id);
|
void closeMessageBox(int id);
|
||||||
|
|
||||||
|
float domainLoadingProgress();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onWindowGeometryChanged(const QRect& geometry);
|
void onWindowGeometryChanged(const QRect& geometry);
|
||||||
void onMessageBoxSelected(int button);
|
void onMessageBoxSelected(int button);
|
||||||
|
|
|
@ -106,6 +106,10 @@ extern std::atomic<size_t> DECIMATED_TEXTURE_COUNT;
|
||||||
extern std::atomic<size_t> RECTIFIED_TEXTURE_COUNT;
|
extern std::atomic<size_t> RECTIFIED_TEXTURE_COUNT;
|
||||||
|
|
||||||
void Stats::updateStats(bool force) {
|
void Stats::updateStats(bool force) {
|
||||||
|
|
||||||
|
if (qApp->isInterstitialMode()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
QQuickItem* parent = parentItem();
|
QQuickItem* parent = parentItem();
|
||||||
if (!force) {
|
if (!force) {
|
||||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
|
if (!Menu::getInstance()->isOptionChecked(MenuOption::Stats)) {
|
||||||
|
|
|
@ -305,6 +305,16 @@ void AudioClient::audioMixerKilled() {
|
||||||
emit disconnected();
|
emit disconnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioClient::setAudioPaused(bool pause) {
|
||||||
|
if (_audioPaused != pause) {
|
||||||
|
_audioPaused = pause;
|
||||||
|
|
||||||
|
if (!_audioPaused) {
|
||||||
|
negotiateAudioFormat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) {
|
QAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) {
|
||||||
QAudioDeviceInfo result;
|
QAudioDeviceInfo result;
|
||||||
foreach(QAudioDeviceInfo audioDevice, getAvailableDevices(mode)) {
|
foreach(QAudioDeviceInfo audioDevice, getAvailableDevices(mode)) {
|
||||||
|
@ -651,7 +661,6 @@ void AudioClient::stop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioClient::handleAudioEnvironmentDataPacket(QSharedPointer<ReceivedMessage> message) {
|
void AudioClient::handleAudioEnvironmentDataPacket(QSharedPointer<ReceivedMessage> message) {
|
||||||
|
|
||||||
char bitset;
|
char bitset;
|
||||||
message->readPrimitive(&bitset);
|
message->readPrimitive(&bitset);
|
||||||
|
|
||||||
|
@ -668,7 +677,6 @@ void AudioClient::handleAudioEnvironmentDataPacket(QSharedPointer<ReceivedMessag
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioClient::handleAudioDataPacket(QSharedPointer<ReceivedMessage> message) {
|
void AudioClient::handleAudioDataPacket(QSharedPointer<ReceivedMessage> message) {
|
||||||
|
|
||||||
if (message->getType() == PacketType::SilentAudioFrame) {
|
if (message->getType() == PacketType::SilentAudioFrame) {
|
||||||
_silentInbound.increment();
|
_silentInbound.increment();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1026,6 +1034,7 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioClient::handleAudioInput(QByteArray& audioBuffer) {
|
void AudioClient::handleAudioInput(QByteArray& audioBuffer) {
|
||||||
|
if (!_audioPaused) {
|
||||||
if (_muted) {
|
if (_muted) {
|
||||||
_lastInputLoudness = 0.0f;
|
_lastInputLoudness = 0.0f;
|
||||||
_timeSinceLastClip = 0.0f;
|
_timeSinceLastClip = 0.0f;
|
||||||
|
@ -1101,6 +1110,7 @@ void AudioClient::handleAudioInput(QByteArray& audioBuffer) {
|
||||||
packetType, _selectedCodecName);
|
packetType, _selectedCodecName);
|
||||||
_stats.sentPacket();
|
_stats.sentPacket();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AudioClient::handleMicAudioInput() {
|
void AudioClient::handleMicAudioInput() {
|
||||||
if (!_inputDevice || _isPlayingBackRecording) {
|
if (!_inputDevice || _isPlayingBackRecording) {
|
||||||
|
|
|
@ -162,6 +162,7 @@ public:
|
||||||
|
|
||||||
bool startRecording(const QString& filename);
|
bool startRecording(const QString& filename);
|
||||||
void stopRecording();
|
void stopRecording();
|
||||||
|
void setAudioPaused(bool pause);
|
||||||
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
@ -416,6 +417,7 @@ private:
|
||||||
QVector<AudioInjectorPointer> _activeLocalAudioInjectors;
|
QVector<AudioInjectorPointer> _activeLocalAudioInjectors;
|
||||||
|
|
||||||
bool _isPlayingBackRecording { false };
|
bool _isPlayingBackRecording { false };
|
||||||
|
bool _audioPaused { false };
|
||||||
|
|
||||||
CodecPluginPointer _codec;
|
CodecPluginPointer _codec;
|
||||||
QString _selectedCodecName;
|
QString _selectedCodecName;
|
||||||
|
|
|
@ -1297,9 +1297,20 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check for removal
|
|
||||||
ModelPointer model;
|
ModelPointer model;
|
||||||
withReadLock([&] { model = _model; });
|
withReadLock([&] { model = _model; });
|
||||||
|
|
||||||
|
withWriteLock([&] {
|
||||||
|
bool visuallyReady = true;
|
||||||
|
if (_hasModel) {
|
||||||
|
if (model && _didLastVisualGeometryRequestSucceed) {
|
||||||
|
visuallyReady = (_prevModelLoaded && _texturesLoaded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
entity->setVisuallyReady(visuallyReady);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check for removal
|
||||||
if (!_hasModel) {
|
if (!_hasModel) {
|
||||||
if (model) {
|
if (model) {
|
||||||
model->removeFromScene(scene, transaction);
|
model->removeFromScene(scene, transaction);
|
||||||
|
|
|
@ -288,6 +288,17 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen
|
||||||
updateHazeFromEntity(entity);
|
updateHazeFromEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool visuallyReady = true;
|
||||||
|
uint32_t skyboxMode = entity->getSkyboxMode();
|
||||||
|
if (skyboxMode == COMPONENT_MODE_ENABLED && !_skyboxTextureURL.isEmpty()) {
|
||||||
|
bool skyboxLoadedOrFailed = (_skyboxTexture && (_skyboxTexture->isLoaded() || _skyboxTexture->isFailed()));
|
||||||
|
|
||||||
|
visuallyReady = skyboxLoadedOrFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
entity->setVisuallyReady(visuallyReady);
|
||||||
|
|
||||||
if (bloomChanged) {
|
if (bloomChanged) {
|
||||||
updateBloomFromEntity(entity);
|
updateBloomFromEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
|
@ -305,6 +305,7 @@ public:
|
||||||
void setDynamic(bool value);
|
void setDynamic(bool value);
|
||||||
|
|
||||||
virtual bool shouldBePhysical() const { return false; }
|
virtual bool shouldBePhysical() const { return false; }
|
||||||
|
bool isVisuallyReady() const { return _visuallyReady; }
|
||||||
|
|
||||||
bool getLocked() const;
|
bool getLocked() const;
|
||||||
void setLocked(bool value);
|
void setLocked(bool value);
|
||||||
|
@ -527,6 +528,7 @@ public:
|
||||||
void removeCloneID(const QUuid& cloneID);
|
void removeCloneID(const QUuid& cloneID);
|
||||||
const QVector<QUuid> getCloneIDs() const;
|
const QVector<QUuid> getCloneIDs() const;
|
||||||
void setCloneIDs(const QVector<QUuid>& cloneIDs);
|
void setCloneIDs(const QVector<QUuid>& cloneIDs);
|
||||||
|
void setVisuallyReady(bool visuallyReady) { _visuallyReady = visuallyReady; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void requestRenderUpdate();
|
void requestRenderUpdate();
|
||||||
|
@ -639,6 +641,7 @@ protected:
|
||||||
EntityTreeElementPointer _element; // set by EntityTreeElement
|
EntityTreeElementPointer _element; // set by EntityTreeElement
|
||||||
void* _physicsInfo { nullptr }; // set by EntitySimulation
|
void* _physicsInfo { nullptr }; // set by EntitySimulation
|
||||||
bool _simulated { false }; // set by EntitySimulation
|
bool _simulated { false }; // set by EntitySimulation
|
||||||
|
bool _visuallyReady { true };
|
||||||
|
|
||||||
bool addActionInternal(EntitySimulationPointer simulation, EntityDynamicPointer action);
|
bool addActionInternal(EntitySimulationPointer simulation, EntityDynamicPointer action);
|
||||||
bool removeActionInternal(const QUuid& actionID, EntitySimulationPointer simulation = nullptr);
|
bool removeActionInternal(const QUuid& actionID, EntitySimulationPointer simulation = nullptr);
|
||||||
|
|
|
@ -40,6 +40,7 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID) : EntityItem(
|
||||||
_type = EntityTypes::Model;
|
_type = EntityTypes::Model;
|
||||||
_lastKnownCurrentFrame = -1;
|
_lastKnownCurrentFrame = -1;
|
||||||
_color[0] = _color[1] = _color[2] = 0;
|
_color[0] = _color[1] = _color[2] = 0;
|
||||||
|
_visuallyReady = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString ModelEntityItem::getTextures() const {
|
const QString ModelEntityItem::getTextures() const {
|
||||||
|
|
|
@ -42,6 +42,7 @@ ZoneEntityItem::ZoneEntityItem(const EntityItemID& entityItemID) : EntityItem(en
|
||||||
|
|
||||||
_shapeType = DEFAULT_SHAPE_TYPE;
|
_shapeType = DEFAULT_SHAPE_TYPE;
|
||||||
_compoundShapeURL = DEFAULT_COMPOUND_SHAPE_URL;
|
_compoundShapeURL = DEFAULT_COMPOUND_SHAPE_URL;
|
||||||
|
_visuallyReady = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityItemProperties ZoneEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
EntityItemProperties ZoneEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "udt/PacketHeaders.h"
|
#include "udt/PacketHeaders.h"
|
||||||
|
|
||||||
const QString DEFAULT_HIFI_ADDRESS = "file:///~/serverless/tutorial.json";
|
const QString DEFAULT_HIFI_ADDRESS = "file:///~/serverless/tutorial.json";
|
||||||
|
const QString REDIRECT_HIFI_ADDRESS = "file:///~/serverless/redirect.json";
|
||||||
const QString ADDRESS_MANAGER_SETTINGS_GROUP = "AddressManager";
|
const QString ADDRESS_MANAGER_SETTINGS_GROUP = "AddressManager";
|
||||||
const QString SETTINGS_CURRENT_ADDRESS_KEY = "address";
|
const QString SETTINGS_CURRENT_ADDRESS_KEY = "address";
|
||||||
|
|
||||||
|
@ -111,6 +112,9 @@ QUrl AddressManager::currentFacingPublicAddress() const {
|
||||||
return shareableAddress;
|
return shareableAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QUrl AddressManager::lastAddress() const {
|
||||||
|
return _lastVisitedURL;
|
||||||
|
}
|
||||||
|
|
||||||
void AddressManager::loadSettings(const QString& lookupString) {
|
void AddressManager::loadSettings(const QString& lookupString) {
|
||||||
#if defined(USE_GLES) && defined(Q_OS_WIN)
|
#if defined(USE_GLES) && defined(Q_OS_WIN)
|
||||||
|
@ -247,9 +251,12 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) {
|
||||||
|
|
||||||
UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_USER, lookupUrl.toString());
|
UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_USER, lookupUrl.toString());
|
||||||
|
|
||||||
|
// save the last visited domain URL.
|
||||||
|
_lastVisitedURL = lookupUrl;
|
||||||
|
|
||||||
// in case we're failing to connect to where we thought this user was
|
// in case we're failing to connect to where we thought this user was
|
||||||
// store their username as previous lookup so we can refresh their location via API
|
// store their username as previous lookup so we can refresh their location via API
|
||||||
_previousLookup = lookupUrl;
|
_previousAPILookup = lookupUrl;
|
||||||
} else {
|
} else {
|
||||||
// we're assuming this is either a network address or global place name
|
// we're assuming this is either a network address or global place name
|
||||||
// check if it is a network address first
|
// check if it is a network address first
|
||||||
|
@ -259,8 +266,11 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) {
|
||||||
|
|
||||||
UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_NETWORK_ADDRESS, lookupUrl.toString());
|
UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_NETWORK_ADDRESS, lookupUrl.toString());
|
||||||
|
|
||||||
|
// save the last visited domain URL.
|
||||||
|
_lastVisitedURL = lookupUrl;
|
||||||
|
|
||||||
// a network address lookup clears the previous lookup since we don't expect to re-attempt it
|
// a network address lookup clears the previous lookup since we don't expect to re-attempt it
|
||||||
_previousLookup.clear();
|
_previousAPILookup.clear();
|
||||||
|
|
||||||
// If the host changed then we have already saved to history
|
// If the host changed then we have already saved to history
|
||||||
if (hostChanged) {
|
if (hostChanged) {
|
||||||
|
@ -278,8 +288,11 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) {
|
||||||
} else if (handleDomainID(lookupUrl.host())){
|
} else if (handleDomainID(lookupUrl.host())){
|
||||||
UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_DOMAIN_ID, lookupUrl.toString());
|
UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_DOMAIN_ID, lookupUrl.toString());
|
||||||
|
|
||||||
|
// save the last visited domain URL.
|
||||||
|
_lastVisitedURL = lookupUrl;
|
||||||
|
|
||||||
// store this domain ID as the previous lookup in case we're failing to connect and want to refresh API info
|
// store this domain ID as the previous lookup in case we're failing to connect and want to refresh API info
|
||||||
_previousLookup = lookupUrl;
|
_previousAPILookup = lookupUrl;
|
||||||
|
|
||||||
// no place name - this is probably a domain ID
|
// no place name - this is probably a domain ID
|
||||||
// try to look up the domain ID on the metaverse API
|
// try to look up the domain ID on the metaverse API
|
||||||
|
@ -287,8 +300,11 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) {
|
||||||
} else {
|
} else {
|
||||||
UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_PLACE, lookupUrl.toString());
|
UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_PLACE, lookupUrl.toString());
|
||||||
|
|
||||||
|
// save the last visited domain URL.
|
||||||
|
_lastVisitedURL = lookupUrl;
|
||||||
|
|
||||||
// store this place name as the previous lookup in case we fail to connect and want to refresh API info
|
// store this place name as the previous lookup in case we fail to connect and want to refresh API info
|
||||||
_previousLookup = lookupUrl;
|
_previousAPILookup = lookupUrl;
|
||||||
|
|
||||||
// wasn't an address - lookup the place name
|
// wasn't an address - lookup the place name
|
||||||
// we may have a path that defines a relative viewpoint - pass that through the lookup so we can go to it after
|
// we may have a path that defines a relative viewpoint - pass that through the lookup so we can go to it after
|
||||||
|
@ -302,7 +318,7 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) {
|
||||||
qCDebug(networking) << "Going to relative path" << lookupUrl.path();
|
qCDebug(networking) << "Going to relative path" << lookupUrl.path();
|
||||||
|
|
||||||
// a path lookup clears the previous lookup since we don't expect to re-attempt it
|
// a path lookup clears the previous lookup since we don't expect to re-attempt it
|
||||||
_previousLookup.clear();
|
_previousAPILookup.clear();
|
||||||
|
|
||||||
// if this is a relative path then handle it as a relative viewpoint
|
// if this is a relative path then handle it as a relative viewpoint
|
||||||
handlePath(lookupUrl.path(), trigger, true);
|
handlePath(lookupUrl.path(), trigger, true);
|
||||||
|
@ -314,7 +330,10 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) {
|
||||||
// be loaded over http(s)
|
// be loaded over http(s)
|
||||||
// lookupUrl.scheme() == URL_SCHEME_HTTP ||
|
// lookupUrl.scheme() == URL_SCHEME_HTTP ||
|
||||||
// lookupUrl.scheme() == URL_SCHEME_HTTPS ||
|
// lookupUrl.scheme() == URL_SCHEME_HTTPS ||
|
||||||
_previousLookup.clear();
|
// TODO once a file can return a connection refusal if there were to be some kind of load error, we'd
|
||||||
|
// need to store the previous domain tried in _lastVisitedURL. For now , do not store it.
|
||||||
|
|
||||||
|
_previousAPILookup.clear();
|
||||||
_shareablePlaceName.clear();
|
_shareablePlaceName.clear();
|
||||||
setDomainInfo(lookupUrl, trigger);
|
setDomainInfo(lookupUrl, trigger);
|
||||||
emit lookupResultsFinished();
|
emit lookupResultsFinished();
|
||||||
|
@ -381,7 +400,7 @@ void AddressManager::handleAPIResponse(QNetworkReply* requestReply) {
|
||||||
QJsonObject dataObject = responseObject["data"].toObject();
|
QJsonObject dataObject = responseObject["data"].toObject();
|
||||||
|
|
||||||
// Lookup succeeded, don't keep re-trying it (especially on server restarts)
|
// Lookup succeeded, don't keep re-trying it (especially on server restarts)
|
||||||
_previousLookup.clear();
|
_previousAPILookup.clear();
|
||||||
|
|
||||||
if (!dataObject.isEmpty()) {
|
if (!dataObject.isEmpty()) {
|
||||||
goToAddressFromObject(dataObject.toVariantMap(), requestReply);
|
goToAddressFromObject(dataObject.toVariantMap(), requestReply);
|
||||||
|
@ -547,7 +566,7 @@ void AddressManager::handleAPIError(QNetworkReply* errorReply) {
|
||||||
|
|
||||||
if (errorReply->error() == QNetworkReply::ContentNotFoundError) {
|
if (errorReply->error() == QNetworkReply::ContentNotFoundError) {
|
||||||
// if this is a lookup that has no result, don't keep re-trying it
|
// if this is a lookup that has no result, don't keep re-trying it
|
||||||
_previousLookup.clear();
|
_previousAPILookup.clear();
|
||||||
|
|
||||||
emit lookupResultIsNotFound();
|
emit lookupResultIsNotFound();
|
||||||
}
|
}
|
||||||
|
@ -709,7 +728,6 @@ bool AddressManager::handleViewpoint(const QString& viewpointString, bool should
|
||||||
// We use _newHostLookupPath to determine if the client has already stored its last address
|
// We use _newHostLookupPath to determine if the client has already stored its last address
|
||||||
// before moving to a new host thanks to the information in the same lookup URL.
|
// before moving to a new host thanks to the information in the same lookup URL.
|
||||||
|
|
||||||
|
|
||||||
if (definitelyPathOnly || (!pathString.isEmpty() && pathString != _newHostLookupPath)
|
if (definitelyPathOnly || (!pathString.isEmpty() && pathString != _newHostLookupPath)
|
||||||
|| trigger == Back || trigger == Forward) {
|
|| trigger == Back || trigger == Forward) {
|
||||||
addCurrentAddressToHistory(trigger);
|
addCurrentAddressToHistory(trigger);
|
||||||
|
@ -843,8 +861,8 @@ void AddressManager::goToUser(const QString& username, bool shouldMatchOrientati
|
||||||
|
|
||||||
void AddressManager::refreshPreviousLookup() {
|
void AddressManager::refreshPreviousLookup() {
|
||||||
// if we have a non-empty previous lookup, fire it again now (but don't re-store it in the history)
|
// if we have a non-empty previous lookup, fire it again now (but don't re-store it in the history)
|
||||||
if (!_previousLookup.isEmpty()) {
|
if (!_previousAPILookup.isEmpty()) {
|
||||||
handleUrl(_previousLookup, LookupTrigger::AttemptedRefresh);
|
handleUrl(_previousAPILookup, LookupTrigger::AttemptedRefresh);
|
||||||
} else {
|
} else {
|
||||||
handleUrl(currentAddress(), LookupTrigger::AttemptedRefresh);
|
handleUrl(currentAddress(), LookupTrigger::AttemptedRefresh);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "AccountManager.h"
|
#include "AccountManager.h"
|
||||||
|
|
||||||
extern const QString DEFAULT_HIFI_ADDRESS;
|
extern const QString DEFAULT_HIFI_ADDRESS;
|
||||||
|
extern const QString REDIRECT_HIFI_ADDRESS;
|
||||||
|
|
||||||
const QString SANDBOX_HIFI_ADDRESS = "hifi://localhost";
|
const QString SANDBOX_HIFI_ADDRESS = "hifi://localhost";
|
||||||
const QString INDEX_PATH = "/";
|
const QString INDEX_PATH = "/";
|
||||||
|
@ -55,7 +56,6 @@ const QString GET_PLACE = "/api/v1/places/%1";
|
||||||
* <em>Read-only.</em>
|
* <em>Read-only.</em>
|
||||||
* @property {boolean} isConnected - <code>true</code> if you're connected to the domain in your current <code>href</code>
|
* @property {boolean} isConnected - <code>true</code> if you're connected to the domain in your current <code>href</code>
|
||||||
* metaverse address, otherwise <code>false</code>.
|
* metaverse address, otherwise <code>false</code>.
|
||||||
* <em>Read-only.</em>
|
|
||||||
* @property {string} pathname - The location and orientation in your current <code>href</code> metaverse address
|
* @property {string} pathname - The location and orientation in your current <code>href</code> metaverse address
|
||||||
* (e.g., <code>"/15,-10,26/0,0,0,1"</code>).
|
* (e.g., <code>"/15,-10,26/0,0,0,1"</code>).
|
||||||
* <em>Read-only.</em>
|
* <em>Read-only.</em>
|
||||||
|
@ -140,7 +140,8 @@ public:
|
||||||
* </table>
|
* </table>
|
||||||
* @typedef {number} location.LookupTrigger
|
* @typedef {number} location.LookupTrigger
|
||||||
*/
|
*/
|
||||||
enum LookupTrigger {
|
enum LookupTrigger
|
||||||
|
{
|
||||||
UserInput,
|
UserInput,
|
||||||
Back,
|
Back,
|
||||||
Forward,
|
Forward,
|
||||||
|
@ -164,6 +165,8 @@ public:
|
||||||
QString currentPath(bool withOrientation = true) const;
|
QString currentPath(bool withOrientation = true) const;
|
||||||
QString currentFacingPath() const;
|
QString currentFacingPath() const;
|
||||||
|
|
||||||
|
QUrl lastAddress() const;
|
||||||
|
|
||||||
const QUuid& getRootPlaceID() const { return _rootPlaceID; }
|
const QUuid& getRootPlaceID() const { return _rootPlaceID; }
|
||||||
QString getPlaceName() const;
|
QString getPlaceName() const;
|
||||||
QString getDomainID() const;
|
QString getDomainID() const;
|
||||||
|
@ -204,8 +207,9 @@ public slots:
|
||||||
// functions and signals that should be exposed are moved to a scripting interface class.
|
// functions and signals that should be exposed are moved to a scripting interface class.
|
||||||
//
|
//
|
||||||
// we currently expect this to be called from NodeList once handleLookupString has been called with a path
|
// we currently expect this to be called from NodeList once handleLookupString has been called with a path
|
||||||
bool goToViewpointForPath(const QString& viewpointString, const QString& pathString)
|
bool goToViewpointForPath(const QString& viewpointString, const QString& pathString) {
|
||||||
{ return handleViewpoint(viewpointString, false, DomainPathResponse, false, pathString); }
|
return handleViewpoint(viewpointString, false, DomainPathResponse, false, pathString);
|
||||||
|
}
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Go back to the previous location in your navigation history, if there is one.
|
* Go back to the previous location in your navigation history, if there is one.
|
||||||
|
@ -226,7 +230,9 @@ public slots:
|
||||||
* @param {location.LookupTrigger} trigger=StartupFromSettings - The reason for the function call. Helps ensure that user's
|
* @param {location.LookupTrigger} trigger=StartupFromSettings - The reason for the function call. Helps ensure that user's
|
||||||
* location history is correctly maintained.
|
* location history is correctly maintained.
|
||||||
*/
|
*/
|
||||||
void goToLocalSandbox(QString path = "", LookupTrigger trigger = LookupTrigger::StartupFromSettings) { handleUrl(SANDBOX_HIFI_ADDRESS + path, trigger); }
|
void goToLocalSandbox(QString path = "", LookupTrigger trigger = LookupTrigger::StartupFromSettings) {
|
||||||
|
handleUrl(SANDBOX_HIFI_ADDRESS + path, trigger);
|
||||||
|
}
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Go to the default "welcome" metaverse address.
|
* Go to the default "welcome" metaverse address.
|
||||||
|
@ -245,6 +251,12 @@ public slots:
|
||||||
*/
|
*/
|
||||||
void goToUser(const QString& username, bool shouldMatchOrientation = true);
|
void goToUser(const QString& username, bool shouldMatchOrientation = true);
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Go to the last address tried. This will be the last URL tried from location.handleLookupString
|
||||||
|
* @function location.goToLastAddress
|
||||||
|
*/
|
||||||
|
void goToLastAddress() { handleUrl(_lastVisitedURL, LookupTrigger::AttemptedRefresh); }
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Refresh the current address, e.g., after connecting to a domain in order to position the user to the desired location.
|
* Refresh the current address, e.g., after connecting to a domain in order to position the user to the desired location.
|
||||||
* @function location.refreshPreviousLookup
|
* @function location.refreshPreviousLookup
|
||||||
|
@ -352,7 +364,8 @@ signals:
|
||||||
* location.locationChangeRequired.connect(onLocationChangeRequired);
|
* location.locationChangeRequired.connect(onLocationChangeRequired);
|
||||||
*/
|
*/
|
||||||
void locationChangeRequired(const glm::vec3& newPosition,
|
void locationChangeRequired(const glm::vec3& newPosition,
|
||||||
bool hasOrientationChange, const glm::quat& newOrientation,
|
bool hasOrientationChange,
|
||||||
|
const glm::quat& newOrientation,
|
||||||
bool shouldFaceLocation);
|
bool shouldFaceLocation);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
|
@ -435,8 +448,11 @@ private:
|
||||||
|
|
||||||
bool handleNetworkAddress(const QString& lookupString, LookupTrigger trigger, bool& hostChanged);
|
bool handleNetworkAddress(const QString& lookupString, LookupTrigger trigger, bool& hostChanged);
|
||||||
void handlePath(const QString& path, LookupTrigger trigger, bool wasPathOnly = false);
|
void handlePath(const QString& path, LookupTrigger trigger, bool wasPathOnly = false);
|
||||||
bool handleViewpoint(const QString& viewpointString, bool shouldFace, LookupTrigger trigger,
|
bool handleViewpoint(const QString& viewpointString,
|
||||||
bool definitelyPathOnly = false, const QString& pathString = QString());
|
bool shouldFace,
|
||||||
|
LookupTrigger trigger,
|
||||||
|
bool definitelyPathOnly = false,
|
||||||
|
const QString& pathString = QString());
|
||||||
bool handleUsername(const QString& lookupString);
|
bool handleUsername(const QString& lookupString);
|
||||||
bool handleDomainID(const QString& host);
|
bool handleDomainID(const QString& host);
|
||||||
|
|
||||||
|
@ -446,6 +462,7 @@ private:
|
||||||
void addCurrentAddressToHistory(LookupTrigger trigger);
|
void addCurrentAddressToHistory(LookupTrigger trigger);
|
||||||
|
|
||||||
QUrl _domainURL;
|
QUrl _domainURL;
|
||||||
|
QUrl _lastVisitedURL;
|
||||||
|
|
||||||
QUuid _rootPlaceID;
|
QUuid _rootPlaceID;
|
||||||
PositionGetter _positionGetter;
|
PositionGetter _positionGetter;
|
||||||
|
@ -459,7 +476,7 @@ private:
|
||||||
|
|
||||||
QString _newHostLookupPath;
|
QString _newHostLookupPath;
|
||||||
|
|
||||||
QUrl _previousLookup;
|
QUrl _previousAPILookup;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AddressManager_h
|
#endif // hifi_AddressManager_h
|
||||||
|
|
|
@ -99,6 +99,7 @@ void DomainHandler::softReset() {
|
||||||
|
|
||||||
clearSettings();
|
clearSettings();
|
||||||
|
|
||||||
|
_isInErrorState = false;
|
||||||
_connectionDenialsSinceKeypairRegen = 0;
|
_connectionDenialsSinceKeypairRegen = 0;
|
||||||
_checkInPacketsSinceLastReply = 0;
|
_checkInPacketsSinceLastReply = 0;
|
||||||
|
|
||||||
|
@ -128,6 +129,11 @@ void DomainHandler::hardReset() {
|
||||||
_pendingPath.clear();
|
_pendingPath.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DomainHandler::setErrorDomainURL(const QUrl& url) {
|
||||||
|
_errorDomainURL = url;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void DomainHandler::setSockAddr(const HifiSockAddr& sockAddr, const QString& hostname) {
|
void DomainHandler::setSockAddr(const HifiSockAddr& sockAddr, const QString& hostname) {
|
||||||
if (_sockAddr != sockAddr) {
|
if (_sockAddr != sockAddr) {
|
||||||
// we should reset on a sockAddr change
|
// we should reset on a sockAddr change
|
||||||
|
@ -171,7 +177,8 @@ void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) {
|
||||||
domainPort = DEFAULT_DOMAIN_SERVER_PORT;
|
domainPort = DEFAULT_DOMAIN_SERVER_PORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_domainURL != domainURL || _sockAddr.getPort() != domainPort) {
|
// if it's in the error state, reset and try again.
|
||||||
|
if ((_domainURL != domainURL || _sockAddr.getPort() != domainPort) || _isInErrorState) {
|
||||||
// re-set the domain info so that auth information is reloaded
|
// re-set the domain info so that auth information is reloaded
|
||||||
hardReset();
|
hardReset();
|
||||||
|
|
||||||
|
@ -206,7 +213,8 @@ void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) {
|
||||||
|
|
||||||
void DomainHandler::setIceServerHostnameAndID(const QString& iceServerHostname, const QUuid& id) {
|
void DomainHandler::setIceServerHostnameAndID(const QString& iceServerHostname, const QUuid& id) {
|
||||||
|
|
||||||
if (_iceServerSockAddr.getAddress().toString() != iceServerHostname || id != _pendingDomainID) {
|
// if it's in the error state, reset and try again.
|
||||||
|
if ((_iceServerSockAddr.getAddress().toString() != iceServerHostname || id != _pendingDomainID) || _isInErrorState) {
|
||||||
// re-set the domain info to connect to new domain
|
// re-set the domain info to connect to new domain
|
||||||
hardReset();
|
hardReset();
|
||||||
|
|
||||||
|
@ -316,6 +324,23 @@ void DomainHandler::connectedToServerless(std::map<QString, QString> namedPaths)
|
||||||
setIsConnected(true);
|
setIsConnected(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DomainHandler::loadedErrorDomain(std::map<QString, QString> namedPaths) {
|
||||||
|
auto lookup = namedPaths.find("/");
|
||||||
|
QString viewpoint;
|
||||||
|
if (lookup != namedPaths.end()) {
|
||||||
|
viewpoint = lookup->second;
|
||||||
|
} else {
|
||||||
|
viewpoint = DOMAIN_SPAWNING_POINT;
|
||||||
|
}
|
||||||
|
DependencyManager::get<AddressManager>()->goToViewpointForPath(viewpoint, QString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DomainHandler::setRedirectErrorState(QUrl errorUrl, int reasonCode) {
|
||||||
|
_errorDomainURL = errorUrl;
|
||||||
|
_lastDomainConnectionError = reasonCode;
|
||||||
|
emit redirectToErrorDomainURL(_errorDomainURL);
|
||||||
|
}
|
||||||
|
|
||||||
void DomainHandler::requestDomainSettings() {
|
void DomainHandler::requestDomainSettings() {
|
||||||
qCDebug(networking) << "Requesting settings from domain server";
|
qCDebug(networking) << "Requesting settings from domain server";
|
||||||
|
|
||||||
|
@ -451,7 +476,18 @@ void DomainHandler::processDomainServerConnectionDeniedPacket(QSharedPointer<Rec
|
||||||
|
|
||||||
if (!_domainConnectionRefusals.contains(reasonMessage)) {
|
if (!_domainConnectionRefusals.contains(reasonMessage)) {
|
||||||
_domainConnectionRefusals.insert(reasonMessage);
|
_domainConnectionRefusals.insert(reasonMessage);
|
||||||
|
#if defined(Q_OS_ANDROID)
|
||||||
emit domainConnectionRefused(reasonMessage, (int)reasonCode, extraInfo);
|
emit domainConnectionRefused(reasonMessage, (int)reasonCode, extraInfo);
|
||||||
|
#else
|
||||||
|
if (reasonCode == ConnectionRefusedReason::ProtocolMismatch || reasonCode == ConnectionRefusedReason::NotAuthorized) {
|
||||||
|
_isInErrorState = true;
|
||||||
|
// ingest the error - this is a "hard" connection refusal.
|
||||||
|
emit redirectToErrorDomainURL(_errorDomainURL);
|
||||||
|
} else {
|
||||||
|
emit domainConnectionRefused(reasonMessage, (int)reasonCode, extraInfo);
|
||||||
|
}
|
||||||
|
_lastDomainConnectionError = (int)reasonCode;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
auto accountManager = DependencyManager::get<AccountManager>();
|
auto accountManager = DependencyManager::get<AccountManager>();
|
||||||
|
|
|
@ -50,6 +50,11 @@ public:
|
||||||
|
|
||||||
QString getHostname() const { return _domainURL.host(); }
|
QString getHostname() const { return _domainURL.host(); }
|
||||||
|
|
||||||
|
QUrl getErrorDomainURL(){ return _errorDomainURL; }
|
||||||
|
void setErrorDomainURL(const QUrl& url);
|
||||||
|
|
||||||
|
int getLastDomainConnectionError() { return _lastDomainConnectionError; }
|
||||||
|
|
||||||
const QHostAddress& getIP() const { return _sockAddr.getAddress(); }
|
const QHostAddress& getIP() const { return _sockAddr.getAddress(); }
|
||||||
void setIPToLocalhost() { _sockAddr.setAddress(QHostAddress(QHostAddress::LocalHost)); }
|
void setIPToLocalhost() { _sockAddr.setAddress(QHostAddress(QHostAddress::LocalHost)); }
|
||||||
|
|
||||||
|
@ -81,6 +86,10 @@ public:
|
||||||
|
|
||||||
void connectedToServerless(std::map<QString, QString> namedPaths);
|
void connectedToServerless(std::map<QString, QString> namedPaths);
|
||||||
|
|
||||||
|
void loadedErrorDomain(std::map<QString, QString> namedPaths);
|
||||||
|
// sets domain handler in error state.
|
||||||
|
void setRedirectErrorState(QUrl errorUrl, int reasonCode);
|
||||||
|
|
||||||
QString getViewPointFromNamedPath(QString namedPath);
|
QString getViewPointFromNamedPath(QString namedPath);
|
||||||
|
|
||||||
bool hasSettings() const { return !_settingsObject.isEmpty(); }
|
bool hasSettings() const { return !_settingsObject.isEmpty(); }
|
||||||
|
@ -135,6 +144,11 @@ public:
|
||||||
* <td><code>4</code></td>
|
* <td><code>4</code></td>
|
||||||
* <td>The domain already has its maximum number of users.</td>
|
* <td>The domain already has its maximum number of users.</td>
|
||||||
* </tr>
|
* </tr>
|
||||||
|
* <tr>
|
||||||
|
* <td><strong>TimedOut</strong></td>
|
||||||
|
* <td><code>5</code></td>
|
||||||
|
* <td>Connecting to the domain timed out.</td>
|
||||||
|
* </tr>
|
||||||
* </tbody>
|
* </tbody>
|
||||||
* </table>
|
* </table>
|
||||||
* @typedef {number} Window.ConnectionRefusedReason
|
* @typedef {number} Window.ConnectionRefusedReason
|
||||||
|
@ -144,7 +158,8 @@ public:
|
||||||
ProtocolMismatch,
|
ProtocolMismatch,
|
||||||
LoginError,
|
LoginError,
|
||||||
NotAuthorized,
|
NotAuthorized,
|
||||||
TooManyUsers
|
TooManyUsers,
|
||||||
|
TimedOut
|
||||||
};
|
};
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -164,6 +179,8 @@ private slots:
|
||||||
signals:
|
signals:
|
||||||
void domainURLChanged(QUrl domainURL);
|
void domainURLChanged(QUrl domainURL);
|
||||||
|
|
||||||
|
void domainConnectionErrorChanged(int reasonCode);
|
||||||
|
|
||||||
// NOTE: the emission of completedSocketDiscovery does not mean a connection to DS is established
|
// NOTE: the emission of completedSocketDiscovery does not mean a connection to DS is established
|
||||||
// It means that, either from DNS lookup or ICE, we think we have a socket we can talk to DS on
|
// It means that, either from DNS lookup or ICE, we think we have a socket we can talk to DS on
|
||||||
void completedSocketDiscovery();
|
void completedSocketDiscovery();
|
||||||
|
@ -179,6 +196,7 @@ signals:
|
||||||
void settingsReceiveFail();
|
void settingsReceiveFail();
|
||||||
|
|
||||||
void domainConnectionRefused(QString reasonMessage, int reason, const QString& extraInfo);
|
void domainConnectionRefused(QString reasonMessage, int reason, const QString& extraInfo);
|
||||||
|
void redirectToErrorDomainURL(QUrl errorDomainURL);
|
||||||
|
|
||||||
void limitOfSilentDomainCheckInsReached();
|
void limitOfSilentDomainCheckInsReached();
|
||||||
|
|
||||||
|
@ -190,6 +208,7 @@ private:
|
||||||
QUuid _uuid;
|
QUuid _uuid;
|
||||||
Node::LocalID _localID;
|
Node::LocalID _localID;
|
||||||
QUrl _domainURL;
|
QUrl _domainURL;
|
||||||
|
QUrl _errorDomainURL;
|
||||||
HifiSockAddr _sockAddr;
|
HifiSockAddr _sockAddr;
|
||||||
QUuid _assignmentUUID;
|
QUuid _assignmentUUID;
|
||||||
QUuid _connectionToken;
|
QUuid _connectionToken;
|
||||||
|
@ -198,6 +217,7 @@ private:
|
||||||
HifiSockAddr _iceServerSockAddr;
|
HifiSockAddr _iceServerSockAddr;
|
||||||
NetworkPeer _icePeer;
|
NetworkPeer _icePeer;
|
||||||
bool _isConnected { false };
|
bool _isConnected { false };
|
||||||
|
bool _isInErrorState { false };
|
||||||
QJsonObject _settingsObject;
|
QJsonObject _settingsObject;
|
||||||
QString _pendingPath;
|
QString _pendingPath;
|
||||||
QTimer _settingsTimer;
|
QTimer _settingsTimer;
|
||||||
|
@ -210,6 +230,9 @@ private:
|
||||||
QTimer _apiRefreshTimer;
|
QTimer _apiRefreshTimer;
|
||||||
|
|
||||||
std::map<QString, QString> _namedPaths;
|
std::map<QString, QString> _namedPaths;
|
||||||
|
|
||||||
|
// domain connection error upon connection refusal.
|
||||||
|
int _lastDomainConnectionError{ -1 };
|
||||||
};
|
};
|
||||||
|
|
||||||
const QString DOMAIN_SPAWNING_POINT { "/0, -10, 0" };
|
const QString DOMAIN_SPAWNING_POINT { "/0, -10, 0" };
|
||||||
|
|
|
@ -35,6 +35,7 @@ var DEFAULT_SCRIPTS_COMBINED = [
|
||||||
];
|
];
|
||||||
var DEFAULT_SCRIPTS_SEPARATE = [
|
var DEFAULT_SCRIPTS_SEPARATE = [
|
||||||
"system/controllers/controllerScripts.js",
|
"system/controllers/controllerScripts.js",
|
||||||
|
"system/interstitialPage.js"
|
||||||
//"system/chat.js"
|
//"system/chat.js"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
476
scripts/system/interstitialPage.js
Normal file
476
scripts/system/interstitialPage.js
Normal file
|
@ -0,0 +1,476 @@
|
||||||
|
//
|
||||||
|
// interstitialPage.js
|
||||||
|
// scripts/system
|
||||||
|
//
|
||||||
|
// Created by Dante Ruiz on 08/02/2018.
|
||||||
|
// Copyright 2012 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
|
||||||
|
//
|
||||||
|
|
||||||
|
/* global Script, Controller, Overlays, Quat, MyAvatar, Entities, print, Vec3, AddressManager, Render, Window, Toolbars,
|
||||||
|
Camera, HMD, location, Account, Xform*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
Script.include("/~/system/libraries/Xform.js");
|
||||||
|
var DEBUG = false;
|
||||||
|
var MIN_LOADING_PROGRESS = 3.6;
|
||||||
|
var TOTAL_LOADING_PROGRESS = 3.8;
|
||||||
|
var EPSILON = 0.01;
|
||||||
|
var isVisible = false;
|
||||||
|
var VOLUME = 0.4;
|
||||||
|
var tune = SoundCache.getSound("http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/crystals_and_voices.wav");
|
||||||
|
var sample = null;
|
||||||
|
var MAX_LEFT_MARGIN = 1.9;
|
||||||
|
var INNER_CIRCLE_WIDTH = 4.7;
|
||||||
|
var DEFAULT_Z_OFFSET = 5.45;
|
||||||
|
var previousCameraMode = Camera.mode;
|
||||||
|
|
||||||
|
var renderViewTask = Render.getConfig("RenderMainView");
|
||||||
|
var toolbar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system");
|
||||||
|
var request = Script.require('request').request;
|
||||||
|
var BUTTON_PROPERTIES = {
|
||||||
|
text: "Interstitial"
|
||||||
|
};
|
||||||
|
|
||||||
|
var tablet = null;
|
||||||
|
var button = null;
|
||||||
|
|
||||||
|
// Tips have a character limit of 69
|
||||||
|
var userTips = [
|
||||||
|
"Tip: Visit TheSpot to explore featured domains!",
|
||||||
|
"Tip: Visit our docs online to learn more about scripting!",
|
||||||
|
"Tip: Don't want others invading your personal space? Turn on the Bubble!",
|
||||||
|
"Tip: Want to make a friend? Shake hands with them in VR!",
|
||||||
|
"Tip: Enjoy live music? Visit Rust to dance your heart out!",
|
||||||
|
"Tip: Have you visited BodyMart to check out the new avatars recently?",
|
||||||
|
"Tip: Use the Create app to import models and create custom entities.",
|
||||||
|
"Tip: We're open source! Feel free to contribute to our code on GitHub!",
|
||||||
|
"Tip: What emotes have you used in the Emote app?",
|
||||||
|
"Tip: Take and share your snapshots with the everyone using the Snap app.",
|
||||||
|
"Tip: Did you know you can show websites in-world by creating a web entity?",
|
||||||
|
"Tip: Find out more information about domains by visiting our website!",
|
||||||
|
"Tip: Did you know you can get cool new apps from the Marketplace?",
|
||||||
|
"Tip: Print your snapshots from the Snap app to share with others!",
|
||||||
|
"Tip: Log in to make friends, visit new domains, and save avatars!"
|
||||||
|
];
|
||||||
|
|
||||||
|
var DEFAULT_DIMENSIONS = { x: 24, y: 24, z: 24 };
|
||||||
|
|
||||||
|
var loadingSphereID = Overlays.addOverlay("model", {
|
||||||
|
name: "Loading-Sphere",
|
||||||
|
position: Vec3.sum(Vec3.sum(MyAvatar.position, {x: 0.0, y: -1.0, z: 0.0}), Vec3.multiplyQbyV(MyAvatar.orientation, {x: 0, y: 0.95, z: 0})),
|
||||||
|
orientation: Quat.multiply(Quat.fromVec3Degrees({x: 0, y: 180, z: 0}), MyAvatar.orientation),
|
||||||
|
url: "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/black-sphere.fbx",
|
||||||
|
dimensions: DEFAULT_DIMENSIONS,
|
||||||
|
alpha: 1,
|
||||||
|
visible: isVisible,
|
||||||
|
ignoreRayIntersection: true,
|
||||||
|
drawInFront: true,
|
||||||
|
grabbable: false,
|
||||||
|
parentID: MyAvatar.SELF_ID
|
||||||
|
});
|
||||||
|
|
||||||
|
var anchorOverlay = Overlays.addOverlay("cube", {
|
||||||
|
dimensions: {x: 0.2, y: 0.2, z: 0.2},
|
||||||
|
visible: false,
|
||||||
|
grabbable: false,
|
||||||
|
ignoreRayIntersection: true,
|
||||||
|
localPosition: {x: 0.0, y: getAnchorLocalYOffset(), z: DEFAULT_Z_OFFSET },
|
||||||
|
orientation: Quat.multiply(Quat.fromVec3Degrees({x: 0, y: 180, z: 0}), MyAvatar.orientation),
|
||||||
|
solid: true,
|
||||||
|
drawInFront: true,
|
||||||
|
parentID: loadingSphereID
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
var domainName = "";
|
||||||
|
var domainNameTextID = Overlays.addOverlay("text3d", {
|
||||||
|
name: "Loading-Destination-Card-Text",
|
||||||
|
localPosition: { x: 0.0, y: 0.8, z: -0.001 },
|
||||||
|
text: domainName,
|
||||||
|
textAlpha: 1,
|
||||||
|
backgroundAlpha: 1,
|
||||||
|
lineHeight: 0.42,
|
||||||
|
visible: isVisible,
|
||||||
|
ignoreRayIntersection: true,
|
||||||
|
drawInFront: true,
|
||||||
|
grabbable: false,
|
||||||
|
localOrientation: Quat.fromVec3Degrees({ x: 0, y: 180, z: 0 }),
|
||||||
|
parentID: anchorOverlay
|
||||||
|
});
|
||||||
|
|
||||||
|
var domainText = "";
|
||||||
|
var domainDescription = Overlays.addOverlay("text3d", {
|
||||||
|
name: "Loading-Hostname",
|
||||||
|
localPosition: { x: 0.0, y: 0.32, z: 0.0 },
|
||||||
|
text: domainText,
|
||||||
|
textAlpha: 1,
|
||||||
|
backgroundAlpha: 1,
|
||||||
|
lineHeight: 0.13,
|
||||||
|
visible: isVisible,
|
||||||
|
backgroundAlpha: 0,
|
||||||
|
ignoreRayIntersection: true,
|
||||||
|
drawInFront: true,
|
||||||
|
grabbable: false,
|
||||||
|
localOrientation: Quat.fromVec3Degrees({ x: 0, y: 180, z: 0 }),
|
||||||
|
parentID: anchorOverlay
|
||||||
|
});
|
||||||
|
|
||||||
|
var toolTip = "";
|
||||||
|
|
||||||
|
var domainToolTip = Overlays.addOverlay("text3d", {
|
||||||
|
name: "Loading-Tooltip",
|
||||||
|
localPosition: { x: 0.0 , y: -1.6, z: 0.0 },
|
||||||
|
text: toolTip,
|
||||||
|
textAlpha: 1,
|
||||||
|
backgroundAlpha: 1,
|
||||||
|
lineHeight: 0.13,
|
||||||
|
visible: isVisible,
|
||||||
|
ignoreRayIntersection: true,
|
||||||
|
drawInFront: true,
|
||||||
|
grabbable: false,
|
||||||
|
localOrientation: Quat.fromVec3Degrees({ x: 0, y: 180, z: 0 }),
|
||||||
|
parentID: anchorOverlay
|
||||||
|
});
|
||||||
|
|
||||||
|
var loadingToTheSpotID = Overlays.addOverlay("image3d", {
|
||||||
|
name: "Loading-Destination-Card-Text",
|
||||||
|
localPosition: { x: 0.0 , y: -1.8, z: 0.0 },
|
||||||
|
url: "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/goTo_button.png",
|
||||||
|
alpha: 1,
|
||||||
|
dimensions: { x: 1.2, y: 0.6},
|
||||||
|
visible: isVisible,
|
||||||
|
emissive: true,
|
||||||
|
ignoreRayIntersection: false,
|
||||||
|
drawInFront: true,
|
||||||
|
grabbable: false,
|
||||||
|
localOrientation: Quat.fromVec3Degrees({ x: 0.0, y: 180.0, z: 0.0 }),
|
||||||
|
parentID: anchorOverlay
|
||||||
|
});
|
||||||
|
|
||||||
|
var loadingBarPlacard = Overlays.addOverlay("image3d", {
|
||||||
|
name: "Loading-Bar-Placard",
|
||||||
|
localPosition: { x: 0.0, y: -0.99, z: 0.3 },
|
||||||
|
url: Script.resourcesPath() + "images/loadingBar_placard.png",
|
||||||
|
alpha: 1,
|
||||||
|
dimensions: { x: 4, y: 2.8},
|
||||||
|
visible: isVisible,
|
||||||
|
emissive: true,
|
||||||
|
ignoreRayIntersection: false,
|
||||||
|
drawInFront: true,
|
||||||
|
grabbable: false,
|
||||||
|
localOrientation: Quat.fromVec3Degrees({ x: 0.0, y: 180.0, z: 0.0 }),
|
||||||
|
parentID: anchorOverlay
|
||||||
|
});
|
||||||
|
|
||||||
|
var loadingBarProgress = Overlays.addOverlay("image3d", {
|
||||||
|
name: "Loading-Bar-Progress",
|
||||||
|
localPosition: { x: 0.0, y: -0.90, z: 0.0 },
|
||||||
|
url: Script.resourcesPath() + "images/loadingBar_progress.png",
|
||||||
|
alpha: 1,
|
||||||
|
dimensions: {x: 3.8, y: 2.8},
|
||||||
|
visible: isVisible,
|
||||||
|
emissive: true,
|
||||||
|
ignoreRayIntersection: false,
|
||||||
|
drawInFront: true,
|
||||||
|
grabbable: false,
|
||||||
|
localOrientation: Quat.fromVec3Degrees({ x: 0.0, y: 180.0, z: 0.0 }),
|
||||||
|
parentID: anchorOverlay
|
||||||
|
});
|
||||||
|
|
||||||
|
var TARGET_UPDATE_HZ = 60; // 50hz good enough, but we're using update
|
||||||
|
var BASIC_TIMER_INTERVAL_MS = 1000 / TARGET_UPDATE_HZ;
|
||||||
|
var lastInterval = Date.now();
|
||||||
|
var currentDomain = "no domain";
|
||||||
|
var timer = null;
|
||||||
|
var target = 0;
|
||||||
|
|
||||||
|
var connectionToDomainFailed = false;
|
||||||
|
|
||||||
|
|
||||||
|
function getAnchorLocalYOffset() {
|
||||||
|
var loadingSpherePosition = Overlays.getProperty(loadingSphereID, "position");
|
||||||
|
var loadingSphereOrientation = Overlays.getProperty(loadingSphereID, "rotation");
|
||||||
|
var overlayXform = new Xform(loadingSphereOrientation, loadingSpherePosition);
|
||||||
|
var worldToOverlayXform = overlayXform.inv();
|
||||||
|
var headPosition = MyAvatar.getHeadPosition();
|
||||||
|
var headPositionInOverlaySpace = worldToOverlayXform.xformPoint(headPosition);
|
||||||
|
return headPositionInOverlaySpace.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLeftMargin(overlayID, text) {
|
||||||
|
var textSize = Overlays.textSize(overlayID, text);
|
||||||
|
var sizeDifference = ((INNER_CIRCLE_WIDTH - textSize.width) / 2);
|
||||||
|
var leftMargin = -(MAX_LEFT_MARGIN - sizeDifference);
|
||||||
|
return leftMargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
function lerp(a, b, t) {
|
||||||
|
return ((1 - t) * a + t * b);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetValues() {
|
||||||
|
var properties = {
|
||||||
|
localPosition: { x: 1.85, y: -0.935, z: 0.0 },
|
||||||
|
dimensions: {
|
||||||
|
x: 0.1,
|
||||||
|
y: 2.8
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Overlays.editOverlay(loadingBarProgress, properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
function startInterstitialPage() {
|
||||||
|
if (timer === null) {
|
||||||
|
updateOverlays(false);
|
||||||
|
startAudio();
|
||||||
|
target = 0;
|
||||||
|
currentProgress = 0.1;
|
||||||
|
connectionToDomainFailed = false;
|
||||||
|
previousCameraMode = Camera.mode;
|
||||||
|
Camera.mode = "first person";
|
||||||
|
timer = Script.setTimeout(update, BASIC_TIMER_INTERVAL_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function startAudio() {
|
||||||
|
sample = Audio.playSound(tune, {
|
||||||
|
localOnly: true,
|
||||||
|
position: MyAvatar.getHeadPosition(),
|
||||||
|
volume: VOLUME
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function endAudio() {
|
||||||
|
sample.stop();
|
||||||
|
sample = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function domainChanged(domain) {
|
||||||
|
if (domain !== currentDomain) {
|
||||||
|
MyAvatar.restoreAnimation();
|
||||||
|
var name = location.placename;
|
||||||
|
domainName = name.charAt(0).toUpperCase() + name.slice(1);
|
||||||
|
var doRequest = true;
|
||||||
|
if (name.length === 0 && location.href === "file:///~/serverless/tutorial.json") {
|
||||||
|
domainName = "Serveless Domain (Tutorial)";
|
||||||
|
doRequest = false;
|
||||||
|
}
|
||||||
|
var domainNameLeftMargin = getLeftMargin(domainNameTextID, domainName);
|
||||||
|
var textProperties = {
|
||||||
|
text: domainName,
|
||||||
|
leftMargin: domainNameLeftMargin
|
||||||
|
};
|
||||||
|
|
||||||
|
if (doRequest) {
|
||||||
|
var url = Account.metaverseServerURL + '/api/v1/places/' + domain;
|
||||||
|
request({
|
||||||
|
uri: url
|
||||||
|
}, function(error, data) {
|
||||||
|
if (data.status === "success") {
|
||||||
|
var domainInfo = data.data;
|
||||||
|
var domainDescriptionText = domainInfo.place.description;
|
||||||
|
var leftMargin = getLeftMargin(domainDescription, domainDescriptionText);
|
||||||
|
var domainDescriptionProperties = {
|
||||||
|
text: domainDescriptionText,
|
||||||
|
leftMargin: leftMargin
|
||||||
|
};
|
||||||
|
Overlays.editOverlay(domainDescription, domainDescriptionProperties);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var domainDescriptionProperties = {
|
||||||
|
text: ""
|
||||||
|
};
|
||||||
|
Overlays.editOverlay(domainDescription, domainDescriptionProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
var randomIndex = Math.floor(Math.random() * userTips.length);
|
||||||
|
var tip = userTips[randomIndex];
|
||||||
|
var tipLeftMargin = getLeftMargin(domainToolTip, tip);
|
||||||
|
var toolTipProperties = {
|
||||||
|
text: tip,
|
||||||
|
leftMargin: tipLeftMargin
|
||||||
|
};
|
||||||
|
|
||||||
|
Overlays.editOverlay(domainNameTextID, textProperties);
|
||||||
|
Overlays.editOverlay(domainToolTip, toolTipProperties);
|
||||||
|
|
||||||
|
|
||||||
|
startInterstitialPage();
|
||||||
|
currentDomain = domain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var THE_PLACE = (HifiAbout.buildVersion === "dev") ? "hifi://TheSpot-dev": "hifi://TheSpot";
|
||||||
|
function clickedOnOverlay(overlayID, event) {
|
||||||
|
if (loadingToTheSpotID === overlayID) {
|
||||||
|
location.handleLookupString(THE_PLACE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentProgress = 0.1;
|
||||||
|
|
||||||
|
function updateOverlays(physicsEnabled) {
|
||||||
|
var properties = {
|
||||||
|
visible: !physicsEnabled
|
||||||
|
};
|
||||||
|
|
||||||
|
var mainSphereProperties = {
|
||||||
|
visible: !physicsEnabled
|
||||||
|
};
|
||||||
|
|
||||||
|
var domainTextProperties = {
|
||||||
|
text: domainText,
|
||||||
|
visible: !physicsEnabled
|
||||||
|
};
|
||||||
|
|
||||||
|
var loadingBarProperties = {
|
||||||
|
dimensions: { x: 0.0, y: 2.8 },
|
||||||
|
visible: !physicsEnabled
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!HMD.active) {
|
||||||
|
MyAvatar.headOrientation = Quat.multiply(Quat.cancelOutRollAndPitch(MyAvatar.headOrientation), Quat.fromPitchYawRollDegrees(-3.0, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
renderViewTask.getConfig("LightingModel")["enableAmbientLight"] = physicsEnabled;
|
||||||
|
renderViewTask.getConfig("LightingModel")["enableDirectionalLight"] = physicsEnabled;
|
||||||
|
renderViewTask.getConfig("LightingModel")["enablePointLight"] = physicsEnabled;
|
||||||
|
Overlays.editOverlay(loadingSphereID, mainSphereProperties);
|
||||||
|
Overlays.editOverlay(loadingToTheSpotID, properties);
|
||||||
|
Overlays.editOverlay(domainNameTextID, properties);
|
||||||
|
Overlays.editOverlay(domainDescription, domainTextProperties);
|
||||||
|
Overlays.editOverlay(domainToolTip, properties);
|
||||||
|
Overlays.editOverlay(loadingBarPlacard, properties);
|
||||||
|
Overlays.editOverlay(loadingBarProgress, loadingBarProperties);
|
||||||
|
|
||||||
|
|
||||||
|
Menu.setIsOptionChecked("Show Overlays", physicsEnabled);
|
||||||
|
if (!HMD.active) {
|
||||||
|
toolbar.writeProperty("visible", physicsEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
resetValues();
|
||||||
|
|
||||||
|
if (physicsEnabled) {
|
||||||
|
Camera.mode = previousCameraMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function scaleInterstitialPage(sensorToWorldScale) {
|
||||||
|
var yOffset = getAnchorLocalYOffset();
|
||||||
|
var localPosition = {
|
||||||
|
x: 0.0,
|
||||||
|
y: yOffset,
|
||||||
|
z: 5.45
|
||||||
|
};
|
||||||
|
|
||||||
|
Overlays.editOverlay(anchorOverlay, { localPosition: localPosition });
|
||||||
|
}
|
||||||
|
|
||||||
|
function update() {
|
||||||
|
var physicsEnabled = Window.isPhysicsEnabled();
|
||||||
|
var thisInterval = Date.now();
|
||||||
|
var deltaTime = (thisInterval - lastInterval);
|
||||||
|
lastInterval = thisInterval;
|
||||||
|
|
||||||
|
var domainLoadingProgressPercentage = Window.domainLoadingProgress();
|
||||||
|
|
||||||
|
var progress = MIN_LOADING_PROGRESS * domainLoadingProgressPercentage;
|
||||||
|
if (progress >= target) {
|
||||||
|
target = progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((physicsEnabled && (currentProgress < TOTAL_LOADING_PROGRESS))) {
|
||||||
|
target = TOTAL_LOADING_PROGRESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentProgress = lerp(currentProgress, target, 0.2);
|
||||||
|
var properties = {
|
||||||
|
localPosition: { x: (1.85 - (currentProgress / 2) - (-0.029 * (currentProgress / TOTAL_LOADING_PROGRESS))), y: -0.935, z: 0.0 },
|
||||||
|
dimensions: {
|
||||||
|
x: currentProgress,
|
||||||
|
y: 2.8
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Overlays.editOverlay(loadingBarProgress, properties);
|
||||||
|
if ((physicsEnabled && (currentProgress >= (TOTAL_LOADING_PROGRESS - EPSILON)))) {
|
||||||
|
updateOverlays((physicsEnabled || connectionToDomainFailed));
|
||||||
|
endAudio();
|
||||||
|
currentDomain = "no domain";
|
||||||
|
timer = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer = Script.setTimeout(update, BASIC_TIMER_INTERVAL_MS);
|
||||||
|
}
|
||||||
|
var whiteColor = {red: 255, green: 255, blue: 255};
|
||||||
|
var greyColor = {red: 125, green: 125, blue: 125};
|
||||||
|
Overlays.mouseReleaseOnOverlay.connect(clickedOnOverlay);
|
||||||
|
Overlays.hoverEnterOverlay.connect(function(overlayID, event) {
|
||||||
|
if (overlayID === loadingToTheSpotID) {
|
||||||
|
Overlays.editOverlay(loadingToTheSpotID, { color: greyColor});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Overlays.hoverLeaveOverlay.connect(function(overlayID, event) {
|
||||||
|
if (overlayID === loadingToTheSpotID) {
|
||||||
|
Overlays.editOverlay(loadingToTheSpotID, { color: whiteColor});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
location.hostChanged.connect(domainChanged);
|
||||||
|
location.lookupResultsFinished.connect(function() {
|
||||||
|
Script.setTimeout(function() {
|
||||||
|
connectionToDomainFailed = !location.isConnected;
|
||||||
|
}, 1200);
|
||||||
|
});
|
||||||
|
|
||||||
|
MyAvatar.sensorToWorldScaleChanged.connect(scaleInterstitialPage);
|
||||||
|
MyAvatar.sessionUUIDChanged.connect(function() {
|
||||||
|
var avatarSessionUUID = MyAvatar.sessionUUID;
|
||||||
|
Overlays.editOverlay(loadingSphereID, { parentID: avatarSessionUUID });
|
||||||
|
});
|
||||||
|
|
||||||
|
var toggle = true;
|
||||||
|
if (DEBUG) {
|
||||||
|
tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
||||||
|
button = tablet.addButton(BUTTON_PROPERTIES);
|
||||||
|
|
||||||
|
button.clicked.connect(function() {
|
||||||
|
toggle = !toggle;
|
||||||
|
updateOverlays(toggle);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanup() {
|
||||||
|
Overlays.deleteOverlay(loadingSphereID);
|
||||||
|
Overlays.deleteOverlay(loadingToTheSpotID);
|
||||||
|
Overlays.deleteOverlay(domainNameTextID);
|
||||||
|
Overlays.deleteOverlay(domainDescription);
|
||||||
|
Overlays.deleteOverlay(domainToolTip);
|
||||||
|
Overlays.deleteOverlay(loadingBarPlacard);
|
||||||
|
Overlays.deleteOverlay(loadingBarProgress);
|
||||||
|
Overlays.deleteOverlay(anchorOverlay);
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
tablet.removeButton(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderViewTask.getConfig("LightingModel")["enableAmbientLight"] = true;
|
||||||
|
renderViewTask.getConfig("LightingModel")["enableDirectionalLight"] = true;
|
||||||
|
renderViewTask.getConfig("LightingModel")["enablePointLight"] = true;
|
||||||
|
Menu.setIsOptionChecked("Show Overlays", true);
|
||||||
|
if (!HMD.active) {
|
||||||
|
toolbar.writeProperty("visible", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Script.scriptEnding.connect(cleanup);
|
||||||
|
}());
|
Loading…
Reference in a new issue