mirror of
https://github.com/lubosz/overte.git
synced 2025-04-27 05:15:34 +02:00
Merge branch 'mm_c8bef86' into android_places_goto
This commit is contained in:
commit
77caa4d402
119 changed files with 3930 additions and 1863 deletions
assignment-client/src/assets
interface
resources
fonts
qml
controls-uit
hifi/commerce
styles-uit
windows
src
libraries
avatars-renderer/src/avatars-renderer
avatars/src
display-plugins/src/display-plugins
entities-renderer/src
entities/src
EntityItemProperties.cppEntityScriptingInterface.cppEntityScriptingInterface.hEntityTree.cppEntityTree.h
graphics/src/graphics
networking/src
procedural/src/procedural
render-utils/src
DefaultMaterials.slhDeferredBufferWrite.slhDeferredGlobalLight.slhDrawHaze.cppForwardGlobalLight.slhGeometryCache.cppGeometryCache.hHaze.slfHaze.slhLightAmbient.slhLightingModel.slhMaterialTextures.slhShadows_shared.slhSubsurfaceScattering.cppSurfaceGeometryPass.cppSurfaceGeometryPass.hToneMappingEffect.cppToneMappingEffect.hforward_model_normal_map.slfforward_simple.slfforward_simple_textured.slfforward_simple_textured_transparent.slfforward_simple_textured_unlit.slfforward_simple_transparent.slfmodel_fade.slfmodel_fade.slvmodel_normal_map.slfmodel_normal_map.slvmodel_normal_map_fade.slfmodel_normal_map_fade.slvmodel_translucent.slfmodel_translucent.slvmodel_translucent_fade.slfmodel_translucent_normal_map.slfmodel_translucent_normal_map.slvmodel_translucent_normal_map_fade.slfmodel_translucent_unlit_fade.slfmodel_unlit_fade.slfsimple.slfsimple.slvsimple_fade.slfsimple_fade.slvsimple_textured.slfsimple_textured_fade.slfsimple_transparent.slf
|
@ -61,13 +61,13 @@ static const ScriptBakeVersion CURRENT_SCRIPT_BAKE_VERSION = (ScriptBakeVersion)
|
|||
BakedAssetType assetTypeForExtension(const QString& extension) {
|
||||
auto extensionLower = extension.toLower();
|
||||
if (BAKEABLE_MODEL_EXTENSIONS.contains(extensionLower)) {
|
||||
return Model;
|
||||
return BakedAssetType::Model;
|
||||
} else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(extensionLower.toLocal8Bit())) {
|
||||
return Texture;
|
||||
return BakedAssetType::Texture;
|
||||
} else if (BAKEABLE_SCRIPT_EXTENSIONS.contains(extensionLower)) {
|
||||
return Script;
|
||||
return BakedAssetType::Script;
|
||||
}
|
||||
return Undefined;
|
||||
return BakedAssetType::Undefined;
|
||||
}
|
||||
|
||||
BakedAssetType assetTypeForFilename(const QString& filename) {
|
||||
|
@ -82,11 +82,11 @@ BakedAssetType assetTypeForFilename(const QString& filename) {
|
|||
|
||||
QString bakedFilenameForAssetType(BakedAssetType type) {
|
||||
switch (type) {
|
||||
case Model:
|
||||
case BakedAssetType::Model:
|
||||
return BAKED_MODEL_SIMPLE_NAME;
|
||||
case Texture:
|
||||
case BakedAssetType::Texture:
|
||||
return BAKED_TEXTURE_SIMPLE_NAME;
|
||||
case Script:
|
||||
case BakedAssetType::Script:
|
||||
return BAKED_SCRIPT_SIMPLE_NAME;
|
||||
default:
|
||||
return "";
|
||||
|
@ -95,11 +95,11 @@ QString bakedFilenameForAssetType(BakedAssetType type) {
|
|||
|
||||
BakeVersion currentBakeVersionForAssetType(BakedAssetType type) {
|
||||
switch (type) {
|
||||
case Model:
|
||||
case BakedAssetType::Model:
|
||||
return (BakeVersion)CURRENT_MODEL_BAKE_VERSION;
|
||||
case Texture:
|
||||
case BakedAssetType::Texture:
|
||||
return (BakeVersion)CURRENT_TEXTURE_BAKE_VERSION;
|
||||
case Script:
|
||||
case BakedAssetType::Script:
|
||||
return (BakeVersion)CURRENT_SCRIPT_BAKE_VERSION;
|
||||
default:
|
||||
return 0;
|
||||
|
@ -222,7 +222,7 @@ bool AssetServer::needsToBeBaked(const AssetUtils::AssetPath& path, const AssetU
|
|||
|
||||
BakedAssetType type = assetTypeForFilename(path);
|
||||
|
||||
if (type == Undefined) {
|
||||
if (type == BakedAssetType::Undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -241,7 +241,7 @@ bool AssetServer::needsToBeBaked(const AssetUtils::AssetPath& path, const AssetU
|
|||
AssetMeta meta;
|
||||
std::tie(loaded, meta) = readMetaFile(assetHash);
|
||||
|
||||
if (type == Texture && !loaded) {
|
||||
if (type == BakedAssetType::Texture && !loaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1546,7 +1546,7 @@ bool AssetServer::setBakingEnabled(const AssetUtils::AssetPathList& paths, bool
|
|||
auto it = _fileMappings.find(path);
|
||||
if (it != _fileMappings.end()) {
|
||||
auto type = assetTypeForFilename(path);
|
||||
if (type == Undefined) {
|
||||
if (type == BakedAssetType::Undefined) {
|
||||
continue;
|
||||
}
|
||||
QString bakedFilename = bakedFilenameForAssetType(type);
|
||||
|
|
|
@ -27,7 +27,7 @@ using BakeVersion = int;
|
|||
static const BakeVersion INITIAL_BAKE_VERSION = 0;
|
||||
static const BakeVersion NEEDS_BAKING_BAKE_VERSION = -1;
|
||||
|
||||
enum BakedAssetType : int {
|
||||
enum class BakedAssetType : int {
|
||||
Model = 0,
|
||||
Texture,
|
||||
Script,
|
||||
|
|
Binary file not shown.
|
@ -25,7 +25,6 @@
|
|||
<glyph glyph-name="web" unicode="q" d="M438 390c0 8-6 15-14 15l-333 0c-8 0-15-7-15-15l0-298c0-8 7-14 15-14l333 0c8 0 14 6 14 14z m-219-8l172 0c8 0 15-7 15-16 0-9-7-16-15-16l-172 0c-8 0-15 7-15 16 0 9 7 16 15 16z m-47 1c9 0 16-7 16-16 0-10-7-17-16-17-10 0-17 7-17 17 0 9 7 16 17 16z m-51 0c9 0 17-7 17-16 0-10-8-17-17-17-9 0-17 7-17 17 0 9 8 16 17 16z m291-276l-308 0 0 219 308 0z m-250 84l-15 0-20 60 13 0 14-45 15 45 13 0 15-45 14 45 13 0-20-60-14 0-14 41z m137 25l-46 0c0-5 2-8 6-11 3-2 8-4 12-4 8 0 13 3 17 7l7-8c-6-6-14-9-25-9-8 0-15 2-21 8-6 5-9 13-9 22 0 9 3 17 9 22 6 6 13 9 21 9 8 0 15-3 21-8 6-5 8-11 8-20z m-46 9l34 0c0 5-2 9-5 12-3 3-7 4-11 4-5 0-9-1-13-4-3-3-5-7-5-12z m101 27c8 0 14-3 20-9 6-5 9-12 9-22 0-9-3-16-9-22-5-6-12-8-19-8-8 0-15 3-21 9l0-9-12 0 0 83 12 0 0-34c5 8 12 12 20 12z m-20-31c0-6 2-10 5-14 4-4 8-5 13-5 5 0 9 1 13 5 3 4 5 8 5 14 0 6-2 10-5 14-4 4-8 6-13 6-5 0-9-2-13-6-3-4-5-8-5-14z"/>
|
||||
<glyph glyph-name="web-2" unicode="r" d="M438 390c0 8-6 15-14 15l-333 0c-8 0-15-7-15-15l0-298c0-8 7-14 15-14l333 0c8 0 14 6 14 14z m-219-8l172 0c8 0 15-7 15-16 0-9-7-16-15-16l-172 0c-8 0-15 7-15 16 0 9 7 16 15 16z m-47 1c9 0 16-7 16-16 0-10-7-17-16-17-10 0-17 7-17 17 0 9 7 16 17 16z m-51 0c9 0 17-7 17-16 0-10-8-17-17-17-9 0-17 7-17 17 0 9 8 16 17 16z m291-276l-308 0 0 219 308 0z"/>
|
||||
<glyph glyph-name="edit" unicode="s" d="M196 214c-27-27-54-54-81-81-6 6-13 13-19 19 27 27 54 54 81 81l-22 21c-31-31-61-62-92-92-7-7-11-13-12-22-3-25-7-50-11-76 3 0 4 0 6 0 24 5 48 10 72 15 5 1 10 4 13 7 32 32 64 64 96 96z m126 207c10 10 21 21 33 32 4 4 10 4 14 0 19-19 38-38 57-57 4-5 4-10 0-15-11-11-22-22-34-33-23 24-46 48-70 73z m23-181c-5-1-8 0-11 3-8 8-15 15-23 23 18 18 37 37 55 55 2 2 4 4 4 4-24 25-47 49-71 74-2-2-3-4-5-6-18-18-37-37-55-55-34 34-67 67-101 101-2 2-5 5-8 7-18 14-42 12-57-5-15-17-14-42 2-58 50-51 101-101 151-151 17-16 33-33 50-49 2-3 3-5 2-8-2-8-4-15-4-23-4-48 27-90 73-102 20-5 39-4 58 4-1 2-3 3-5 4-14 14-28 28-42 42-10 11-11 26-2 36 8 8 16 16 24 24 11 10 24 10 35 0 2-1 4-4 6-6 15-14 29-28 43-42 0 0 1 0 2 1 1 8 3 16 4 24 7 69-59 123-125 103z m-243 162c-7 0-14 6-14 14 0 8 6 14 14 14 8 0 15-6 15-14 0-7-7-14-15-14z m198-46c6-6 13-12 19-19-13-13-26-26-39-39-7 6-13 12-20 19 14 13 27 26 40 39z"/>
|
||||
<glyph glyph-name="market" unicode="t" d="M88 370c3 0 7 0 10 0 6 0 11-1 15-2 9-2 16-8 20-16 3-5 4-10 6-15 2-6 3-13 5-19 3-10 5-19 8-27 2-6 3-13 5-19 3-7 5-15 7-23 3-9 6-19 9-30 0-2 1-4 1-6 2-8 5-17 9-24 3-7 8-12 13-15 6-3 13-5 22-6 2 0 5 0 7 0l21 0 57 0c25 0 50 0 75 0 12 0 25 0 37 0 1 0 1 0 2 0 6 0 13 0 17 2 5 3 7 9 9 16l3 10c0 0 0 0 0 0 0 2 1 3 1 3 5 20 11 40 17 60 1 4 2 9 4 13 2 8 4 16 7 24 2 7 4 16 0 22-3 4-9 5-14 5-6 0-188-2-284-4l-4 0-5 22c0 3-1 6-2 9 0 3-1 5-1 7-1 2-1 3-1 4-1 4-2 7-3 11-2 6-6 12-11 17-5 5-11 8-17 9-3 1-6 1-10 1-5 1-9 1-14 1-19 0-38 0-59 0-1 0-3 0-4 0-3 0-7 0-10-1-3 0-6-2-8-4-3-5-4-11-2-17 2-5 6-6 9-7 4-1 8-1 13-1 5 0 10 0 16 0l16 0c3 0 5 0 8 0z m353-78l-26-92-6-4-2 0c-2 0-21 0-55 0-50 0-118-1-125-1l-1-1 0 0c-6 0-12 2-16 6-4 4-6 10-8 16-3 12-6 25-10 39-1 4-2 8-3 12-2 4-3 8-4 13l-4 12z m-194-164c-9 0-15-2-20-7-5-5-8-11-8-20 0-8 3-16 8-21 5-5 13-8 20-8 17 0 30 12 30 28 0 8-3 15-9 20-5 6-12 8-21 8z m139 0c-9 0-16-2-21-6-5-6-8-13-8-21 0-9 3-16 8-21 5-6 12-8 21-8 16 0 29 13 29 29 0 8-3 14-8 20-5 5-13 7-21 7z"/>
|
||||
<glyph glyph-name="directory" unicode="u" d="M432 451l-99-38c-2 0-3-1-4-1-3 1-5 2-8 2l-116 38c-8 3-15 6-30-1l-91-35c-17-5-32-16-32-31l0-303c0-15 14-27 32-27l99 38c3 1 6 2 9 4 1-1 3-2 4-2 3-1 5-2 7-3 0 0 1 0 1-1 0 0 1 0 1 0l116-38 0 0c8-1 12-1 21 3l90 34c13 6 32 16 32 31l0 304c0 14-14 26-32 26z m-351-371c-1 0-1 1-1 2l0 303c0 2 5 6 14 9l1 0 1 1 89 34c1-1 0-1 0-2l0-303c0-1-3-4-16-10z m356 42c-1-2-5-5-17-11l-90-34c0 1-1 1-1 2l0 304c0 1 5 5 14 8l1 0 1 1 91 34c0 0 1-1 1-1z"/>
|
||||
<glyph glyph-name="menu" unicode="v" d="M257 22c-60 0-119 22-164 67-44 44-68 102-68 164 0 62 24 120 68 163 90 91 237 91 327 0 44-43 68-101 68-163 0-62-24-120-68-164-45-45-104-67-163-67z m0 431c-52 0-103-20-142-59-38-38-58-88-58-141 0-54 20-104 58-142 78-78 205-78 283 0 38 38 59 88 59 142 0 53-21 103-59 141-39 39-90 59-141 59z m101-133l-203 0c-8 0-15 7-15 15 0 8 7 15 15 15l203 0c8 0 14-7 14-15 0-8-6-15-14-15z m0-84l-203 0c-8 0-15 7-15 15 0 8 7 15 15 15l203 0c8 0 14-7 14-15 0-8-6-15-14-15z m0-81l-203 0c-8 0-15 7-15 15 0 8 7 14 15 14l203 0c8 0 14-6 14-14 0-8-6-15-14-15z"/>
|
||||
<glyph glyph-name="close" unicode="w" d="M258 19c-59 0-118 23-163 68-44 43-68 101-68 163 0 62 24 120 68 164 90 90 237 90 327 0 44-44 68-102 68-164 0-62-24-120-68-163-45-45-104-68-164-68z m0 431c-51 0-102-19-141-58-38-38-59-88-59-142 0-53 21-103 59-141 78-78 205-78 283 0 38 38 58 88 58 141 0 54-20 104-58 142-39 39-90 58-142 58z m25-200l67 67c7 7 7 18 0 25-7 7-18 7-25 0l-67-67-66 67c-7 7-18 7-25 0-7-7-7-18 0-25l66-67-66-66c-7-7-7-18 0-25 7-7 18-7 25 0l66 66 67-66c7-7 18-7 25 0 7 7 7 18 0 25z"/>
|
||||
|
@ -145,4 +144,14 @@
|
|||
<glyph glyph-name="rez" unicode="" d="M373 321c-2 5-6 8-11 8l-49 8 55 61c4 4 5 9 3 14-2 5-7 8-12 8 0 0 0 0 0 0l-114-1c-5-1-10-4-12-9l-54-136c-1-4-1-8 1-11 2-4 6-6 9-7l38-5-54-136c-2-6 0-13 6-16 2-1 4-2 7-2 3 0 7 2 10 5l175 206c3 4 3 9 2 13z"/>
|
||||
<glyph glyph-name="keyboard-collapse" unicode="" d="M373 249l-26 0 0 25 26 0z m-35 0l-27 0 0 25 27 0z m-36 0l-27 0 0 25 27 0z m-36 0l-26 0 0 25 26 0z m-35 0l-27 0 0 25 27 0z m-36 0l-27 0 0 25 27 0z m-36 0l-26 0 0 25 26 0z m224-1l18 0c7 0 13 6 13 13 0 7-6 13-13 13l-18 0m-262 0l-17 0c-7 0-13-6-13-13 0-7 6-13 13-13l17 0m252 39l-31 0 0 25 31 0z m-42 0l-31 0 0 25 31 0z m-41 0l-32 0 0 25 32 0z m-42 0l-32 0 0 25 32 0z m-42 0l-32 0 0 25 32 0z m-41 0l-32 0 0 25 32 0z m218-1l18 0c7 0 13 6 13 13 0 8-6 14-13 14l-18 0m-262 0l-17 0c-7 0-13-6-13-14 0-7 6-13 13-13l17 0m288-124l-315 0c-33 0-59 28-59 61l0 76c0 34 26 61 59 61l315 0c33 0 59-27 59-61l0-76c1-33-26-61-59-61z m-315 172c-18 0-33-16-33-34l0-77c0-19 15-34 33-34l315 0c18 0 33 15 33 34l0 77c0 19-15 34-33 34z m248-99l32 0 0-25-32 0z m-41 0l31 0 0-25-31 0z m-42 0l31 0 0-25-31 0z m-43 0l32 0 0-25-32 0z m-42 0l32 0 0-25-32 0z m-41 0l31 0 0-25-31 0z m250-26l18 0c7 0 13 6 13 14 0 7-6 13-13 13l-18 0m-262 0l-17 0c-7 0-13-6-13-13 0-8 6-13 13-13l17 0m81-82l50-50 53 54-107 0"/>
|
||||
<glyph glyph-name="image" unicode="" d="M257 428c52 0 104 0 156 0 24 0 37-13 37-37 1-90 1-179 0-269 0-25-13-38-39-38-103 0-207 0-311 0-26 0-39 13-39 40 0 88 0 176 0 263 0 28 13 41 41 41 51 0 103 0 155 0z m167-263c0 7 0 10 0 14 0 69 0 138 0 206 0 17 0 17-17 17-101 0-202 0-303 0-16 0-17-1-17-17 0-58 0-115 0-173 0-3 0-7 0-12 8 3 14 6 19 9 17 8 30 7 44-6 5-5 10-10 15-15 5-7 11-8 19-4 40 21 81 41 121 61 19 10 31 8 46-7 9-9 18-18 27-27 15-15 29-29 46-46z m-328-54c7 0 11-1 15-1 98 0 197 0 296 0 6 0 14 2 16 6 5 7 0 14-6 20-27 26-54 53-80 80-8 9-15 9-26 4-67-35-135-68-203-102-3-2-6-4-12-7z m-8 26c21 10 40 20 63 31-8 7-14 12-20 17-2 2-7 3-10 3-30-9-36-17-34-48 0 0 0-1 1-3z m134 169c1-25-21-46-46-46-25-1-46 20-47 46 0 25 21 46 47 47 25 0 46-21 46-47z m-46 22c-12 0-22-9-22-21 0-13 9-22 21-23 13 0 23 9 23 22 0 13-10 22-22 22z"/>
|
||||
<glyph glyph-name="environments" unicode="" d="M256 454c-110 0-199-89-199-199 0-110 89-199 199-199 0 0 0 0 0 0l2-1 0 1c109 1 197 90 197 199 0 110-89 199-199 199z m114-204l0 0 0 5c0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 2l0 4 0 0c-1 22-4 43-10 63 21 5 36 11 46 15 15-26 24-56 24-87 0-30-8-59-23-85-8 4-23 11-47 16 6 21 9 42 10 64z m-19 102c-13 30-30 53-46 69 34-10 64-30 86-57-9-4-22-8-40-12z m-6-95c0-23-4-45-11-66-20 4-42 6-65 6l0 120c23 1 45 3 66 6 6-21 10-43 10-66z m-46-170c17 17 37 41 52 75 20-5 34-10 42-13-24-31-57-53-94-62z m-30 256l0 77c17-14 40-37 56-73-17-2-36-4-56-4z m0-248l0 77c20-1 39-3 56-5-16-35-40-59-56-72z m-83 252c17 35 40 59 56 73l0-77c-19 0-38 1-56 4z m-19-90c0 23 4 45 10 65 20-3 42-5 65-5l0-120c-23 0-45-1-65-4-6 20-10 42-10 64z m-47 106c22 28 52 48 86 58-15-16-33-39-46-70-18 4-31 8-40 12z m40-199c15-36 37-61 53-77-38 10-72 32-96 64 9 4 24 9 43 13z m82 8l0-77c-16 13-39 37-56 73 18 2 37 3 56 4z m-100 92l-1 0 0-4c0-1 0-1 0-2 0 0 0 0 0-1 0 0 0 0 0-1 0 0 0-1 0-1l0-5 1 0c0-21 4-42 10-62-23-5-39-10-49-15-14 25-21 53-21 82 0 30 8 60 23 86 10-4 25-10 47-14-6-20-10-41-10-63z"/>
|
||||
<glyph glyph-name="wand" unicode="" d="M438 107l-80 78c-5 5-12 7-18 6l-77 78c-5 5-14 5-19 0-5-5-6-14 0-19l77-79c0-6 2-12 7-17l80-78c5-4 10-6 15-6 6 0 12 2 16 6 8 9 8 22-1 31z m-185 209l-28 0 0 27c0 6-5 11-12 11-6 0-11-5-11-11l0-27-27 0c-6 0-11-5-11-12 0-6 5-11 11-11l27 0 0-28c0-6 5-11 11-11 7 0 12 5 12 11l0 28 28 0c6 0 11 5 11 11 0 7-5 12-11 12z m51-22c-6 0-10 4-10 10 0 5 4 10 10 10 15 0 31 0 45 0 6 0 10-5 10-10 0-6-4-10-10-10-14 0-30 0-45 0 0 0 0 0 0 0z m-184 0c0 0 0 0 0 0-12 0-26 0-40 0 0 0 0 0 0 0-5 0-10 4-10 10 0 5 5 10 10 10 14 0 28 0 41 0 5 0 10-5 10-10-1-6-5-10-11-10z m94-129c-5 0-10 4-10 9 0 14 0 26 0 40 0 5 5 9 10 9 0 0 0 0 0 0 6 0 10-5 10-10 0-13 0-25 0-38 0-6-4-10-10-10 0 0 0 0 0 0z m0 223c-5 0-10 4-10 9 0 14 0 26 0 40 0 5 5 9 10 9 6 0 10-5 10-10 0-13 0-25 0-38 0-6-4-10-10-10 0 0 0 0 0 0z m-68-26c-2 0-4 0-6 2-6 5-11 10-16 15-4 5-8 9-12 13-4 4-5 10-1 14 4 4 10 4 14 1 5-5 9-9 14-14 4-5 9-10 14-14 4-4 4-10 1-14-2-2-5-3-8-3z m-24-159c-3 0-5 1-7 3-4 3-4 10-1 14 5 5 9 10 14 14 5 4 9 8 12 12 4 4 10 5 14 1 4-4 5-10 1-14-4-5-9-10-13-14-5-4-9-8-13-12-2-2-4-4-7-4z m157 157c-3 0-5 1-6 2-5 3-6 10-2 14 4 6 10 11 15 16 5 4 10 8 13 12 3 5 10 6 14 2 4-3 5-9 2-14-5-6-10-10-15-15-5-4-10-8-13-13-2-2-5-4-8-4z"/>
|
||||
<glyph glyph-name="market" unicode="t" d="M428 332c-2 4-7 7-12 7-5 1-10 1-14 1-5 0-10 1-15 1-27 1-51 2-75 3-23 1-47 2-74 3-10 0-18 1-27 1-9 0-18 1-27 1l-1 0 0 1c-2 8-8 26-12 39-2 5-3 9-4 12-2 8-7 12-16 12l-48 0c-9 0-16-6-16-15 0-8 7-14 16-14l32 0c5 0 7-3 8-7l0 0c6-25 13-51 19-76 7-24 13-50 19-75 2-9 3-16 0-24-1-4-2-9-3-14-1-4-2-9-3-14-2-8-2-14 1-17 3-4 8-6 16-6l190 0c4 1 7 3 9 6 3 3 4 8 3 12-1 8-7 12-17 12l-170 0 1 1c0 1 1 4 1 6 2 7 5 17 4 20l0 1c1 6 5 10 12 10 8 0 16 0 24 0 43 2 87 3 128 5 8 1 12 4 15 10 8 15 29 65 36 86l0 0c3 4 3 8 0 12z m-45-224c0-16-13-30-29-30-16 0-29 13-29 30 0 15 13 30 29 30 16-1 29-15 29-30z m-177 1c0-16-14-29-29-29-16 0-29 14-29 29 0 17 13 30 29 30 16-1 29-14 29-30z"/>
|
||||
<glyph glyph-name="wear" unicode="" d="M451 180c3 1 5 4 6 7 1 3 1 7-1 10-2 3-4 5-8 6-3 1-6 1-10-1-6-4-13-5-19-6-3-1-6-1-7-1-1 0-1 0-1 0l-1 0-26 0 0 66c0 9-3 43-27 73-24 29-58 44-101 44-54 0-84-24-100-44-24-30-26-64-27-73l0-66-17 0c-2 0-4 0-8 1-8 1-17 3-27 7-7 3-14-1-17-7-2-7 1-14 8-17 14-6 27-8 33-9 3 0 6 0 8-1 1 0 1 0 2 0l299 0c1 0 2 0 3 0l0 0c2 1 6 1 10 2 6 1 18 3 28 9z m-295 80c0 15 6 39 20 58 18 22 45 34 80 34 35 0 62-12 80-34 15-19 21-43 22-58l0-6-202 0z m202-65l-202 0 0 33 202 0z"/>
|
||||
<glyph glyph-name="certificate" unicode="" d="M168 320l172 0c7 0 14 6 14 14 0 7-7 13-14 13l-172 0c-8 0-14-6-14-13 0-8 6-14 14-14z m0-55l63 0c7 0 13 6 13 13 0 8-6 13-13 13l-63 0c-8 0-14-5-14-13 0-7 6-13 14-13z m0-57l46 0c8 0 14 6 14 14 0 7-6 14-14 14l-46 0c-8 0-14-7-14-14 0-8 6-14 14-14z m-65 210l0-283 139 0c7 0 12 6 12 13 0 6-5 12-12 12l-114 0 0 233 256 0 0-83c0-7 6-12 13-12 6 0 12 5 12 12l0 108z m304-200c0 43-35 78-78 78-43 0-78-35-78-78 0-27 14-52 37-66l-3-69c0-5 2-9 6-11 5-3 10-2 13 1l27 20 26-21c2-2 5-3 8-3 2 0 4 0 5 1 4 2 7 7 7 12l-4 72c21 14 34 38 34 64z m-68-101c-4 4-10 4-14 1l-15-11 1 36c6-2 12-2 18-2 7 0 14 1 20 2l2-36z"/>
|
||||
<glyph glyph-name="gift" unicode="" d="M342 330c1 1 3 2 4 3 19 17 21 47 4 66-9 10-22 16-35 16-6 0-12-1-17-3-6 19-24 33-45 33-22 0-41-15-46-35-5 2-11 3-17 3-13 0-26-6-35-16-17-20-15-50 5-66 0 0 0 0 0-1l-82 0 0-84 27 0 0-166 298 0 0 166 27 0 0 84z m-45 50l0 1c1 1 2 2 4 3 5 5 10 6 14 6 6 0 12-3 16-8 4-4 6-9 5-15 0-6-3-11-7-15-2-2-3-3-4-3l0 0 0 0c-5-1-27-10-52-18 10 22 22 44 24 49z m-44 40c12 0 21-9 21-21 0-3 0-4 0-5l0 0 0 0c-2-5-11-24-21-48-10 23-19 42-21 47l0 1c0 1-1 3-1 5 0 12 10 21 22 21z m-79-40c4 5 10 8 16 8 4 0 9-1 14-5 2-2 3-3 4-4l0 0 0 0c2-5 11-23 22-47-24 7-44 13-49 15l-1 0c-1 1-2 2-4 3-9 8-10 21-2 30z m67-274l-110 0 0 140 110 0z m0 166l-137 0 0 32 137 0z m136-166l-111 0 0 140 111 0z m27 166l-138 0 0 32 138 0z"/>
|
||||
<glyph glyph-name="update" unicode="" d="M380 170c-7 0-13-6-13-13l0-12c0-5-4-9-9-9l-203 0c-5 0-9 4-9 9l0 114 33-27c6-4 14-4 19 2 4 5 4 13-2 18l-54 47c-3 2-5 3-8 3-4 0-7-1-9-3l-54-47c-6-5-6-13-1-18 4-6 13-6 18-1l32 26 0-114c0-19 16-35 35-35l203 0c19 0 35 16 35 35l0 12c0 7-6 13-13 13z m-248 153c7 0 13 5 13 13l0 12c0 5 4 8 9 8l203 0c5 0 9-4 9-8l0-115-33 27c-5 5-14 4-18-1-5-6-5-14 1-19l54-47c3-2 5-3 9-3 3 0 6 1 8 3l54 47c6 5 6 13 2 19-5 5-13 6-19 1l-32-27 0 115c0 19-16 34-35 34l-203 0c-19 0-35-15-35-34l0-12c0-8 6-13 13-13z"/>
|
||||
<glyph glyph-name="uninstall" unicode="" d="M83 227c-7 0-13-6-13-13l0-78c0-19 16-35 35-35l297 0c19 0 35 16 35 35l0 78c0 7-6 13-13 13-7 0-13-6-13-13l0-78c0-5-4-9-9-9l-297 0c-5 0-9 4-9 9l0 78c0 7-6 13-13 13z m191 47l50 50c5 5 5 14 0 19-5 5-13 5-19 0l-50-50-50 50c-5 5-13 5-19 0-5-5-5-14 0-19l50-50-50-50c-5-5-5-14 0-19 5-5 14-5 19 0l50 50 50-50c5-5 14-5 19 0 5 5 5 14 0 19z"/>
|
||||
<glyph glyph-name="install" unicode="" d="M83 227c-7 0-13-6-13-13l0-78c0-19 16-35 35-35l297 0c19 0 35 16 35 35l0 78c0 7-6 13-13 13-7 0-13-6-13-13l0-78c0-5-4-9-9-9l-297 0c-5 0-9 4-9 9l0 78c0 7-6 13-13 13z m170 171l0-155-33 27c-6 5-14 5-19-1-4-5-4-14 2-18l54-48c3-2 5-3 8-3 3 0 7 1 9 3l54 48c5 4 6 13 1 18-4 5-13 6-18 1l-32-27 0 154c0 8-6 13-13 13-7 0-13-5-13-12z"/>
|
||||
<glyph glyph-name="ellipsis-vertical" unicode="" d="M276 178c0-14-11-24-24-24-14 0-25 10-25 24 0 13 11 24 25 24 13 0 24-11 24-24z m0 78c0-14-11-24-24-24-14 0-25 10-25 24 0 13 11 24 25 24 13 0 24-11 24-24z m0 78c0-14-11-24-24-24-14 0-25 10-25 24 0 13 11 24 25 24 13 0 24-11 24-24z"/>
|
||||
</font></defs></svg>
|
Before (image error) Size: 78 KiB After (image error) Size: 83 KiB |
Binary file not shown.
Binary file not shown.
|
@ -12,7 +12,7 @@
|
|||
<body>
|
||||
<div class="container">
|
||||
<h1>HiFi Glyphs</h1>
|
||||
<p class="small">This font was created for use in<a href="http://highfidelity.io/">High Fidelity</a></p>
|
||||
<p class="small">This font was created for use in <a href="http://highfidelity.io/">High Fidelity</a></p>
|
||||
<h2>CSS mapping</h2>
|
||||
<ul class="glyphs css-mapping">
|
||||
<li>
|
||||
|
@ -87,10 +87,6 @@
|
|||
<div class="icon icon-edit"></div>
|
||||
<input type="text" readonly="readonly" value="edit">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-market"></div>
|
||||
<input type="text" readonly="readonly" value="market">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-directory"></div>
|
||||
<input type="text" readonly="readonly" value="directory">
|
||||
|
@ -567,6 +563,46 @@
|
|||
<div class="icon icon-image"></div>
|
||||
<input type="text" readonly="readonly" value="image">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-environments"></div>
|
||||
<input type="text" readonly="readonly" value="environments">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-wand"></div>
|
||||
<input type="text" readonly="readonly" value="wand">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-market"></div>
|
||||
<input type="text" readonly="readonly" value="market">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-wear"></div>
|
||||
<input type="text" readonly="readonly" value="wear">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-certificate"></div>
|
||||
<input type="text" readonly="readonly" value="certificate">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-gift"></div>
|
||||
<input type="text" readonly="readonly" value="gift">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-update"></div>
|
||||
<input type="text" readonly="readonly" value="update">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-uninstall"></div>
|
||||
<input type="text" readonly="readonly" value="uninstall">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-install"></div>
|
||||
<input type="text" readonly="readonly" value="install">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-ellipsis-vertical"></div>
|
||||
<input type="text" readonly="readonly" value="ellipsis-vertical">
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Character mapping</h2>
|
||||
<ul class="glyphs character-mapping">
|
||||
|
@ -642,10 +678,6 @@
|
|||
<div data-icon="s" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="s">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="t" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="t">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="u" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="u">
|
||||
|
@ -1122,6 +1154,46 @@
|
|||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe02a;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe02c;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe02d;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="t" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="t">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe02e;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe030;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe031;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe032;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe033;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe02f;">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&#xe034;">
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<script>(function() {
|
|
@ -92,9 +92,6 @@
|
|||
.icon-edit:before {
|
||||
content: "\73";
|
||||
}
|
||||
.icon-market:before {
|
||||
content: "\74";
|
||||
}
|
||||
.icon-directory:before {
|
||||
content: "\75";
|
||||
}
|
||||
|
@ -452,3 +449,33 @@
|
|||
.icon-image:before {
|
||||
content: "\e02a";
|
||||
}
|
||||
.icon-environments:before {
|
||||
content: "\e02c";
|
||||
}
|
||||
.icon-wand:before {
|
||||
content: "\e02d";
|
||||
}
|
||||
.icon-market:before {
|
||||
content: "\74";
|
||||
}
|
||||
.icon-wear:before {
|
||||
content: "\e02e";
|
||||
}
|
||||
.icon-certificate:before {
|
||||
content: "\e030";
|
||||
}
|
||||
.icon-gift:before {
|
||||
content: "\e031";
|
||||
}
|
||||
.icon-update:before {
|
||||
content: "\e032";
|
||||
}
|
||||
.icon-uninstall:before {
|
||||
content: "\e033";
|
||||
}
|
||||
.icon-install:before {
|
||||
content: "\e02f";
|
||||
}
|
||||
.icon-ellipsis-vertical:before {
|
||||
content: "\e034";
|
||||
}
|
Binary file not shown.
Binary file not shown.
|
@ -8,8 +8,9 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick 2.5
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
|
||||
import "../styles-uit"
|
||||
import "../controls-uit" as HifiControls
|
||||
|
@ -28,17 +29,11 @@ TextField {
|
|||
property int roundedBorderRadius: 4
|
||||
property bool error: false;
|
||||
property bool hasClearButton: false;
|
||||
property alias textColor: textField.color
|
||||
property string leftPermanentGlyph: "";
|
||||
property string centerPlaceholderGlyph: "";
|
||||
|
||||
placeholderText: textField.placeholderText
|
||||
|
||||
property bool rightAnchorSet: false;
|
||||
anchors.onRightChanged: {
|
||||
rightAnchorSet = true;
|
||||
}
|
||||
|
||||
font.family: "Fira Sans"
|
||||
font.pixelSize: hifi.fontSizes.textFieldInput
|
||||
height: implicitHeight + 3 // Make surrounding box higher so that highlight is vertically centered.
|
||||
|
@ -49,56 +44,42 @@ TextField {
|
|||
// workaround for https://bugreports.qt.io/browse/QTBUG-49297
|
||||
Keys.onPressed: {
|
||||
switch (event.key) {
|
||||
case Qt.Key_Return:
|
||||
case Qt.Key_Enter:
|
||||
event.accepted = true;
|
||||
case Qt.Key_Return:
|
||||
case Qt.Key_Enter:
|
||||
event.accepted = true;
|
||||
|
||||
// emit accepted signal manually
|
||||
if (acceptableInput) {
|
||||
accepted();
|
||||
}
|
||||
// emit accepted signal manually
|
||||
if (acceptableInput) {
|
||||
accepted();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: placeholder
|
||||
x: textField.leftPadding
|
||||
y: textField.topPadding
|
||||
width: textField.width - (textField.leftPadding + textField.rightPadding)
|
||||
height: textField.height - (textField.topPadding + textField.bottomPadding)
|
||||
|
||||
text: textField.placeholderText
|
||||
font: textField.font
|
||||
color: textField.placeholderTextColor
|
||||
verticalAlignment: textField.verticalAlignment
|
||||
visible: !textField.length && !textField.preeditText && (!textField.activeFocus || textField.horizontalAlignment !== Qt.AlignHCenter)
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
color: {
|
||||
if (isLightColorScheme) {
|
||||
if (textField.activeFocus) {
|
||||
hifi.colors.black
|
||||
style: TextFieldStyle {
|
||||
id: style;
|
||||
textColor: {
|
||||
if (isLightColorScheme) {
|
||||
if (textField.activeFocus) {
|
||||
hifi.colors.black
|
||||
} else {
|
||||
hifi.colors.lightGray
|
||||
}
|
||||
} else if (isFaintGrayColorScheme) {
|
||||
if (textField.activeFocus) {
|
||||
hifi.colors.black
|
||||
} else {
|
||||
hifi.colors.lightGray
|
||||
}
|
||||
} else {
|
||||
hifi.colors.lightGray
|
||||
}
|
||||
} else if (isFaintGrayColorScheme) {
|
||||
if (textField.activeFocus) {
|
||||
hifi.colors.black
|
||||
} else {
|
||||
hifi.colors.lightGray
|
||||
}
|
||||
} else {
|
||||
if (textField.activeFocus) {
|
||||
hifi.colors.white
|
||||
} else {
|
||||
hifi.colors.lightGrayText
|
||||
if (textField.activeFocus) {
|
||||
hifi.colors.white
|
||||
} else {
|
||||
hifi.colors.lightGrayText
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: {
|
||||
background: Rectangle {
|
||||
color: {
|
||||
if (isLightColorScheme) {
|
||||
if (textField.activeFocus) {
|
||||
hifi.colors.white
|
||||
|
@ -119,22 +100,22 @@ TextField {
|
|||
}
|
||||
}
|
||||
}
|
||||
border.color: textField.error ? hifi.colors.redHighlight :
|
||||
border.color: textField.error ? hifi.colors.redHighlight :
|
||||
(textField.activeFocus ? hifi.colors.primaryHighlight : (hasDefocusedBorder ? (isFaintGrayColorScheme ? hifi.colors.lightGrayText : hifi.colors.lightGray) : color))
|
||||
border.width: textField.activeFocus || hasRoundedBorder || textField.error ? 1 : 0
|
||||
border.width: textField.activeFocus || hasRoundedBorder || textField.error ? 1 : 0
|
||||
radius: isSearchField ? textField.height / 2 : (hasRoundedBorder ? roundedBorderRadius : 0)
|
||||
|
||||
HiFiGlyphs {
|
||||
HiFiGlyphs {
|
||||
text: textField.leftPermanentGlyph;
|
||||
color: textColor;
|
||||
size: hifi.fontSizes.textFieldSearchIcon;
|
||||
anchors.left: parent.left;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
anchors.leftMargin: hifi.dimensions.textPadding - 2;
|
||||
visible: text;
|
||||
}
|
||||
color: textColor;
|
||||
size: hifi.fontSizes.textFieldSearchIcon;
|
||||
anchors.left: parent.left;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
anchors.leftMargin: hifi.dimensions.textPadding - 2;
|
||||
visible: text;
|
||||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
HiFiGlyphs {
|
||||
text: textField.centerPlaceholderGlyph;
|
||||
color: textColor;
|
||||
size: parent.height;
|
||||
|
@ -144,57 +125,48 @@ TextField {
|
|||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
text: hifi.glyphs.search
|
||||
color: textColor
|
||||
size: hifi.fontSizes.textFieldSearchIcon
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.leftMargin: hifi.dimensions.textPadding - 2
|
||||
visible: isSearchField
|
||||
}
|
||||
text: hifi.glyphs.search
|
||||
color: textColor
|
||||
size: hifi.fontSizes.textFieldSearchIcon
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.leftMargin: hifi.dimensions.textPadding - 2
|
||||
visible: isSearchField
|
||||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
text: hifi.glyphs.error
|
||||
color: textColor
|
||||
size: 40
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: hifi.dimensions.textPadding - 2
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: hasClearButton && textField.text !== "";
|
||||
HiFiGlyphs {
|
||||
text: hifi.glyphs.error
|
||||
color: textColor
|
||||
size: 40
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: hifi.dimensions.textPadding - 2
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: hasClearButton && textField.text !== "";
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
textField.text = "";
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
textField.text = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
placeholderTextColor: isFaintGrayColorScheme ? hifi.colors.lightGrayText : hifi.colors.lightGray
|
||||
selectedTextColor: hifi.colors.black
|
||||
selectionColor: hifi.colors.primaryHighlight
|
||||
padding.left: hasRoundedBorder ? textField.height / 2 : ((isSearchField || textField.leftPermanentGlyph !== "") ? textField.height - 2 : 0) + hifi.dimensions.textPadding
|
||||
padding.right: (hasClearButton ? textField.height - 2 : 0) + hifi.dimensions.textPadding
|
||||
}
|
||||
|
||||
property color placeholderTextColor: isFaintGrayColorScheme ? hifi.colors.lightGrayText : hifi.colors.lightGray
|
||||
selectedTextColor: hifi.colors.black
|
||||
selectionColor: hifi.colors.primaryHighlight
|
||||
leftPadding: hasRoundedBorder ? textField.height / 2 : ((isSearchField || textField.leftPermanentGlyph !== "") ? textField.height - 2 : 0) + hifi.dimensions.textPadding
|
||||
rightPadding: (hasClearButton ? textField.height - 2 : 0) + hifi.dimensions.textPadding
|
||||
|
||||
|
||||
HifiControls.Label {
|
||||
id: textFieldLabel
|
||||
text: textField.label
|
||||
colorScheme: textField.colorScheme
|
||||
anchors.left: parent.left
|
||||
|
||||
Binding on anchors.right {
|
||||
when: rightAnchorSet
|
||||
value: textField.right
|
||||
}
|
||||
Binding on wrapMode {
|
||||
when: rightAnchorSet
|
||||
value: Text.WordWrap
|
||||
}
|
||||
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.top
|
||||
anchors.bottomMargin: 3
|
||||
wrapMode: Text.WordWrap
|
||||
visible: label != ""
|
||||
}
|
||||
}
|
||||
|
|
|
@ -257,9 +257,14 @@ Rectangle {
|
|||
lightboxPopup.bodyImageSource = msg.securityImageSource;
|
||||
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "GO TO WALLET";
|
||||
lightboxPopup.button2method = "sendToParent({method: 'checkout_openWallet'});";
|
||||
lightboxPopup.button2method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
sendToScript({method: 'checkout_openWallet'});
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
|
@ -623,10 +628,16 @@ Rectangle {
|
|||
lightboxPopup.bodyText = "You will not be able to replace this domain's content with <b>" + root.itemName +
|
||||
" </b>until the server owner gives you 'Replace Content' permissions.<br><br>Are you sure you want to purchase this content set?";
|
||||
lightboxPopup.button1text = "CANCEL";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "CONFIRM";
|
||||
lightboxPopup.button2method = "Commerce.buy('" + root.itemId + "', " + root.itemPrice + ");" +
|
||||
"root.visible = false; buyButton.enabled = false; loading.visible = true;";
|
||||
lightboxPopup.button2method = function() {
|
||||
Commerce.buy(root.itemId, root.itemPrice);
|
||||
lightboxPopup.visible = false;
|
||||
buyButton.enabled = false;
|
||||
loading.visible = true;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else {
|
||||
buyButton.enabled = false;
|
||||
|
@ -771,19 +782,30 @@ Rectangle {
|
|||
"<a href='https://docs.highfidelity.com/create-and-explore/start-working-in-your-sandbox/restoring-sandbox-content'>" +
|
||||
"click here to open info on your desktop browser.";
|
||||
lightboxPopup.button1text = "CANCEL";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "CONFIRM";
|
||||
lightboxPopup.button2method = "Commerce.replaceContentSet('" + root.itemHref + "', '" + root.certificateId + "');" +
|
||||
"root.visible = false;rezzedNotifContainer.visible = true; rezzedNotifContainerTimer.start();" +
|
||||
"UserActivityLogger.commerceEntityRezzed('" + root.itemId + "', 'checkout', '" + root.itemType + "');";
|
||||
lightboxPopup.button2method = function() {
|
||||
Commerce.replaceContentSet(root.itemHref);
|
||||
lightboxPopup.visible = false;
|
||||
rezzedNotifContainer.visible = true;
|
||||
rezzedNotifContainerTimer.start();
|
||||
UserActivityLogger.commerceEntityRezzed(root.itemId, 'checkout', root.itemType);
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else if (root.itemType === "avatar") {
|
||||
lightboxPopup.titleText = "Change Avatar";
|
||||
lightboxPopup.bodyText = "This will change your current avatar to " + root.itemName + " while retaining your wearables.";
|
||||
lightboxPopup.button1text = "CANCEL";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "CONFIRM";
|
||||
lightboxPopup.button2method = "MyAvatar.useFullAvatarURL('" + root.itemHref + "'); root.visible = false;";
|
||||
lightboxPopup.button2method = function() {
|
||||
MyAvatar.useFullAvatarURL(root.itemHref);
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else if (root.itemType === "app") {
|
||||
if (root.isInstalled) {
|
||||
|
@ -822,9 +844,14 @@ Rectangle {
|
|||
lightboxPopup.bodyText = "You don't have permission to rez certified items in this domain.<br><br>" +
|
||||
"Use the <b>GOTO app</b> to visit another domain or <b>go to your own sandbox.</b>";
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "OPEN GOTO";
|
||||
lightboxPopup.button2method = "sendToParent({method: 'purchases_openGoTo'});";
|
||||
lightboxPopup.button2method = function() {
|
||||
sendToScript({method: 'purchases_openGoTo'});
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
}
|
||||
|
@ -918,7 +945,9 @@ Rectangle {
|
|||
lightboxPopup.bodyText = 'Your item is marked "pending" while your purchase is being confirmed.<br><br>' +
|
||||
'Confirmations usually take about 90 seconds.';
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,10 +26,10 @@ Rectangle {
|
|||
property string bodyText;
|
||||
property string button1color: hifi.buttons.noneBorderlessGray;
|
||||
property string button1text;
|
||||
property string button1method;
|
||||
property string button2color: hifi.buttons.noneBorderless;
|
||||
property var button1method;
|
||||
property string button2color: hifi.buttons.blue;
|
||||
property string button2text;
|
||||
property string button2method;
|
||||
property var button2method;
|
||||
property string buttonLayout: "leftright";
|
||||
|
||||
readonly property string securityPicBodyText: "When you see your Security Pic, your actions and data are securely making use of your " +
|
||||
|
@ -72,7 +72,7 @@ Rectangle {
|
|||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 30;
|
||||
height: paintedHeight;
|
||||
color: hifi.colors.baseGray;
|
||||
color: hifi.colors.black;
|
||||
size: 24;
|
||||
verticalAlignment: Text.AlignTop;
|
||||
wrapMode: Text.WordWrap;
|
||||
|
@ -104,7 +104,7 @@ Rectangle {
|
|||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 30;
|
||||
height: paintedHeight;
|
||||
color: hifi.colors.baseGray;
|
||||
color: hifi.colors.black;
|
||||
size: 20;
|
||||
verticalAlignment: Text.AlignTop;
|
||||
wrapMode: Text.WordWrap;
|
||||
|
@ -129,15 +129,15 @@ Rectangle {
|
|||
colorScheme: hifi.colorSchemes.light;
|
||||
anchors.top: root.buttonLayout === "leftright" ? parent.top : parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 10;
|
||||
anchors.leftMargin: root.buttonLayout === "leftright" ? 30 : 10;
|
||||
anchors.right: root.buttonLayout === "leftright" ? undefined : parent.right;
|
||||
anchors.rightMargin: root.buttonLayout === "leftright" ? undefined : 10;
|
||||
width: root.buttonLayout === "leftright" ? (root.button2text ? parent.width/2 - anchors.leftMargin*2 : parent.width - anchors.leftMargin * 2) :
|
||||
(undefined);
|
||||
height: 50;
|
||||
height: 40;
|
||||
text: root.button1text;
|
||||
onClicked: {
|
||||
eval(button1method);
|
||||
button1method();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,12 +152,12 @@ Rectangle {
|
|||
anchors.left: root.buttonLayout === "leftright" ? undefined : parent.left;
|
||||
anchors.leftMargin: root.buttonLayout === "leftright" ? undefined : 10;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 10;
|
||||
anchors.rightMargin: root.buttonLayout === "leftright" ? 30 : 10;
|
||||
width: root.buttonLayout === "leftright" ? parent.width/2 - anchors.rightMargin*2 : undefined;
|
||||
height: 50;
|
||||
height: 40;
|
||||
text: root.button2text;
|
||||
onClicked: {
|
||||
eval(button2method);
|
||||
button2method();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,10 +174,10 @@ Rectangle {
|
|||
root.bodyText = "";
|
||||
root.button1color = hifi.buttons.noneBorderlessGray;
|
||||
root.button1text = "";
|
||||
root.button1method = "";
|
||||
root.button2color = hifi.buttons.noneBorderless;
|
||||
root.button1method = function() {};
|
||||
root.button2color = hifi.buttons.blue;
|
||||
root.button2text = "";
|
||||
root.button2method = "";
|
||||
root.button2method = function() {};
|
||||
root.buttonLayout = "leftright";
|
||||
}
|
||||
//
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// ConnectionItem.qml
|
||||
// qml/hifi/commerce/wallet/sendMoney
|
||||
// qml/hifi/commerce/common/sendAsset
|
||||
//
|
||||
// ConnectionItem
|
||||
//
|
||||
|
@ -113,7 +113,7 @@ Item {
|
|||
text: "CHOOSE";
|
||||
onClicked: {
|
||||
var msg = { method: 'chooseConnection', userName: root.userName, profilePicUrl: root.profilePicUrl };
|
||||
sendToSendMoney(msg);
|
||||
sendToParent(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ Item {
|
|||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
signal sendToSendMoney(var msg);
|
||||
signal sendToParent(var msg);
|
||||
//
|
||||
// FUNCTION DEFINITIONS END
|
||||
//
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// RecipientDisplay.qml
|
||||
// qml/hifi/commerce/wallet/sendMoney
|
||||
// qml/hifi/commerce/common/sendAsset
|
||||
//
|
||||
// RecipientDisplay
|
||||
//
|
||||
|
@ -18,7 +18,7 @@ import QtGraphicalEffects 1.0
|
|||
import "../../../../styles-uit"
|
||||
import "../../../../controls-uit" as HifiControlsUit
|
||||
import "../../../../controls" as HifiControls
|
||||
import "../../common" as HifiCommerceCommon
|
||||
import "../" as HifiCommerceCommon
|
||||
|
||||
Item {
|
||||
HifiConstants { id: hifi; }
|
File diff suppressed because it is too large
Load diff
Before (image error) Size: 921 B After (image error) Size: 921 B |
Before (image error) Size: 2.1 KiB After (image error) Size: 2.1 KiB |
Before (image error) Size: 2.3 KiB After (image error) Size: 2.3 KiB |
Before (image error) Size: 2.5 KiB After (image error) Size: 2.5 KiB |
Before ![]() (image error) Size: 22 KiB After ![]() (image error) Size: 22 KiB ![]() ![]() |
|
@ -13,7 +13,6 @@
|
|||
|
||||
import Hifi 1.0 as Hifi
|
||||
import QtQuick 2.5
|
||||
import QtGraphicalEffects 1.0
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import "../../../styles-uit"
|
||||
|
@ -22,14 +21,11 @@ import "../../../controls" as HifiControls
|
|||
import "../wallet" as HifiWallet
|
||||
import TabletScriptingInterface 1.0
|
||||
|
||||
// references XXX from root context
|
||||
|
||||
Item {
|
||||
HifiConstants { id: hifi; }
|
||||
|
||||
id: root;
|
||||
property string purchaseStatus;
|
||||
property bool purchaseStatusChanged;
|
||||
property string itemName;
|
||||
property string itemId;
|
||||
property string itemPreviewImageUrl;
|
||||
|
@ -46,16 +42,18 @@ Item {
|
|||
property var buttonGlyph: [hifi.glyphs.wand, hifi.glyphs.hat, hifi.glyphs.globe, hifi.glyphs.install, hifi.glyphs.avatar];
|
||||
property bool showConfirmation: false;
|
||||
property bool hasPermissionToRezThis;
|
||||
property bool permissionExplanationCardVisible;
|
||||
property bool cardBackVisible;
|
||||
property bool isInstalled;
|
||||
property string wornEntityID;
|
||||
property string upgradeUrl;
|
||||
property string upgradeTitle;
|
||||
property bool updateAvailable: root.upgradeUrl !== "" && !root.isShowingMyItems;
|
||||
property bool isShowingMyItems;
|
||||
|
||||
property string originalStatusText;
|
||||
property string originalStatusColor;
|
||||
|
||||
height: (root.upgradeUrl === "" || root.isShowingMyItems) ? 110 : 150;
|
||||
height: 102;
|
||||
width: parent.width;
|
||||
|
||||
Connections {
|
||||
|
@ -99,16 +97,6 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
onPurchaseStatusChangedChanged: {
|
||||
if (root.purchaseStatusChanged === true && root.purchaseStatus === "confirmed") {
|
||||
root.originalStatusText = statusText.text;
|
||||
root.originalStatusColor = statusText.color;
|
||||
statusText.text = "CONFIRMED!";
|
||||
statusText.color = hifi.colors.blueAccent;
|
||||
confirmedTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
onShowConfirmationChanged: {
|
||||
if (root.showConfirmation) {
|
||||
rezzedNotifContainer.visible = true;
|
||||
|
@ -118,35 +106,307 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: confirmedTimer;
|
||||
interval: 3000;
|
||||
onTriggered: {
|
||||
statusText.text = root.originalStatusText;
|
||||
statusText.color = root.originalStatusColor;
|
||||
root.purchaseStatusChanged = false;
|
||||
Rectangle {
|
||||
id: background;
|
||||
z: 10;
|
||||
color: Qt.rgba(0, 0, 0, 0.25);
|
||||
anchors.fill: parent;
|
||||
}
|
||||
|
||||
Flipable {
|
||||
id: flipable;
|
||||
z: 50;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.top: parent.top;
|
||||
height: root.height - 2;
|
||||
|
||||
front: mainContainer;
|
||||
back: Rectangle {
|
||||
anchors.fill: parent;
|
||||
color: hifi.colors.white;
|
||||
|
||||
Item {
|
||||
id: closeContextMenuContainer;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 8;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 8;
|
||||
width: 30;
|
||||
height: width;
|
||||
|
||||
HiFiGlyphs {
|
||||
id: closeContextMenuGlyph;
|
||||
text: hifi.glyphs.close;
|
||||
anchors.fill: parent;
|
||||
size: 26;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
color: hifi.colors.black;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
root.sendToPurchases({ method: 'flipCard', closeAll: true });
|
||||
}
|
||||
onEntered: {
|
||||
closeContextMenuGlyph.text = hifi.glyphs.closeInverted;
|
||||
}
|
||||
onExited: {
|
||||
closeContextMenuGlyph.text = hifi.glyphs.close;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: contextCard;
|
||||
z: 2;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: closeContextMenuContainer.left;
|
||||
anchors.rightMargin: 8;
|
||||
color: hifi.colors.white;
|
||||
|
||||
Component {
|
||||
id: contextCardButton;
|
||||
|
||||
Item {
|
||||
property alias buttonGlyphText: buttonGlyph.text;
|
||||
property alias buttonText: buttonText.text;
|
||||
property string buttonColor: hifi.colors.black;
|
||||
property string buttonColor_hover: hifi.colors.blueHighlight;
|
||||
property alias enabled: buttonMouseArea.enabled;
|
||||
property var buttonClicked;
|
||||
|
||||
HiFiGlyphs {
|
||||
id: buttonGlyph;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 4;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
anchors.bottom: parent.verticalCenter;
|
||||
width: parent.width;
|
||||
size: 40;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
color: buttonMouseArea.enabled ? buttonColor : hifi.colors.lightGrayText;
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
id: buttonText;
|
||||
anchors.top: parent.verticalCenter;
|
||||
anchors.topMargin: 4;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 12;
|
||||
anchors.horizontalCenter: parent.horizontalCenter;
|
||||
width: parent.width;
|
||||
color: buttonMouseArea.enabled ? buttonColor : hifi.colors.lightGrayText;
|
||||
size: 16;
|
||||
wrapMode: Text.Wrap;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: buttonMouseArea;
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
parent.buttonClicked();
|
||||
}
|
||||
onEntered: {
|
||||
buttonGlyph.color = buttonColor_hover;
|
||||
buttonText.color = buttonColor_hover;
|
||||
}
|
||||
onExited: {
|
||||
buttonGlyph.color = buttonColor;
|
||||
buttonText.color = buttonColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: giftButton;
|
||||
visible: !root.isShowingMyItems;
|
||||
sourceComponent: contextCardButton;
|
||||
anchors.right: parent.right;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: 62;
|
||||
|
||||
onLoaded: {
|
||||
item.enabled = (root.purchaseStatus === "confirmed");
|
||||
item.buttonGlyphText = hifi.glyphs.gift;
|
||||
item.buttonText = "Gift";
|
||||
item.buttonClicked = function() {
|
||||
sendToPurchases({ method: 'flipCard', closeAll: true });
|
||||
sendToPurchases({
|
||||
method: 'giftAsset',
|
||||
itemName: root.itemName,
|
||||
certId: root.certificateId,
|
||||
itemType: root.itemType,
|
||||
itemHref: root.itemHref,
|
||||
isInstalled: root.isInstalled,
|
||||
wornEntityID: root.wornEntityID,
|
||||
effectImage: root.itemPreviewImageUrl
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: marketplaceButton;
|
||||
sourceComponent: contextCardButton;
|
||||
anchors.right: giftButton.visible ? giftButton.left : parent.right;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: 100;
|
||||
|
||||
onLoaded: {
|
||||
item.buttonGlyphText = hifi.glyphs.market;
|
||||
item.buttonText = "View in Marketplace";
|
||||
item.buttonClicked = function() {
|
||||
sendToPurchases({ method: 'flipCard', closeAll: true });
|
||||
sendToPurchases({method: 'purchases_itemInfoClicked', itemId: root.itemId});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: certificateButton;
|
||||
sourceComponent: contextCardButton;
|
||||
anchors.right: marketplaceButton.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: 100;
|
||||
|
||||
onLoaded: {
|
||||
item.buttonGlyphText = hifi.glyphs.certificate;
|
||||
item.buttonText = "View Certificate";
|
||||
item.buttonClicked = function() {
|
||||
sendToPurchases({ method: 'flipCard', closeAll: true });
|
||||
sendToPurchases({method: 'purchases_itemCertificateClicked', itemCertificateId: root.certificateId});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: uninstallButton;
|
||||
visible: root.isInstalled;
|
||||
sourceComponent: contextCardButton;
|
||||
anchors.right: certificateButton.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: 78;
|
||||
|
||||
onLoaded: {
|
||||
item.buttonGlyphText = hifi.glyphs.uninstall;
|
||||
item.buttonText = "Uninstall";
|
||||
item.buttonClicked = function() {
|
||||
sendToPurchases({ method: 'flipCard', closeAll: true });
|
||||
Commerce.uninstallApp(root.itemHref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: updateButton;
|
||||
visible: root.updateAvailable;
|
||||
sourceComponent: contextCardButton;
|
||||
anchors.right: uninstallButton.visible ? uninstallButton.left : certificateButton.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: 84;
|
||||
|
||||
onLoaded: {
|
||||
item.buttonGlyphText = hifi.glyphs.update;
|
||||
item.buttonText = "Update";
|
||||
item.buttonColor = "#E2334D";
|
||||
item.buttonClicked = function() {
|
||||
sendToPurchases({ method: 'flipCard', closeAll: true });
|
||||
sendToPurchases({method: 'updateItemClicked', itemId: root.itemId, itemEdition: root.itemEdition, upgradeUrl: root.upgradeUrl});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: permissionExplanationCard;
|
||||
z: 1;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: closeContextMenuContainer.left;
|
||||
anchors.rightMargin: 8;
|
||||
color: hifi.colors.white;
|
||||
|
||||
RalewayRegular {
|
||||
id: permissionExplanationText;
|
||||
anchors.fill: parent;
|
||||
text: {
|
||||
if (root.itemType === "contentSet") {
|
||||
"You do not have 'Replace Content' permissions in this domain. <a href='#replaceContentPermission'>Learn more</a>";
|
||||
} else if (root.itemType === "entity") {
|
||||
"You do not have 'Rez Certified' permissions in this domain. <a href='#rezCertifiedPermission'>Learn more</a>";
|
||||
} else {
|
||||
"Hey! You're not supposed to see this. How is it even possible that you're here? Are you a developer???"
|
||||
}
|
||||
}
|
||||
size: 16;
|
||||
color: hifi.colors.baseGray;
|
||||
wrapMode: Text.Wrap;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
||||
onLinkActivated: {
|
||||
sendToPurchases({method: 'showPermissionsExplanation', itemType: root.itemType});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
transform: Rotation {
|
||||
id: rotation;
|
||||
origin.x: flipable.width/2;
|
||||
origin.y: flipable.height/2;
|
||||
axis.x: 1;
|
||||
axis.y: 0;
|
||||
axis.z: 0;
|
||||
angle: 0;
|
||||
}
|
||||
|
||||
states: State {
|
||||
name: "back";
|
||||
PropertyChanges {
|
||||
target: rotation;
|
||||
angle: 180;
|
||||
}
|
||||
when: root.cardBackVisible;
|
||||
}
|
||||
|
||||
transitions: Transition {
|
||||
SmoothedAnimation {
|
||||
target: rotation;
|
||||
property: "angle";
|
||||
velocity: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: mainContainer;
|
||||
z: 51;
|
||||
// Style
|
||||
color: hifi.colors.white;
|
||||
// Size
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
height: root.height - 10;
|
||||
|
||||
// START "incorrect indentation to prevent insane diffs"
|
||||
Item {
|
||||
id: itemContainer;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.top: parent.top;
|
||||
height: 100;
|
||||
height: root.height - 2;
|
||||
|
||||
Image {
|
||||
id: itemPreviewImage;
|
||||
|
@ -154,8 +414,9 @@ Item {
|
|||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: height;
|
||||
width: height * 1.78;
|
||||
fillMode: Image.PreserveAspectCrop;
|
||||
mipmap: true;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
|
@ -165,218 +426,53 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
TextMetrics {
|
||||
id: itemNameTextMetrics;
|
||||
font: itemName.font;
|
||||
text: itemName.text;
|
||||
}
|
||||
RalewaySemiBold {
|
||||
RalewayRegular {
|
||||
id: itemName;
|
||||
anchors.top: itemPreviewImage.top;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: itemPreviewImage.right;
|
||||
anchors.leftMargin: 8;
|
||||
width: !noPermissionGlyph.visible ? (buttonContainer.x - itemPreviewImage.x - itemPreviewImage.width - anchors.leftMargin) :
|
||||
Math.min(itemNameTextMetrics.tightBoundingRect.width + 2,
|
||||
buttonContainer.x - itemPreviewImage.x - itemPreviewImage.width - anchors.leftMargin - noPermissionGlyph.width + 2);
|
||||
anchors.leftMargin: 10;
|
||||
anchors.right: contextMenuButtonContainer.left;
|
||||
anchors.rightMargin: 4;
|
||||
height: paintedHeight;
|
||||
// Text size
|
||||
size: 24;
|
||||
size: 20;
|
||||
// Style
|
||||
color: hifi.colors.blueAccent;
|
||||
color: hifi.colors.black;
|
||||
text: root.itemName;
|
||||
elide: Text.ElideRight;
|
||||
// Alignment
|
||||
horizontalAlignment: Text.AlignLeft;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
sendToPurchases({method: 'purchases_itemInfoClicked', itemId: root.itemId});
|
||||
}
|
||||
onEntered: {
|
||||
itemName.color = hifi.colors.blueHighlight;
|
||||
}
|
||||
onExited: {
|
||||
itemName.color = hifi.colors.blueAccent;
|
||||
}
|
||||
}
|
||||
}
|
||||
HiFiGlyphs {
|
||||
id: noPermissionGlyph;
|
||||
visible: !root.hasPermissionToRezThis;
|
||||
anchors.verticalCenter: itemName.verticalCenter;
|
||||
anchors.left: itemName.right;
|
||||
anchors.leftMargin: itemName.truncated ? -10 : -2;
|
||||
text: hifi.glyphs.info;
|
||||
// Size
|
||||
size: 40;
|
||||
width: 32;
|
||||
// Style
|
||||
color: hifi.colors.redAccent;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: true;
|
||||
|
||||
onEntered: {
|
||||
noPermissionGlyph.color = hifi.colors.redHighlight;
|
||||
}
|
||||
onExited: {
|
||||
noPermissionGlyph.color = hifi.colors.redAccent;
|
||||
}
|
||||
onClicked: {
|
||||
root.sendToPurchases({ method: 'openPermissionExplanationCard' });
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
id: permissionExplanationCard;
|
||||
z: 995;
|
||||
visible: root.permissionExplanationCardVisible;
|
||||
anchors.fill: parent;
|
||||
color: hifi.colors.white;
|
||||
|
||||
RalewayRegular {
|
||||
id: permissionExplanationText;
|
||||
text: {
|
||||
if (root.itemType === "contentSet") {
|
||||
"You do not have 'Replace Content' permissions in this domain. <a href='#replaceContentPermission'>Learn more</a>";
|
||||
} else if (root.itemType === "entity") {
|
||||
"You do not have 'Rez Certified' permissions in this domain. <a href='#rezCertifiedPermission'>Learn more</a>";
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
size: 16;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 30;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: permissionExplanationGlyph.left;
|
||||
color: hifi.colors.baseGray;
|
||||
wrapMode: Text.WordWrap;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
||||
onLinkActivated: {
|
||||
sendToPurchases({method: 'showPermissionsExplanation', itemType: root.itemType});
|
||||
}
|
||||
}
|
||||
// "Close" button
|
||||
HiFiGlyphs {
|
||||
id: permissionExplanationGlyph;
|
||||
text: hifi.glyphs.close;
|
||||
color: hifi.colors.baseGray;
|
||||
size: 26;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
width: 77;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: true;
|
||||
onEntered: {
|
||||
parent.text = hifi.glyphs.closeInverted;
|
||||
}
|
||||
onExited: {
|
||||
parent.text = hifi.glyphs.close;
|
||||
}
|
||||
onClicked: {
|
||||
root.sendToPurchases({ method: 'openPermissionExplanationCard', closeAll: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: certificateContainer;
|
||||
anchors.top: itemName.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: itemName.left;
|
||||
anchors.right: buttonContainer.left;
|
||||
anchors.rightMargin: 2;
|
||||
height: 24;
|
||||
|
||||
HiFiGlyphs {
|
||||
id: certificateIcon;
|
||||
text: hifi.glyphs.scriptNew;
|
||||
// Size
|
||||
size: 30;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: 32;
|
||||
// Style
|
||||
color: hifi.colors.black;
|
||||
}
|
||||
|
||||
RalewayRegular {
|
||||
id: viewCertificateText;
|
||||
text: "VIEW CERTIFICATE";
|
||||
size: 13;
|
||||
anchors.left: certificateIcon.right;
|
||||
anchors.leftMargin: 4;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
color: hifi.colors.black;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
sendToPurchases({method: 'purchases_itemCertificateClicked', itemCertificateId: root.certificateId});
|
||||
}
|
||||
onEntered: {
|
||||
certificateIcon.color = hifi.colors.lightGray;
|
||||
viewCertificateText.color = hifi.colors.lightGray;
|
||||
}
|
||||
onExited: {
|
||||
certificateIcon.color = hifi.colors.black;
|
||||
viewCertificateText.color = hifi.colors.black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: editionContainer;
|
||||
RalewayRegular {
|
||||
id: editionNumberText;
|
||||
visible: root.displayedItemCount > 1 && !statusContainer.visible;
|
||||
anchors.left: itemName.left;
|
||||
anchors.top: certificateContainer.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: buttonContainer.left;
|
||||
anchors.rightMargin: 2;
|
||||
|
||||
RalewayRegular {
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
text: "#" + root.itemEdition;
|
||||
size: 13;
|
||||
color: hifi.colors.black;
|
||||
verticalAlignment: Text.AlignTop;
|
||||
}
|
||||
anchors.right: itemName.right;
|
||||
anchors.top: itemName.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.bottom: buttonContainer.top;
|
||||
anchors.bottomMargin: 4;
|
||||
width: itemName.width;
|
||||
text: "Edition #" + root.itemEdition;
|
||||
size: 13;
|
||||
color: hifi.colors.black;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
Item {
|
||||
id: statusContainer;
|
||||
visible: root.purchaseStatus === "pending" || root.purchaseStatus === "invalidated" || root.purchaseStatusChanged || root.numberSold > -1;
|
||||
visible: root.purchaseStatus === "pending" || root.purchaseStatus === "invalidated" || root.numberSold > -1;
|
||||
anchors.left: itemName.left;
|
||||
anchors.top: certificateContainer.bottom;
|
||||
anchors.topMargin: 8;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: buttonContainer.left;
|
||||
anchors.rightMargin: 2;
|
||||
anchors.right: itemName.right;
|
||||
anchors.top: itemName.bottom;
|
||||
anchors.topMargin: 4;
|
||||
anchors.bottom: buttonContainer.top;
|
||||
anchors.bottomMargin: 4;
|
||||
|
||||
RalewaySemiBold {
|
||||
RalewayRegular {
|
||||
id: statusText;
|
||||
anchors.left: parent.left;
|
||||
anchors.top: parent.top;
|
||||
|
@ -393,7 +489,7 @@ Item {
|
|||
""
|
||||
}
|
||||
}
|
||||
size: 18;
|
||||
size: 13;
|
||||
color: {
|
||||
if (root.purchaseStatus === "pending") {
|
||||
hifi.colors.blueAccent
|
||||
|
@ -418,10 +514,10 @@ Item {
|
|||
}
|
||||
}
|
||||
// Size
|
||||
size: 36;
|
||||
size: 34;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: -8;
|
||||
anchors.topMargin: -10;
|
||||
anchors.left: statusText.right;
|
||||
anchors.bottom: parent.bottom;
|
||||
// Style
|
||||
|
@ -468,6 +564,50 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contextMenuButtonContainer;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 8;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 8;
|
||||
width: 30;
|
||||
height: width;
|
||||
|
||||
Rectangle {
|
||||
visible: root.updateAvailable;
|
||||
anchors.fill: parent;
|
||||
radius: height;
|
||||
border.width: 1;
|
||||
border.color: "#E2334D";
|
||||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
id: contextMenuGlyph;
|
||||
text: hifi.glyphs.verticalEllipsis;
|
||||
anchors.fill: parent;
|
||||
size: 46;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
color: root.updateAvailable ? "#E2334D" : hifi.colors.black;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: enabled;
|
||||
onClicked: {
|
||||
contextCard.z = 1;
|
||||
permissionExplanationCard.z = 0;
|
||||
root.sendToPurchases({ method: 'flipCard' });
|
||||
}
|
||||
onEntered: {
|
||||
contextMenuGlyph.color = root.updateAvailable ? hifi.colors.redHighlight : hifi.colors.blueHighlight;
|
||||
}
|
||||
onExited: {
|
||||
contextMenuGlyph.color = root.updateAvailable ? "#E2334D" : hifi.colors.black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rezzedNotifContainer;
|
||||
z: 998;
|
||||
|
@ -489,62 +629,22 @@ Item {
|
|||
horizontalAlignment: Text.AlignHCenter;
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: rezzedNotifContainerTimer;
|
||||
interval: 2000;
|
||||
onTriggered: rezzedNotifContainer.visible = false
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: appButtonContainer;
|
||||
color: hifi.colors.white;
|
||||
z: 994;
|
||||
visible: root.isInstalled;
|
||||
anchors.fill: buttonContainer;
|
||||
|
||||
HifiControlsUit.Button {
|
||||
id: openAppButton;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.light;
|
||||
anchors.top: parent.top;
|
||||
anchors.right: parent.right;
|
||||
anchors.left: parent.left;
|
||||
width: 92;
|
||||
height: 44;
|
||||
text: "OPEN"
|
||||
onClicked: {
|
||||
Commerce.openApp(root.itemHref);
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Button {
|
||||
id: uninstallAppButton;
|
||||
color: hifi.buttons.noneBorderless;
|
||||
colorScheme: hifi.colorSchemes.light;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.right: parent.right;
|
||||
anchors.left: parent.left;
|
||||
height: 44;
|
||||
text: "UNINSTALL"
|
||||
onClicked: {
|
||||
Commerce.uninstallApp(root.itemHref);
|
||||
}
|
||||
Timer {
|
||||
id: rezzedNotifContainerTimer;
|
||||
interval: 2000;
|
||||
onTriggered: rezzedNotifContainer.visible = false
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: buttonContainer;
|
||||
property int color: hifi.buttons.blue;
|
||||
property int colorScheme: hifi.colorSchemes.light;
|
||||
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 4;
|
||||
anchors.left: itemName.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 4;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 4;
|
||||
width: height;
|
||||
anchors.bottomMargin: 8;
|
||||
width: 160;
|
||||
height: 40;
|
||||
enabled: root.hasPermissionToRezThis &&
|
||||
root.purchaseStatus !== "invalidated" &&
|
||||
MyAvatar.skeletonModelURL !== root.itemHref;
|
||||
|
@ -568,8 +668,12 @@ Item {
|
|||
} else if (root.itemType === "avatar") {
|
||||
sendToPurchases({method: 'showChangeAvatarLightbox', itemName: root.itemName, itemHref: root.itemHref});
|
||||
} else if (root.itemType === "app") {
|
||||
// "Run" and "Uninstall" buttons are separate.
|
||||
Commerce.installApp(root.itemHref);
|
||||
if (root.isInstalled) {
|
||||
Commerce.openApp(root.itemHref);
|
||||
} else {
|
||||
// "Run" and "Uninstall" buttons are separate.
|
||||
Commerce.installApp(root.itemHref);
|
||||
}
|
||||
} else {
|
||||
sendToPurchases({method: 'purchases_rezClicked', itemHref: root.itemHref, itemType: root.itemType});
|
||||
root.showConfirmation = true;
|
||||
|
@ -612,93 +716,76 @@ Item {
|
|||
}
|
||||
|
||||
label: Item {
|
||||
TextMetrics {
|
||||
id: rezIconTextMetrics;
|
||||
font: rezIcon.font;
|
||||
text: rezIcon.text;
|
||||
}
|
||||
HiFiGlyphs {
|
||||
id: rezIcon;
|
||||
text: (root.buttonGlyph)[itemTypesArray.indexOf(root.itemType)];
|
||||
// Size
|
||||
size: 60;
|
||||
// Anchors
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 0;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
anchors.right: rezIconLabel.left;
|
||||
anchors.rightMargin: 2;
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
size: 36;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
// Style
|
||||
color: enabled ? hifi.buttons.textColor[control.color]
|
||||
: hifi.buttons.disabledTextColor[control.colorScheme]
|
||||
: hifi.buttons.disabledTextColor[control.colorScheme]
|
||||
}
|
||||
TextMetrics {
|
||||
id: rezIconLabelTextMetrics;
|
||||
font: rezIconLabel.font;
|
||||
text: rezIconLabel.text;
|
||||
}
|
||||
RalewayBold {
|
||||
id: rezIconLabel;
|
||||
anchors.top: rezIcon.bottom;
|
||||
anchors.topMargin: -4;
|
||||
anchors.right: parent.right;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
font.capitalization: Font.AllUppercase
|
||||
color: enabled ? hifi.buttons.textColor[control.color]
|
||||
: hifi.buttons.disabledTextColor[control.colorScheme]
|
||||
text: root.isInstalled ? "OPEN" : (MyAvatar.skeletonModelURL === root.itemHref ? "CURRENT" : (root.buttonTextNormal)[itemTypesArray.indexOf(root.itemType)]);
|
||||
anchors.verticalCenter: parent.verticalCenter;
|
||||
width: rezIconLabelTextMetrics.width;
|
||||
x: parent.width/2 - rezIconLabelTextMetrics.width/2 + rezIconTextMetrics.width/2;
|
||||
size: 15;
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: MyAvatar.skeletonModelURL === root.itemHref ? "CURRENT" : (root.buttonTextNormal)[itemTypesArray.indexOf(root.itemType)];
|
||||
font.capitalization: Font.AllUppercase;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
color: enabled ? hifi.buttons.textColor[control.color]
|
||||
: hifi.buttons.disabledTextColor[control.colorScheme]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// END "incorrect indentation to prevent insane diffs"
|
||||
HiFiGlyphs {
|
||||
id: noPermissionGlyph;
|
||||
visible: !root.hasPermissionToRezThis;
|
||||
anchors.verticalCenter: buttonContainer.verticalCenter;
|
||||
anchors.left: buttonContainer.left;
|
||||
anchors.right: buttonContainer.right;
|
||||
anchors.rightMargin: -40;
|
||||
text: hifi.glyphs.info;
|
||||
// Size
|
||||
size: 44;
|
||||
// Style
|
||||
color: hifi.colors.redAccent;
|
||||
horizontalAlignment: Text.AlignRight;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: true;
|
||||
|
||||
Rectangle {
|
||||
id: upgradeAvailableContainer;
|
||||
visible: root.upgradeUrl !== "" && !root.isShowingMyItems;
|
||||
anchors.top: itemContainer.bottom;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
color: "#B5EAFF";
|
||||
|
||||
RalewayRegular {
|
||||
id: updateAvailableText;
|
||||
text: "UPDATE AVAILABLE";
|
||||
size: 13;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 12;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
color: hifi.colors.black;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
}
|
||||
|
||||
RalewaySemiBold {
|
||||
id: updateNowText;
|
||||
text: "<font color='#0093C5'><a href='#'>Update this item now</a></font>";
|
||||
size: 13;
|
||||
anchors.left: updateAvailableText.right;
|
||||
anchors.leftMargin: 16;
|
||||
anchors.top: parent.top;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: paintedWidth;
|
||||
color: hifi.colors.black;
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
||||
onLinkActivated: {
|
||||
sendToPurchases({method: 'updateItemClicked', itemId: root.itemId, itemEdition: root.itemEdition, upgradeUrl: root.upgradeUrl});
|
||||
onEntered: {
|
||||
noPermissionGlyph.color = hifi.colors.redHighlight;
|
||||
}
|
||||
onExited: {
|
||||
noPermissionGlyph.color = hifi.colors.redAccent;
|
||||
}
|
||||
onClicked: {
|
||||
contextCard.z = 0;
|
||||
permissionExplanationCard.z = 1;
|
||||
root.sendToPurchases({ method: 'flipCard' });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
anchors.fill: mainContainer;
|
||||
horizontalOffset: 0;
|
||||
verticalOffset: 4;
|
||||
radius: 4.0;
|
||||
samples: 9
|
||||
color: Qt.rgba(0, 0, 0, 0.25);
|
||||
source: mainContainer;
|
||||
}
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
|
|
|
@ -19,6 +19,7 @@ import "../../../controls" as HifiControls
|
|||
import "../wallet" as HifiWallet
|
||||
import "../common" as HifiCommerceCommon
|
||||
import "../inspectionCertificate" as HifiInspectionCertificate
|
||||
import "../common/sendAsset" as HifiSendAsset
|
||||
|
||||
// references XXX from root context
|
||||
|
||||
|
@ -31,7 +32,6 @@ Rectangle {
|
|||
property bool securityImageResultReceived: false;
|
||||
property bool purchasesReceived: false;
|
||||
property bool punctuationMode: false;
|
||||
property bool pendingInventoryReply: true;
|
||||
property bool isShowingMyItems: false;
|
||||
property bool isDebuggingFirstUseTutorial: false;
|
||||
property int pendingItemCount: 0;
|
||||
|
@ -114,12 +114,6 @@ Rectangle {
|
|||
|
||||
purchasesContentsList.positionViewAtIndex(currentIndex, ListView.Beginning);
|
||||
}
|
||||
|
||||
if (root.pendingInventoryReply && root.pendingItemCount > 0) {
|
||||
inventoryTimer.start();
|
||||
}
|
||||
|
||||
root.pendingInventoryReply = false;
|
||||
}
|
||||
|
||||
onAvailableUpdatesResult: {
|
||||
|
@ -142,7 +136,7 @@ Rectangle {
|
|||
|
||||
HifiInspectionCertificate.InspectionCertificate {
|
||||
id: inspectionCertificate;
|
||||
z: 999;
|
||||
z: 998;
|
||||
visible: false;
|
||||
anchors.fill: parent;
|
||||
|
||||
|
@ -155,6 +149,7 @@ Rectangle {
|
|||
|
||||
HifiCommerceCommon.CommerceLightbox {
|
||||
id: lightboxPopup;
|
||||
z: 999;
|
||||
visible: false;
|
||||
anchors.fill: parent;
|
||||
|
||||
|
@ -169,12 +164,33 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
HifiSendAsset.SendAsset {
|
||||
id: sendAsset;
|
||||
z: 998;
|
||||
visible: root.activeView === "giftAsset";
|
||||
anchors.fill: parent;
|
||||
parentAppTitleBarHeight: 70;
|
||||
parentAppNavBarHeight: 0;
|
||||
|
||||
Connections {
|
||||
onSendSignalToParent: {
|
||||
if (msg.method === 'sendAssetHome_back' || msg.method === 'closeSendAsset') {
|
||||
root.activeView = "purchasesMain";
|
||||
Commerce.inventory();
|
||||
Commerce.getAvailableUpdates();
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TITLE BAR START
|
||||
//
|
||||
HifiCommerceCommon.EmulatedMarketplaceHeader {
|
||||
id: titleBarContainer;
|
||||
z: 998;
|
||||
z: 997;
|
||||
visible: !needsLogIn.visible;
|
||||
// Size
|
||||
width: parent.width;
|
||||
|
@ -191,9 +207,14 @@ Rectangle {
|
|||
lightboxPopup.bodyImageSource = msg.securityImageSource;
|
||||
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "GO TO WALLET";
|
||||
lightboxPopup.button2method = "sendToParent({method: 'purchases_openWallet'});";
|
||||
lightboxPopup.button2method = function() {
|
||||
sendToScript({method: 'purchases_openWallet'});
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else {
|
||||
sendToScript(msg);
|
||||
|
@ -308,7 +329,7 @@ Rectangle {
|
|||
// FILTER BAR START
|
||||
//
|
||||
Item {
|
||||
z: 997;
|
||||
z: 996;
|
||||
id: filterBarContainer;
|
||||
// Size
|
||||
height: 40;
|
||||
|
@ -316,7 +337,7 @@ Rectangle {
|
|||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 16;
|
||||
anchors.rightMargin: 8;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 4;
|
||||
|
||||
|
@ -341,6 +362,7 @@ Rectangle {
|
|||
colorScheme: hifi.colorSchemes.faintGray;
|
||||
anchors.top: parent.top;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 8;
|
||||
anchors.left: myText.right;
|
||||
anchors.leftMargin: 16;
|
||||
textFieldHeight: 39;
|
||||
|
@ -396,7 +418,7 @@ Rectangle {
|
|||
//
|
||||
|
||||
HifiControlsUit.Separator {
|
||||
z: 996;
|
||||
z: 995;
|
||||
id: separator;
|
||||
colorScheme: 2;
|
||||
anchors.left: parent.left;
|
||||
|
@ -426,7 +448,6 @@ Rectangle {
|
|||
snapMode: ListView.SnapToItem;
|
||||
// Anchors
|
||||
anchors.top: separator.bottom;
|
||||
anchors.topMargin: 12;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: updatesAvailableBanner.visible ? updatesAvailableBanner.top : parent.bottom;
|
||||
width: parent.width;
|
||||
|
@ -437,13 +458,13 @@ Rectangle {
|
|||
itemHref: download_url;
|
||||
certificateId: certificate_id;
|
||||
purchaseStatus: status;
|
||||
purchaseStatusChanged: statusChanged;
|
||||
itemEdition: model.edition_number;
|
||||
numberSold: model.number_sold;
|
||||
limitedRun: model.limited_run;
|
||||
displayedItemCount: model.displayedItemCount;
|
||||
permissionExplanationCardVisible: model.permissionExplanationCardVisible;
|
||||
cardBackVisible: model.cardBackVisible;
|
||||
isInstalled: model.isInstalled;
|
||||
wornEntityID: model.wornEntityID;
|
||||
upgradeUrl: model.upgrade_url;
|
||||
upgradeTitle: model.upgrade_title;
|
||||
itemType: model.itemType;
|
||||
|
@ -457,6 +478,11 @@ Rectangle {
|
|||
sendToScript({method: 'purchases_itemInfoClicked', itemId: itemId});
|
||||
} else if (msg.method === "purchases_rezClicked") {
|
||||
sendToScript({method: 'purchases_rezClicked', itemHref: itemHref, itemType: itemType});
|
||||
|
||||
// Race condition - Wearable might not be rezzed by the time the "currently worn wearbles" model is created
|
||||
if (itemType === "wearable") {
|
||||
sendToScript({ method: 'purchases_updateWearables' });
|
||||
}
|
||||
} else if (msg.method === 'purchases_itemCertificateClicked') {
|
||||
inspectionCertificate.visible = true;
|
||||
inspectionCertificate.isLightbox = true;
|
||||
|
@ -466,14 +492,18 @@ Rectangle {
|
|||
lightboxPopup.bodyText = 'Your item is marked "invalidated" because this item has been suspended ' +
|
||||
"from the Marketplace due to a claim against its author.";
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
} else if (msg.method === "showPendingLightbox") {
|
||||
lightboxPopup.titleText = "Item Pending";
|
||||
lightboxPopup.bodyText = 'Your item is marked "pending" while your purchase is being confirmed. ' +
|
||||
"Usually, purchases take about 90 seconds to confirm.";
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
} else if (msg.method === "showReplaceContentLightbox") {
|
||||
lightboxPopup.titleText = "Replace Content";
|
||||
|
@ -483,17 +513,27 @@ Rectangle {
|
|||
"<a href='https://docs.highfidelity.com/create-and-explore/start-working-in-your-sandbox/restoring-sandbox-content'>" +
|
||||
"click here to open info on your desktop browser.";
|
||||
lightboxPopup.button1text = "CANCEL";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "CONFIRM";
|
||||
lightboxPopup.button2method = "Commerce.replaceContentSet('" + msg.itemHref + "', '" + msg.certID + "'); root.visible = false;";
|
||||
lightboxPopup.button2method = function() {
|
||||
Commerce.replaceContentSet(msg.itemHref, msg.certID);
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else if (msg.method === "showChangeAvatarLightbox") {
|
||||
lightboxPopup.titleText = "Change Avatar";
|
||||
lightboxPopup.bodyText = "This will change your current avatar to " + msg.itemName + " while retaining your wearables.";
|
||||
lightboxPopup.button1text = "CANCEL";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "CONFIRM";
|
||||
lightboxPopup.button2method = "MyAvatar.useFullAvatarURL('" + msg.itemHref + "'); root.visible = false;";
|
||||
lightboxPopup.button2method = function() {
|
||||
MyAvatar.useFullAvatarURL(msg.itemHref);
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else if (msg.method === "showPermissionsExplanation") {
|
||||
if (msg.itemType === "entity") {
|
||||
|
@ -501,27 +541,86 @@ Rectangle {
|
|||
lightboxPopup.bodyText = "You don't have permission to rez certified items in this domain.<br><br>" +
|
||||
"Use the <b>GOTO app</b> to visit another domain or <b>go to your own sandbox.</b>";
|
||||
lightboxPopup.button2text = "OPEN GOTO";
|
||||
lightboxPopup.button2method = "sendToParent({method: 'purchases_openGoTo'});";
|
||||
lightboxPopup.button2method = function() {
|
||||
sendToScript({method: 'purchases_openGoTo'});
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
} else if (msg.itemType === "contentSet") {
|
||||
lightboxPopup.titleText = "Replace Content Permission";
|
||||
lightboxPopup.bodyText = "You do not have the permission 'Replace Content' in this <b>domain's server settings</b>. The domain owner " +
|
||||
"must enable it for you before you can replace content sets in this domain.";
|
||||
}
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
} else if (msg.method === "setFilterText") {
|
||||
filterBar.text = msg.filterText;
|
||||
} else if (msg.method === "openPermissionExplanationCard") {
|
||||
} else if (msg.method === "flipCard") {
|
||||
for (var i = 0; i < filteredPurchasesModel.count; i++) {
|
||||
if (i !== index || msg.closeAll) {
|
||||
filteredPurchasesModel.setProperty(i, "permissionExplanationCardVisible", false);
|
||||
filteredPurchasesModel.setProperty(i, "cardBackVisible", false);
|
||||
} else {
|
||||
filteredPurchasesModel.setProperty(i, "permissionExplanationCardVisible", true);
|
||||
filteredPurchasesModel.setProperty(i, "cardBackVisible", true);
|
||||
}
|
||||
}
|
||||
} else if (msg.method === "updateItemClicked") {
|
||||
sendToScript(msg);
|
||||
} else if (msg.method === "giftAsset") {
|
||||
sendAsset.assetName = msg.itemName;
|
||||
sendAsset.assetCertID = msg.certId;
|
||||
sendAsset.sendingPubliclyEffectImage = msg.effectImage;
|
||||
|
||||
if (msg.itemType === "avatar" && MyAvatar.skeletonModelURL === msg.itemHref) {
|
||||
lightboxPopup.titleText = "Change Avatar to Default";
|
||||
lightboxPopup.bodyText = "You are currently wearing the avatar that you are trying to gift.<br><br>" +
|
||||
"If you proceed, your avatar will be changed to the default avatar.";
|
||||
lightboxPopup.button1text = "CANCEL";
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "CONFIRM";
|
||||
lightboxPopup.button2method = function() {
|
||||
MyAvatar.skeletonModelURL = '';
|
||||
root.activeView = "giftAsset";
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else if (msg.itemType === "app" && msg.isInstalled) {
|
||||
lightboxPopup.titleText = "Uninstall App";
|
||||
lightboxPopup.bodyText = "You are currently using the app that you are trying to gift.<br><br>" +
|
||||
"If you proceed, the app will be uninstalled.";
|
||||
lightboxPopup.button1text = "CANCEL";
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "CONFIRM";
|
||||
lightboxPopup.button2method = function() {
|
||||
Commerce.uninstallApp(msg.itemHref);
|
||||
root.activeView = "giftAsset";
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else if (msg.itemType === "wearable" && msg.wornEntityID !== '') {
|
||||
lightboxPopup.titleText = "Remove Wearable";
|
||||
lightboxPopup.bodyText = "You are currently wearing the wearable that you are trying to send.<br><br>" +
|
||||
"If you proceed, this wearable will be removed.";
|
||||
lightboxPopup.button1text = "CANCEL";
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.button2text = "CONFIRM";
|
||||
lightboxPopup.button2method = function() {
|
||||
Entities.deleteEntity(msg.wornEntityID);
|
||||
filteredPurchasesModel.setProperty(index, 'wornEntityID', '');
|
||||
root.activeView = "giftAsset";
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.visible = true;
|
||||
} else {
|
||||
root.activeView = "giftAsset";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -693,6 +792,7 @@ Rectangle {
|
|||
|
||||
HifiControlsUit.Keyboard {
|
||||
id: keyboard;
|
||||
z: 999;
|
||||
raised: HMD.mounted && parent.keyboardRaised;
|
||||
numeric: parent.punctuationMode;
|
||||
anchors {
|
||||
|
@ -702,26 +802,6 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (!visible) {
|
||||
inventoryTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: inventoryTimer;
|
||||
interval: 4000; // Change this back to 90000 after demo
|
||||
//interval: 90000;
|
||||
onTriggered: {
|
||||
if (root.activeView === "purchasesMain" && !root.pendingInventoryReply) {
|
||||
console.log("Refreshing Purchases...");
|
||||
root.pendingInventoryReply = true;
|
||||
Commerce.inventory();
|
||||
Commerce.getAvailableUpdates();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// FUNCTION DEFINITIONS START
|
||||
//
|
||||
|
@ -833,10 +913,12 @@ Rectangle {
|
|||
continue;
|
||||
}
|
||||
filteredPurchasesModel.append(tempPurchasesModel.get(i));
|
||||
filteredPurchasesModel.setProperty(i, 'permissionExplanationCardVisible', false);
|
||||
filteredPurchasesModel.setProperty(i, 'cardBackVisible', false);
|
||||
filteredPurchasesModel.setProperty(i, 'isInstalled', ((root.installedApps).indexOf(currentId) > -1));
|
||||
filteredPurchasesModel.setProperty(i, 'wornEntityID', '');
|
||||
}
|
||||
|
||||
|
||||
sendToScript({ method: 'purchases_updateWearables' });
|
||||
populateDisplayedItemCounts();
|
||||
sortByDate();
|
||||
}
|
||||
|
@ -863,6 +945,19 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateCurrentlyWornWearables(wearables) {
|
||||
for (var i = 0; i < filteredPurchasesModel.count; i++) {
|
||||
for (var j = 0; j < wearables.length; j++) {
|
||||
if (filteredPurchasesModel.get(i).itemType === "wearable" &&
|
||||
wearables[j].entityCertID === filteredPurchasesModel.get(i).certificate_id &&
|
||||
wearables[j].entityEdition.toString() === filteredPurchasesModel.get(i).edition_number) {
|
||||
filteredPurchasesModel.setProperty(i, 'wornEntityID', wearables[j].entityID);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Function Name: fromScript()
|
||||
|
@ -890,6 +985,16 @@ Rectangle {
|
|||
case 'purchases_showMyItems':
|
||||
root.isShowingMyItems = true;
|
||||
break;
|
||||
case 'updateConnections':
|
||||
sendAsset.updateConnections(message.connections);
|
||||
break;
|
||||
case 'selectRecipient':
|
||||
case 'updateSelectedRecipientUsername':
|
||||
sendAsset.fromScript(message);
|
||||
break;
|
||||
case 'updateWearables':
|
||||
updateCurrentlyWornWearables(message.wornWearables);
|
||||
break;
|
||||
default:
|
||||
console.log('Unrecognized message from marketplaces.js:', JSON.stringify(message));
|
||||
}
|
||||
|
|
|
@ -143,7 +143,9 @@ Item {
|
|||
lightboxPopup.bodyImageSource = titleBarSecurityImage.source;
|
||||
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,18 +42,6 @@ Item {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This will cause a bug -- if you bring up security image selection in HUD mode while
|
||||
// in HMD while having HMD preview enabled, then move, then finish passphrase selection,
|
||||
// HMD preview will stay off.
|
||||
// TODO: Fix this unlikely bug
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
sendSignalToWallet({method: 'disableHmdPreview'});
|
||||
} else {
|
||||
sendSignalToWallet({method: 'maybeEnableHmdPreview'});
|
||||
}
|
||||
}
|
||||
|
||||
// Security Image
|
||||
Item {
|
||||
|
|
|
@ -18,7 +18,7 @@ import "../../../styles-uit"
|
|||
import "../../../controls-uit" as HifiControlsUit
|
||||
import "../../../controls" as HifiControls
|
||||
import "../common" as HifiCommerceCommon
|
||||
import "./sendMoney"
|
||||
import "../common/sendAsset"
|
||||
|
||||
Rectangle {
|
||||
HifiConstants { id: hifi; }
|
||||
|
@ -160,7 +160,9 @@ Rectangle {
|
|||
lightboxPopup.bodyImageSource = titleBarSecurityImage.source;
|
||||
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
}
|
||||
|
@ -341,7 +343,7 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
SendMoney {
|
||||
SendAsset {
|
||||
id: sendMoney;
|
||||
z: 997;
|
||||
visible: root.activeView === "sendMoney";
|
||||
|
@ -350,7 +352,7 @@ Rectangle {
|
|||
parentAppNavBarHeight: tabButtonsContainer.height;
|
||||
|
||||
Connections {
|
||||
onSendSignalToWallet: {
|
||||
onSendSignalToParent: {
|
||||
sendToScript(msg);
|
||||
}
|
||||
}
|
||||
|
@ -405,7 +407,7 @@ Rectangle {
|
|||
//
|
||||
Item {
|
||||
id: tabButtonsContainer;
|
||||
visible: !needsLogIn.visible && root.activeView !== "passphraseChange" && root.activeView !== "securityImageChange" && sendMoney.currentActiveView !== "sendMoneyStep";
|
||||
visible: !needsLogIn.visible && root.activeView !== "passphraseChange" && root.activeView !== "securityImageChange" && sendMoney.currentActiveView !== "sendAssetStep";
|
||||
property int numTabs: 5;
|
||||
// Size
|
||||
width: root.width;
|
||||
|
|
|
@ -206,9 +206,14 @@ Item {
|
|||
"This step cannot be undone.";
|
||||
lightboxPopup.button1color = hifi.buttons.red;
|
||||
lightboxPopup.button1text = "YES, CREATE NEW WALLET";
|
||||
lightboxPopup.button1method = "root.visible = false;proceed(true);";
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
proceed(true);
|
||||
}
|
||||
lightboxPopup.button2text = "CANCEL";
|
||||
lightboxPopup.button2method = "root.visible = false;"
|
||||
lightboxPopup.button2method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
};
|
||||
lightboxPopup.buttonLayout = "topbottom";
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
|
@ -241,7 +246,9 @@ Item {
|
|||
"If you'd prefer to create a new wallet (not recommended - you will lose your money and past " +
|
||||
"purchases), click 'Create New Wallet'.";
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
} else {
|
||||
lightboxPopup.titleText = "You may have set up more than one wallet";
|
||||
|
@ -251,7 +258,9 @@ Item {
|
|||
"If you would prefer to use another wallet, click 'Locate Other Keys' to show us where " +
|
||||
"you've stored the private keys for that wallet.";
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ Item {
|
|||
UserActivityLogger.commerceWalletSetupProgress(timestamp, root.setupAttemptID,
|
||||
Math.round((timestamp - root.startingTimestamp)/1000), currentStepNumber, root.setupStepNames[currentStepNumber - 1]);
|
||||
|
||||
if (root.activeView === "step_2" || root.activeView === "step_3") {
|
||||
if (root.activeView === "step_3") {
|
||||
sendSignalToWallet({method: 'disableHmdPreview'});
|
||||
} else {
|
||||
sendSignalToWallet({method: 'maybeEnableHmdPreview'});
|
||||
|
@ -150,7 +150,9 @@ Item {
|
|||
lightboxPopup.bodyImageSource = titleBarSecurityImage.source;
|
||||
lightboxPopup.bodyText = lightboxPopup.securityPicBodyText;
|
||||
lightboxPopup.button1text = "CLOSE";
|
||||
lightboxPopup.button1method = "root.visible = false;"
|
||||
lightboxPopup.button1method = function() {
|
||||
lightboxPopup.visible = false;
|
||||
}
|
||||
lightboxPopup.visible = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -344,5 +344,10 @@ QtObject {
|
|||
readonly property string wand: "\ue02d"
|
||||
readonly property string hat: "\ue02e"
|
||||
readonly property string install: "\ue02f"
|
||||
readonly property string certificate: "\ue030"
|
||||
readonly property string gift: "\ue031"
|
||||
readonly property string update: "\ue032"
|
||||
readonly property string uninstall: "\ue033"
|
||||
readonly property string verticalEllipsis: "\ue034"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// DefaultFrame.qml
|
||||
// Decoration.qml
|
||||
//
|
||||
// Created by Bradley Austin Davis on 12 Jan 2016
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
|
|
|
@ -2568,6 +2568,7 @@ void Application::initializeUi() {
|
|||
QUrl{ "hifi/commerce/common/EmulatedMarketplaceHeader.qml" },
|
||||
QUrl{ "hifi/commerce/common/FirstUseTutorial.qml" },
|
||||
QUrl{ "hifi/commerce/common/SortableListModel.qml" },
|
||||
QUrl{ "hifi/commerce/common/sendAsset/SendAsset.qml" },
|
||||
QUrl{ "hifi/commerce/inspectionCertificate/InspectionCertificate.qml" },
|
||||
QUrl{ "hifi/commerce/purchases/PurchasedItem.qml" },
|
||||
QUrl{ "hifi/commerce/purchases/Purchases.qml" },
|
||||
|
@ -2580,7 +2581,6 @@ void Application::initializeUi() {
|
|||
QUrl{ "hifi/commerce/wallet/SecurityImageChange.qml" },
|
||||
QUrl{ "hifi/commerce/wallet/SecurityImageModel.qml" },
|
||||
QUrl{ "hifi/commerce/wallet/SecurityImageSelection.qml" },
|
||||
QUrl{ "hifi/commerce/wallet/sendMoney/SendMoney.qml" },
|
||||
QUrl{ "hifi/commerce/wallet/Wallet.qml" },
|
||||
QUrl{ "hifi/commerce/wallet/WalletHome.qml" },
|
||||
QUrl{ "hifi/commerce/wallet/WalletSetup.qml" },
|
||||
|
@ -3157,6 +3157,10 @@ void Application::loadServerlessDomain(QUrl domainURL) {
|
|||
tmpTree->sendEntities(&_entityEditSender, getEntities()->getTree(), 0, 0, 0);
|
||||
}
|
||||
|
||||
std::map<QString, QString> namedPaths = tmpTree->getNamedPaths();
|
||||
nodeList->getDomainHandler().connectedToServerless(namedPaths);
|
||||
|
||||
|
||||
_fullSceneReceivedCounter++;
|
||||
}
|
||||
|
||||
|
@ -5920,6 +5924,9 @@ void Application::nodeActivated(SharedNodePointer node) {
|
|||
}
|
||||
getMyAvatar()->markIdentityDataChanged();
|
||||
getMyAvatar()->resetLastSent();
|
||||
|
||||
// transmit a "sendAll" packet to the AvatarMixer we just connected to.
|
||||
getMyAvatar()->sendAvatarDataPacket(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,8 +56,8 @@ Handler(buy)
|
|||
Handler(receiveAt)
|
||||
Handler(balance)
|
||||
Handler(inventory)
|
||||
Handler(transferHfcToNode)
|
||||
Handler(transferHfcToUsername)
|
||||
Handler(transferAssetToNode)
|
||||
Handler(transferAssetToUsername)
|
||||
Handler(alreadyOwned)
|
||||
Handler(availableUpdates)
|
||||
Handler(updateItem)
|
||||
|
@ -173,7 +173,8 @@ QString userLink(const QString& username, const QString& placename) {
|
|||
QString transactionString(const QJsonObject& valueObject) {
|
||||
int sentCerts = valueObject["sent_certs"].toInt();
|
||||
int receivedCerts = valueObject["received_certs"].toInt();
|
||||
int sent = valueObject["sent_money"].toInt();
|
||||
int sentMoney = valueObject["sent_money"].toInt();
|
||||
int receivedMoney = valueObject["received_money"].toInt();
|
||||
int dateInteger = valueObject["created_at"].toInt();
|
||||
QString message = valueObject["message"].toString();
|
||||
QDateTime createdAt(QDateTime::fromSecsSinceEpoch(dateInteger, Qt::UTC));
|
||||
|
@ -181,7 +182,7 @@ QString transactionString(const QJsonObject& valueObject) {
|
|||
|
||||
if (sentCerts <= 0 && receivedCerts <= 0 && !KNOWN_USERS.contains(valueObject["sender_name"].toString())) {
|
||||
// this is an hfc transfer.
|
||||
if (sent > 0) {
|
||||
if (sentMoney > 0) {
|
||||
QString recipient = userLink(valueObject["recipient_name"].toString(), valueObject["place_name"].toString());
|
||||
result += QString("Money sent to %1").arg(recipient);
|
||||
} else {
|
||||
|
@ -191,6 +192,18 @@ QString transactionString(const QJsonObject& valueObject) {
|
|||
if (!message.isEmpty()) {
|
||||
result += QString("<br>with memo: <i>\"%1\"</i>").arg(message);
|
||||
}
|
||||
} else if (sentMoney <= 0 && receivedMoney <= 0 && (sentCerts > 0 || receivedCerts > 0) && !KNOWN_USERS.contains(valueObject["sender_name"].toString())) {
|
||||
// this is a non-HFC asset transfer.
|
||||
if (sentCerts > 0) {
|
||||
QString recipient = userLink(valueObject["recipient_name"].toString(), valueObject["place_name"].toString());
|
||||
result += QString("Gift sent to %1").arg(recipient);
|
||||
} else {
|
||||
QString sender = userLink(valueObject["sender_name"].toString(), valueObject["place_name"].toString());
|
||||
result += QString("Gift from %1").arg(sender);
|
||||
}
|
||||
if (!message.isEmpty()) {
|
||||
result += QString("<br>with memo: <i>\"%1\"</i>").arg(message);
|
||||
}
|
||||
} else {
|
||||
result += valueObject["message"].toString();
|
||||
}
|
||||
|
@ -354,27 +367,41 @@ void Ledger::certificateInfo(const QString& certificateId) {
|
|||
send(endpoint, "certificateInfoSuccess", "certificateInfoFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::None, request);
|
||||
}
|
||||
|
||||
void Ledger::transferHfcToNode(const QString& hfc_key, const QString& nodeID, const int& amount, const QString& optionalMessage) {
|
||||
void Ledger::transferAssetToNode(const QString& hfc_key, const QString& nodeID, const QString& certificateID, const int& amount, const QString& optionalMessage) {
|
||||
QJsonObject transaction;
|
||||
transaction["public_key"] = hfc_key;
|
||||
transaction["node_id"] = nodeID;
|
||||
transaction["quantity"] = amount;
|
||||
transaction["message"] = optionalMessage;
|
||||
transaction["place_name"] = DependencyManager::get<AddressManager>()->getPlaceName();
|
||||
if (!certificateID.isEmpty()) {
|
||||
transaction["certificate_id"] = certificateID;
|
||||
}
|
||||
QJsonDocument transactionDoc{ transaction };
|
||||
auto transactionString = transactionDoc.toJson(QJsonDocument::Compact);
|
||||
signedSend("transaction", transactionString, hfc_key, "transfer_hfc_to_node", "transferHfcToNodeSuccess", "transferHfcToNodeFailure");
|
||||
if (certificateID.isEmpty()) {
|
||||
signedSend("transaction", transactionString, hfc_key, "transfer_hfc_to_node", "transferAssetToNodeSuccess", "transferAssetToNodeFailure");
|
||||
} else {
|
||||
signedSend("transaction", transactionString, hfc_key, "transfer_asset_to_node", "transferAssetToNodeSuccess", "transferAssetToNodeFailure");
|
||||
}
|
||||
}
|
||||
|
||||
void Ledger::transferHfcToUsername(const QString& hfc_key, const QString& username, const int& amount, const QString& optionalMessage) {
|
||||
void Ledger::transferAssetToUsername(const QString& hfc_key, const QString& username, const QString& certificateID, const int& amount, const QString& optionalMessage) {
|
||||
QJsonObject transaction;
|
||||
transaction["public_key"] = hfc_key;
|
||||
transaction["username"] = username;
|
||||
transaction["quantity"] = amount;
|
||||
transaction["message"] = optionalMessage;
|
||||
if (!certificateID.isEmpty()) {
|
||||
transaction["certificate_id"] = certificateID;
|
||||
}
|
||||
QJsonDocument transactionDoc{ transaction };
|
||||
auto transactionString = transactionDoc.toJson(QJsonDocument::Compact);
|
||||
signedSend("transaction", transactionString, hfc_key, "transfer_hfc_to_user", "transferHfcToUsernameSuccess", "transferHfcToUsernameFailure");
|
||||
if (certificateID.isEmpty()) {
|
||||
signedSend("transaction", transactionString, hfc_key, "transfer_hfc_to_user", "transferAssetToUsernameSuccess", "transferAssetToUsernameFailure");
|
||||
} else {
|
||||
signedSend("transaction", transactionString, hfc_key, "transfer_asset_to_user", "transferAssetToUsernameSuccess", "transferAssetToUsernameFailure");
|
||||
}
|
||||
}
|
||||
|
||||
void Ledger::alreadyOwned(const QString& marketplaceId) {
|
||||
|
|
|
@ -33,8 +33,8 @@ public:
|
|||
void account();
|
||||
void updateLocation(const QString& asset_id, const QString& location, const bool& alsoUpdateSiblings = false, const bool controlledFailure = false);
|
||||
void certificateInfo(const QString& certificateId);
|
||||
void transferHfcToNode(const QString& hfc_key, const QString& nodeID, const int& amount, const QString& optionalMessage);
|
||||
void transferHfcToUsername(const QString& hfc_key, const QString& username, const int& amount, const QString& optionalMessage);
|
||||
void transferAssetToNode(const QString& hfc_key, const QString& nodeID, const QString& certificateID, const int& amount, const QString& optionalMessage);
|
||||
void transferAssetToUsername(const QString& hfc_key, const QString& username, const QString& certificateID, const int& amount, const QString& optionalMessage);
|
||||
void alreadyOwned(const QString& marketplaceId);
|
||||
void getAvailableUpdates(const QString& itemId = "");
|
||||
void updateItem(const QString& hfc_key, const QString& certificate_id);
|
||||
|
@ -56,8 +56,8 @@ signals:
|
|||
void accountResult(QJsonObject result);
|
||||
void locationUpdateResult(QJsonObject result);
|
||||
void certificateInfoResult(QJsonObject result);
|
||||
void transferHfcToNodeResult(QJsonObject result);
|
||||
void transferHfcToUsernameResult(QJsonObject result);
|
||||
void transferAssetToNodeResult(QJsonObject result);
|
||||
void transferAssetToUsernameResult(QJsonObject result);
|
||||
void alreadyOwnedResult(QJsonObject result);
|
||||
void availableUpdatesResult(QJsonObject result);
|
||||
void updateItemResult(QJsonObject result);
|
||||
|
@ -81,10 +81,10 @@ public slots:
|
|||
void updateLocationFailure(QNetworkReply& reply);
|
||||
void certificateInfoSuccess(QNetworkReply& reply);
|
||||
void certificateInfoFailure(QNetworkReply& reply);
|
||||
void transferHfcToNodeSuccess(QNetworkReply& reply);
|
||||
void transferHfcToNodeFailure(QNetworkReply& reply);
|
||||
void transferHfcToUsernameSuccess(QNetworkReply& reply);
|
||||
void transferHfcToUsernameFailure(QNetworkReply& reply);
|
||||
void transferAssetToNodeSuccess(QNetworkReply& reply);
|
||||
void transferAssetToNodeFailure(QNetworkReply& reply);
|
||||
void transferAssetToUsernameSuccess(QNetworkReply& reply);
|
||||
void transferAssetToUsernameFailure(QNetworkReply& reply);
|
||||
void alreadyOwnedSuccess(QNetworkReply& reply);
|
||||
void alreadyOwnedFailure(QNetworkReply& reply);
|
||||
void availableUpdatesSuccess(QNetworkReply& reply);
|
||||
|
|
|
@ -36,8 +36,8 @@ QmlCommerce::QmlCommerce() {
|
|||
connect(ledger.data(), &Ledger::certificateInfoResult, this, &QmlCommerce::certificateInfoResult);
|
||||
connect(ledger.data(), &Ledger::alreadyOwnedResult, this, &QmlCommerce::alreadyOwnedResult);
|
||||
connect(ledger.data(), &Ledger::updateCertificateStatus, this, &QmlCommerce::updateCertificateStatus);
|
||||
connect(ledger.data(), &Ledger::transferHfcToNodeResult, this, &QmlCommerce::transferHfcToNodeResult);
|
||||
connect(ledger.data(), &Ledger::transferHfcToUsernameResult, this, &QmlCommerce::transferHfcToUsernameResult);
|
||||
connect(ledger.data(), &Ledger::transferAssetToNodeResult, this, &QmlCommerce::transferAssetToNodeResult);
|
||||
connect(ledger.data(), &Ledger::transferAssetToUsernameResult, this, &QmlCommerce::transferAssetToUsernameResult);
|
||||
connect(ledger.data(), &Ledger::availableUpdatesResult, this, &QmlCommerce::availableUpdatesResult);
|
||||
connect(ledger.data(), &Ledger::updateItemResult, this, &QmlCommerce::updateItemResult);
|
||||
|
||||
|
@ -166,28 +166,28 @@ void QmlCommerce::certificateInfo(const QString& certificateId) {
|
|||
ledger->certificateInfo(certificateId);
|
||||
}
|
||||
|
||||
void QmlCommerce::transferHfcToNode(const QString& nodeID, const int& amount, const QString& optionalMessage) {
|
||||
void QmlCommerce::transferAssetToNode(const QString& nodeID, const QString& certificateID, const int& amount, const QString& optionalMessage) {
|
||||
auto ledger = DependencyManager::get<Ledger>();
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
QStringList keys = wallet->listPublicKeys();
|
||||
if (keys.count() == 0) {
|
||||
QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } };
|
||||
return emit buyResult(result);
|
||||
return emit transferAssetToNodeResult(result);
|
||||
}
|
||||
QString key = keys[0];
|
||||
ledger->transferHfcToNode(key, nodeID, amount, optionalMessage);
|
||||
ledger->transferAssetToNode(key, nodeID, certificateID, amount, optionalMessage);
|
||||
}
|
||||
|
||||
void QmlCommerce::transferHfcToUsername(const QString& username, const int& amount, const QString& optionalMessage) {
|
||||
void QmlCommerce::transferAssetToUsername(const QString& username, const QString& certificateID, const int& amount, const QString& optionalMessage) {
|
||||
auto ledger = DependencyManager::get<Ledger>();
|
||||
auto wallet = DependencyManager::get<Wallet>();
|
||||
QStringList keys = wallet->listPublicKeys();
|
||||
if (keys.count() == 0) {
|
||||
QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } };
|
||||
return emit buyResult(result);
|
||||
return emit transferAssetToUsernameResult(result);
|
||||
}
|
||||
QString key = keys[0];
|
||||
ledger->transferHfcToUsername(key, username, amount, optionalMessage);
|
||||
ledger->transferAssetToUsername(key, username, certificateID, amount, optionalMessage);
|
||||
}
|
||||
|
||||
void QmlCommerce::replaceContentSet(const QString& itemHref, const QString& certificateID) {
|
||||
|
|
|
@ -48,8 +48,8 @@ signals:
|
|||
|
||||
void updateCertificateStatus(const QString& certID, uint certStatus);
|
||||
|
||||
void transferHfcToNodeResult(QJsonObject result);
|
||||
void transferHfcToUsernameResult(QJsonObject result);
|
||||
void transferAssetToNodeResult(QJsonObject result);
|
||||
void transferAssetToUsernameResult(QJsonObject result);
|
||||
|
||||
void contentSetChanged(const QString& contentSetHref);
|
||||
|
||||
|
@ -81,8 +81,8 @@ protected:
|
|||
Q_INVOKABLE void certificateInfo(const QString& certificateId);
|
||||
Q_INVOKABLE void alreadyOwned(const QString& marketplaceId);
|
||||
|
||||
Q_INVOKABLE void transferHfcToNode(const QString& nodeID, const int& amount, const QString& optionalMessage);
|
||||
Q_INVOKABLE void transferHfcToUsername(const QString& username, const int& amount, const QString& optionalMessage);
|
||||
Q_INVOKABLE void transferAssetToNode(const QString& nodeID, const QString& certificateID, const int& amount, const QString& optionalMessage);
|
||||
Q_INVOKABLE void transferAssetToUsername(const QString& username, const QString& certificateID, const int& amount, const QString& optionalMessage);
|
||||
|
||||
Q_INVOKABLE void replaceContentSet(const QString& itemHref, const QString& certificateID);
|
||||
|
||||
|
|
|
@ -13,8 +13,9 @@
|
|||
#include "Ledger.h"
|
||||
#include "Wallet.h"
|
||||
#include "Application.h"
|
||||
#include "ui/ImageProvider.h"
|
||||
#include "ui/SecurityImageProvider.h"
|
||||
#include "scripting/HMDScriptingInterface.h"
|
||||
#include <ui/TabletScriptingInterface.h>
|
||||
|
||||
#include <PathUtils.h>
|
||||
#include <OffscreenUi.h>
|
||||
|
@ -566,7 +567,6 @@ bool Wallet::generateKeyPair() {
|
|||
}
|
||||
|
||||
QStringList Wallet::listPublicKeys() {
|
||||
qCInfo(commerce) << "Enumerating public keys.";
|
||||
return _publicKeys;
|
||||
}
|
||||
|
||||
|
@ -607,11 +607,17 @@ QString Wallet::signWithKey(const QByteArray& text, const QString& key) {
|
|||
}
|
||||
|
||||
void Wallet::updateImageProvider() {
|
||||
// inform the image provider. Note it doesn't matter which one you inform, as the
|
||||
// images are statics
|
||||
auto engine = DependencyManager::get<OffscreenUi>()->getSurfaceContext()->engine();
|
||||
auto imageProvider = reinterpret_cast<ImageProvider*>(engine->imageProvider(ImageProvider::PROVIDER_NAME));
|
||||
imageProvider->setSecurityImage(_securityImage);
|
||||
SecurityImageProvider* securityImageProvider;
|
||||
|
||||
// inform offscreenUI security image provider
|
||||
QQmlEngine* engine = DependencyManager::get<OffscreenUi>()->getSurfaceContext()->engine();
|
||||
securityImageProvider = reinterpret_cast<SecurityImageProvider*>(engine->imageProvider(SecurityImageProvider::PROVIDER_NAME));
|
||||
securityImageProvider->setSecurityImage(_securityImage);
|
||||
|
||||
// inform tablet security image provider
|
||||
QQmlEngine* tabletEngine = DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system")->getTabletSurface()->getSurfaceContext()->engine();
|
||||
securityImageProvider = reinterpret_cast<SecurityImageProvider*>(tabletEngine->imageProvider(SecurityImageProvider::PROVIDER_NAME));
|
||||
securityImageProvider->setSecurityImage(_securityImage);
|
||||
}
|
||||
|
||||
void Wallet::chooseSecurityImage(const QString& filename) {
|
||||
|
@ -651,6 +657,7 @@ bool Wallet::getSecurityImage() {
|
|||
|
||||
// if already decrypted, don't do it again
|
||||
if (_securityImage) {
|
||||
updateImageProvider();
|
||||
emit securityImageResult(true);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,36 @@ class QScriptEngine;
|
|||
|
||||
#include <QReadWriteLock>
|
||||
|
||||
/**jsdoc
|
||||
* The HMD API provides access to the HMD used in VR display mode.
|
||||
*
|
||||
* @namespace HMD
|
||||
* @property {Vec3} position - The position of the HMD if currently in VR display mode, otherwise
|
||||
* {@link Vec3(0)|Vec3.ZERO}. <em>Read-only.</em>
|
||||
* @property {Quat} orientation - The orientation of the HMD if currently in VR display mode, otherwise
|
||||
* {@link Quat(0)|Quat.IDENTITY}. <em>Read-only.</em>
|
||||
* @property {boolean} active - <code>true</code> if the display mode is HMD, otherwise <code>false</code>. <em>Read-only.</em>
|
||||
* @property {boolean} mounted - <code>true</code> if currently in VR display mode and the HMD is being worn, otherwise
|
||||
* <code>false</code>. <em>Read-only.</em>
|
||||
*
|
||||
* @property {number} playerHeight - The real-world height of the user. <em>Read-only.</em> <em>Currently always returns a
|
||||
* value of <code>1.755</code>.</em>
|
||||
* @property {number} eyeHeight - The real-world height of the user's eyes. <em>Read-only.</em> <em>Currently always returns a
|
||||
* value of <code>1.655</code>.</em>
|
||||
* @property {number} ipd - The inter-pupillary distance (distance between eyes) of the user, used for rendering. Defaults to
|
||||
* the human average of <code>0.064</code> unless set by the HMD. <em>Read-only.</em>
|
||||
* @property {number} ipdScale=1.0 - A scale factor applied to the <code>ipd</code> property value.
|
||||
*
|
||||
* @property {boolean} showTablet - <code>true</code> if the tablet is being displayed, <code>false</code> otherwise.
|
||||
* <em>Read-only.</em>
|
||||
* @property {boolean} tabletContextualMode - <code>true</code> if the tablet has been opened in contextual mode, otherwise
|
||||
* <code>false</code>. In contextual mode, the tablet has been opened at a specific world position and orientation rather
|
||||
* than at a position and orientation relative to the user. <em>Read-only.</em>
|
||||
* @property {Uuid} tabletID - The UUID of the tablet body model overlay.
|
||||
* @property {Uuid} tabletScreenID - The UUID of the tablet's screen overlay.
|
||||
* @property {Uuid} homeButtonID - The UUID of the tablet's "home" button overlay.
|
||||
* @property {Uuid} homeButtonHighlightID - The UUID of the tablet's "home" button highlight overlay.
|
||||
*/
|
||||
class HMDScriptingInterface : public AbstractHMDScriptingInterface, public Dependency {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(glm::vec3 position READ getPosition)
|
||||
|
@ -37,26 +67,217 @@ class HMDScriptingInterface : public AbstractHMDScriptingInterface, public Depen
|
|||
Q_PROPERTY(QUuid tabletScreenID READ getCurrentTabletScreenID WRITE setCurrentTabletScreenID)
|
||||
|
||||
public:
|
||||
|
||||
/**jsdoc
|
||||
* Calculate the intersection of a ray with the HUD overlay.
|
||||
* @function HMD.calculateRayUICollisionPoint
|
||||
* @param {Vec3} position - The origin of the ray.
|
||||
* @param {Vec3} direction - The direction of the ray.
|
||||
* @returns {Vec3} The point of intersection with the HUD overlay if it intersects, otherwise {@link Vec3(0)|Vec3.ZERO}.
|
||||
* @example <caption>Draw a square on the HUD overlay in the direction you're looking.</caption>
|
||||
* var hudIntersection = HMD.calculateRayUICollisionPoint(MyAvatar.getHeadPosition(),
|
||||
* Quat.getForward(MyAvatar.headOrientation));
|
||||
* var hudPoint = HMD.overlayFromWorldPoint(hudIntersection);
|
||||
*
|
||||
* var DIMENSIONS = { x: 50, y: 50 };
|
||||
* var square = Overlays.addOverlay("rectangle", {
|
||||
* x: hudPoint.x - DIMENSIONS.x / 2,
|
||||
* y: hudPoint.y - DIMENSIONS.y / 2,
|
||||
* width: DIMENSIONS.x,
|
||||
* height: DIMENSIONS.y,
|
||||
* color: { red: 255, green: 0, blue: 0 }
|
||||
* });
|
||||
*
|
||||
* Script.scriptEnding.connect(function () {
|
||||
* Overlays.deleteOverlay(square);
|
||||
* });
|
||||
*/
|
||||
Q_INVOKABLE glm::vec3 calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction) const;
|
||||
|
||||
/**jsdoc
|
||||
* Get the 2D HUD overlay coordinates of a 3D point on the HUD overlay.
|
||||
* 2D HUD overlay coordinates are pixels with the origin at the top left of the overlay.
|
||||
* @function HMD.overlayFromWorldPoint
|
||||
* @param {Vec3} position - The point on the HUD overlay in world coordinates.
|
||||
* @returns {Vec2} The point on the HUD overlay in HUD coordinates.
|
||||
* @example <caption>Draw a square on the HUD overlay in the direction you're looking.</caption>
|
||||
* var hudIntersection = HMD.calculateRayUICollisionPoint(MyAvatar.getHeadPosition(),
|
||||
* Quat.getForward(MyAvatar.headOrientation));
|
||||
* var hudPoint = HMD.overlayFromWorldPoint(hudIntersection);
|
||||
*
|
||||
* var DIMENSIONS = { x: 50, y: 50 };
|
||||
* var square = Overlays.addOverlay("rectangle", {
|
||||
* x: hudPoint.x - DIMENSIONS.x / 2,
|
||||
* y: hudPoint.y - DIMENSIONS.y / 2,
|
||||
* width: DIMENSIONS.x,
|
||||
* height: DIMENSIONS.y,
|
||||
* color: { red: 255, green: 0, blue: 0 }
|
||||
* });
|
||||
*
|
||||
* Script.scriptEnding.connect(function () {
|
||||
* Overlays.deleteOverlay(square);
|
||||
* });
|
||||
*/
|
||||
Q_INVOKABLE glm::vec2 overlayFromWorldPoint(const glm::vec3& position) const;
|
||||
|
||||
/**jsdoc
|
||||
* Get the 3D world coordinates of a 2D point on the HUD overlay.
|
||||
* 2D HUD overlay coordinates are pixels with the origin at the top left of the overlay.
|
||||
* @function HMD.worldPointFromOverlay
|
||||
* @param {Vec2} coordinates - The point on the HUD overlay in HUD coordinates.
|
||||
* @returns {Vec3} The point on the HUD overlay in world coordinates.
|
||||
*/
|
||||
Q_INVOKABLE glm::vec3 worldPointFromOverlay(const glm::vec2& overlay) const;
|
||||
|
||||
/**jsdoc
|
||||
* Get the 2D point on the HUD overlay represented by given spherical coordinates.
|
||||
* 2D HUD overlay coordinates are pixels with the origin at the top left of the overlay.
|
||||
* Spherical coordinates are polar coordinates in radians with <code>{ x: 0, y: 0 }</code> being the center of the HUD
|
||||
* overlay.
|
||||
* @function HMD.sphericalToOverlay
|
||||
* @param {Vec2} sphericalPos - The point on the HUD overlay in spherical coordinates.
|
||||
* @returns {Vec2} The point on the HUD overlay in HUD coordinates.
|
||||
*/
|
||||
Q_INVOKABLE glm::vec2 sphericalToOverlay(const glm::vec2 & sphericalPos) const;
|
||||
|
||||
/**jsdoc
|
||||
* Get the spherical coordinates of a 2D point on the HUD overlay.
|
||||
* 2D HUD overlay coordinates are pixels with the origin at the top left of the overlay.
|
||||
* Spherical coordinates are polar coordinates in radians with <code>{ x: 0, y: 0 }</code> being the center of the HUD
|
||||
* overlay.
|
||||
* @function HMD.overlayToSpherical
|
||||
* @param {Vec2} overlayPos - The point on the HUD overlay in HUD coordinates.
|
||||
* @returns {Vec2} The point on the HUD overlay in spherical coordinates.
|
||||
*/
|
||||
Q_INVOKABLE glm::vec2 overlayToSpherical(const glm::vec2 & overlayPos) const;
|
||||
|
||||
/**jsdoc
|
||||
* Recenter the HMD HUD to the current HMD position and orientation.
|
||||
* @function HMD.centerUI
|
||||
*/
|
||||
Q_INVOKABLE void centerUI();
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Get the name of the HMD audio input device.
|
||||
* @function HMD.preferredAudioInput
|
||||
* @returns {string} The name of the HMD audio input device if in HMD mode, otherwise an empty string.
|
||||
*/
|
||||
Q_INVOKABLE QString preferredAudioInput() const;
|
||||
|
||||
/**jsdoc
|
||||
* Get the name of the HMD audio output device.
|
||||
* @function HMD.preferredAudioOutput
|
||||
* @returns {string} The name of the HMD audio output device if in HMD mode, otherwise an empty string.
|
||||
*/
|
||||
Q_INVOKABLE QString preferredAudioOutput() const;
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Check whether there is an HMD available.
|
||||
* @function HMD.isHMDAvailable
|
||||
* @param {string} [name=""] - The name of the HMD to check for, e.g., <code>"Oculus Rift"</code>. The name is the same as
|
||||
* may be displayed in Interface's "Display" menu. If no name is specified then any HMD matches.
|
||||
* @returns {boolean} <code>true</code> if an HMD of the specified <code>name</code> is available, otherwise
|
||||
* <code>false</code>.
|
||||
* @example <caption>Report on HMD availability.</caption>
|
||||
* print("Is any HMD available: " + HMD.isHMDAvailable());
|
||||
* print("Is an Oculus Rift HMD available: " + HMD.isHMDAvailable("Oculus Rift"));
|
||||
* print("Is a Vive HMD available: " + HMD.isHMDAvailable("OpenVR (Vive)"));
|
||||
*/
|
||||
Q_INVOKABLE bool isHMDAvailable(const QString& name = "");
|
||||
|
||||
/**jsdoc
|
||||
* Check whether there is an HMD head controller available.
|
||||
* @function HMD.isHeadControllerAvailable
|
||||
* @param {string} [name=""] - The name of the HMD head controller to check for, e.g., <code>"Oculus"</code>. If no name is
|
||||
* specified then any HMD head controller matches.
|
||||
* @returns {boolean} <code>true</code> if an HMD head controller of the specified <code>name</code> is available,
|
||||
* otherwise <code>false</code>.
|
||||
* @example <caption>Report HMD head controller availability.</caption>
|
||||
* print("Is any HMD head controller available: " + HMD.isHeadControllerAvailable());
|
||||
* print("Is an Oculus head controller available: " + HMD.isHeadControllerAvailable("Oculus"));
|
||||
* print("Is a Vive head controller available: " + HMD.isHeadControllerAvailable("OpenVR"));
|
||||
*/
|
||||
Q_INVOKABLE bool isHeadControllerAvailable(const QString& name = "");
|
||||
|
||||
/**jsdoc
|
||||
* Check whether there are HMD hand controllers available.
|
||||
* @function HMD.isHandControllerAvailable
|
||||
* @param {string} [name=""] - The name of the HMD hand controller to check for, e.g., <code>"Oculus"</code>. If no name is
|
||||
* specified then any HMD hand controller matches.
|
||||
* @returns {boolean} <code>true</code> if an HMD hand controller of the specified <code>name</code> is available,
|
||||
* otherwise <code>false</code>.
|
||||
* @example <caption>Report HMD hand controller availability.</caption>
|
||||
* print("Are any HMD hand controllers available: " + HMD.isHandControllerAvailable());
|
||||
* print("Are Oculus hand controllers available: " + HMD.isHandControllerAvailable("Oculus"));
|
||||
* print("Are Vive hand controllers available: " + HMD.isHandControllerAvailable("OpenVR"));
|
||||
*/
|
||||
Q_INVOKABLE bool isHandControllerAvailable(const QString& name = "");
|
||||
|
||||
/**jsdoc
|
||||
* Check whether there are specific HMD controllers available.
|
||||
* @function HMD.isSubdeviceContainingNameAvailable
|
||||
* @param {string} name - The name of the HMD controller to check for, e.g., <code>"OculusTouch"</code>.
|
||||
* @returns {boolean} <code>true</code> if an HMD controller with a name containing the specified <code>name</code> is
|
||||
* available, otherwise <code>false</code>.
|
||||
* @example <caption>Report if particular Oculus controllers are available.</caption>
|
||||
* print("Is an Oculus Touch controller available: " + HMD.isSubdeviceContainingNameAvailable("Touch"));
|
||||
* print("Is an Oculus Remote controller available: " + HMD.isSubdeviceContainingNameAvailable("Remote"));
|
||||
*/
|
||||
Q_INVOKABLE bool isSubdeviceContainingNameAvailable(const QString& name);
|
||||
|
||||
/**jsdoc
|
||||
* Signal that models of the HMD hand controllers being used should be displayed. The models are displayed at their actual,
|
||||
* real-world locations.
|
||||
* @function HMD.requestShowHandControllers
|
||||
* @example <caption>Show your hand controllers for 10 seconds.</caption>
|
||||
* HMD.requestShowHandControllers();
|
||||
* Script.setTimeout(function () {
|
||||
* HMD.requestHideHandControllers();
|
||||
* }, 10000);
|
||||
*/
|
||||
Q_INVOKABLE void requestShowHandControllers();
|
||||
|
||||
/**jsdoc
|
||||
* Signal that it is no longer necessary to display models of the HMD hand controllers being used. If no other scripts
|
||||
* want the models displayed then they are no longer displayed.
|
||||
* @function HMD.requestHideHandControllers
|
||||
*/
|
||||
Q_INVOKABLE void requestHideHandControllers();
|
||||
|
||||
/**jsdoc
|
||||
* Check whether any script wants models of the HMD hand controllers displayed. Requests are made and canceled using
|
||||
* {@link HMD.requestShowHandControllers|requestShowHandControllers} and
|
||||
* {@link HMD.requestHideHandControllers|requestHideHandControllers}.
|
||||
* @function HMD.shouldShowHandControllers
|
||||
* @returns {boolean} <code>true</code> if any script is requesting that HMD hand controller models be displayed.
|
||||
*/
|
||||
Q_INVOKABLE bool shouldShowHandControllers() const;
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Causes the borders in HUD windows to be enlarged when the laser intersects them in HMD mode. By default, borders are not
|
||||
* enlarged.
|
||||
* @function HMD.activateHMDHandMouse
|
||||
*/
|
||||
Q_INVOKABLE void activateHMDHandMouse();
|
||||
|
||||
/**jsdoc
|
||||
* Causes the border in HUD windows to no longer be enlarged when the laser intersects them in HMD mode. By default,
|
||||
* borders are not enlarged.
|
||||
* @function HMD.deactivateHMDHandMouse
|
||||
*/
|
||||
Q_INVOKABLE void deactivateHMDHandMouse();
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Suppress the activation of the HMD-provided keyboard, if any. Successful calls should be balanced with a call to
|
||||
* {@link HMD.unspressKeyboard|unspressKeyboard} within a reasonable amount of time.
|
||||
* @function HMD.suppressKeyboard
|
||||
* @returns {boolean} <code>true</code> if the current HMD provides a keyboard and it was successfully suppressed (e.g., it
|
||||
* isn't being displayed), otherwise <code>false</code>.
|
||||
*/
|
||||
/// Suppress the activation of any on-screen keyboard so that a script operation will
|
||||
/// not be interrupted by a keyboard popup
|
||||
/// Returns false if there is already an active keyboard displayed.
|
||||
|
@ -65,21 +286,68 @@ public:
|
|||
/// call to unsuppressKeyboard() within a reasonable amount of time
|
||||
Q_INVOKABLE bool suppressKeyboard();
|
||||
|
||||
/**jsdoc
|
||||
* Unsuppress the activation of the HMD-provided keyboard, if any.
|
||||
* @function HMD.unsuppressKeyboard
|
||||
*/
|
||||
/// Enable the keyboard following a suppressKeyboard call
|
||||
Q_INVOKABLE void unsuppressKeyboard();
|
||||
|
||||
/**jsdoc
|
||||
* Check whether the HMD-provided keyboard, if any, is visible.
|
||||
* @function HMD.isKeyboardVisible
|
||||
* @returns {boolean} <code>true</code> if the current HMD provides a keyboard and it is visible, otherwise
|
||||
* <code>false</code>.
|
||||
*/
|
||||
/// Query the display plugin to determine the current VR keyboard visibility
|
||||
Q_INVOKABLE bool isKeyboardVisible();
|
||||
|
||||
// rotate the overlay UI sphere so that it is centered about the the current HMD position and orientation
|
||||
Q_INVOKABLE void centerUI();
|
||||
|
||||
/**jsdoc
|
||||
* Closes the tablet if it is open.
|
||||
* @function HMD.closeTablet
|
||||
*/
|
||||
Q_INVOKABLE void closeTablet();
|
||||
|
||||
/**jsdoc
|
||||
* Opens the tablet if the tablet is used in the current display mode and it isn't already showing, and sets the tablet to
|
||||
* contextual mode if requested. In contextual mode, the page displayed on the tablet is wholly controlled by script (i.e.,
|
||||
* the user cannot navigate to another).
|
||||
* @function HMD.openTablet
|
||||
* @param {boolean} [contextualMode=false] - If <code>true</code> then the tablet is opened at a specific position and
|
||||
* orientation already set by the script, otherwise it opens at a position and orientation relative to the user. For
|
||||
* contextual mode, set the world or local position and orientation of the <code>HMD.tabletID</code> overlay.
|
||||
*/
|
||||
Q_INVOKABLE void openTablet(bool contextualMode = false);
|
||||
|
||||
signals:
|
||||
/**jsdoc
|
||||
* Triggered when a request to show or hide models of the HMD hand controllers is made using
|
||||
* {@link HMD.requestShowHandControllers|requestShowHandControllers} or
|
||||
* {@link HMD.requestHideHandControllers|requestHideHandControllers}.
|
||||
* @function HMD.shouldShowHandControllersChanged
|
||||
* @returns {Signal}
|
||||
* @example <caption>Report when showing of hand controllers changes.</caption>
|
||||
* function onShouldShowHandControllersChanged() {
|
||||
* print("Should show hand controllers: " + HMD.shouldShowHandControllers());
|
||||
* }
|
||||
* HMD.shouldShowHandControllersChanged.connect(onShouldShowHandControllersChanged);
|
||||
*
|
||||
* HMD.requestShowHandControllers();
|
||||
* Script.setTimeout(function () {
|
||||
* HMD.requestHideHandControllers();
|
||||
* }, 10000);
|
||||
*/
|
||||
bool shouldShowHandControllersChanged();
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the <code>HMD.mounted</code> property value changes.
|
||||
* @function HMD.mountedChanged
|
||||
* @returns {Signal}
|
||||
* @example <caption>Report when there's a change in the HMD being worn.</caption>
|
||||
* HMD.mountedChanged.connect(function () {
|
||||
* print("Mounted changed. HMD is mounted: " + HMD.mounted);
|
||||
* });
|
||||
*/
|
||||
void mountedChanged();
|
||||
|
||||
public:
|
||||
|
|
|
@ -58,6 +58,13 @@ void SkeletonModel::initJointStates() {
|
|||
glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset);
|
||||
_rig.initJointStates(geometry, modelOffset);
|
||||
|
||||
{
|
||||
// initialize _jointData with proper values for default joints
|
||||
QVector<JointData> defaultJointData;
|
||||
_rig.copyJointsIntoJointData(defaultJointData);
|
||||
_owningAvatar->setRawJointData(defaultJointData);
|
||||
}
|
||||
|
||||
// Determine the default eye position for avatar scale = 1.0
|
||||
int headJointIndex = geometry.headJointIndex;
|
||||
if (0 > headJointIndex || headJointIndex >= _rig.getJointStateCount()) {
|
||||
|
|
|
@ -559,7 +559,8 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
|||
const JointData& last = lastSentJointData[i];
|
||||
|
||||
if (!data.rotationIsDefaultPose) {
|
||||
if (sendAll || last.rotationIsDefaultPose || last.rotation != data.rotation) {
|
||||
bool mustSend = sendAll || last.rotationIsDefaultPose;
|
||||
if (mustSend || last.rotation != data.rotation) {
|
||||
|
||||
bool largeEnoughRotation = true;
|
||||
if (cullSmallChanges) {
|
||||
|
@ -568,7 +569,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
|||
largeEnoughRotation = fabsf(glm::dot(last.rotation, data.rotation)) < minRotationDOT;
|
||||
}
|
||||
|
||||
if (sendAll || !cullSmallChanges || largeEnoughRotation) {
|
||||
if (mustSend || !cullSmallChanges || largeEnoughRotation) {
|
||||
validity |= (1 << validityBit);
|
||||
#ifdef WANT_DEBUG
|
||||
rotationSentCount++;
|
||||
|
@ -608,10 +609,12 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
|||
float maxTranslationDimension = 0.0;
|
||||
for (int i = 0; i < _jointData.size(); i++) {
|
||||
const JointData& data = _jointData[i];
|
||||
const JointData& last = lastSentJointData[i];
|
||||
|
||||
if (!data.translationIsDefaultPose) {
|
||||
if (sendAll || lastSentJointData[i].translation != data.translation) {
|
||||
if (sendAll || !cullSmallChanges || glm::distance(data.translation, lastSentJointData[i].translation) > minTranslation) {
|
||||
bool mustSend = sendAll || last.translationIsDefaultPose;
|
||||
if (mustSend || last.translation != data.translation) {
|
||||
if (mustSend || !cullSmallChanges || glm::distance(data.translation, lastSentJointData[i].translation) > minTranslation) {
|
||||
validity |= (1 << validityBit);
|
||||
#ifdef WANT_DEBUG
|
||||
translationSentCount++;
|
||||
|
@ -669,6 +672,19 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
|||
}
|
||||
|
||||
if (sentJointDataOut) {
|
||||
|
||||
// Mark default poses in lastSentJointData, so when they become non-default we send them.
|
||||
for (int i = 0; i < _jointData.size(); i++) {
|
||||
const JointData& data = _jointData[i];
|
||||
JointData& local = localSentJointDataOut[i];
|
||||
if (data.rotationIsDefaultPose) {
|
||||
local.rotationIsDefaultPose = true;
|
||||
}
|
||||
if (data.translationIsDefaultPose) {
|
||||
local.translationIsDefaultPose = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Push new sent joint data to sentJointDataOut
|
||||
sentJointDataOut->swap(localSentJointDataOut);
|
||||
}
|
||||
|
@ -1816,13 +1832,13 @@ void AvatarData::setJointMappingsFromNetworkReply() {
|
|||
networkReply->deleteLater();
|
||||
}
|
||||
|
||||
void AvatarData::sendAvatarDataPacket() {
|
||||
void AvatarData::sendAvatarDataPacket(bool sendAll) {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
// about 2% of the time, we send a full update (meaning, we transmit all the joint data), even if nothing has changed.
|
||||
// this is to guard against a joint moving once, the packet getting lost, and the joint never moving again.
|
||||
|
||||
bool cullSmallData = (randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO);
|
||||
bool cullSmallData = !sendAll && (randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO);
|
||||
auto dataDetail = cullSmallData ? SendAllData : CullSmallData;
|
||||
QByteArray avatarByteArray = toByteArrayStateful(dataDetail);
|
||||
|
||||
|
|
|
@ -256,6 +256,11 @@ namespace AvatarDataPacket {
|
|||
SixByteQuat rotation[numValidRotations]; // encodeded and compressed by packOrientationQuatToSixBytes()
|
||||
uint8_t translationValidityBits[ceil(numJoints / 8)]; // one bit per joint, if true then a compressed translation follows.
|
||||
SixByteTrans translation[numValidTranslations]; // encodeded and compressed by packFloatVec3ToSignedTwoByteFixed()
|
||||
|
||||
SixByteQuat leftHandControllerRotation;
|
||||
SixByteTrans leftHandControllerTranslation;
|
||||
SixByteQuat rightHandControllerRotation;
|
||||
SixByteTrans rightHandControllerTranslation;
|
||||
};
|
||||
*/
|
||||
size_t maxJointDataSize(size_t numJoints);
|
||||
|
@ -707,11 +712,11 @@ signals:
|
|||
void sessionUUIDChanged();
|
||||
|
||||
public slots:
|
||||
void sendAvatarDataPacket();
|
||||
void sendAvatarDataPacket(bool sendAll = false);
|
||||
void sendIdentityPacket();
|
||||
|
||||
void setJointMappingsFromNetworkReply();
|
||||
void setSessionUUID(const QUuid& sessionUUID) {
|
||||
virtual void setSessionUUID(const QUuid& sessionUUID) {
|
||||
if (sessionUUID != getID()) {
|
||||
if (sessionUUID == QUuid()) {
|
||||
setID(AVATAR_SELF_ID);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <GLMHelpers.h>
|
||||
|
||||
// These properties have JSDoc documentation in HMDScriptingInterface.h.
|
||||
class AbstractHMDScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool active READ isHMDMode)
|
||||
|
@ -30,7 +31,27 @@ public:
|
|||
bool isHMDMode() const;
|
||||
|
||||
signals:
|
||||
/**jsdoc
|
||||
* Triggered when the <code>HMD.ipdScale</code> property value changes.
|
||||
* @function HMD.IPDScaleChanged
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void IPDScaleChanged();
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when Interface's display mode changes and when the user puts on or takes off their HMD.
|
||||
* @function HMD.displayModeChanged
|
||||
* @param {boolean} isHMDMode - <code>true</code> if the display mode is HMD, otherwise <code>false</code>. This is the
|
||||
* same value as provided by <code>HMD.active</code>.
|
||||
* @returns {Signal}
|
||||
* @example <caption>Report when the display mode changes.</caption>
|
||||
* HMD.displayModeChanged.connect(function (isHMDMode) {
|
||||
* print("Display mode changed");
|
||||
* print("isHMD = " + isHMDMode);
|
||||
* print("HMD.active = " + HMD.active);
|
||||
* print("HMD.mounted = " + HMD.mounted);
|
||||
* });
|
||||
*/
|
||||
void displayModeChanged(bool isHMDMode);
|
||||
|
||||
private:
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
#include "render-utils/simple_vert.h"
|
||||
#include "render-utils/simple_frag.h"
|
||||
#include "render-utils/simple_transparent_frag.h"
|
||||
#include "render-utils/forward_simple_frag.h"
|
||||
#include "render-utils/forward_simple_transparent_frag.h"
|
||||
|
||||
#include "RenderPipelines.h"
|
||||
|
||||
|
@ -35,13 +38,23 @@ static const float SPHERE_ENTITY_SCALE = 0.5f;
|
|||
|
||||
ShapeEntityRenderer::ShapeEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {
|
||||
_procedural._vertexSource = simple_vert::getSource();
|
||||
_procedural._fragmentSource = simple_frag::getSource();
|
||||
// FIXME: Setup proper uniform slots and use correct pipelines for forward rendering
|
||||
_procedural._opaquefragmentSource = simple_frag::getSource();
|
||||
// FIXME: Transparent procedural entities only seem to work if they use the opaque pipelines
|
||||
//_procedural._transparentfragmentSource = simple_transparent_frag::getSource();
|
||||
_procedural._transparentfragmentSource = simple_frag::getSource();
|
||||
_procedural._opaqueState->setCullMode(gpu::State::CULL_NONE);
|
||||
_procedural._opaqueState->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||
PrepareStencil::testMaskDrawShape(*_procedural._opaqueState);
|
||||
_procedural._opaqueState->setBlendFunction(false,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
_procedural._transparentState->setCullMode(gpu::State::CULL_BACK);
|
||||
_procedural._transparentState->setDepthTest(true, true, gpu::LESS_EQUAL);
|
||||
PrepareStencil::testMask(*_procedural._transparentState);
|
||||
_procedural._transparentState->setBlendFunction(true,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
}
|
||||
|
||||
bool ShapeEntityRenderer::needsRenderUpdate() const {
|
||||
|
@ -218,9 +231,9 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
|
|||
if (mat) {
|
||||
outColor = glm::vec4(mat->getAlbedo(), mat->getOpacity());
|
||||
if (_procedural.isReady()) {
|
||||
_procedural.prepare(batch, _position, _dimensions, _orientation);
|
||||
outColor = _procedural.getColor(outColor);
|
||||
outColor.a *= _procedural.isFading() ? Interpolate::calculateFadeRatio(_procedural.getFadeStartTime()) : 1.0f;
|
||||
_procedural.prepare(batch, _position, _dimensions, _orientation, outColor);
|
||||
proceduralRender = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -477,18 +477,19 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
* @property {boolean} visible=true - Whether or not the entity is rendered. If <code>true</code> then the entity is rendered.
|
||||
* @property {boolean} canCastShadows=true - Whether or not the entity casts shadows. Currently applicable only to
|
||||
* {@link Entities.EntityType|Model} and {@link Entities.EntityType|Shape} entities. Shadows are cast if inside a
|
||||
* {@link Entities.EntityType|Zone} entity with <code>castShadows</code> enabled in its {@link Entities.EntityProperties-Zone|keyLight} property.
|
||||
* {@link Entities.EntityType|Zone} entity with <code>castShadows</code> enabled in its
|
||||
* {@link Entities.EntityProperties-Zone|keyLight} property.
|
||||
*
|
||||
* @property {Vec3} position=0,0,0 - The position of the entity.
|
||||
* @property {Quat} rotation=0,0,0,1 - The orientation of the entity with respect to world coordinates.
|
||||
* @property {Vec3} registrationPoint=0.5,0.5,0.5 - The point in the entity that is set to the entity's position and is rotated
|
||||
* about, {@link Vec3|Vec3.ZERO} – {@link Vec3|Vec3.ONE}. A value of {@link Vec3|Vec3.ZERO} is the entity's
|
||||
* minimum x, y, z corner; a value of {@link Vec3|Vec3.ONE} is the entity's maximum x, y, z corner.
|
||||
* about, {@link Vec3(0)|Vec3.ZERO} – {@link Vec3(0)|Vec3.ONE}. A value of {@link Vec3(0)|Vec3.ZERO} is the entity's
|
||||
* minimum x, y, z corner; a value of {@link Vec3(0)|Vec3.ONE} is the entity's maximum x, y, z corner.
|
||||
*
|
||||
* @property {Vec3} naturalPosition=0,0,0 - The center of the entity's unscaled mesh model if it has one, otherwise
|
||||
* {@link Vec3|Vec3.ZERO}. <em>Read-only.</em>
|
||||
* {@link Vec3(0)|Vec3.ZERO}. <em>Read-only.</em>
|
||||
* @property {Vec3} naturalDimensions - The dimensions of the entity's unscaled mesh model if it has one, otherwise
|
||||
* {@link Vec3|Vec3.ONE}. <em>Read-only.</em>
|
||||
* {@link Vec3(0)|Vec3.ONE}. <em>Read-only.</em>
|
||||
*
|
||||
* @property {Vec3} velocity=0,0,0 - The linear velocity of the entity in m/s with respect to world coordinates.
|
||||
* @property {number} damping=0.39347 - How much to slow down the linear velocity of an entity over time, <code>0.0</code>
|
||||
|
@ -505,13 +506,13 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
* @property {Vec3} gravity=0,0,0 - The acceleration due to gravity in m/s<sup>2</sup> that the entity should move with, in
|
||||
* world coordinates. Set to <code>{ x: 0, y: -9.8, z: 0 }</code> to simulate Earth's gravity. Gravity is applied to an
|
||||
* entity's motion only if its <code>dynamic</code> property is <code>true</code>. If changing an entity's
|
||||
* <code>gravity</code> from {@link Vec3|Vec3.ZERO}, you need to give it a small <code>velocity</code> in order to kick off
|
||||
* physics simulation.
|
||||
* <code>gravity</code> from {@link Vec3(0)|Vec3.ZERO}, you need to give it a small <code>velocity</code> in order to kick
|
||||
* off physics simulation.
|
||||
* The <code>gravity</code> value is applied in addition to the <code>acceleration</code> value.
|
||||
* @property {Vec3} acceleration=0,0,0 - A general acceleration in m/s<sup>2</sup> that the entity should move with, in world
|
||||
* coordinates. The acceleration is applied to an entity's motion only if its <code>dynamic</code> property is
|
||||
* <code>true</code>. If changing an entity's <code>acceleration</code> from {@link Vec3|Vec3.ZERO}, you need to give it a
|
||||
* small <code>velocity</code> in order to kick off physics simulation.
|
||||
* <code>true</code>. If changing an entity's <code>acceleration</code> from {@link Vec3(0)|Vec3.ZERO}, you need to give it
|
||||
* a small <code>velocity</code> in order to kick off physics simulation.
|
||||
* The <code>acceleration</code> value is applied in addition to the <code>gravity</code> value.
|
||||
* @property {number} restitution=0.5 - The "bounciness" of an entity when it collides, <code>0.0</code> –
|
||||
* <code>0.99</code>. The higher the value, the more bouncy.
|
||||
|
|
|
@ -759,7 +759,7 @@ QVector<QUuid> EntityScriptingInterface::findEntitiesByType(const QString entity
|
|||
|
||||
foreach(EntityItemPointer entity, entities) {
|
||||
if (entity->getType() == type) {
|
||||
result << entity->getEntityItemID();
|
||||
result << entity->getEntityItemID().toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -694,7 +694,7 @@ public slots:
|
|||
* @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity.
|
||||
* @param {Vec3} voxelCoords - The voxel coordinates. May be fractional and outside the entity's bounding box.
|
||||
* @returns {Vec3} The world coordinates of the <code>voxelCoords</code> if the <code>entityID</code> is a
|
||||
* {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3|Vec3.ZERO}.
|
||||
* {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3(0)|Vec3.ZERO}.
|
||||
* @example <caption>Create a PolyVox cube with the 0,0,0 voxel replaced by a sphere.</caption>
|
||||
* // Cube PolyVox with 0,0,0 voxel missing.
|
||||
* var polyVox = Entities.addEntity({
|
||||
|
@ -729,7 +729,7 @@ public slots:
|
|||
* @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity.
|
||||
* @param {Vec3} worldCoords - The world coordinates. May be outside the entity's bounding box.
|
||||
* @returns {Vec3} The voxel coordinates of the <code>worldCoords</code> if the <code>entityID</code> is a
|
||||
* {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3|Vec3.ZERO}. The value may be fractional.
|
||||
* {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3(0)|Vec3.ZERO}. The value may be fractional.
|
||||
*/
|
||||
// FIXME move to a renderable entity interface
|
||||
Q_INVOKABLE glm::vec3 worldCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 worldCoords);
|
||||
|
@ -741,7 +741,7 @@ public slots:
|
|||
* @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity.
|
||||
* @param {Vec3} voxelCoords - The voxel coordinates. May be fractional and outside the entity's bounding box.
|
||||
* @returns {Vec3} The local coordinates of the <code>voxelCoords</code> if the <code>entityID</code> is a
|
||||
* {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3|Vec3.ZERO}.
|
||||
* {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3(0)|Vec3.ZERO}.
|
||||
* @example <caption>Get the world dimensions of a voxel in a PolyVox entity.</caption>
|
||||
* var polyVox = Entities.addEntity({
|
||||
* type: "PolyVox",
|
||||
|
@ -763,7 +763,7 @@ public slots:
|
|||
* @param {Uuid} entityID - The ID of the {@link Entities.EntityType|PolyVox} entity.
|
||||
* @param {Vec3} localCoords - The local coordinates. May be outside the entity's bounding box.
|
||||
* @returns {Vec3} The voxel coordinates of the <code>worldCoords</code> if the <code>entityID</code> is a
|
||||
* {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3|Vec3.ZERO}. The value may be fractional.
|
||||
* {@link Entities.EntityType|PolyVox} entity, otherwise {@link Vec3(0)|Vec3.ZERO}. The value may be fractional.
|
||||
*/
|
||||
// FIXME move to a renderable entity interface
|
||||
Q_INVOKABLE glm::vec3 localCoordsToVoxelCoords(const QUuid& entityID, glm::vec3 localCoords);
|
||||
|
|
|
@ -2320,6 +2320,16 @@ bool EntityTree::readFromMap(QVariantMap& map) {
|
|||
_persistDataVersion = map["DataVersion"].toInt();
|
||||
}
|
||||
|
||||
_namedPaths.clear();
|
||||
if (map.contains("Paths")) {
|
||||
QVariantMap namedPathsMap = map["Paths"].toMap();
|
||||
for(QVariantMap::const_iterator iter = namedPathsMap.begin(); iter != namedPathsMap.end(); ++iter) {
|
||||
QString namedPathName = iter.key();
|
||||
QString namedPathViewPoint = iter.value().toString();
|
||||
_namedPaths[namedPathName] = namedPathViewPoint;
|
||||
}
|
||||
}
|
||||
|
||||
// map will have a top-level list keyed as "Entities". This will be extracted
|
||||
// and iterated over. Each member of this list is converted to a QVariantMap, then
|
||||
// to a QScriptValue, and then to EntityItemProperties. These properties are used
|
||||
|
|
|
@ -301,6 +301,8 @@ public:
|
|||
static bool addMaterialToOverlay(const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName);
|
||||
static bool removeMaterialFromOverlay(const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName);
|
||||
|
||||
std::map<QString, QString> getNamedPaths() const { return _namedPaths; }
|
||||
|
||||
signals:
|
||||
void deletingEntity(const EntityItemID& entityID);
|
||||
void deletingEntityPointer(EntityItem* entityID);
|
||||
|
@ -417,6 +419,8 @@ private:
|
|||
static std::function<bool(const QUuid&, graphics::MaterialPointer, const std::string&)> _removeMaterialFromOverlayOperator;
|
||||
|
||||
bool _serverlessDomain { false };
|
||||
|
||||
std::map<QString, QString> _namedPaths;
|
||||
};
|
||||
|
||||
#endif // hifi_EntityTree_h
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace graphics {
|
|||
// limit range and altitude to no less than 1.0 metres
|
||||
static inline float convertHazeRangeToHazeRangeFactor(const float hazeRange) { return -LOG_P_005 / glm::max(hazeRange, 1.0f); }
|
||||
|
||||
static inline float convertHazeAltitudeToHazeAltitudeFactor(const float hazeHeight) { return -LOG_P_005 / glm::max(hazeHeight, 1.0f); }
|
||||
static inline float convertHazeAltitudeToHazeAltitudeFactor(const float hazeHeight) { return -(LOG_P_005 * glm::sign(hazeHeight)) / glm::max(glm::abs(hazeHeight), 1.0f); }
|
||||
|
||||
// Derivation (s is the proportion of sun blend, a is the angle at which the blend is 50%, solve for m = 0.5
|
||||
// s = dot(lookAngle, sunAngle) = cos(a)
|
||||
|
|
|
@ -314,7 +314,17 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) {
|
|||
_shareablePlaceName.clear();
|
||||
setDomainInfo(lookupUrl, trigger);
|
||||
emit lookupResultsFinished();
|
||||
handlePath(DOMAIN_SPAWNING_POINT, LookupTrigger::Internal, false);
|
||||
|
||||
QString path = DOMAIN_SPAWNING_POINT;
|
||||
QUrlQuery queryArgs(lookupUrl);
|
||||
const QString LOCATION_QUERY_KEY = "location";
|
||||
if (queryArgs.hasQueryItem(LOCATION_QUERY_KEY)) {
|
||||
path = queryArgs.queryItemValue(LOCATION_QUERY_KEY);
|
||||
} else {
|
||||
path = DEFAULT_NAMED_PATH;
|
||||
}
|
||||
|
||||
handlePath(path, LookupTrigger::Internal, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -431,7 +441,9 @@ void AddressManager::goToAddressFromObject(const QVariantMap& dataObject, const
|
|||
QUrl domainURL;
|
||||
domainURL.setScheme(URL_SCHEME_HIFI);
|
||||
domainURL.setHost(domainHostname);
|
||||
domainURL.setPort(domainPort);
|
||||
if (domainPort > 0) {
|
||||
domainURL.setPort(domainPort);
|
||||
}
|
||||
emit possibleDomainChangeRequired(domainURL, domainID);
|
||||
} else {
|
||||
QString iceServerAddress = domainObject[DOMAIN_ICE_SERVER_ADDRESS_KEY].toString();
|
||||
|
@ -602,7 +614,9 @@ bool AddressManager::handleNetworkAddress(const QString& lookupString, LookupTri
|
|||
QUrl domainURL;
|
||||
domainURL.setScheme(URL_SCHEME_HIFI);
|
||||
domainURL.setHost(domainIPString);
|
||||
domainURL.setPort(domainPort);
|
||||
if (domainPort > 0) {
|
||||
domainURL.setPort(domainPort);
|
||||
}
|
||||
hostChanged = setDomainInfo(domainURL, trigger);
|
||||
|
||||
return true;
|
||||
|
@ -623,7 +637,9 @@ bool AddressManager::handleNetworkAddress(const QString& lookupString, LookupTri
|
|||
QUrl domainURL;
|
||||
domainURL.setScheme(URL_SCHEME_HIFI);
|
||||
domainURL.setHost(domainHostname);
|
||||
domainURL.setPort(domainPort);
|
||||
if (domainPort > 0) {
|
||||
domainURL.setPort(domainPort);
|
||||
}
|
||||
hostChanged = setDomainInfo(domainURL, trigger);
|
||||
|
||||
return true;
|
||||
|
@ -755,7 +771,9 @@ bool AddressManager::setHost(const QString& host, LookupTrigger trigger, quint16
|
|||
_domainURL = QUrl();
|
||||
_domainURL.setScheme(URL_SCHEME_HIFI);
|
||||
_domainURL.setHost(host);
|
||||
_domainURL.setPort(port);
|
||||
if (port > 0) {
|
||||
_domainURL.setPort(port);
|
||||
}
|
||||
|
||||
// any host change should clear the shareable place name
|
||||
_shareablePlaceName.clear();
|
||||
|
|
|
@ -173,15 +173,15 @@ void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) {
|
|||
QString previousHost = _domainURL.host();
|
||||
_domainURL = domainURL;
|
||||
|
||||
if (domainURL.scheme() != URL_SCHEME_HIFI) {
|
||||
setIsConnected(true);
|
||||
} else if (previousHost != domainURL.host()) {
|
||||
if (previousHost != domainURL.host()) {
|
||||
qCDebug(networking) << "Updated domain hostname to" << domainURL.host();
|
||||
|
||||
if (!domainURL.host().isEmpty()) {
|
||||
// re-set the sock addr to null and fire off a lookup of the IP address for this domain-server's hostname
|
||||
qCDebug(networking, "Looking up DS hostname %s.", domainURL.host().toLocal8Bit().constData());
|
||||
QHostInfo::lookupHost(domainURL.host(), this, SLOT(completedHostnameLookup(const QHostInfo&)));
|
||||
if (domainURL.scheme() == URL_SCHEME_HIFI) {
|
||||
// re-set the sock addr to null and fire off a lookup of the IP address for this domain-server's hostname
|
||||
qCDebug(networking, "Looking up DS hostname %s.", domainURL.host().toLocal8Bit().constData());
|
||||
QHostInfo::lookupHost(domainURL.host(), this, SLOT(completedHostnameLookup(const QHostInfo&)));
|
||||
}
|
||||
|
||||
DependencyManager::get<NodeList>()->flagTimeForConnectionStep(
|
||||
LimitedNodeList::ConnectionStep::SetDomainHostname);
|
||||
|
@ -250,6 +250,17 @@ void DomainHandler::activateICEPublicSocket() {
|
|||
emit completedSocketDiscovery();
|
||||
}
|
||||
|
||||
QString DomainHandler::getViewPointFromNamedPath(QString namedPath) {
|
||||
auto lookup = _namedPaths.find(namedPath);
|
||||
if (lookup != _namedPaths.end()) {
|
||||
return lookup->second;
|
||||
}
|
||||
if (namedPath == DEFAULT_NAMED_PATH) {
|
||||
return DOMAIN_SPAWNING_POINT;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
void DomainHandler::completedHostnameLookup(const QHostInfo& hostInfo) {
|
||||
for (int i = 0; i < hostInfo.addresses().size(); i++) {
|
||||
if (hostInfo.addresses()[i].protocol() == QAbstractSocket::IPv4Protocol) {
|
||||
|
@ -297,6 +308,11 @@ void DomainHandler::setIsConnected(bool isConnected) {
|
|||
}
|
||||
}
|
||||
|
||||
void DomainHandler::connectedToServerless(std::map<QString, QString> namedPaths) {
|
||||
_namedPaths = namedPaths;
|
||||
setIsConnected(true);
|
||||
}
|
||||
|
||||
void DomainHandler::requestDomainSettings() {
|
||||
qCDebug(networking) << "Requesting settings from domain server";
|
||||
|
||||
|
|
|
@ -76,6 +76,10 @@ public:
|
|||
void setIsConnected(bool isConnected);
|
||||
bool isServerless() const { return _domainURL.scheme() != URL_SCHEME_HIFI; }
|
||||
|
||||
void connectedToServerless(std::map<QString, QString> namedPaths);
|
||||
|
||||
QString getViewPointFromNamedPath(QString namedPath);
|
||||
|
||||
bool hasSettings() const { return !_settingsObject.isEmpty(); }
|
||||
void requestDomainSettings();
|
||||
const QJsonObject& getSettingsObject() const { return _settingsObject; }
|
||||
|
@ -200,9 +204,11 @@ private:
|
|||
int _checkInPacketsSinceLastReply { 0 };
|
||||
|
||||
QTimer _apiRefreshTimer;
|
||||
|
||||
std::map<QString, QString> _namedPaths;
|
||||
};
|
||||
|
||||
const QString DOMAIN_SPAWNING_POINT { "/0, -10, 0" };
|
||||
|
||||
const QString DEFAULT_NAMED_PATH { "/" };
|
||||
|
||||
#endif // hifi_DomainHandler_h
|
||||
|
|
|
@ -413,7 +413,16 @@ void NodeList::sendDomainServerCheckIn() {
|
|||
}
|
||||
|
||||
void NodeList::handleDSPathQuery(const QString& newPath) {
|
||||
if (_domainHandler.isSocketKnown()) {
|
||||
if (_domainHandler.isServerless()) {
|
||||
if (_domainHandler.isConnected()) {
|
||||
auto viewpoint = _domainHandler.getViewPointFromNamedPath(newPath);
|
||||
if (!newPath.isEmpty()) {
|
||||
DependencyManager::get<AddressManager>()->goToViewpointForPath(viewpoint, newPath);
|
||||
}
|
||||
} else {
|
||||
_domainHandler.setPendingPath(newPath);
|
||||
}
|
||||
} else if (_domainHandler.isSocketKnown()) {
|
||||
// if we have a DS socket we assume it will get this packet and send if off right away
|
||||
sendDSPathQuery(newPath);
|
||||
} else {
|
||||
|
@ -427,10 +436,17 @@ void NodeList::sendPendingDSPathQuery() {
|
|||
QString pendingPath = _domainHandler.getPendingPath();
|
||||
|
||||
if (!pendingPath.isEmpty()) {
|
||||
qCDebug(networking) << "Attempting to send pending query to DS for path" << pendingPath;
|
||||
|
||||
// this is a slot triggered if we just established a network link with a DS and want to send a path query
|
||||
sendDSPathQuery(_domainHandler.getPendingPath());
|
||||
if (_domainHandler.isServerless()) {
|
||||
auto viewpoint = _domainHandler.getViewPointFromNamedPath(pendingPath);
|
||||
if (!pendingPath.isEmpty()) {
|
||||
DependencyManager::get<AddressManager>()->goToViewpointForPath(viewpoint, pendingPath);
|
||||
}
|
||||
} else {
|
||||
qCDebug(networking) << "Attempting to send pending query to DS for path" << pendingPath;
|
||||
// this is a slot triggered if we just established a network link with a DS and want to send a path query
|
||||
sendDSPathQuery(_domainHandler.getPendingPath());
|
||||
}
|
||||
|
||||
// clear whatever the pending path was
|
||||
_domainHandler.clearPendingPath();
|
||||
|
@ -498,7 +514,7 @@ void NodeList::processDomainServerPathResponse(QSharedPointer<ReceivedMessage> m
|
|||
QString viewpoint = QString::fromUtf8(message->getRawMessage() + message->getPosition(), numViewpointBytes);
|
||||
|
||||
// Hand it off to the AddressManager so it can handle it as a relative viewpoint
|
||||
if (DependencyManager::get<AddressManager>()->goToViewpointForPath(viewpoint, pathQuery)) {
|
||||
if (!pathQuery.isEmpty() && DependencyManager::get<AddressManager>()->goToViewpointForPath(viewpoint, pathQuery)) {
|
||||
qCDebug(networking) << "Going to viewpoint" << viewpoint << "which was the lookup result for path" << pathQuery;
|
||||
} else {
|
||||
qCDebug(networking) << "Could not go to viewpoint" << viewpoint
|
||||
|
|
|
@ -219,7 +219,29 @@ bool Procedural::isReady() const {
|
|||
return true;
|
||||
}
|
||||
|
||||
void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size, const glm::quat& orientation) {
|
||||
std::string Procedural::replaceProceduralBlock(const std::string& fragmentSource) {
|
||||
std::string fragmentShaderSource = fragmentSource;
|
||||
size_t replaceIndex = fragmentShaderSource.find(PROCEDURAL_COMMON_BLOCK);
|
||||
if (replaceIndex != std::string::npos) {
|
||||
fragmentShaderSource.replace(replaceIndex, PROCEDURAL_COMMON_BLOCK.size(), ProceduralCommon_frag::getSource());
|
||||
}
|
||||
|
||||
replaceIndex = fragmentShaderSource.find(PROCEDURAL_VERSION);
|
||||
if (replaceIndex != std::string::npos) {
|
||||
if (_data.version == 1) {
|
||||
fragmentShaderSource.replace(replaceIndex, PROCEDURAL_VERSION.size(), "#define PROCEDURAL_V1 1");
|
||||
} else if (_data.version == 2) {
|
||||
fragmentShaderSource.replace(replaceIndex, PROCEDURAL_VERSION.size(), "#define PROCEDURAL_V2 1");
|
||||
}
|
||||
}
|
||||
replaceIndex = fragmentShaderSource.find(PROCEDURAL_BLOCK);
|
||||
if (replaceIndex != std::string::npos) {
|
||||
fragmentShaderSource.replace(replaceIndex, PROCEDURAL_BLOCK.size(), _shaderSource.toLocal8Bit().data());
|
||||
}
|
||||
return fragmentShaderSource;
|
||||
}
|
||||
|
||||
void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size, const glm::quat& orientation, const glm::vec4& color) {
|
||||
_entityDimensions = size;
|
||||
_entityPosition = position;
|
||||
_entityOrientation = glm::mat3_cast(orientation);
|
||||
|
@ -242,58 +264,48 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm
|
|||
}
|
||||
|
||||
// Build the fragment shader
|
||||
std::string fragmentShaderSource = _fragmentSource;
|
||||
size_t replaceIndex = fragmentShaderSource.find(PROCEDURAL_COMMON_BLOCK);
|
||||
if (replaceIndex != std::string::npos) {
|
||||
fragmentShaderSource.replace(replaceIndex, PROCEDURAL_COMMON_BLOCK.size(), ProceduralCommon_frag::getSource());
|
||||
}
|
||||
|
||||
replaceIndex = fragmentShaderSource.find(PROCEDURAL_VERSION);
|
||||
if (replaceIndex != std::string::npos) {
|
||||
if (_data.version == 1) {
|
||||
fragmentShaderSource.replace(replaceIndex, PROCEDURAL_VERSION.size(), "#define PROCEDURAL_V1 1");
|
||||
} else if (_data.version == 2) {
|
||||
fragmentShaderSource.replace(replaceIndex, PROCEDURAL_VERSION.size(), "#define PROCEDURAL_V2 1");
|
||||
}
|
||||
}
|
||||
replaceIndex = fragmentShaderSource.find(PROCEDURAL_BLOCK);
|
||||
if (replaceIndex != std::string::npos) {
|
||||
fragmentShaderSource.replace(replaceIndex, PROCEDURAL_BLOCK.size(), _shaderSource.toLocal8Bit().data());
|
||||
}
|
||||
std::string opaqueShaderSource = replaceProceduralBlock(_opaquefragmentSource);
|
||||
std::string transparentShaderSource = replaceProceduralBlock(_transparentfragmentSource);
|
||||
|
||||
// Leave this here for debugging
|
||||
// qCDebug(procedural) << "FragmentShader:\n" << fragmentShaderSource.c_str();
|
||||
|
||||
_fragmentShader = gpu::Shader::createPixel(fragmentShaderSource);
|
||||
_shader = gpu::Shader::createProgram(_vertexShader, _fragmentShader);
|
||||
_opaqueFragmentShader = gpu::Shader::createPixel(opaqueShaderSource);
|
||||
_opaqueShader = gpu::Shader::createProgram(_vertexShader, _opaqueFragmentShader);
|
||||
_transparentFragmentShader = gpu::Shader::createPixel(transparentShaderSource);
|
||||
_transparentShader = gpu::Shader::createProgram(_vertexShader, _transparentFragmentShader);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("iChannel0"), 0));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("iChannel1"), 1));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("iChannel2"), 2));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("iChannel3"), 3));
|
||||
gpu::Shader::makeProgram(*_shader, slotBindings);
|
||||
gpu::Shader::makeProgram(*_opaqueShader, slotBindings);
|
||||
gpu::Shader::makeProgram(*_transparentShader, slotBindings);
|
||||
|
||||
_opaquePipeline = gpu::Pipeline::create(_shader, _opaqueState);
|
||||
_transparentPipeline = gpu::Pipeline::create(_shader, _transparentState);
|
||||
_opaquePipeline = gpu::Pipeline::create(_opaqueShader, _opaqueState);
|
||||
_transparentPipeline = gpu::Pipeline::create(_transparentShader, _transparentState);
|
||||
for (size_t i = 0; i < NUM_STANDARD_UNIFORMS; ++i) {
|
||||
const std::string& name = STANDARD_UNIFORM_NAMES[i];
|
||||
_standardUniformSlots[i] = _shader->getUniforms().findLocation(name);
|
||||
_standardOpaqueUniformSlots[i] = _opaqueShader->getUniforms().findLocation(name);
|
||||
_standardTransparentUniformSlots[i] = _transparentShader->getUniforms().findLocation(name);
|
||||
}
|
||||
_start = usecTimestampNow();
|
||||
_frameCount = 0;
|
||||
}
|
||||
|
||||
batch.setPipeline(isFading() ? _transparentPipeline : _opaquePipeline);
|
||||
bool transparent = color.a < 1.0f;
|
||||
batch.setPipeline(transparent ? _transparentPipeline : _opaquePipeline);
|
||||
|
||||
if (_shaderDirty || _uniformsDirty) {
|
||||
setupUniforms();
|
||||
if (_shaderDirty || _uniformsDirty || _prevTransparent != transparent) {
|
||||
setupUniforms(transparent);
|
||||
}
|
||||
|
||||
if (_shaderDirty || _uniformsDirty || _channelsDirty) {
|
||||
setupChannels(_shaderDirty || _uniformsDirty);
|
||||
if (_shaderDirty || _uniformsDirty || _channelsDirty || _prevTransparent != transparent) {
|
||||
setupChannels(_shaderDirty || _uniformsDirty, transparent);
|
||||
}
|
||||
|
||||
_prevTransparent = transparent;
|
||||
_shaderDirty = _uniformsDirty = _channelsDirty = false;
|
||||
|
||||
for (auto lambda : _uniforms) {
|
||||
|
@ -319,12 +331,12 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm
|
|||
}
|
||||
}
|
||||
|
||||
void Procedural::setupUniforms() {
|
||||
void Procedural::setupUniforms(bool transparent) {
|
||||
_uniforms.clear();
|
||||
// Set any userdata specified uniforms
|
||||
foreach(QString key, _data.uniforms.keys()) {
|
||||
std::string uniformName = key.toLocal8Bit().data();
|
||||
int32_t slot = _shader->getUniforms().findLocation(uniformName);
|
||||
int32_t slot = (transparent ? _transparentShader : _opaqueShader)->getUniforms().findLocation(uniformName);
|
||||
if (gpu::Shader::INVALID_LOCATION == slot) {
|
||||
continue;
|
||||
}
|
||||
|
@ -385,15 +397,17 @@ void Procedural::setupUniforms() {
|
|||
}
|
||||
}
|
||||
|
||||
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[TIME]) {
|
||||
auto uniformSlots = transparent ? _standardTransparentUniformSlots : _standardOpaqueUniformSlots;
|
||||
|
||||
if (gpu::Shader::INVALID_LOCATION != uniformSlots[TIME]) {
|
||||
_uniforms.push_back([=](gpu::Batch& batch) {
|
||||
// Minimize floating point error by doing an integer division to milliseconds, before the floating point division to seconds
|
||||
float time = (float)((usecTimestampNow() - _start) / USECS_PER_MSEC) / MSECS_PER_SECOND;
|
||||
batch._glUniform(_standardUniformSlots[TIME], time);
|
||||
batch._glUniform(uniformSlots[TIME], time);
|
||||
});
|
||||
}
|
||||
|
||||
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[DATE]) {
|
||||
if (gpu::Shader::INVALID_LOCATION != uniformSlots[DATE]) {
|
||||
_uniforms.push_back([=](gpu::Batch& batch) {
|
||||
QDateTime now = QDateTime::currentDateTimeUtc();
|
||||
QDate date = now.date();
|
||||
|
@ -406,40 +420,41 @@ void Procedural::setupUniforms() {
|
|||
v.z = date.day();
|
||||
float fractSeconds = (time.msec() / 1000.0f);
|
||||
v.w = (time.hour() * 3600) + (time.minute() * 60) + time.second() + fractSeconds;
|
||||
batch._glUniform(_standardUniformSlots[DATE], v);
|
||||
batch._glUniform(uniformSlots[DATE], v);
|
||||
});
|
||||
}
|
||||
|
||||
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[FRAME_COUNT]) {
|
||||
if (gpu::Shader::INVALID_LOCATION != uniformSlots[FRAME_COUNT]) {
|
||||
_uniforms.push_back([=](gpu::Batch& batch) {
|
||||
batch._glUniform(_standardUniformSlots[FRAME_COUNT], ++_frameCount);
|
||||
batch._glUniform(uniformSlots[FRAME_COUNT], ++_frameCount);
|
||||
});
|
||||
}
|
||||
|
||||
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[SCALE]) {
|
||||
if (gpu::Shader::INVALID_LOCATION != uniformSlots[SCALE]) {
|
||||
// FIXME move into the 'set once' section, since this doesn't change over time
|
||||
_uniforms.push_back([=](gpu::Batch& batch) {
|
||||
batch._glUniform(_standardUniformSlots[SCALE], _entityDimensions);
|
||||
batch._glUniform(uniformSlots[SCALE], _entityDimensions);
|
||||
});
|
||||
}
|
||||
|
||||
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[ORIENTATION]) {
|
||||
if (gpu::Shader::INVALID_LOCATION != uniformSlots[ORIENTATION]) {
|
||||
// FIXME move into the 'set once' section, since this doesn't change over time
|
||||
_uniforms.push_back([=](gpu::Batch& batch) {
|
||||
batch._glUniform(_standardUniformSlots[ORIENTATION], _entityOrientation);
|
||||
batch._glUniform(uniformSlots[ORIENTATION], _entityOrientation);
|
||||
});
|
||||
}
|
||||
|
||||
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[POSITION]) {
|
||||
if (gpu::Shader::INVALID_LOCATION != uniformSlots[POSITION]) {
|
||||
// FIXME move into the 'set once' section, since this doesn't change over time
|
||||
_uniforms.push_back([=](gpu::Batch& batch) {
|
||||
batch._glUniform(_standardUniformSlots[POSITION], _entityPosition);
|
||||
batch._glUniform(uniformSlots[POSITION], _entityPosition);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void Procedural::setupChannels(bool shouldCreate) {
|
||||
if (gpu::Shader::INVALID_LOCATION != _standardUniformSlots[CHANNEL_RESOLUTION]) {
|
||||
void Procedural::setupChannels(bool shouldCreate, bool transparent) {
|
||||
auto uniformSlots = transparent ? _standardTransparentUniformSlots : _standardOpaqueUniformSlots;
|
||||
if (gpu::Shader::INVALID_LOCATION != uniformSlots[CHANNEL_RESOLUTION]) {
|
||||
if (!shouldCreate) {
|
||||
// Instead of modifying the last element, just remove and recreate it.
|
||||
_uniforms.pop_back();
|
||||
|
@ -451,7 +466,7 @@ void Procedural::setupChannels(bool shouldCreate) {
|
|||
channelSizes[i] = vec3(_channels[i]->getWidth(), _channels[i]->getHeight(), 1.0);
|
||||
}
|
||||
}
|
||||
batch._glUniform3fv(_standardUniformSlots[CHANNEL_RESOLUTION], MAX_PROCEDURAL_TEXTURE_CHANNELS, &channelSizes[0].x);
|
||||
batch._glUniform3fv(uniformSlots[CHANNEL_RESOLUTION], MAX_PROCEDURAL_TEXTURE_CHANNELS, &channelSizes[0].x);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,8 +55,8 @@ public:
|
|||
|
||||
bool isReady() const;
|
||||
bool isEnabled() const { return _enabled; }
|
||||
void prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size, const glm::quat& orientation);
|
||||
const gpu::ShaderPointer& getShader() const { return _shader; }
|
||||
void prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size, const glm::quat& orientation, const glm::vec4& color = glm::vec4(1));
|
||||
const gpu::ShaderPointer& getOpaqueShader() const { return _opaqueShader; }
|
||||
|
||||
glm::vec4 getColor(const glm::vec4& entityColor);
|
||||
quint64 getFadeStartTime() const { return _fadeStartTime; }
|
||||
|
@ -65,7 +65,8 @@ public:
|
|||
void setDoesFade(bool doesFade) { _doesFade = doesFade; }
|
||||
|
||||
std::string _vertexSource;
|
||||
std::string _fragmentSource;
|
||||
std::string _opaquefragmentSource;
|
||||
std::string _transparentfragmentSource;
|
||||
|
||||
gpu::StatePointer _opaqueState { std::make_shared<gpu::State>() };
|
||||
gpu::StatePointer _transparentState { std::make_shared<gpu::State>() };
|
||||
|
@ -101,13 +102,16 @@ protected:
|
|||
|
||||
// Rendering objects
|
||||
UniformLambdas _uniforms;
|
||||
int32_t _standardUniformSlots[NUM_STANDARD_UNIFORMS];
|
||||
int32_t _standardOpaqueUniformSlots[NUM_STANDARD_UNIFORMS];
|
||||
int32_t _standardTransparentUniformSlots[NUM_STANDARD_UNIFORMS];
|
||||
NetworkTexturePointer _channels[MAX_PROCEDURAL_TEXTURE_CHANNELS];
|
||||
gpu::PipelinePointer _opaquePipeline;
|
||||
gpu::PipelinePointer _transparentPipeline;
|
||||
gpu::ShaderPointer _vertexShader;
|
||||
gpu::ShaderPointer _fragmentShader;
|
||||
gpu::ShaderPointer _shader;
|
||||
gpu::ShaderPointer _opaqueFragmentShader;
|
||||
gpu::ShaderPointer _transparentFragmentShader;
|
||||
gpu::ShaderPointer _opaqueShader;
|
||||
gpu::ShaderPointer _transparentShader;
|
||||
|
||||
// Entity metadata
|
||||
glm::vec3 _entityDimensions;
|
||||
|
@ -116,13 +120,16 @@ protected:
|
|||
|
||||
private:
|
||||
// This should only be called from the render thread, as it shares data with Procedural::prepare
|
||||
void setupUniforms();
|
||||
void setupChannels(bool shouldCreate);
|
||||
void setupUniforms(bool transparent);
|
||||
void setupChannels(bool shouldCreate, bool transparent);
|
||||
|
||||
std::string replaceProceduralBlock(const std::string& fragmentSource);
|
||||
|
||||
mutable quint64 _fadeStartTime { 0 };
|
||||
mutable bool _hasStartedFade { false };
|
||||
mutable bool _isFading { false };
|
||||
bool _doesFade { true };
|
||||
bool _prevTransparent { false };
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
ProceduralSkybox::ProceduralSkybox() : graphics::Skybox() {
|
||||
_procedural._vertexSource = skybox_vert::getSource();
|
||||
_procedural._fragmentSource = skybox_frag::getSource();
|
||||
_procedural._opaquefragmentSource = skybox_frag::getSource();
|
||||
// Adjust the pipeline state for background using the stencil test
|
||||
_procedural.setDoesFade(false);
|
||||
// Must match PrepareStencil::STENCIL_BACKGROUND
|
||||
|
@ -61,8 +61,8 @@ void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum,
|
|||
|
||||
auto& procedural = skybox._procedural;
|
||||
procedural.prepare(batch, glm::vec3(0), glm::vec3(1), glm::quat());
|
||||
auto textureSlot = procedural.getShader()->getTextures().findLocation("cubeMap");
|
||||
auto bufferSlot = procedural.getShader()->getUniformBuffers().findLocation("skyboxBuffer");
|
||||
auto textureSlot = procedural.getOpaqueShader()->getTextures().findLocation("cubeMap");
|
||||
auto bufferSlot = procedural.getOpaqueShader()->getUniformBuffers().findLocation("skyboxBuffer");
|
||||
skybox.prepare(batch, textureSlot, bufferSlot);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
}
|
||||
|
|
23
libraries/render-utils/src/DefaultMaterials.slh
Normal file
23
libraries/render-utils/src/DefaultMaterials.slh
Normal file
|
@ -0,0 +1,23 @@
|
|||
<!
|
||||
// DefaultMaterials.slh
|
||||
// libraries/render-utils/src
|
||||
//
|
||||
// Created by Sam Gondelman on 3/22/18
|
||||
// Copyright 2018 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
|
||||
!>
|
||||
<@if not DEFAULT_MATERIAL_SLH@>
|
||||
<@def DEFAULT_MATERIAL_SLH@>
|
||||
|
||||
const float DEFAULT_ROUGHNESS = 0.9;
|
||||
const float DEFAULT_SHININESS = 10.0;
|
||||
const float DEFAULT_METALLIC = 0.0;
|
||||
const vec3 DEFAULT_SPECULAR = vec3(0.1);
|
||||
const vec3 DEFAULT_EMISSIVE = vec3(0.0);
|
||||
const float DEFAULT_OCCLUSION = 1.0;
|
||||
const float DEFAULT_SCATTERING = 0.0;
|
||||
const vec3 DEFAULT_FRESNEL = DEFAULT_EMISSIVE;
|
||||
|
||||
<@endif@>
|
|
@ -26,14 +26,7 @@ float evalOpaqueFinalAlpha(float alpha, float mapAlpha) {
|
|||
return mix(alpha, 1.0 - alpha, step(mapAlpha, alphaThreshold));
|
||||
}
|
||||
|
||||
const float DEFAULT_ROUGHNESS = 0.9;
|
||||
const float DEFAULT_SHININESS = 10.0;
|
||||
const float DEFAULT_METALLIC = 0.0;
|
||||
const vec3 DEFAULT_SPECULAR = vec3(0.1);
|
||||
const vec3 DEFAULT_EMISSIVE = vec3(0.0);
|
||||
const float DEFAULT_OCCLUSION = 1.0;
|
||||
const float DEFAULT_SCATTERING = 0.0;
|
||||
const vec3 DEFAULT_FRESNEL = DEFAULT_EMISSIVE;
|
||||
<@include DefaultMaterials.slh@>
|
||||
|
||||
void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness, float metallic, vec3 emissive, float occlusion, float scattering) {
|
||||
if (alpha != 1.0) {
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
<@include LightAmbient.slh@>
|
||||
<@include LightDirectional.slh@>
|
||||
|
||||
|
||||
<@func fetchGlobalLight()@>
|
||||
// Get light
|
||||
Light light = getKeyLight();
|
||||
|
@ -32,12 +31,13 @@
|
|||
vec3 color = vec3(0.0);
|
||||
<@endfunc@>
|
||||
|
||||
<@func prepareGlobalLight(isScattering)@>
|
||||
<@func prepareGlobalLight(positionES, normalWS)@>
|
||||
// prepareGlobalLight
|
||||
// Transform directions to worldspace
|
||||
vec3 fragNormal = vec3((normal));
|
||||
vec3 fragEyeVector = vec3(invViewMat * vec4(-position, 0.0));
|
||||
vec3 fragEyeDir = normalize(fragEyeVector);
|
||||
vec3 fragNormalWS = vec3(<$normalWS$>);
|
||||
vec3 fragPositionWS = vec3(invViewMat * vec4(<$positionES$>, 1.0));
|
||||
vec3 fragEyeVectorWS = invViewMat[3].xyz - fragPositionWS;
|
||||
vec3 fragEyeDirWS = normalize(fragEyeVectorWS);
|
||||
|
||||
<$fetchGlobalLight()$>
|
||||
|
||||
|
@ -46,7 +46,7 @@
|
|||
|
||||
<@func declareEvalAmbientGlobalColor()@>
|
||||
vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, float roughness) {
|
||||
<$prepareGlobalLight()$>
|
||||
<$prepareGlobalLight(position, normal)$>
|
||||
color += albedo * getLightColor(light) * obscurance * getLightAmbientIntensity(lightAmbient);
|
||||
return color;
|
||||
}
|
||||
|
@ -67,14 +67,14 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness
|
|||
, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
|
||||
<@endif@> ) {
|
||||
|
||||
<$prepareGlobalLight($supportScattering$)$>
|
||||
<$prepareGlobalLight(position, normal)$>
|
||||
|
||||
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
|
||||
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
|
||||
|
||||
// Ambient
|
||||
vec3 ambientDiffuse;
|
||||
vec3 ambientSpecular;
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance
|
||||
<@if supportScattering@>
|
||||
,scattering, midNormalCurvature, lowNormalCurvature
|
||||
<@endif@> );
|
||||
|
@ -85,7 +85,7 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness
|
|||
// Directional
|
||||
vec3 directionalDiffuse;
|
||||
vec3 directionalSpecular;
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation
|
||||
<@if supportScattering@>
|
||||
,scattering, midNormalCurvature, lowNormalCurvature
|
||||
<@endif@> );
|
||||
|
@ -114,14 +114,14 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
|
|||
, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
|
||||
<@endif@>
|
||||
) {
|
||||
<$prepareGlobalLight($supportScattering$)$>
|
||||
<$prepareGlobalLight(position, normal)$>
|
||||
|
||||
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
|
||||
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
|
||||
|
||||
// Ambient
|
||||
vec3 ambientDiffuse;
|
||||
vec3 ambientSpecular;
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance
|
||||
<@if supportScattering@>
|
||||
,scattering, midNormalCurvature, lowNormalCurvature
|
||||
<@endif@>
|
||||
|
@ -131,7 +131,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
|
|||
|
||||
vec3 directionalDiffuse;
|
||||
vec3 directionalSpecular;
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation
|
||||
<@if supportScattering@>
|
||||
,scattering, midNormalCurvature, lowNormalCurvature
|
||||
<@endif@>
|
||||
|
@ -141,7 +141,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
|
|||
|
||||
// Attenuate the light if haze effect selected
|
||||
if ((hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) {
|
||||
color = computeHazeColorKeyLightAttenuation(color, lightDirection, position);
|
||||
color = computeHazeColorKeyLightAttenuation(color, lightDirection, fragPositionWS);
|
||||
}
|
||||
|
||||
return color;
|
||||
|
@ -180,9 +180,9 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscur
|
|||
<$declareLightingDirectional()$>
|
||||
|
||||
vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity, vec3 prevLighting) {
|
||||
<$prepareGlobalLight()$>
|
||||
<$prepareGlobalLight(position, normal)$>
|
||||
|
||||
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
|
||||
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
|
||||
|
||||
color = prevLighting;
|
||||
color += emissive * isEmissiveEnabled();
|
||||
|
@ -190,16 +190,15 @@ vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, fl
|
|||
// Ambient
|
||||
vec3 ambientDiffuse;
|
||||
vec3 ambientSpecular;
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance);
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance);
|
||||
color += ambientDiffuse;
|
||||
color += ambientSpecular / opacity;
|
||||
|
||||
// Directional
|
||||
vec3 directionalDiffuse;
|
||||
vec3 directionalSpecular;
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation);
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation);
|
||||
color += directionalDiffuse;
|
||||
color += directionalSpecular / opacity;
|
||||
color += (ambientSpecular + directionalSpecular) / opacity;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
@ -211,37 +210,37 @@ vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, fl
|
|||
<$declareLightingDirectional()$>
|
||||
|
||||
vec3 evalGlobalLightingAlphaBlendedWithHaze(
|
||||
mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal,
|
||||
mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 positionES, vec3 normalWS,
|
||||
vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity)
|
||||
{
|
||||
<$prepareGlobalLight()$>
|
||||
|
||||
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
|
||||
<$prepareGlobalLight(positionES, normalWS)$>
|
||||
|
||||
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
|
||||
|
||||
color += emissive * isEmissiveEnabled();
|
||||
|
||||
// Ambient
|
||||
vec3 ambientDiffuse;
|
||||
vec3 ambientSpecular;
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance);
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance);
|
||||
color += ambientDiffuse;
|
||||
color += ambientSpecular / opacity;
|
||||
|
||||
// Directional
|
||||
vec3 directionalDiffuse;
|
||||
vec3 directionalSpecular;
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation);
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation);
|
||||
color += directionalDiffuse;
|
||||
color += directionalSpecular / opacity;
|
||||
color += (ambientSpecular + directionalSpecular) / opacity;
|
||||
|
||||
// Haze
|
||||
if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
|
||||
vec4 colorV4 = computeHazeColor(
|
||||
vec4(color, 1.0), // fragment original color
|
||||
position, // fragment position in eye coordinates
|
||||
fragEyeVector, // fragment position in world coordinates
|
||||
invViewMat[3].y, // eye height in world coordinates
|
||||
lightDirection // keylight direction vector
|
||||
positionES, // fragment position in eye coordinates
|
||||
fragPositionWS, // fragment position in world coordinates
|
||||
invViewMat[3].xyz, // eye position in world coordinates
|
||||
lightDirection // keylight direction vector in world coordinates
|
||||
);
|
||||
|
||||
color = colorV4.rgb;
|
||||
|
@ -251,7 +250,7 @@ vec3 evalGlobalLightingAlphaBlendedWithHaze(
|
|||
}
|
||||
|
||||
vec3 evalGlobalLightingAlphaBlendedWithHaze(
|
||||
mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position,
|
||||
mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 positionES, vec3 positionWS,
|
||||
vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, SurfaceData surface, float opacity, vec3 prevLighting)
|
||||
{
|
||||
<$fetchGlobalLight()$>
|
||||
|
@ -276,9 +275,9 @@ vec3 evalGlobalLightingAlphaBlendedWithHaze(
|
|||
if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
|
||||
vec4 colorV4 = computeHazeColor(
|
||||
vec4(color, 1.0), // fragment original color
|
||||
position, // fragment position in eye coordinates
|
||||
surface.eyeDir, // fragment eye vector in world coordinates
|
||||
invViewMat[3].y, // eye height in world coordinates
|
||||
positionES, // fragment position in eye coordinates
|
||||
positionWS, // fragment position in world coordinates
|
||||
invViewMat[3].xyz, // eye position in world coordinates
|
||||
lightDirection // keylight direction vector
|
||||
);
|
||||
|
||||
|
|
|
@ -142,15 +142,18 @@ void DrawHaze::run(const render::RenderContextPointer& renderContext, const Inpu
|
|||
// Mask out haze on the tablet
|
||||
PrepareStencil::testMask(*state);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("hazeBuffer"), HazeEffect_ParamsSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), HazeEffect_TransformBufferSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), HazeEffect_ColorMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("linearDepthMap"), HazeEffect_LinearDepthMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), HazeEffect_LightingMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
_hazePipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state));
|
||||
gpu::doInBatch("DrawHaze::build", args->_context, [program](gpu::Batch& batch) {
|
||||
batch.runLambda([program]() {
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("hazeBuffer"), HazeEffect_ParamsSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), HazeEffect_TransformBufferSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), HazeEffect_ColorMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("linearDepthMap"), HazeEffect_LinearDepthMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), HazeEffect_LightingMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
auto sourceFramebufferSize = glm::ivec2(inputBuffer->getDimensions());
|
||||
|
|
|
@ -20,13 +20,13 @@
|
|||
<@include LightAmbient.slh@>
|
||||
<@include LightDirectional.slh@>
|
||||
|
||||
|
||||
<@func prepareGlobalLight(isScattering)@>
|
||||
<@func prepareGlobalLight(positionES, normalWS)@>
|
||||
// prepareGlobalLight
|
||||
// Transform directions to worldspace
|
||||
vec3 fragNormal = vec3((normal));
|
||||
vec3 fragEyeVector = vec3(invViewMat * vec4(-1.0*position, 0.0));
|
||||
vec3 fragEyeDir = normalize(fragEyeVector);
|
||||
vec3 fragNormalWS = vec3(<$normalWS$>);
|
||||
vec3 fragPositionWS = vec3(invViewMat * vec4(<$positionES$>, 1.0));
|
||||
vec3 fragEyeVectorWS = invViewMat[3].xyz - fragPositionWS;
|
||||
vec3 fragEyeDirWS = normalize(fragEyeVectorWS);
|
||||
|
||||
// Get light
|
||||
Light light = getKeyLight();
|
||||
|
@ -42,7 +42,7 @@
|
|||
|
||||
<@func declareEvalAmbientGlobalColor()@>
|
||||
vec3 evalAmbientGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, float roughness) {
|
||||
<$prepareGlobalLight()$>
|
||||
<$prepareGlobalLight(position, normal)$>
|
||||
color += albedo * getLightColor(light) * obscurance * getLightAmbientIntensity(lightAmbient);
|
||||
return color;
|
||||
}
|
||||
|
@ -63,14 +63,14 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness
|
|||
, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
|
||||
<@endif@> ) {
|
||||
|
||||
<$prepareGlobalLight($supportScattering$)$>
|
||||
<$prepareGlobalLight(position, normal)$>
|
||||
|
||||
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
|
||||
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
|
||||
|
||||
// Ambient
|
||||
vec3 ambientDiffuse;
|
||||
vec3 ambientSpecular;
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance
|
||||
<@if supportScattering@>
|
||||
,scattering, midNormalCurvature, lowNormalCurvature
|
||||
<@endif@> );
|
||||
|
@ -81,7 +81,7 @@ vec3 albedo, vec3 fresnel, float metallic, float roughness
|
|||
// Directional
|
||||
vec3 directionalDiffuse;
|
||||
vec3 directionalSpecular;
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation
|
||||
<@if supportScattering@>
|
||||
,scattering, midNormalCurvature, lowNormalCurvature
|
||||
<@endif@> );
|
||||
|
@ -109,14 +109,14 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
|
|||
, float scattering, vec4 midNormalCurvature, vec4 lowNormalCurvature
|
||||
<@endif@>
|
||||
) {
|
||||
<$prepareGlobalLight($supportScattering$)$>
|
||||
<$prepareGlobalLight(position, normal)$>
|
||||
|
||||
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
|
||||
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
|
||||
|
||||
// Ambient
|
||||
vec3 ambientDiffuse;
|
||||
vec3 ambientSpecular;
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance
|
||||
<@if supportScattering@>
|
||||
,scattering, midNormalCurvature, lowNormalCurvature
|
||||
<@endif@>
|
||||
|
@ -126,7 +126,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
|
|||
|
||||
vec3 directionalDiffuse;
|
||||
vec3 directionalSpecular;
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation
|
||||
<@if supportScattering@>
|
||||
,scattering, midNormalCurvature, lowNormalCurvature
|
||||
<@endif@>
|
||||
|
@ -137,7 +137,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, float obscu
|
|||
// FIXME - temporarily removed until we support it for forward...
|
||||
// Attenuate the light if haze effect selected
|
||||
// if ((hazeParams.hazeMode & HAZE_MODE_IS_KEYLIGHT_ATTENUATED) == HAZE_MODE_IS_KEYLIGHT_ATTENUATED) {
|
||||
// color = computeHazeColorKeyLightAttenuation(color, lightDirection, position);
|
||||
// color = computeHazeColorKeyLightAttenuation(color, lightDirection, fragPositionWS);
|
||||
// }
|
||||
|
||||
return color;
|
||||
|
@ -180,25 +180,24 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, float obscur
|
|||
<$declareLightingDirectional()$>
|
||||
|
||||
vec3 evalGlobalLightingAlphaBlended(mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal, vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity) {
|
||||
<$prepareGlobalLight()$>
|
||||
<$prepareGlobalLight(position, normal)$>
|
||||
|
||||
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
|
||||
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
|
||||
|
||||
color += emissive * isEmissiveEnabled();
|
||||
|
||||
// Ambient
|
||||
vec3 ambientDiffuse;
|
||||
vec3 ambientSpecular;
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance);
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance);
|
||||
color += ambientDiffuse;
|
||||
color += ambientSpecular / opacity;
|
||||
|
||||
// Directional
|
||||
vec3 directionalDiffuse;
|
||||
vec3 directionalSpecular;
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation);
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation);
|
||||
color += directionalDiffuse;
|
||||
color += directionalSpecular / opacity;
|
||||
color += (ambientSpecular + directionalSpecular) / opacity;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
@ -207,34 +206,33 @@ vec3 evalGlobalLightingAlphaBlendedWithHaze(
|
|||
mat4 invViewMat, float shadowAttenuation, float obscurance, vec3 position, vec3 normal,
|
||||
vec3 albedo, vec3 fresnel, float metallic, vec3 emissive, float roughness, float opacity)
|
||||
{
|
||||
<$prepareGlobalLight()$>
|
||||
<$prepareGlobalLight(position, normal)$>
|
||||
|
||||
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
|
||||
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragEyeDirWS);
|
||||
|
||||
color += emissive * isEmissiveEnabled();
|
||||
|
||||
// Ambient
|
||||
vec3 ambientDiffuse;
|
||||
vec3 ambientSpecular;
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surface, metallic, fresnel, albedo, obscurance);
|
||||
evalLightingAmbient(ambientDiffuse, ambientSpecular, lightAmbient, surfaceWS, metallic, fresnel, albedo, obscurance);
|
||||
color += ambientDiffuse;
|
||||
color += ambientSpecular / opacity;
|
||||
|
||||
// Directional
|
||||
vec3 directionalDiffuse;
|
||||
vec3 directionalSpecular;
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surface, metallic, fresnel, albedo, shadowAttenuation);
|
||||
evalLightingDirectional(directionalDiffuse, directionalSpecular, lightDirection, lightIrradiance, surfaceWS, metallic, fresnel, albedo, shadowAttenuation);
|
||||
color += directionalDiffuse;
|
||||
color += directionalSpecular / opacity;
|
||||
color += (ambientSpecular + directionalSpecular) / opacity;
|
||||
|
||||
// Haze
|
||||
// FIXME - temporarily removed until we support it for forward...
|
||||
/* if ((hazeParams.hazeMode & HAZE_MODE_IS_ACTIVE) == HAZE_MODE_IS_ACTIVE) {
|
||||
vec4 colorV4 = computeHazeColor(
|
||||
vec4(color, 1.0), // fragment original color
|
||||
position, // fragment position in eye coordinates
|
||||
fragEyeVector, // fragment position in world coordinates
|
||||
invViewMat[3].y, // eye height in world coordinates
|
||||
positionES, // fragment position in eye coordinates
|
||||
fragPositionWS, // fragment position in world coordinates
|
||||
invViewMat[3].xyz, // eye position in world coordinates
|
||||
lightDirection // keylight direction vector
|
||||
);
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
|
||||
#include "simple_vert.h"
|
||||
#include "simple_textured_frag.h"
|
||||
#include "simple_transparent_textured_frag.h"
|
||||
#include "simple_textured_unlit_frag.h"
|
||||
#include "simple_fade_vert.h"
|
||||
#include "simple_textured_fade_frag.h"
|
||||
|
@ -49,6 +50,19 @@
|
|||
#include "glowLine_vert.h"
|
||||
#include "glowLine_frag.h"
|
||||
|
||||
#include "forward_simple_textured_frag.h"
|
||||
#include "forward_simple_textured_transparent_frag.h"
|
||||
#include "forward_simple_textured_unlit_frag.h"
|
||||
|
||||
#include "DeferredLightingEffect.h"
|
||||
|
||||
#if defined(USE_GLES)
|
||||
static bool DISABLE_DEFERRED = true;
|
||||
#else
|
||||
static const QString RENDER_FORWARD{ "HIFI_RENDER_FORWARD" };
|
||||
static bool DISABLE_DEFERRED = QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD);
|
||||
#endif
|
||||
|
||||
#include "grid_frag.h"
|
||||
|
||||
//#define WANT_DEBUG
|
||||
|
@ -679,6 +693,7 @@ gpu::Stream::FormatPointer& getInstancedSolidFadeStreamFormat() {
|
|||
QHash<SimpleProgramKey, gpu::PipelinePointer> GeometryCache::_simplePrograms;
|
||||
|
||||
gpu::ShaderPointer GeometryCache::_simpleShader;
|
||||
gpu::ShaderPointer GeometryCache::_transparentShader;
|
||||
gpu::ShaderPointer GeometryCache::_unlitShader;
|
||||
gpu::ShaderPointer GeometryCache::_simpleFadeShader;
|
||||
gpu::ShaderPointer GeometryCache::_unlitFadeShader;
|
||||
|
@ -774,8 +789,12 @@ render::ShapePipelinePointer GeometryCache::getShapePipeline(bool textured, bool
|
|||
bool unlit, bool depthBias) {
|
||||
|
||||
return std::make_shared<render::ShapePipeline>(getSimplePipeline(textured, transparent, culled, unlit, depthBias, false, true), nullptr,
|
||||
[](const render::ShapePipeline& , gpu::Batch& batch, render::Args*) {
|
||||
[](const render::ShapePipeline& pipeline, gpu::Batch& batch, render::Args* args) {
|
||||
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::ALBEDO, DependencyManager::get<TextureCache>()->getWhiteTexture());
|
||||
DependencyManager::get<DeferredLightingEffect>()->setupKeyLightBatch(args, batch,
|
||||
pipeline.pipeline->getProgram()->getUniformBuffers().findLocation("keyLightBuffer"),
|
||||
pipeline.pipeline->getProgram()->getUniformBuffers().findLocation("lightAmbientBuffer"),
|
||||
pipeline.pipeline->getProgram()->getUniformBuffers().findLocation("skyboxMap"));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -798,7 +817,7 @@ render::ShapePipelinePointer GeometryCache::getOpaqueShapePipeline(bool isFading
|
|||
return isFading ? _simpleOpaqueFadePipeline : _simpleOpaquePipeline;
|
||||
}
|
||||
|
||||
render::ShapePipelinePointer GeometryCache::getTransparentShapePipeline(bool isFading) {
|
||||
render::ShapePipelinePointer GeometryCache::getTransparentShapePipeline(bool isFading) {
|
||||
return isFading ? _simpleTransparentFadePipeline : _simpleTransparentPipeline;
|
||||
}
|
||||
|
||||
|
@ -843,7 +862,7 @@ void GeometryCache::renderWireShapeInstances(gpu::Batch& batch, Shape shape, siz
|
|||
_shapes[shape].drawWireInstances(batch, count);
|
||||
}
|
||||
|
||||
void setupBatchFadeInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer,
|
||||
void setupBatchFadeInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer,
|
||||
gpu::BufferPointer fadeBuffer1, gpu::BufferPointer fadeBuffer2, gpu::BufferPointer fadeBuffer3) {
|
||||
gpu::BufferView colorView(colorBuffer, COLOR_ELEMENT);
|
||||
gpu::BufferView texCoord2View(fadeBuffer1, TEXCOORD4_ELEMENT);
|
||||
|
@ -2003,7 +2022,7 @@ void GeometryCache::renderGlowLine(gpu::Batch& batch, const glm::vec3& p1, const
|
|||
auto program = gpu::Shader::createProgram(VS, PS);
|
||||
state->setCullMode(gpu::State::CULL_NONE);
|
||||
state->setDepthTest(true, false, gpu::LESS_EQUAL);
|
||||
state->setBlendFunction(true,
|
||||
state->setBlendFunction(true,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
|
||||
|
@ -2231,29 +2250,41 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp
|
|||
static std::once_flag once;
|
||||
std::call_once(once, [&]() {
|
||||
auto VS = simple_vert::getShader();
|
||||
auto PS = simple_textured_frag::getShader();
|
||||
auto PSUnlit = simple_textured_unlit_frag::getShader();
|
||||
auto PS = DISABLE_DEFERRED ? forward_simple_textured_frag::getShader() : simple_textured_frag::getShader();
|
||||
// Use the forward pipeline for both here, otherwise transparents will be unlit
|
||||
auto PSTransparent = DISABLE_DEFERRED ? forward_simple_textured_transparent_frag::getShader() : forward_simple_textured_transparent_frag::getShader();
|
||||
auto PSUnlit = DISABLE_DEFERRED ? forward_simple_textured_unlit_frag::getShader() : simple_textured_unlit_frag::getShader();
|
||||
|
||||
_simpleShader = gpu::Shader::createProgram(VS, PS);
|
||||
_transparentShader = gpu::Shader::createProgram(VS, PSTransparent);
|
||||
_unlitShader = gpu::Shader::createProgram(VS, PSUnlit);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("originalTexture"), render::ShapePipeline::Slot::MAP::ALBEDO));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightingModelBuffer"), render::ShapePipeline::Slot::LIGHTING_MODEL));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), render::ShapePipeline::Slot::KEY_LIGHT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), render::ShapePipeline::Slot::LIGHT_AMBIENT_BUFFER));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), render::ShapePipeline::Slot::MAP::LIGHT_AMBIENT));
|
||||
gpu::Shader::makeProgram(*_simpleShader, slotBindings);
|
||||
gpu::Shader::makeProgram(*_transparentShader, slotBindings);
|
||||
gpu::Shader::makeProgram(*_unlitShader, slotBindings);
|
||||
});
|
||||
} else {
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [&]() {
|
||||
auto VS = simple_fade_vert::getShader();
|
||||
auto PS = simple_textured_fade_frag::getShader();
|
||||
auto PSUnlit = simple_textured_unlit_fade_frag::getShader();
|
||||
auto PS = DISABLE_DEFERRED ? forward_simple_textured_frag::getShader() : simple_textured_fade_frag::getShader();
|
||||
auto PSUnlit = DISABLE_DEFERRED ? forward_simple_textured_unlit_frag::getShader() : simple_textured_unlit_fade_frag::getShader();
|
||||
|
||||
_simpleFadeShader = gpu::Shader::createProgram(VS, PS);
|
||||
_unlitFadeShader = gpu::Shader::createProgram(VS, PSUnlit);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("originalTexture"), render::ShapePipeline::Slot::MAP::ALBEDO));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightingModelBuffer"), render::ShapePipeline::Slot::LIGHTING_MODEL));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("keyLightBuffer"), render::ShapePipeline::Slot::KEY_LIGHT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("lightAmbientBuffer"), render::ShapePipeline::Slot::LIGHT_AMBIENT_BUFFER));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), render::ShapePipeline::Slot::MAP::LIGHT_AMBIENT));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("fadeMaskMap"), render::ShapePipeline::Slot::MAP::FADE_MASK));
|
||||
gpu::Shader::makeProgram(*_simpleFadeShader, slotBindings);
|
||||
gpu::Shader::makeProgram(*_unlitFadeShader, slotBindings);
|
||||
|
@ -2282,7 +2313,8 @@ gpu::PipelinePointer GeometryCache::getSimplePipeline(bool textured, bool transp
|
|||
PrepareStencil::testMaskDrawShapeNoAA(*state);
|
||||
}
|
||||
|
||||
gpu::ShaderPointer program = (config.isUnlit()) ? (config.isFading() ? _unlitFadeShader : _unlitShader) : (config.isFading() ? _simpleFadeShader : _simpleShader);
|
||||
gpu::ShaderPointer program = (config.isUnlit()) ? (config.isFading() ? _unlitFadeShader : _unlitShader) :
|
||||
(config.isFading() ? _simpleFadeShader : (config.isTransparent() ? _transparentShader : _simpleShader));
|
||||
gpu::PipelinePointer pipeline = gpu::Pipeline::create(program, state);
|
||||
_simplePrograms.insert(config, pipeline);
|
||||
return pipeline;
|
||||
|
@ -2363,11 +2395,11 @@ void renderFadeInstances(RenderArgs* args, gpu::Batch& batch, const glm::vec4& c
|
|||
pipeline->prepare(batch, args);
|
||||
|
||||
if (isWire) {
|
||||
DependencyManager::get<GeometryCache>()->renderWireFadeShapeInstances(batch, shape, data.count(),
|
||||
DependencyManager::get<GeometryCache>()->renderWireFadeShapeInstances(batch, shape, data.count(),
|
||||
buffers[INSTANCE_COLOR_BUFFER], buffers[INSTANCE_FADE_BUFFER1], buffers[INSTANCE_FADE_BUFFER2], buffers[INSTANCE_FADE_BUFFER3]);
|
||||
}
|
||||
else {
|
||||
DependencyManager::get<GeometryCache>()->renderFadeShapeInstances(batch, shape, data.count(),
|
||||
DependencyManager::get<GeometryCache>()->renderFadeShapeInstances(batch, shape, data.count(),
|
||||
buffers[INSTANCE_COLOR_BUFFER], buffers[INSTANCE_FADE_BUFFER1], buffers[INSTANCE_FADE_BUFFER2], buffers[INSTANCE_FADE_BUFFER3]);
|
||||
}
|
||||
});
|
||||
|
@ -2383,15 +2415,15 @@ void GeometryCache::renderWireShapeInstance(RenderArgs* args, gpu::Batch& batch,
|
|||
renderInstances(args, batch, color, true, pipeline, shape);
|
||||
}
|
||||
|
||||
void GeometryCache::renderSolidFadeShapeInstance(RenderArgs* args, gpu::Batch& batch, GeometryCache::Shape shape, const glm::vec4& color,
|
||||
int fadeCategory, float fadeThreshold, const glm::vec3& fadeNoiseOffset, const glm::vec3& fadeBaseOffset, const glm::vec3& fadeBaseInvSize,
|
||||
void GeometryCache::renderSolidFadeShapeInstance(RenderArgs* args, gpu::Batch& batch, GeometryCache::Shape shape, const glm::vec4& color,
|
||||
int fadeCategory, float fadeThreshold, const glm::vec3& fadeNoiseOffset, const glm::vec3& fadeBaseOffset, const glm::vec3& fadeBaseInvSize,
|
||||
const render::ShapePipelinePointer& pipeline) {
|
||||
assert(pipeline != nullptr);
|
||||
renderFadeInstances(args, batch, color, fadeCategory, fadeThreshold, fadeNoiseOffset, fadeBaseOffset, fadeBaseInvSize, false, pipeline, shape);
|
||||
}
|
||||
|
||||
void GeometryCache::renderWireFadeShapeInstance(RenderArgs* args, gpu::Batch& batch, GeometryCache::Shape shape, const glm::vec4& color,
|
||||
int fadeCategory, float fadeThreshold, const glm::vec3& fadeNoiseOffset, const glm::vec3& fadeBaseOffset, const glm::vec3& fadeBaseInvSize,
|
||||
void GeometryCache::renderWireFadeShapeInstance(RenderArgs* args, gpu::Batch& batch, GeometryCache::Shape shape, const glm::vec4& color,
|
||||
int fadeCategory, float fadeThreshold, const glm::vec3& fadeNoiseOffset, const glm::vec3& fadeBaseOffset, const glm::vec3& fadeBaseInvSize,
|
||||
const render::ShapePipelinePointer& pipeline) {
|
||||
assert(pipeline != nullptr);
|
||||
renderFadeInstances(args, batch, color, fadeCategory, fadeThreshold, fadeNoiseOffset, fadeBaseOffset, fadeBaseInvSize, true, pipeline, shape);
|
||||
|
|
|
@ -471,6 +471,7 @@ private:
|
|||
QHash<int, GridBuffer> _registeredGridBuffers;
|
||||
|
||||
static gpu::ShaderPointer _simpleShader;
|
||||
static gpu::ShaderPointer _transparentShader;
|
||||
static gpu::ShaderPointer _unlitShader;
|
||||
static gpu::ShaderPointer _simpleFadeShader;
|
||||
static gpu::ShaderPointer _unlitFadeShader;
|
||||
|
@ -478,8 +479,6 @@ private:
|
|||
static render::ShapePipelinePointer _simpleTransparentPipeline;
|
||||
static render::ShapePipelinePointer _simpleOpaqueFadePipeline;
|
||||
static render::ShapePipelinePointer _simpleTransparentFadePipeline;
|
||||
static render::ShapePipelinePointer _simpleOpaqueOverlayPipeline;
|
||||
static render::ShapePipelinePointer _simpleTransparentOverlayPipeline;
|
||||
static render::ShapePipelinePointer _simpleWirePipeline;
|
||||
gpu::PipelinePointer _glowLinePipeline;
|
||||
|
||||
|
|
|
@ -47,14 +47,14 @@ void main(void) {
|
|||
}
|
||||
|
||||
vec4 fragColor = texture(colorMap, varTexCoord0);
|
||||
vec4 eyeFragPos = unpackPositionFromZeye(varTexCoord0);
|
||||
vec4 fragPositionES = unpackPositionFromZeye(varTexCoord0);
|
||||
|
||||
mat4 viewInverse = getViewInverse();
|
||||
vec4 worldFragPos = viewInverse * eyeFragPos;
|
||||
vec4 worldEyePos = viewInverse[3];
|
||||
vec4 fragPositionWS = viewInverse * fragPositionES;
|
||||
vec4 eyePositionWS = viewInverse[3];
|
||||
|
||||
Light light = getKeyLight();
|
||||
vec3 lightDirection = getLightDirection(light);
|
||||
vec3 lightDirectionWS = getLightDirection(light);
|
||||
|
||||
outFragColor = computeHazeColor(fragColor, eyeFragPos.xyz, worldFragPos.xyz, worldEyePos.y, lightDirection);
|
||||
outFragColor = computeHazeColor(fragColor, fragPositionES.xyz, fragPositionWS.xyz, eyePositionWS.xyz, lightDirectionWS);
|
||||
}
|
||||
|
|
|
@ -43,16 +43,16 @@ layout(std140) uniform hazeBuffer {
|
|||
|
||||
// Input:
|
||||
// color - fragment original color
|
||||
// lightDirection - parameters of the keylight
|
||||
// worldFragPos - fragment position in world coordinates
|
||||
// lightDirectionWS - parameters of the keylight
|
||||
// fragPositionWS - fragment position in world coordinates
|
||||
// Output:
|
||||
// fragment colour after haze effect
|
||||
//
|
||||
// General algorithm taken from http://www.iquilezles.org/www/articles/fog/fog.htm, with permission
|
||||
//
|
||||
vec3 computeHazeColorKeyLightAttenuation(vec3 color, vec3 lightDirection, vec3 worldFragPos) {
|
||||
vec3 computeHazeColorKeyLightAttenuation(vec3 color, vec3 lightDirectionWS, vec3 fragPositionWS) {
|
||||
// Directional light attenuation is simulated by assuming the light source is at a fixed height above the
|
||||
// fragment. This height is where the haze density is reduced by 95% from the haze at the fragment's height
|
||||
// fragment. This height is where the haze density is reduced by 95% from the haze at the fragment's height
|
||||
//
|
||||
// The distance is computed from the height and the directional light orientation
|
||||
// The distance is limited to height * 1,000, which gives an angle of ~0.057 degrees
|
||||
|
@ -65,7 +65,7 @@ vec3 computeHazeColorKeyLightAttenuation(vec3 color, vec3 lightDirection, vec3 w
|
|||
}
|
||||
|
||||
// Note that we need the sine to be positive
|
||||
float sin_pitch = abs(lightDirection.y);
|
||||
float sin_pitch = abs(lightDirectionWS.y);
|
||||
|
||||
float distance;
|
||||
const float minimumSinPitch = 0.001;
|
||||
|
@ -79,7 +79,7 @@ vec3 computeHazeColorKeyLightAttenuation(vec3 color, vec3 lightDirection, vec3 w
|
|||
// Note that the haze base reference affects only the haze density as function of altitude
|
||||
float hazeDensityDistribution =
|
||||
hazeParams.hazeKeyLightRangeFactor *
|
||||
exp(-hazeParams.hazeKeyLightAltitudeFactor * (worldFragPos.y - hazeParams.hazeBaseReference));
|
||||
exp(-hazeParams.hazeKeyLightAltitudeFactor * (fragPositionWS.y - hazeParams.hazeBaseReference));
|
||||
|
||||
float hazeIntegral = hazeDensityDistribution * distance;
|
||||
|
||||
|
@ -92,33 +92,34 @@ vec3 computeHazeColorKeyLightAttenuation(vec3 color, vec3 lightDirection, vec3 w
|
|||
}
|
||||
|
||||
// Input:
|
||||
// fragColor - fragment original color
|
||||
// eyeFragPos - fragment position in eye coordinates
|
||||
// worldFragPos - fragment position in world coordinates
|
||||
// worldEyeHeight - eye height in world coordinates
|
||||
// fragColor - fragment original color
|
||||
// fragPositionES - fragment position in eye coordinates
|
||||
// fragPositionWS - fragment position in world coordinates
|
||||
// eyePositionWS - eye position in world coordinates
|
||||
// Output:
|
||||
// fragment colour after haze effect
|
||||
//
|
||||
// General algorithm taken from http://www.iquilezles.org/www/articles/fog/fog.htm, with permission
|
||||
//
|
||||
vec4 computeHazeColor(vec4 fragColor, vec3 eyeFragPos, vec3 worldFragPos, float worldEyeHeight, vec3 lightDirection) {
|
||||
vec4 computeHazeColor(vec4 fragColor, vec3 fragPositionES, vec3 fragPositionWS, vec3 eyePositionWS, vec3 lightDirectionWS) {
|
||||
// Distance to fragment
|
||||
float distance = length(eyeFragPos);
|
||||
float distance = length(fragPositionES);
|
||||
float eyeWorldHeight = eyePositionWS.y;
|
||||
|
||||
// Convert haze colour from uniform into a vec4
|
||||
vec4 hazeColor = vec4(hazeParams.hazeColor, 1.0);
|
||||
|
||||
// Directional light component is a function of the angle from the eye, between the fragment and the sun
|
||||
vec3 eyeFragDir = normalize(worldFragPos);
|
||||
|
||||
float glareComponent = max(0.0, dot(eyeFragDir, -lightDirection));
|
||||
float power = min(1.0, pow(glareComponent, hazeParams.hazeGlareBlend));
|
||||
|
||||
vec4 glareColor = vec4(hazeParams.hazeGlareColor, 1.0);
|
||||
|
||||
// Use the haze colour for the glare colour, if blend is not enabled
|
||||
vec4 blendedHazeColor;
|
||||
if ((hazeParams.hazeMode & HAZE_MODE_IS_ENABLE_LIGHT_BLEND) == HAZE_MODE_IS_ENABLE_LIGHT_BLEND) {
|
||||
// Directional light component is a function of the angle from the eye, between the fragment and the sun
|
||||
vec3 fragToEyeDirWS = normalize(fragPositionWS - eyePositionWS);
|
||||
|
||||
float glareComponent = max(0.0, dot(fragToEyeDirWS, -lightDirectionWS));
|
||||
float power = min(1.0, pow(glareComponent, hazeParams.hazeGlareBlend));
|
||||
|
||||
vec4 glareColor = vec4(hazeParams.hazeGlareColor, 1.0);
|
||||
|
||||
blendedHazeColor = mix(hazeColor, glareColor, power);
|
||||
} else {
|
||||
blendedHazeColor = hazeColor;
|
||||
|
@ -134,12 +135,12 @@ vec4 computeHazeColor(vec4 fragColor, vec3 eyeFragPos, vec3 worldFragPos, float
|
|||
// Note that the haze base reference affects only the haze density as function of altitude
|
||||
vec3 hazeDensityDistribution =
|
||||
hazeParams.colorModulationFactor *
|
||||
exp(-hazeParams.hazeHeightFactor * (worldEyeHeight - hazeParams.hazeBaseReference));
|
||||
exp(-hazeParams.hazeHeightFactor * (eyeWorldHeight - hazeParams.hazeBaseReference));
|
||||
|
||||
vec3 hazeIntegral = hazeDensityDistribution * distance;
|
||||
vec3 hazeIntegral = hazeDensityDistribution * distance;
|
||||
|
||||
const float slopeThreshold = 0.01;
|
||||
float deltaHeight = worldFragPos.y - worldEyeHeight;
|
||||
float deltaHeight = fragPositionWS.y - eyeWorldHeight;
|
||||
if (abs(deltaHeight) > slopeThreshold) {
|
||||
float t = hazeParams.hazeHeightFactor * deltaHeight;
|
||||
hazeIntegral *= (1.0 - exp (-t)) / t;
|
||||
|
@ -162,12 +163,12 @@ vec4 computeHazeColor(vec4 fragColor, vec3 eyeFragPos, vec3 worldFragPos, float
|
|||
// Note that the haze base reference affects only the haze density as function of altitude
|
||||
float hazeDensityDistribution =
|
||||
hazeParams.hazeRangeFactor *
|
||||
exp(-hazeParams.hazeHeightFactor * (worldEyeHeight - hazeParams.hazeBaseReference));
|
||||
exp(-hazeParams.hazeHeightFactor * (eyeWorldHeight - hazeParams.hazeBaseReference));
|
||||
|
||||
float hazeIntegral = hazeDensityDistribution * distance;
|
||||
|
||||
const float slopeThreshold = 0.01;
|
||||
float deltaHeight = worldFragPos.y - worldEyeHeight;
|
||||
float deltaHeight = fragPositionWS.y - eyeWorldHeight;
|
||||
if (abs(deltaHeight) > slopeThreshold) {
|
||||
float t = hazeParams.hazeHeightFactor * deltaHeight;
|
||||
// Protect from wild values
|
||||
|
|
|
@ -111,15 +111,11 @@ void evalLightingAmbient(out vec3 diffuse, out vec3 specular, LightAmbient ambie
|
|||
}
|
||||
<@endif@>
|
||||
|
||||
if (!(isObscuranceEnabled() > 0.0)) {
|
||||
obscurance = 1.0;
|
||||
}
|
||||
obscurance = mix(1.0, obscurance, isObscuranceEnabled());
|
||||
|
||||
float lightEnergy = obscurance * getLightAmbientIntensity(ambient);
|
||||
|
||||
if (isAlbedoEnabled() > 0.0) {
|
||||
diffuse *= albedo;
|
||||
}
|
||||
diffuse *= mix(vec3(1), albedo, isAlbedoEnabled());
|
||||
|
||||
lightEnergy *= isAmbientEnabled();
|
||||
diffuse *= lightEnergy * isDiffuseEnabled();
|
||||
|
|
|
@ -13,11 +13,19 @@
|
|||
|
||||
<@func declareLightingModel()@>
|
||||
|
||||
#ifndef PRECISIONQ
|
||||
#ifdef GL_ES
|
||||
#define PRECISIONQ highp
|
||||
#else
|
||||
#define PRECISIONQ
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct LightingModel {
|
||||
vec4 _UnlitEmissiveLightmapBackground;
|
||||
vec4 _ScatteringDiffuseSpecularAlbedo;
|
||||
vec4 _AmbientDirectionalPointSpot;
|
||||
vec4 _ShowContourObscuranceWireframe;
|
||||
PRECISIONQ vec4 _UnlitEmissiveLightmapBackground;
|
||||
PRECISIONQ vec4 _ScatteringDiffuseSpecularAlbedo;
|
||||
PRECISIONQ vec4 _AmbientDirectionalPointSpot;
|
||||
PRECISIONQ vec4 _ShowContourObscuranceWireframe;
|
||||
};
|
||||
|
||||
uniform lightingModelBuffer{
|
||||
|
@ -256,9 +264,7 @@ void evalFragShading(out vec3 diffuse, out vec3 specular,
|
|||
float metallic, vec3 fresnel, SurfaceData surface, vec3 albedo) {
|
||||
vec4 shading = evalPBRShading(metallic, fresnel, surface);
|
||||
diffuse = vec3(shading.w);
|
||||
if (isAlbedoEnabled() > 0.0) {
|
||||
diffuse *= albedo;
|
||||
}
|
||||
diffuse *= mix(vec3(1.0), albedo, isAlbedoEnabled());
|
||||
specular = shading.xyz;
|
||||
}
|
||||
|
||||
|
|
|
@ -228,14 +228,14 @@ vec3 fetchLightmapMap(vec2 uv) {
|
|||
}
|
||||
<@endfunc@>
|
||||
|
||||
<@func evalMaterialNormalLOD(fragPos, fetchedNormal, interpolatedNormal, interpolatedTangent, normal)@>
|
||||
<@func evalMaterialNormalLOD(fragPosES, fetchedNormal, interpolatedNormal, interpolatedTangent, normal)@>
|
||||
{
|
||||
vec3 normalizedNormal = normalize(<$interpolatedNormal$>.xyz);
|
||||
vec3 normalizedTangent = normalize(<$interpolatedTangent$>.xyz);
|
||||
vec3 normalizedBitangent = cross(normalizedNormal, normalizedTangent);
|
||||
// attenuate the normal map divergence from the mesh normal based on distance
|
||||
// The attenuation range [20,100] meters from the eye is arbitrary for now
|
||||
vec3 localNormal = mix(<$fetchedNormal$>, vec3(0.0, 1.0, 0.0), smoothstep(20.0, 100.0, (-<$fragPos$>).z));
|
||||
vec3 localNormal = mix(<$fetchedNormal$>, vec3(0.0, 1.0, 0.0), smoothstep(20.0, 100.0, (-<$fragPosES$>).z));
|
||||
<$normal$> = vec3(normalizedBitangent * localNormal.x + normalizedNormal * localNormal.y + normalizedTangent * localNormal.z);
|
||||
}
|
||||
<@endfunc@>
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
// glsl / C++ compatible source as interface for Shadows
|
||||
#ifdef __cplusplus
|
||||
# define MAT4 glm::mat4
|
||||
# define VEC3 glm::vec3
|
||||
#else
|
||||
# define MAT4 mat4
|
||||
# define VEC3 vec3
|
||||
#endif
|
||||
|
||||
#define SHADOW_CASCADE_MAX_COUNT 4
|
||||
|
|
|
@ -311,9 +311,6 @@ void diffuseProfileGPU(gpu::TexturePointer& profileMap, RenderArgs* args) {
|
|||
auto ps = subsurfaceScattering_makeProfile_frag::getShader();
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
makePipeline = gpu::Pipeline::create(program, state);
|
||||
|
@ -342,26 +339,27 @@ void diffuseScatterGPU(const gpu::TexturePointer& profileMap, gpu::TexturePointe
|
|||
int height = lut->getHeight();
|
||||
|
||||
gpu::PipelinePointer makePipeline;
|
||||
{
|
||||
auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
|
||||
auto ps = subsurfaceScattering_makeLUT_frag::getShader();
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS();
|
||||
auto ps = subsurfaceScattering_makeLUT_frag::getShader();
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("scatteringProfile"), 0));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
makePipeline = gpu::Pipeline::create(program, state);
|
||||
}
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
makePipeline = gpu::Pipeline::create(program, state);
|
||||
|
||||
auto makeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("diffuseScatter"));
|
||||
makeFramebuffer->setRenderBuffer(0, lut);
|
||||
|
||||
gpu::doInBatch("SubsurfaceScattering::diffuseScatterGPU", args->_context, [=](gpu::Batch& batch) {
|
||||
batch.enableStereo(false);
|
||||
|
||||
batch.runLambda([program] (){
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("scatteringProfile"), 0));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
});
|
||||
|
||||
batch.setViewportTransform(glm::ivec4(0, 0, width, height));
|
||||
|
||||
batch.setFramebuffer(makeFramebuffer);
|
||||
|
@ -385,9 +383,6 @@ void computeSpecularBeckmannGPU(gpu::TexturePointer& beckmannMap, RenderArgs* ar
|
|||
auto ps = subsurfaceScattering_makeSpecularBeckmann_frag::getShader();
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
makePipeline = gpu::Pipeline::create(program, state);
|
||||
|
@ -495,7 +490,6 @@ gpu::PipelinePointer DebugSubsurfaceScattering::getShowLUTPipeline() {
|
|||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
|
|
|
@ -167,7 +167,7 @@ void LinearDepthPass::run(const render::RenderContextPointer& renderContext, con
|
|||
outputs.edit3() = halfLinearDepthTexture;
|
||||
outputs.edit4() = halfNormalTexture;
|
||||
|
||||
auto linearDepthPipeline = getLinearDepthPipeline();
|
||||
auto linearDepthPipeline = getLinearDepthPipeline(renderContext);
|
||||
auto downsamplePipeline = getDownsamplePipeline();
|
||||
|
||||
auto depthViewport = args->_viewport;
|
||||
|
@ -209,17 +209,12 @@ void LinearDepthPass::run(const render::RenderContextPointer& renderContext, con
|
|||
}
|
||||
|
||||
|
||||
const gpu::PipelinePointer& LinearDepthPass::getLinearDepthPipeline() {
|
||||
const gpu::PipelinePointer& LinearDepthPass::getLinearDepthPipeline(const render::RenderContextPointer& renderContext) {
|
||||
gpu::ShaderPointer program;
|
||||
if (!_linearDepthPipeline) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
|
||||
auto ps = surfaceGeometry_makeLinearDepth_frag::getShader();
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), DepthLinearPass_FrameTransformSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), DepthLinearPass_DepthMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
|
@ -230,8 +225,18 @@ const gpu::PipelinePointer& LinearDepthPass::getLinearDepthPipeline() {
|
|||
|
||||
// Good to go add the brand new pipeline
|
||||
_linearDepthPipeline = gpu::Pipeline::create(program, state);
|
||||
|
||||
gpu::doInBatch("LinearDepthPass::run", renderContext->args->_context, [program](gpu::Batch& batch) {
|
||||
batch.runLambda([program]() {
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), DepthLinearPass_FrameTransformSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), DepthLinearPass_DepthMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return _linearDepthPipeline;
|
||||
}
|
||||
|
||||
|
@ -455,7 +460,7 @@ void SurfaceGeometryPass::run(const render::RenderContextPointer& renderContext,
|
|||
outputs.edit2() = curvatureFramebuffer;
|
||||
outputs.edit3() = lowCurvatureFramebuffer;
|
||||
|
||||
auto curvaturePipeline = getCurvaturePipeline();
|
||||
auto curvaturePipeline = getCurvaturePipeline(renderContext);
|
||||
auto diffuseVPipeline = _diffusePass.getBlurVPipeline();
|
||||
auto diffuseHPipeline = _diffusePass.getBlurHPipeline();
|
||||
|
||||
|
@ -536,21 +541,12 @@ void SurfaceGeometryPass::run(const render::RenderContextPointer& renderContext,
|
|||
config->setGPUBatchRunTime(_gpuTimer->getGPUAverage(), _gpuTimer->getBatchAverage());
|
||||
}
|
||||
|
||||
|
||||
const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() {
|
||||
const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline(const render::RenderContextPointer& renderContext) {
|
||||
if (!_curvaturePipeline) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
|
||||
auto ps = surfaceGeometry_makeCurvature_frag::getShader();
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), SurfaceGeometryPass_FrameTransformSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("surfaceGeometryParamsBuffer"), SurfaceGeometryPass_ParamsSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), SurfaceGeometryPass_DepthMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), SurfaceGeometryPass_NormalMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
#ifdef USE_STENCIL_TEST
|
||||
|
@ -559,6 +555,17 @@ const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() {
|
|||
#endif
|
||||
// Good to go add the brand new pipeline
|
||||
_curvaturePipeline = gpu::Pipeline::create(program, state);
|
||||
|
||||
gpu::doInBatch("SurfaceGeometryPass::CurvaturePipeline", renderContext->args->_context, [program](gpu::Batch& batch) {
|
||||
batch.runLambda([program]() {
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), SurfaceGeometryPass_FrameTransformSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("surfaceGeometryParamsBuffer"), SurfaceGeometryPass_ParamsSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), SurfaceGeometryPass_DepthMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), SurfaceGeometryPass_NormalMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return _curvaturePipeline;
|
||||
|
|
|
@ -81,7 +81,7 @@ private:
|
|||
|
||||
LinearDepthFramebufferPointer _linearDepthFramebuffer;
|
||||
|
||||
const gpu::PipelinePointer& getLinearDepthPipeline();
|
||||
const gpu::PipelinePointer& getLinearDepthPipeline(const render::RenderContextPointer& renderContext);
|
||||
gpu::PipelinePointer _linearDepthPipeline;
|
||||
|
||||
const gpu::PipelinePointer& getDownsamplePipeline();
|
||||
|
@ -195,7 +195,7 @@ private:
|
|||
|
||||
SurfaceGeometryFramebufferPointer _surfaceGeometryFramebuffer;
|
||||
|
||||
const gpu::PipelinePointer& getCurvaturePipeline();
|
||||
const gpu::PipelinePointer& getCurvaturePipeline(const render::RenderContextPointer& renderContext);
|
||||
|
||||
gpu::PipelinePointer _curvaturePipeline;
|
||||
|
||||
|
|
|
@ -27,19 +27,24 @@ ToneMappingEffect::ToneMappingEffect() {
|
|||
_parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Parameters), (const gpu::Byte*) ¶meters));
|
||||
}
|
||||
|
||||
void ToneMappingEffect::init() {
|
||||
void ToneMappingEffect::init(RenderArgs* args) {
|
||||
auto blitPS = toneMapping_frag::getShader();
|
||||
|
||||
auto blitVS = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
|
||||
auto blitProgram = gpu::ShaderPointer(gpu::Shader::createProgram(blitVS, blitPS));
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("toneMappingParamsBuffer"), ToneMappingEffect_ParamsSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), ToneMappingEffect_LightingMapSlot));
|
||||
gpu::Shader::makeProgram(*blitProgram, slotBindings);
|
||||
auto blitState = std::make_shared<gpu::State>();
|
||||
blitState->setColorWriteMask(true, true, true, true);
|
||||
_blitLightBuffer = gpu::PipelinePointer(gpu::Pipeline::create(blitProgram, blitState));
|
||||
|
||||
gpu::doInBatch("ToneMappingEffect::toneMapping", args->_context, [blitProgram](gpu::Batch& batch) {
|
||||
batch.runLambda([blitProgram]() {
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("toneMappingParamsBuffer"), ToneMappingEffect_ParamsSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("colorMap"), ToneMappingEffect_LightingMapSlot));
|
||||
gpu::Shader::makeProgram(*blitProgram, slotBindings);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ToneMappingEffect::setExposure(float exposure) {
|
||||
|
@ -59,7 +64,7 @@ void ToneMappingEffect::setToneCurve(ToneCurve curve) {
|
|||
|
||||
void ToneMappingEffect::render(RenderArgs* args, const gpu::TexturePointer& lightingBuffer, const gpu::FramebufferPointer& requestedDestinationFramebuffer) {
|
||||
if (!_blitLightBuffer) {
|
||||
init();
|
||||
init(args);
|
||||
}
|
||||
|
||||
auto destinationFramebuffer = requestedDestinationFramebuffer;
|
||||
|
|
|
@ -59,7 +59,7 @@ private:
|
|||
typedef gpu::BufferView UniformBufferView;
|
||||
gpu::BufferView _parametersBuffer;
|
||||
|
||||
void init();
|
||||
void init(RenderArgs* args);
|
||||
};
|
||||
|
||||
class ToneMappingConfig : public render::Job::Config {
|
||||
|
|
|
@ -23,11 +23,11 @@
|
|||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC, EMISSIVE, OCCLUSION)$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec4 _positionES;
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec3 _normal;
|
||||
in vec3 _tangent;
|
||||
in vec3 _normalWS;
|
||||
in vec3 _tangentWS;
|
||||
in vec3 _color;
|
||||
|
||||
layout(location = 0) out vec4 _fragColor0;
|
||||
|
@ -56,9 +56,9 @@ void main(void) {
|
|||
<$evalMaterialMetallic(metallicTex, metallic, matKey, metallic)$>;
|
||||
vec3 fresnel = getFresnelF0(metallic, albedo);
|
||||
|
||||
vec3 fragPosition = _position.xyz;
|
||||
vec3 fragPosition = _positionES.xyz;
|
||||
vec3 fragNormal;
|
||||
<$evalMaterialNormal(normalTex, _normal, _tangent, fragNormal)$>
|
||||
<$evalMaterialNormal(normalTex, _normalWS, _tangentWS, fragNormal)$>
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
|
||||
|
|
83
libraries/render-utils/src/forward_simple.slf
Normal file
83
libraries/render-utils/src/forward_simple.slf
Normal file
|
@ -0,0 +1,83 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// forward_simple.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/15/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
<@include DefaultMaterials.slh@>
|
||||
|
||||
<@include ForwardGlobalLight.slh@>
|
||||
<$declareEvalSkyboxGlobalColor()$>
|
||||
|
||||
// the interpolated normal
|
||||
in vec3 _normal;
|
||||
in vec3 _modelNormal;
|
||||
in vec4 _color;
|
||||
in vec2 _texCoord0;
|
||||
in vec4 _position;
|
||||
in vec4 _eyePosition;
|
||||
|
||||
layout(location = 0) out vec4 _fragColor0;
|
||||
|
||||
//PROCEDURAL_COMMON_BLOCK
|
||||
|
||||
#line 1001
|
||||
//PROCEDURAL_BLOCK
|
||||
|
||||
#line 2030
|
||||
void main(void) {
|
||||
vec3 normal = normalize(_normal.xyz);
|
||||
vec3 diffuse = _color.rgb;
|
||||
vec3 specular = DEFAULT_SPECULAR;
|
||||
float shininess = DEFAULT_SHININESS;
|
||||
float emissiveAmount = 0.0;
|
||||
|
||||
#ifdef PROCEDURAL
|
||||
|
||||
#ifdef PROCEDURAL_V1
|
||||
specular = getProceduralColor().rgb;
|
||||
// Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline
|
||||
//specular = pow(specular, vec3(2.2));
|
||||
emissiveAmount = 1.0;
|
||||
#else
|
||||
emissiveAmount = getProceduralColors(diffuse, specular, shininess);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
vec3 fragPosition = _eyePosition.xyz;
|
||||
|
||||
if (emissiveAmount > 0.0) {
|
||||
_fragColor0 = vec4(evalSkyboxGlobalColor(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
DEFAULT_OCCLUSION,
|
||||
fragPosition,
|
||||
normal,
|
||||
diffuse,
|
||||
specular,
|
||||
DEFAULT_METALLIC,
|
||||
max(0.0, 1.0 - shininess / 128.0)),
|
||||
1.0);
|
||||
} else {
|
||||
_fragColor0 = vec4(evalSkyboxGlobalColor(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
DEFAULT_OCCLUSION,
|
||||
fragPosition,
|
||||
normal,
|
||||
diffuse,
|
||||
DEFAULT_FRESNEL,
|
||||
length(specular),
|
||||
max(0.0, 1.0 - shininess / 128.0)),
|
||||
1.0);
|
||||
}
|
||||
}
|
51
libraries/render-utils/src/forward_simple_textured.slf
Normal file
51
libraries/render-utils/src/forward_simple_textured.slf
Normal file
|
@ -0,0 +1,51 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// forward_simple_textured.slf
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Clément Brisset on 5/29/15.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
<@include DefaultMaterials.slh@>
|
||||
|
||||
<@include ForwardGlobalLight.slh@>
|
||||
<$declareEvalSkyboxGlobalColor()$>
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
// the albedo texture
|
||||
uniform sampler2D originalTexture;
|
||||
|
||||
// the interpolated normal
|
||||
in vec3 _normal;
|
||||
in vec4 _color;
|
||||
in vec2 _texCoord0;
|
||||
in vec4 _eyePosition;
|
||||
|
||||
layout(location = 0) out vec4 _fragColor0;
|
||||
|
||||
void main(void) {
|
||||
vec4 texel = texture(originalTexture, _texCoord0);
|
||||
float colorAlpha = _color.a * texel.a;
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
vec3 fragPosition = _eyePosition.xyz;
|
||||
|
||||
_fragColor0 = vec4(evalSkyboxGlobalColor(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
DEFAULT_OCCLUSION,
|
||||
fragPosition,
|
||||
normalize(_normal),
|
||||
_color.rgb * texel.rgb,
|
||||
DEFAULT_FRESNEL,
|
||||
DEFAULT_METALLIC,
|
||||
DEFAULT_ROUGHNESS),
|
||||
1.0);
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// forward_simple_textured_transparent.slf
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Clément Brisset on 5/29/15.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
<@include DefaultMaterials.slh@>
|
||||
|
||||
<@include ForwardGlobalLight.slh@>
|
||||
<$declareEvalGlobalLightingAlphaBlended()$>
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
<$declareStandardCameraTransform()$>
|
||||
|
||||
// the albedo texture
|
||||
uniform sampler2D originalTexture;
|
||||
|
||||
// the interpolated normal
|
||||
in vec3 _normal;
|
||||
in vec4 _color;
|
||||
in vec2 _texCoord0;
|
||||
in vec4 _eyePosition;
|
||||
|
||||
layout(location = 0) out vec4 _fragColor0;
|
||||
|
||||
void main(void) {
|
||||
vec4 texel = texture(originalTexture, _texCoord0);
|
||||
float colorAlpha = _color.a * texel.a;
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
vec3 fragPosition = _eyePosition.xyz;
|
||||
|
||||
_fragColor0 = vec4(evalGlobalLightingAlphaBlendedWithHaze(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
DEFAULT_OCCLUSION,
|
||||
fragPosition,
|
||||
normalize(_normal),
|
||||
_color.rgb * texel.rgb,
|
||||
DEFAULT_FRESNEL,
|
||||
DEFAULT_METALLIC,
|
||||
DEFAULT_EMISSIVE,
|
||||
DEFAULT_ROUGHNESS, colorAlpha),
|
||||
colorAlpha);
|
||||
}
|
31
libraries/render-utils/src/forward_simple_textured_unlit.slf
Normal file
31
libraries/render-utils/src/forward_simple_textured_unlit.slf
Normal file
|
@ -0,0 +1,31 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// simple_textured_unlit.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Clément Brisset on 5/29/15.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include LightingModel.slh@>
|
||||
<@include gpu/Color.slh@>
|
||||
|
||||
layout(location = 0) out vec4 _fragColor0;
|
||||
|
||||
// the albedo texture
|
||||
uniform sampler2D originalTexture;
|
||||
|
||||
in vec4 _color;
|
||||
in vec2 _texCoord0;
|
||||
|
||||
void main(void) {
|
||||
vec4 texel = texture(originalTexture, _texCoord0.st);
|
||||
float colorAlpha = _color.a * texel.a;
|
||||
|
||||
_fragColor0 = vec4(_color.rgb * texel.rgb * isUnlitEnabled(), colorAlpha);
|
||||
}
|
84
libraries/render-utils/src/forward_simple_transparent.slf
Normal file
84
libraries/render-utils/src/forward_simple_transparent.slf
Normal file
|
@ -0,0 +1,84 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// forward_simple_transparent.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/15/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
<@include DefaultMaterials.slh@>
|
||||
|
||||
<@include ForwardGlobalLight.slh@>
|
||||
<$declareEvalGlobalLightingAlphaBlended()$>
|
||||
|
||||
// the interpolated normal
|
||||
in vec3 _normal;
|
||||
in vec3 _modelNormal;
|
||||
in vec4 _color;
|
||||
in vec2 _texCoord0;
|
||||
in vec4 _eyePosition;
|
||||
|
||||
layout(location = 0) out vec4 _fragColor0;
|
||||
|
||||
//PROCEDURAL_COMMON_BLOCK
|
||||
|
||||
#line 1001
|
||||
//PROCEDURAL_BLOCK
|
||||
|
||||
#line 2030
|
||||
void main(void) {
|
||||
vec3 normal = normalize(_normal.xyz);
|
||||
vec3 diffuse = _color.rgb;
|
||||
vec3 specular = DEFAULT_SPECULAR;
|
||||
float shininess = DEFAULT_SHININESS;
|
||||
float emissiveAmount = 0.0;
|
||||
|
||||
#ifdef PROCEDURAL
|
||||
|
||||
#ifdef PROCEDURAL_V1
|
||||
specular = getProceduralColor().rgb;
|
||||
// Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline
|
||||
//specular = pow(specular, vec3(2.2));
|
||||
emissiveAmount = 1.0;
|
||||
#else
|
||||
emissiveAmount = getProceduralColors(diffuse, specular, shininess);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
vec3 fragPosition = _eyePosition.xyz;
|
||||
|
||||
if (emissiveAmount > 0.0) {
|
||||
_fragColor0 = vec4(evalGlobalLightingAlphaBlendedWithHaze(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
DEFAULT_OCCLUSION,
|
||||
fragPosition,
|
||||
normal,
|
||||
specular,
|
||||
DEFAULT_FRESNEL,
|
||||
DEFAULT_METALLIC,
|
||||
DEFAULT_EMISSIVE,
|
||||
DEFAULT_ROUGHNESS, _color.a),
|
||||
_color.a);
|
||||
} else {
|
||||
_fragColor0 = vec4(evalGlobalLightingAlphaBlendedWithHaze(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
DEFAULT_OCCLUSION,
|
||||
fragPosition,
|
||||
normal,
|
||||
diffuse,
|
||||
DEFAULT_FRESNEL,
|
||||
DEFAULT_METALLIC,
|
||||
DEFAULT_EMISSIVE,
|
||||
DEFAULT_ROUGHNESS, _color.a),
|
||||
_color.a);
|
||||
}
|
||||
}
|
|
@ -22,19 +22,19 @@
|
|||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec4 _positionES;
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec3 _normal;
|
||||
in vec3 _normalWS;
|
||||
in vec3 _color;
|
||||
in vec4 _worldPosition;
|
||||
in vec4 _positionWS;
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
FadeObjectParams fadeParams;
|
||||
|
||||
<$fetchFadeObjectParams(fadeParams)$>
|
||||
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
|
||||
applyFade(fadeParams, _positionWS.xyz, fadeEmissive);
|
||||
|
||||
Material mat = getMaterial();
|
||||
BITFIELD matKey = getMaterialKey(mat);
|
||||
|
@ -61,7 +61,7 @@ void main(void) {
|
|||
float scattering = getMaterialScattering(mat);
|
||||
|
||||
packDeferredFragment(
|
||||
normalize(_normal),
|
||||
normalize(_normalWS),
|
||||
opacity,
|
||||
albedo,
|
||||
roughness,
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
out float _alpha;
|
||||
out vec2 _texCoord0;
|
||||
out vec2 _texCoord1;
|
||||
out vec4 _position;
|
||||
out vec4 _worldPosition;
|
||||
out vec3 _normal;
|
||||
out vec4 _positionES;
|
||||
out vec4 _positionWS;
|
||||
out vec3 _normalWS;
|
||||
out vec3 _color;
|
||||
|
||||
void main(void) {
|
||||
|
@ -38,7 +38,7 @@ void main(void) {
|
|||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _worldPosition)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _positionWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
|
||||
}
|
||||
|
|
|
@ -19,11 +19,11 @@
|
|||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTextures(ALBEDO, ROUGHNESS, NORMAL, METALLIC, EMISSIVE, OCCLUSION, SCATTERING)$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec4 _positionES;
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec3 _normal;
|
||||
in vec3 _tangent;
|
||||
in vec3 _normalWS;
|
||||
in vec3 _tangentWS;
|
||||
in vec3 _color;
|
||||
|
||||
void main(void) {
|
||||
|
@ -46,8 +46,8 @@ void main(void) {
|
|||
vec3 emissive = getMaterialEmissive(mat);
|
||||
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
|
||||
|
||||
vec3 fragNormal;
|
||||
<$evalMaterialNormalLOD(_position, normalTex, _normal, _tangent, fragNormal)$>
|
||||
vec3 fragNormalWS;
|
||||
<$evalMaterialNormalLOD(_positionES, normalTex, _normalWS, _tangentWS, fragNormalWS)$>
|
||||
|
||||
float metallic = getMaterialMetallic(mat);
|
||||
<$evalMaterialMetallic(metallicTex, metallic, matKey, metallic)$>;
|
||||
|
@ -56,7 +56,7 @@ void main(void) {
|
|||
<$evalMaterialScattering(scatteringTex, scattering, matKey, scattering)$>;
|
||||
|
||||
packDeferredFragment(
|
||||
normalize(fragNormal.xyz),
|
||||
normalize(fragNormalWS.xyz),
|
||||
opacity,
|
||||
albedo,
|
||||
roughness,
|
||||
|
|
|
@ -20,11 +20,11 @@
|
|||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
out vec4 _position;
|
||||
out vec4 _positionES;
|
||||
out vec2 _texCoord0;
|
||||
out vec2 _texCoord1;
|
||||
out vec3 _normal;
|
||||
out vec3 _tangent;
|
||||
out vec3 _normalWS;
|
||||
out vec3 _tangentWS;
|
||||
out vec3 _color;
|
||||
out float _alpha;
|
||||
|
||||
|
@ -40,7 +40,7 @@ void main(void) {
|
|||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
|
||||
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangent)$>
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangentWS)$>
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// model_normal_specular_map_fade.frag
|
||||
// model_normal_map_fade.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Olivier Prat on 06/05/17.
|
||||
|
@ -22,20 +22,20 @@
|
|||
<@include Fade.slh@>
|
||||
<$declareFadeFragment()$>
|
||||
|
||||
in vec4 _position;
|
||||
in vec4 _positionES;
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec3 _normal;
|
||||
in vec3 _tangent;
|
||||
in vec3 _normalWS;
|
||||
in vec3 _tangentWS;
|
||||
in vec3 _color;
|
||||
in vec4 _worldPosition;
|
||||
in vec4 _positionWS;
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
FadeObjectParams fadeParams;
|
||||
|
||||
<$fetchFadeObjectParams(fadeParams)$>
|
||||
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
|
||||
applyFade(fadeParams, _positionWS.xyz, fadeEmissive);
|
||||
|
||||
Material mat = getMaterial();
|
||||
BITFIELD matKey = getMaterialKey(mat);
|
||||
|
@ -56,8 +56,8 @@ void main(void) {
|
|||
vec3 emissive = getMaterialEmissive(mat);
|
||||
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
|
||||
|
||||
vec3 fragNormal;
|
||||
<$evalMaterialNormalLOD(_position, normalTex, _normal, _tangent, fragNormal)$>
|
||||
vec3 fragNormalWS;
|
||||
<$evalMaterialNormalLOD(_positionES, normalTex, _normalWS, _tangentWS, fragNormalWS)$>
|
||||
|
||||
float metallic = getMaterialMetallic(mat);
|
||||
<$evalMaterialMetallic(metallicTex, metallic, matKey, metallic)$>;
|
||||
|
@ -65,12 +65,12 @@ void main(void) {
|
|||
float scattering = getMaterialScattering(mat);
|
||||
|
||||
packDeferredFragment(
|
||||
normalize(fragNormal.xyz),
|
||||
normalize(fragNormalWS.xyz),
|
||||
opacity,
|
||||
albedo,
|
||||
roughness,
|
||||
metallic,
|
||||
emissive+fadeEmissive,
|
||||
emissive + fadeEmissive,
|
||||
occlusionTex,
|
||||
scattering);
|
||||
}
|
||||
|
|
|
@ -20,12 +20,12 @@
|
|||
<@include MaterialTextures.slh@>
|
||||
<$declareMaterialTexMapArrayBuffer()$>
|
||||
|
||||
out vec4 _position;
|
||||
out vec4 _worldPosition;
|
||||
out vec4 _positionES;
|
||||
out vec4 _positionWS;
|
||||
out vec2 _texCoord0;
|
||||
out vec2 _texCoord1;
|
||||
out vec3 _normal;
|
||||
out vec3 _tangent;
|
||||
out vec3 _normalWS;
|
||||
out vec3 _tangentWS;
|
||||
out vec3 _color;
|
||||
out float _alpha;
|
||||
|
||||
|
@ -41,8 +41,8 @@ void main(void) {
|
|||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _worldPosition)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
|
||||
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangent)$>
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _positionWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangentWS)$>
|
||||
}
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec4 _position;
|
||||
in vec4 _worldPosition;
|
||||
in vec3 _normal;
|
||||
in vec4 _positionES;
|
||||
in vec4 _positionWS;
|
||||
in vec3 _normalWS;
|
||||
in vec3 _color;
|
||||
in float _alpha;
|
||||
|
||||
|
@ -58,33 +58,35 @@ void main(void) {
|
|||
vec3 emissive = getMaterialEmissive(mat);
|
||||
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
|
||||
|
||||
vec3 fragPosition = _position.xyz;
|
||||
vec3 fragPositionES = _positionES.xyz;
|
||||
vec3 fragPositionWS = _positionWS.xyz;
|
||||
// Lighting is done in world space
|
||||
vec3 fragNormal = normalize(_normal);
|
||||
vec3 fragNormalWS = normalize(_normalWS);
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0));
|
||||
vec3 fragEyeDir = normalize(fragEyeVector);
|
||||
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
|
||||
vec3 fragToEyeWS = cam._viewInverse[3].xyz - fragPositionWS;
|
||||
vec3 fragToEyeDirWS = normalize(fragToEyeWS);
|
||||
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragToEyeDirWS);
|
||||
|
||||
vec4 localLighting = vec4(0.0);
|
||||
|
||||
<$fetchClusterInfo(_worldPosition)$>;
|
||||
<$fetchClusterInfo(_positionWS)$>;
|
||||
if (hasLocalLights(numLights, clusterPos, dims)) {
|
||||
localLighting = evalLocalLighting(cluster, numLights, _worldPosition.xyz, surface,
|
||||
localLighting = evalLocalLighting(cluster, numLights, fragPositionWS, surfaceWS,
|
||||
metallic, fresnel, albedo, 0.0,
|
||||
vec4(0), vec4(0), opacity);
|
||||
}
|
||||
|
||||
_fragColor = vec4(evalGlobalLightingAlphaBlendedWithHaze(
|
||||
_fragColor = vec4(evalGlobalLightingAlphaBlendedWithHaze(
|
||||
cam._viewInverse,
|
||||
1.0,
|
||||
occlusionTex,
|
||||
fragPosition,
|
||||
fragPositionES,
|
||||
fragPositionWS,
|
||||
albedo,
|
||||
fresnel,
|
||||
metallic,
|
||||
emissive,
|
||||
surface, opacity, localLighting.rgb),
|
||||
surfaceWS, opacity, localLighting.rgb),
|
||||
opacity);
|
||||
}
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
out float _alpha;
|
||||
out vec2 _texCoord0;
|
||||
out vec2 _texCoord1;
|
||||
out vec4 _position;
|
||||
out vec4 _worldPosition;
|
||||
out vec3 _normal;
|
||||
out vec4 _positionES;
|
||||
out vec4 _positionWS;
|
||||
out vec3 _normalWS;
|
||||
out vec3 _color;
|
||||
|
||||
void main(void) {
|
||||
|
@ -38,7 +38,7 @@ void main(void) {
|
|||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _worldPosition)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _positionWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
|
||||
}
|
||||
|
|
|
@ -24,11 +24,11 @@
|
|||
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec4 _position;
|
||||
in vec3 _normal;
|
||||
in vec4 _positionES;
|
||||
in vec4 _positionWS;
|
||||
in vec3 _normalWS;
|
||||
in vec3 _color;
|
||||
in float _alpha;
|
||||
in vec4 _worldPosition;
|
||||
|
||||
out vec4 _fragColor;
|
||||
|
||||
|
@ -37,7 +37,7 @@ void main(void) {
|
|||
FadeObjectParams fadeParams;
|
||||
|
||||
<$fetchFadeObjectParams(fadeParams)$>
|
||||
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
|
||||
applyFade(fadeParams, _positionWS.xyz, fadeEmissive);
|
||||
|
||||
Material mat = getMaterial();
|
||||
BITFIELD matKey = getMaterialKey(mat);
|
||||
|
@ -60,20 +60,21 @@ void main(void) {
|
|||
vec3 emissive = getMaterialEmissive(mat);
|
||||
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
|
||||
|
||||
vec3 fragPosition = _position.xyz;
|
||||
vec3 fragPositionES = _positionES.xyz;
|
||||
vec3 fragPositionWS = _positionWS.xyz;
|
||||
// Lighting is done in world space
|
||||
vec3 fragNormal = normalize(_normal);
|
||||
vec3 fragNormalWS = normalize(_normalWS);
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0));
|
||||
vec3 fragEyeDir = normalize(fragEyeVector);
|
||||
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
|
||||
vec3 fragToEyeWS = cam._viewInverse[3].xyz - fragPositionWS;
|
||||
vec3 fragToEyeDirWS = normalize(fragToEyeWS);
|
||||
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragToEyeDirWS);
|
||||
|
||||
vec4 localLighting = vec4(0.0);
|
||||
|
||||
<$fetchClusterInfo(_worldPosition)$>;
|
||||
<$fetchClusterInfo(_positionWS)$>;
|
||||
if (hasLocalLights(numLights, clusterPos, dims)) {
|
||||
localLighting = evalLocalLighting(cluster, numLights, _worldPosition.xyz, surface,
|
||||
localLighting = evalLocalLighting(cluster, numLights, fragPositionWS, surfaceWS,
|
||||
metallic, fresnel, albedo, 0.0,
|
||||
vec4(0), vec4(0), opacity);
|
||||
}
|
||||
|
@ -82,11 +83,12 @@ void main(void) {
|
|||
cam._viewInverse,
|
||||
1.0,
|
||||
occlusionTex,
|
||||
fragPosition,
|
||||
fragPositionES,
|
||||
fragPositionWS,
|
||||
albedo,
|
||||
fresnel,
|
||||
metallic,
|
||||
emissive+fadeEmissive,
|
||||
surface, opacity, localLighting.rgb),
|
||||
emissive + fadeEmissive,
|
||||
surfaceWS, opacity, localLighting.rgb),
|
||||
opacity);
|
||||
}
|
||||
|
|
|
@ -28,10 +28,10 @@
|
|||
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec4 _position;
|
||||
in vec4 _worldPosition;
|
||||
in vec3 _normal;
|
||||
in vec3 _tangent;
|
||||
in vec4 _positionES;
|
||||
in vec4 _positionWS;
|
||||
in vec3 _normalWS;
|
||||
in vec3 _tangentWS;
|
||||
in vec3 _color;
|
||||
in float _alpha;
|
||||
|
||||
|
@ -59,20 +59,22 @@ void main(void) {
|
|||
vec3 emissive = getMaterialEmissive(mat);
|
||||
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
|
||||
|
||||
vec3 fragPosition = _position.xyz;
|
||||
vec3 fragNormal;
|
||||
<$evalMaterialNormalLOD(_position, normalTex, _normal, _tangent, fragNormal)$>
|
||||
vec3 fragPositionES = _positionES.xyz;
|
||||
vec3 fragPositionWS = _positionWS.xyz;
|
||||
// Lighting is done in world space
|
||||
vec3 fragNormalWS;
|
||||
<$evalMaterialNormalLOD(_positionES, normalTex, _normalWS, _tangentWS, fragNormalWS)$>
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0));
|
||||
vec3 fragEyeDir = normalize(fragEyeVector);
|
||||
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
|
||||
vec3 fragToEyeWS = cam._viewInverse[3].xyz - fragPositionWS;
|
||||
vec3 fragToEyeDirWS = normalize(fragToEyeWS);
|
||||
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragToEyeDirWS);
|
||||
|
||||
vec4 localLighting = vec4(0.0);
|
||||
|
||||
<$fetchClusterInfo(_worldPosition)$>;
|
||||
<$fetchClusterInfo(_positionWS)$>;
|
||||
if (hasLocalLights(numLights, clusterPos, dims)) {
|
||||
localLighting = evalLocalLighting(cluster, numLights, _worldPosition.xyz, surface,
|
||||
localLighting = evalLocalLighting(cluster, numLights, fragPositionWS, surfaceWS,
|
||||
metallic, fresnel, albedo, 0.0,
|
||||
vec4(0), vec4(0), opacity);
|
||||
}
|
||||
|
@ -81,11 +83,12 @@ void main(void) {
|
|||
cam._viewInverse,
|
||||
1.0,
|
||||
occlusionTex,
|
||||
fragPosition,
|
||||
fragPositionES,
|
||||
fragPositionWS,
|
||||
albedo,
|
||||
fresnel,
|
||||
metallic,
|
||||
emissive,
|
||||
surface, opacity, localLighting.rgb),
|
||||
surfaceWS, opacity, localLighting.rgb),
|
||||
opacity);
|
||||
}
|
||||
|
|
|
@ -22,10 +22,10 @@
|
|||
out float _alpha;
|
||||
out vec2 _texCoord0;
|
||||
out vec2 _texCoord1;
|
||||
out vec4 _position;
|
||||
out vec4 _worldPosition;
|
||||
out vec3 _normal;
|
||||
out vec3 _tangent;
|
||||
out vec4 _positionES;
|
||||
out vec4 _positionWS;
|
||||
out vec3 _normalWS;
|
||||
out vec3 _tangentWS;
|
||||
out vec3 _color;
|
||||
|
||||
void main(void) {
|
||||
|
@ -39,8 +39,8 @@ void main(void) {
|
|||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _position, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _worldPosition)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
|
||||
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangent)$>
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _positionES, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _positionWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normalWS)$>
|
||||
<$transformModelToWorldDir(cam, obj, inTangent.xyz, _tangentWS)$>
|
||||
}
|
||||
|
|
|
@ -31,12 +31,12 @@
|
|||
|
||||
in vec2 _texCoord0;
|
||||
in vec2 _texCoord1;
|
||||
in vec4 _position;
|
||||
in vec3 _normal;
|
||||
in vec3 _tangent;
|
||||
in vec4 _positionES;
|
||||
in vec3 _normalWS;
|
||||
in vec3 _tangentWS;
|
||||
in vec3 _color;
|
||||
in float _alpha;
|
||||
in vec4 _worldPosition;
|
||||
in vec4 _positionWS;
|
||||
|
||||
out vec4 _fragColor;
|
||||
|
||||
|
@ -45,7 +45,7 @@ void main(void) {
|
|||
FadeObjectParams fadeParams;
|
||||
|
||||
<$fetchFadeObjectParams(fadeParams)$>
|
||||
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
|
||||
applyFade(fadeParams, _positionWS.xyz, fadeEmissive);
|
||||
|
||||
Material mat = getMaterial();
|
||||
int matKey = getMaterialKey(mat);
|
||||
|
@ -68,21 +68,22 @@ void main(void) {
|
|||
vec3 emissive = getMaterialEmissive(mat);
|
||||
<$evalMaterialEmissive(emissiveTex, emissive, matKey, emissive)$>;
|
||||
|
||||
vec3 fragPosition = _position.xyz;
|
||||
vec3 fragPositionES = _positionES.xyz;
|
||||
vec3 fragPositionWS = _positionWS.xyz;
|
||||
// Lighting is done in world space
|
||||
vec3 fragNormal;
|
||||
<$evalMaterialNormalLOD(_position, normalTex, _normal, _tangent, fragNormal)$>
|
||||
vec3 fragNormalWS;
|
||||
<$evalMaterialNormalLOD(_positionES, normalTex, _normalWS, _tangentWS, fragNormalWS)$>
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
vec3 fragEyeVector = vec3(cam._viewInverse * vec4(-fragPosition, 0.0));
|
||||
vec3 fragEyeDir = normalize(fragEyeVector);
|
||||
SurfaceData surface = initSurfaceData(roughness, fragNormal, fragEyeDir);
|
||||
vec3 fragToEyeWS = cam._viewInverse[3].xyz - fragPositionWS;
|
||||
vec3 fragToEyeDirWS = normalize(fragToEyeWS);
|
||||
SurfaceData surfaceWS = initSurfaceData(roughness, fragNormalWS, fragToEyeDirWS);
|
||||
|
||||
vec4 localLighting = vec4(0.0);
|
||||
|
||||
<$fetchClusterInfo(_worldPosition)$>;
|
||||
<$fetchClusterInfo(_positionWS)$>;
|
||||
if (hasLocalLights(numLights, clusterPos, dims)) {
|
||||
localLighting = evalLocalLighting(cluster, numLights, _worldPosition.xyz, surface,
|
||||
localLighting = evalLocalLighting(cluster, numLights, fragPositionWS, surfaceWS,
|
||||
metallic, fresnel, albedo, 0.0,
|
||||
vec4(0), vec4(0), opacity);
|
||||
}
|
||||
|
@ -91,11 +92,12 @@ void main(void) {
|
|||
cam._viewInverse,
|
||||
1.0,
|
||||
occlusionTex,
|
||||
fragPosition,
|
||||
fragPositionES,
|
||||
fragPositionWS,
|
||||
albedo,
|
||||
fresnel,
|
||||
metallic,
|
||||
emissive+fadeEmissive,
|
||||
surface, opacity, localLighting.rgb),
|
||||
emissive + fadeEmissive,
|
||||
surfaceWS, opacity, localLighting.rgb),
|
||||
opacity);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
in vec2 _texCoord0;
|
||||
in vec3 _color;
|
||||
in float _alpha;
|
||||
in vec4 _worldPosition;
|
||||
in vec4 _positionWS;
|
||||
|
||||
out vec4 _fragColor;
|
||||
|
||||
|
@ -33,7 +33,7 @@ void main(void) {
|
|||
FadeObjectParams fadeParams;
|
||||
|
||||
<$fetchFadeObjectParams(fadeParams)$>
|
||||
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
|
||||
applyFade(fadeParams, _positionWS.xyz, fadeEmissive);
|
||||
|
||||
Material mat = getMaterial();
|
||||
BITFIELD matKey = getMaterialKey(mat);
|
||||
|
|
|
@ -23,17 +23,17 @@
|
|||
<$declareMaterialTextures(ALBEDO)$>
|
||||
|
||||
in vec2 _texCoord0;
|
||||
in vec3 _normal;
|
||||
in vec3 _normalWS;
|
||||
in vec3 _color;
|
||||
in float _alpha;
|
||||
in vec4 _worldPosition;
|
||||
in vec4 _positionWS;
|
||||
|
||||
void main(void) {
|
||||
vec3 fadeEmissive;
|
||||
FadeObjectParams fadeParams;
|
||||
|
||||
<$fetchFadeObjectParams(fadeParams)$>
|
||||
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
|
||||
applyFade(fadeParams, _positionWS.xyz, fadeEmissive);
|
||||
|
||||
Material mat = getMaterial();
|
||||
BITFIELD matKey = getMaterialKey(mat);
|
||||
|
@ -48,7 +48,7 @@ void main(void) {
|
|||
albedo *= _color;
|
||||
albedo += fadeEmissive;
|
||||
packDeferredFragmentUnlit(
|
||||
normalize(_normal),
|
||||
normalize(_normalWS),
|
||||
opacity,
|
||||
albedo * isUnlitEnabled());
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
//
|
||||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
<@include graphics/Material.slh@>
|
||||
|
||||
// the interpolated normal
|
||||
in vec3 _normal;
|
||||
|
@ -29,9 +28,8 @@ in vec4 _position;
|
|||
|
||||
#line 2030
|
||||
void main(void) {
|
||||
Material material = getMaterial();
|
||||
vec3 normal = normalize(_normal.xyz);
|
||||
vec3 diffuse = _color.rgb;
|
||||
vec3 normal = normalize(_normal.xyz);
|
||||
vec3 diffuse = _color.rgb;
|
||||
vec3 specular = DEFAULT_SPECULAR;
|
||||
float shininess = DEFAULT_SHININESS;
|
||||
float emissiveAmount = 0.0;
|
||||
|
@ -43,49 +41,30 @@ void main(void) {
|
|||
// Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline
|
||||
//specular = pow(specular, vec3(2.2));
|
||||
emissiveAmount = 1.0;
|
||||
#else
|
||||
#else
|
||||
emissiveAmount = getProceduralColors(diffuse, specular, shininess);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
const float ALPHA_THRESHOLD = 0.999;
|
||||
if (_color.a < ALPHA_THRESHOLD) {
|
||||
if (emissiveAmount > 0.0) {
|
||||
packDeferredFragmentTranslucent(
|
||||
normal,
|
||||
_color.a,
|
||||
specular,
|
||||
DEFAULT_FRESNEL,
|
||||
DEFAULT_ROUGHNESS);
|
||||
} else {
|
||||
packDeferredFragmentTranslucent(
|
||||
normal,
|
||||
_color.a,
|
||||
diffuse,
|
||||
DEFAULT_FRESNEL,
|
||||
DEFAULT_ROUGHNESS);
|
||||
}
|
||||
if (emissiveAmount > 0.0) {
|
||||
packDeferredFragmentLightmap(
|
||||
normal,
|
||||
1.0,
|
||||
diffuse,
|
||||
max(0.0, 1.0 - shininess / 128.0),
|
||||
DEFAULT_METALLIC,
|
||||
specular,
|
||||
vec3(clamp(emissiveAmount, 0.0, 1.0)));
|
||||
} else {
|
||||
if (emissiveAmount > 0.0) {
|
||||
packDeferredFragmentLightmap(
|
||||
normal,
|
||||
1.0,
|
||||
diffuse,
|
||||
max(0.0, 1.0 - shininess / 128.0),
|
||||
DEFAULT_METALLIC,
|
||||
specular,
|
||||
vec3(clamp(emissiveAmount, 0.0, 1.0)));
|
||||
} else {
|
||||
packDeferredFragment(
|
||||
normal,
|
||||
1.0,
|
||||
diffuse,
|
||||
max(0.0, 1.0 - shininess / 128.0),
|
||||
length(specular),
|
||||
DEFAULT_EMISSIVE,
|
||||
DEFAULT_OCCLUSION,
|
||||
DEFAULT_SCATTERING);
|
||||
}
|
||||
packDeferredFragment(
|
||||
normal,
|
||||
1.0,
|
||||
diffuse,
|
||||
max(0.0, 1.0 - shininess / 128.0),
|
||||
length(specular),
|
||||
DEFAULT_EMISSIVE,
|
||||
DEFAULT_OCCLUSION,
|
||||
DEFAULT_SCATTERING);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ out vec3 _modelNormal;
|
|||
out vec4 _color;
|
||||
out vec2 _texCoord0;
|
||||
out vec4 _position;
|
||||
out vec4 _eyePosition;
|
||||
|
||||
void main(void) {
|
||||
_color = color_sRGBAToLinear(inColor);
|
||||
|
@ -33,6 +34,6 @@ void main(void) {
|
|||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _eyePosition, gl_Position)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
|
||||
}
|
|
@ -13,7 +13,6 @@
|
|||
//
|
||||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
<@include graphics/Material.slh@>
|
||||
|
||||
<@include Fade.slh@>
|
||||
<$declareFadeFragmentInstanced()$>
|
||||
|
@ -39,7 +38,6 @@ void main(void) {
|
|||
<$fetchFadeObjectParamsInstanced(fadeParams)$>
|
||||
applyFade(fadeParams, _worldPosition.xyz, fadeEmissive);
|
||||
|
||||
Material material = getMaterial();
|
||||
vec3 normal = normalize(_normal.xyz);
|
||||
vec3 diffuse = _color.rgb;
|
||||
vec3 specular = DEFAULT_SPECULAR;
|
||||
|
|
|
@ -26,6 +26,7 @@ out vec3 _modelNormal;
|
|||
out vec4 _color;
|
||||
out vec2 _texCoord0;
|
||||
out vec4 _position;
|
||||
out vec4 _eyePosition;
|
||||
out vec4 _worldPosition;
|
||||
|
||||
void main(void) {
|
||||
|
@ -37,7 +38,7 @@ void main(void) {
|
|||
// standard transform
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
|
||||
<$transformModelToEyeAndClipPos(cam, obj, inPosition, _eyePosition, gl_Position)$>
|
||||
<$transformModelToWorldPos(obj, inPosition, _worldPosition)$>
|
||||
<$transformModelToWorldDir(cam, obj, inNormal.xyz, _normal)$>
|
||||
<$passThroughFadeObjectParams()$>
|
||||
|
|
|
@ -12,9 +12,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include gpu/Color.slh@>
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
<@include graphics/Material.slh@>
|
||||
|
||||
// the albedo texture
|
||||
uniform sampler2D originalTexture;
|
||||
|
@ -26,29 +24,14 @@ in vec2 _texCoord0;
|
|||
|
||||
void main(void) {
|
||||
vec4 texel = texture(originalTexture, _texCoord0);
|
||||
float colorAlpha = _color.a;
|
||||
if (_color.a <= 0.0) {
|
||||
texel = color_sRGBAToLinear(texel);
|
||||
colorAlpha = -_color.a;
|
||||
}
|
||||
|
||||
const float ALPHA_THRESHOLD = 0.999;
|
||||
if (colorAlpha * texel.a < ALPHA_THRESHOLD) {
|
||||
packDeferredFragmentTranslucent(
|
||||
normalize(_normal),
|
||||
colorAlpha * texel.a,
|
||||
_color.rgb * texel.rgb,
|
||||
DEFAULT_FRESNEL,
|
||||
DEFAULT_ROUGHNESS);
|
||||
} else {
|
||||
packDeferredFragment(
|
||||
normalize(_normal),
|
||||
1.0,
|
||||
_color.rgb * texel.rgb,
|
||||
DEFAULT_ROUGHNESS,
|
||||
DEFAULT_METALLIC,
|
||||
DEFAULT_EMISSIVE,
|
||||
DEFAULT_OCCLUSION,
|
||||
DEFAULT_SCATTERING);
|
||||
}
|
||||
packDeferredFragment(
|
||||
normalize(_normal),
|
||||
1.0,
|
||||
_color.rgb * texel.rgb,
|
||||
DEFAULT_ROUGHNESS,
|
||||
DEFAULT_METALLIC,
|
||||
DEFAULT_EMISSIVE,
|
||||
DEFAULT_OCCLUSION,
|
||||
DEFAULT_SCATTERING);
|
||||
}
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
<@include gpu/Color.slh@>
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
<@include graphics/Material.slh@>
|
||||
|
||||
<@include Fade.slh@>
|
||||
|
||||
|
|
65
libraries/render-utils/src/simple_transparent.slf
Normal file
65
libraries/render-utils/src/simple_transparent.slf
Normal file
|
@ -0,0 +1,65 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// simple_transparent.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Andrzej Kapolka on 9/15/14.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
<@include DeferredBufferWrite.slh@>
|
||||
|
||||
// the interpolated normal
|
||||
in vec3 _normal;
|
||||
in vec3 _modelNormal;
|
||||
in vec4 _color;
|
||||
in vec2 _texCoord0;
|
||||
in vec4 _position;
|
||||
|
||||
//PROCEDURAL_COMMON_BLOCK
|
||||
|
||||
#line 1001
|
||||
//PROCEDURAL_BLOCK
|
||||
|
||||
#line 2030
|
||||
void main(void) {
|
||||
vec3 normal = normalize(_normal.xyz);
|
||||
vec3 diffuse = _color.rgb;
|
||||
vec3 specular = DEFAULT_SPECULAR;
|
||||
float shininess = DEFAULT_SHININESS;
|
||||
float emissiveAmount = 0.0;
|
||||
|
||||
#ifdef PROCEDURAL
|
||||
|
||||
#ifdef PROCEDURAL_V1
|
||||
specular = getProceduralColor().rgb;
|
||||
// Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline
|
||||
//specular = pow(specular, vec3(2.2));
|
||||
emissiveAmount = 1.0;
|
||||
#else
|
||||
emissiveAmount = getProceduralColors(diffuse, specular, shininess);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
if (emissiveAmount > 0.0) {
|
||||
packDeferredFragmentTranslucent(
|
||||
normal,
|
||||
_color.a,
|
||||
specular,
|
||||
DEFAULT_FRESNEL,
|
||||
DEFAULT_ROUGHNESS);
|
||||
} else {
|
||||
packDeferredFragmentTranslucent(
|
||||
normal,
|
||||
_color.a,
|
||||
diffuse,
|
||||
DEFAULT_FRESNEL,
|
||||
DEFAULT_ROUGHNESS);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue